From 2042999895180371098e820a0f7e0449b173f873 Mon Sep 17 00:00:00 2001 From: OwnerOfJK Date: Tue, 24 Sep 2024 00:41:22 +0200 Subject: [PATCH 01/18] added join_guild function, and initialise 4 guilds upon game creation --- cairo_prompt | 14614 ++++++++++++++++ .../contracts/pixelaw-actions-16928a49.json | 775 - .../pixelaw-guild_actions-4c9f5931.json | 16 + .../pixelaw-p_war_actions-60819afd.json | 76 + .../models/pixelaw-AllowedApp-4aa27058.json | 425 - .../models/pixelaw-AllowedColor-22c1a796.json | 425 - .../abis/models/pixelaw-App-36504565.json | 415 - .../abis/models/pixelaw-AppName-3b816829.json | 407 - .../abis/models/pixelaw-AppUser-4eda3c52.json | 411 - .../abis/models/pixelaw-Board-124dc3e7.json | 429 - .../pixelaw-CoreActionsAddress-5379e1ce.json | 407 - .../abis/models/pixelaw-Game-5c1fa23f.json | 457 - .../abis/models/pixelaw-GameId-1ee8756e.json | 411 - .../models/pixelaw-GamePalette-49013f2b.json | 407 - .../abis/models/pixelaw-Guild-40e97c00.json | 433 - .../models/pixelaw-InPalette-7a46e3ad.json | 425 - .../models/pixelaw-Instruction-4c7c4844.json | 411 - .../models/pixelaw-PWarPixel-15195913.json | 421 - .../pixelaw-PaletteColors-39a92a0a.json | 411 - .../models/pixelaw-Permissions-72b77307.json | 455 - .../abis/models/pixelaw-Pixel-7e607b2f.json | 439 - .../pixelaw-PixelRecoveryRate-3aa284c0.json | 407 - .../abis/models/pixelaw-Player-30a1b371.json | 441 - .../models/pixelaw-PlayerVote-326c17c6.json | 433 - .../models/pixelaw-Proposal-49e1daf5.json | 457 - .../models/pixelaw-QueueItem-549a17f2.json | 421 - .../contracts/pixelaw-actions-16928a49.toml | 19 - .../pixelaw-guild_actions-4c9f5931.toml | 5 +- .../pixelaw-p_war_actions-60819afd.toml | 5 +- .../models/pixelaw-AllowedApp-4aa27058.toml | 22 - .../models/pixelaw-AllowedColor-22c1a796.toml | 22 - .../dev/base/models/pixelaw-App-36504565.toml | 27 - .../base/models/pixelaw-AppName-3b816829.toml | 17 - .../base/models/pixelaw-AppUser-4eda3c52.toml | 22 - .../base/models/pixelaw-Board-124dc3e7.toml | 27 - .../pixelaw-CoreActionsAddress-5379e1ce.toml | 17 - .../base/models/pixelaw-Game-5c1fa23f.toml | 67 - .../base/models/pixelaw-GameId-1ee8756e.toml | 22 - .../models/pixelaw-GamePalette-49013f2b.toml | 17 - .../base/models/pixelaw-Guild-40e97c00.toml | 37 - .../models/pixelaw-InPalette-7a46e3ad.toml | 22 - .../models/pixelaw-Instruction-4c7c4844.toml | 22 - .../models/pixelaw-PWarPixel-15195913.toml | 17 - .../pixelaw-PaletteColors-39a92a0a.toml | 22 - .../models/pixelaw-Permissions-72b77307.toml | 22 - .../base/models/pixelaw-Pixel-7e607b2f.toml | 57 - .../pixelaw-PixelRecoveryRate-3aa284c0.toml | 17 - .../base/models/pixelaw-Player-30a1b371.toml | 42 - .../models/pixelaw-PlayerVote-326c17c6.toml | 32 - .../models/pixelaw-Proposal-49e1daf5.toml | 62 - .../models/pixelaw-QueueItem-549a17f2.toml | 17 - contracts/src/lib.cairo | 8 +- contracts/src/systems/actions.cairo | 15 + contracts/src/systems/guilds.cairo | 47 +- contracts/src/systems/utils.cairo | 20 +- 55 files changed, 14767 insertions(+), 10810 deletions(-) create mode 100644 cairo_prompt delete mode 100644 contracts/manifests/dev/base/abis/contracts/pixelaw-actions-16928a49.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-AllowedApp-4aa27058.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-AllowedColor-22c1a796.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-App-36504565.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-AppName-3b816829.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-AppUser-4eda3c52.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Board-124dc3e7.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Game-5c1fa23f.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-GameId-1ee8756e.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-GamePalette-49013f2b.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Guild-40e97c00.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-InPalette-7a46e3ad.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Instruction-4c7c4844.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-PWarPixel-15195913.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-PaletteColors-39a92a0a.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Permissions-72b77307.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Pixel-7e607b2f.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Player-30a1b371.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-PlayerVote-326c17c6.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Proposal-49e1daf5.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-QueueItem-549a17f2.json delete mode 100644 contracts/manifests/dev/base/contracts/pixelaw-actions-16928a49.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-AllowedApp-4aa27058.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-AllowedColor-22c1a796.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-App-36504565.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-AppName-3b816829.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-AppUser-4eda3c52.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Board-124dc3e7.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Game-5c1fa23f.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-GameId-1ee8756e.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-GamePalette-49013f2b.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Guild-40e97c00.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-InPalette-7a46e3ad.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Instruction-4c7c4844.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-PWarPixel-15195913.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-PaletteColors-39a92a0a.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Permissions-72b77307.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Pixel-7e607b2f.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Player-30a1b371.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-PlayerVote-326c17c6.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Proposal-49e1daf5.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-QueueItem-549a17f2.toml diff --git a/cairo_prompt b/cairo_prompt new file mode 100644 index 0000000..8e055e3 --- /dev/null +++ b/cairo_prompt @@ -0,0 +1,14614 @@ +# Appendix + +The following sections contain reference material you may find useful in your +Cairo journey. +# Appendix + +The following sections contain reference material you may find useful in your +Starknet journey. +# Appendix A - Keywords + +The following list contains keywords that are reserved for current or future use by the Cairo language. + +There are three keyword categories: + +- strict +- loose +- reserved + +There is a fourth category, which are functions from the core library. While their names are not reserved, +they are not recommended to be used as names of any items to follow good practices. + +--- + +## Strict keywords + +These keywords can only be used in their correct contexts. +They cannot be used as names of any items. + +- `as` - Rename import +- `break` - Exit a loop immediately +- `const` - Define constant items +- `continue` - Continue to the next loop iteration +- `else` - Fallback for `if` and `if let` control flow constructs +- `enum` - Define an enumeration +- `extern` - Function defined at the compiler level that can be compiled to CASM +- `false` - Boolean false literal +- `fn` - Define a function +- `if` - Branch based on the result of a conditional expression +- `impl` - Implement inherent or trait functionality +- `implicits` - Special kind of function parameters that are required to perform certain actions +- `let` - Bind a variable +- `loop` - Loop unconditionally +- `match` - Match a value to patterns +- `mod` - Define a module +- `mut` - Denote variable mutability +- `nopanic` - Functions marked with this notation mean that the function will never panic. +- `of` - Implement a trait +- `pub` - Denote public visibility in items, such as struct and struct fields, enums, consts, traits and impl blocks, or modules +- `ref` - Parameter passed implicitly returned at the end of a function +- `return` - Return from function +- `struct` - Define a structure +- `trait` - Define a trait +- `true` - Boolean true literal +- `type` - Define a type alias +- `use` - Bring symbols into scope +- `while` - loop conditionally based on the result of an expression + +--- + +## Loose Keywords + +These keywords are associated with a specific behaviour, but can also be used to define items. + +- `self` - Method subject +- `super` - Parent module of the current module + +--- + +## Reserved Keywords + +These keywords aren't used yet, but they are reserved for future use. +For now, it is possible to use them to define items, although it is highly recommended not to do so. +The reasoning behind this recommendation is to make current programs forward compatible with future versions of +Cairo by forbidding them to use these keywords. + +- `Self` +- `do` +- `dyn` +- `for` +- `hint` +- `in` +- `macro` +- `move` +- `static_assert` +- `static` +- `try` +- `typeof` +- `unsafe` +- `where` +- `with` +- `yield` + +--- + +## Built-in Functions + +The Cairo programming language provides several specific functions that serve a special purpose. We will not cover all of them in this book, but using the names of these functions as names of other items is not recommended. + +- `assert` - This function checks a boolean expression, and if it evaluates to false, it triggers the panic function. +- `panic` - This function acknowledges the occurrence of an error and terminates the program. +# Appendix B - Operators and Symbols + +This appendix contains a glossary of Cairo's syntax, including operators and other symbols that appear by themselves or in the context of paths, generics, macros, attributes, comments, tuples, and brackets. + +## Operators + +Table B-1 contains the operators in Cairo, an example of how the operator would appear in context, a short explanation, and whether that operator is overloadable. If an operator is overloadable, the relevant trait to use to overload that operator is listed. + +| Operator | Example | Explanation | Overloadable? | +| ------------------------- | ------------------------------------------------------- | ---------------------------------------- | ------------- | +| `!` | `!expr` | Logical complement | `Not` | +| `~` | `~expr` | Bitwise NOT | `BitNot` | +| `!=` | `expr != expr` | Non-equality comparison | `PartialEq` | +| `%` | `expr % expr` | Arithmetic remainder | `Rem` | +| `%=` | `var %= expr` | Arithmetic remainder and assignment | `RemEq` | +| `&` | `expr & expr` | Bitwise AND | `BitAnd` | +| `&&` | `expr && expr` | Short-circuiting logical AND | | +| `*` | `expr * expr` | Arithmetic multiplication | `Mul` | +| `*=` | `var *= expr` | Arithmetic multiplication and assignment | `MulEq` | +| `@` | `@var` | Snapshot | | +| `*` | `*var` | Desnap | | +| `+` | `expr + expr` | Arithmetic addition | `Add` | +| `+=` | `var += expr` | Arithmetic addition and assignment | `AddEq` | +| `,` | `expr, expr` | Argument and element separator | | +| `-` | `-expr` | Arithmetic negation | `Neg` | +| `-` | `expr - expr` | Arithmetic subtraction | `Sub` | +| `-=` | `var -= expr` | Arithmetic subtraction and assignment | `SubEq` | +| `->` | `fn(...) -> type`, |...| -> type | Function and closure return type | | +| `.` | `expr.ident` | Member access | | +| `/` | `expr / expr` | Arithmetic division | `Div` | +| `/=` | `var /= expr` | Arithmetic division and assignment | `DivEq` | +| `:` | `pat: type`, `ident: type` | Constraints | | +| `:` | `ident: expr` | Struct field initializer | | +| `;` | `expr;` | Statement and item terminator | | +| `<` | `expr < expr` | Less than comparison | `PartialOrd` | +| `<=` | `expr <= expr` | Less than or equal to comparison | `PartialOrd` | +| `=` | `var = expr` | Assignment | | +| `==` | `expr == expr` | Equality comparison | `PartialEq` | +| `=>` | `pat => expr` | Part of match arm syntax | | +| `>` | `expr > expr` | Greater than comparison | `PartialOrd` | +| `>=` | `expr >= expr` | Greater than or equal to comparison | `PartialOrd` | +| `^` | `expr ^ expr` | Bitwise exclusive OR | `BitXor` | +| | | expr | expr | Bitwise OR | `BitOr` | +| || | expr || expr | Short-circuiting logical OR | | +| `?` | expr? | Error propagation | + +Table B-1: Operators + +## Non Operator Symbols + +The following list contains all symbols that are not used as operators; that is, they do not have the same behavior as a function or method call. + +Table B-2 shows symbols that appear on their own and are valid in a variety of locations. + +| Symbol | Explanation | +| --------------------------------------- | ----------------------------------------- | +| `..._u8`, `..._usize`, `..._bool`, etc. | Numeric literal of specific type | +| `"..."` | String literal | +| `'...'` | Short string, 31 ASCII characters maximum | +| `_` | “Ignored” pattern binding | + +Table B-2: Stand-Alone Syntax + +Table B-3 shows symbols that are used within the context of a module hierarchy path to access an item. + +| Symbol | Explanation | +| -------------------- | ---------------------------------------------------------------- | +| `ident::ident` | Namespace path | +| `super::path` | Path relative to the parent of the current module | +| `trait::method(...)` | Disambiguating a method call by naming the trait that defines it | + +Table B-3: Path-Related Syntax + +Table B-4 shows symbols that appear in the context of using generic type parameters. + +| Symbol | Explanation | +| ------------------------------ | ------------------------------------------------------------------------------------------------------------ | +| `path<...>` | Specifies parameters to generic type in a type (e.g., `Array`) | +| `path::<...>`, `method::<...>` | Specifies parameters to a generic type, function, or method in an expression; often referred to as turbofish | +| `fn ident<...> ...` | Define generic function | +| `struct ident<...> ...` | Define generic structure | +| `enum ident<...> ...` | Define generic enumeration | +| `impl<...> ...` | Define generic implementation | + +Table B-4: Generics + +Table B-5 shows symbols that appear in the context of specifying attributes on an item. + +| Symbol | Explanation | +| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | +| `#[derive(...)]` | Automatically implements a trait for a type | +| `#[inline]` | Hint to the compiler to allow inlining of annotated function | +| `#[inline(always)]` | Hint to the compiler to systematically inline annotated function | +| `#[inline(never)]` | Hint to the compiler to never inline annotated function | +| `#[must_use]` | Hint to the compiler that the return value of a function or a specific returned type must be used | +| `#[generate_trait]` | Automatically generates a trait for an impl | +| `#[available_gas(...)]` | Set the maximum amount of gas available to execute a function | +| `#[panic_with('...', wrapper_name)]` | Creates a wrapper for the annotated function which will panic if the function returns `None` or `Err`, with the given data as the panic error | +| `#[test]` | Describe a function as a test function | +| `#[cfg(...)]` | Configuration attribute, especially used to configure a `tests` module with `#[cfg(test)]` | +| `#[should_panic]` | Specifies that a test function should necessarily panic | +| `#[starknet::contract]` | Defines a Starknet smart contract | +| `#[starknet::interface]` | Defines a Starknet interface | +| `#[starknet::component]` | Defines a Starknet component | +| `#[starknet::embeddable]` | Defines an isolated embeddable implementation that can be injected in any smart contract | +| `#[embeddable_as(...)]` | Defines an embeddable implementation inside a component | +| `#[storage]` | Defines the storage of a smart contract | +| `#[event]` | Defines an event in a smart contract | +| `#[constructor]` | Defines the constructor in a smart contract | +| `#[abi(embed_v0)]` | Defines an implementation of a trait, exposing the functions of the impl as entrypoints of a contract | +| `#[abi(per_item)]` | Allows individual definition of the entrypoint type of functions inside an impl | +| `#[external(v0)]` | Defines an external function when `#[abi(per_item)]` is used | +| `#[flat]` | Defines a enum variant of the `Event` enum that is not nested, ignoring the variant name in the serialization process, very useful for composability when using Starknet components | +| `#[key]` | Defines an indexed `Event` enum field, allowing for more efficient queries and filtering of events | + +Table B-5: Attributes + +Table B-6 shows symbols that appear in the context of calling or defining macros. + +| Symbol | Explanation | +| ------------------------ | -------------------------------------------------------------------------------------- | +| `print!` | Inline printing | +| `println!` | Print on a new line | +| `consteval_int!` | Declare a constant that is the result of a computation of integers | +| `array!` | Instantiate and fill arrays | +| `panic!` | Calls `panic` function and allows to provide a message error longer than 31 characters | +| `assert!` | Evaluates a Boolean and panics if `false` | +| `assert_eq!` | Evaluates an equality, and panics if not equal | +| `assert_ne!` | Evaluates an equality, and panics if equal | +| `assert_lt!` | Evaluates a comparison, and panics if greater or equal | +| `assert_le!` | Evaluates a comparison, and panics if greater | +| `assert_gt!` | Evaluates a comparison, and panics if lower or equal | +| `assert_ge!` | Evaluates a comparison, and panics if lower | +| `format!` | Format a string and returns a `ByteArray` with the contents | +| `write!` | Write formatted strings in a formatter | +| `writeln!` | Write formatted strings in a formatter on a new line | +| `get_dep_component!` | Returns the requested component state from a snapshot of the state inside a component | +| `get_dep_component_mut!` | Returns the requested component state from a reference of the state inside a component | +| `component!` | Macro used in Starknet contracts to embed a component inside a contract | + + +Table B-6: Macros + +Table B-7 shows symbols that create comments. + +| Symbol | Explanation | +| ------ | ------------ | +| `//` | Line comment | + +Table B-7: Comments + +Table B-8 shows symbols that appear in the context of using tuples. + +| Symbol | Explanation | +| ----------------- | ------------------------------------------------------------------------------------------- | +| `()` | Empty tuple (aka unit), both literal and type | +| `(expr)` | Parenthesized expression | +| `(expr,)` | Single-element tuple expression | +| `(type,)` | Single-element tuple type | +| `(expr, ...)` | Tuple expression | +| `(type, ...)` | Tuple type | +| `expr(expr, ...)` | Function call expression; also used to initialize tuple `struct`s and tuple `enum` variants | + +Table B-8: Tuples + +Table B-9 shows the contexts in which curly braces are used. + +| Context | Explanation | +| ------------ | ---------------- | +| `{...}` | Block expression | +| `Type {...}` | `struct` literal | + +Table B-9: Curly Braces +# Appendix C - Derivable Traits + +In various places in the book, we’ve discussed the `derive` attribute, which you can apply to a struct or enum definition. The `derive` attribute generates code to implement a default trait on the type you’ve annotated with the `derive` syntax. + +In this appendix, we provide a comprehensive reference detailing all the traits in the standard library compatible with the `derive` attribute. + +These traits listed here are the only ones defined by the core library that can be implemented on your types using `derive`. Other traits defined in the standard library don’t have sensible default behavior, so it’s up to you to implement them in a way that makes sense for what you’re trying to accomplish. + +## Drop and Destruct + +When moving out of scope, variables need to be moved first. This is where the `Drop` trait intervenes. You can find more details about its usage [here](ch04-01-what-is-ownership.md#no-op-destruction-the-drop-trait). + +Moreover, Dictionaries need to be squashed before going out of scope. Calling the `squash` method on each of them manually can quickly become redundant. `Destruct` trait allows Dictionaries to be automatically squashed when they get out of scope. You can also find more information about `Destruct` [here](ch04-01-what-is-ownership.md#destruction-with-a-side-effect-the-destruct-trait). + +## `Clone` and `Copy` for Duplicating Values + +The `Clone` trait provides the functionality to explicitly create a deep copy of a value. + +Deriving `Clone` implements the `clone` method, which, in turn, calls clone on each of the type's components. This means all the fields or values in the type must also implement `Clone` to derive `Clone`. + +Here is a simple example: + +```rust +#[derive(Clone, Drop)] +struct A { + item: felt252 +} + +fn main() { + let first_struct = A { item: 2 }; + let second_struct = first_struct.clone(); + assert!(second_struct.item == 2, "Not equal"); +} +``` + +The `Copy` trait allows for the duplication of values. You can derive `Copy` on any type whose parts all implement `Copy`. + +Example: + +```rust +#[derive(Copy, Drop)] +struct A { + item: felt252 +} + +fn main() { + let first_struct = A { item: 2 }; + let second_struct = first_struct; + // Copy Trait prevents first_struct from moving into second_struct + assert!(second_struct.item == 2, "Not equal"); + assert!(first_struct.item == 2, "Not Equal"); +} +``` + +## `Debug` for Printing and Debugging + +The `Debug` trait enables debug formatting in format strings, which you indicate by adding `:?` within `{}` placeholders. + +It allows you to print instances of a type for debugging purposes, so you and other programmers using this type can inspect an instance at a particular point in a program’s execution. + +For example, if you want to print the value of a variable of type `Point`, you can do it as follows: + +```rust +#[derive(Copy, Drop, Debug)] +struct Point { + x: u8, + y: u8 +} + +fn main() { + let p = Point { x: 1, y: 3 }; + println!("{:?}", p); +} +``` + +```shell +scarb cairo-run +Point { x: 1, y: 3 } +``` + +The `Debug` trait is required, for example, when using the `assert_xx!` macros in tests. Theses macros print the values of instances given as arguments if the equality or comparison assertion fails so programmers can see why the two instances weren’t equal. + +## `Default` for Default Values + +The `Default` trait allows creation of a default value of a type. The most common default value is zero. All primitive types in the standard library implement `Default`. + +If you want to derive `Default` on a composite type, each of its elements must already implement `Default`. If you have an [`enum`](ch06-01-enums.md) type, you must declare its default value by using the `#[default]` attribute on one of its variants. + +An example: + +```rust +#[derive(Default, Drop)] +struct A { + item1: felt252, + item2: u64 +} + +#[derive(Default, Drop, PartialEq)] +enum CaseWithDefault { + A: felt252, + B: u128, + #[default] + C: u64, +} + +fn main() { + let defaulted: A = Default::default(); + assert!(defaulted.item1 == 0_felt252, "item1 mismatch"); + assert!(defaulted.item2 == 0_u64, "item2 mismatch"); + + let default_case: CaseWithDefault = Default::default(); + assert!(default_case == CaseWithDefault::C(0_u64), "case mismatch"); +} +``` + +## `PartialEq` for Equality Comparisons + +The `PartialEq` trait allows for comparison between instances of a type for equality, thereby enabling the `==` and `!=` operators. + +When `PartialEq` is derived on structs, two instances are equal only if all their fields are equal; they are not equal if any field is different. When derived for enums, each variant is equal to itself and not equal to the other variants. + +You can write your own implementation of the `PartialEq` trait for your type, if you can't derive it or if you want to implement your custom rules. In the following example, we write an implementation for `PartialEq` in which we consider that two rectangles are equal if they have the same area: + +```rust +#[derive(Copy, Drop)] +struct Rectangle { + width: u64, + height: u64, +} + +impl PartialEqImpl of PartialEq { + fn eq(lhs: @Rectangle, rhs: @Rectangle) -> bool { + (*lhs.width) * (*lhs.height) == (*rhs.width) * (*rhs.height) + } + + fn ne(lhs: @Rectangle, rhs: @Rectangle) -> bool { + (*lhs.width) * (*lhs.height) != (*rhs.width) * (*rhs.height) + } +} + +fn main() { + let rect1 = Rectangle { width: 30, height: 50 }; + let rect2 = Rectangle { width: 50, height: 30 }; + + println!("Are rect1 and rect2 equal? {}", rect1 == rect2); +} +``` + +The `PartialEq` trait is required when using the `assert_eq!` macro in tests, which needs to be able to compare two instances of a type for equality. + +Here is an example: + +```rust +#[derive(PartialEq, Drop)] +struct A { + item: felt252 +} + +fn main() { + let first_struct = A { item: 2 }; + let second_struct = A { item: 2 }; + assert!(first_struct == second_struct, "Structs are different"); +} +``` + +## Serializing with `Serde` + +`Serde` provides trait implementations for `serialize` and `deserialize` functions for data structures defined in your crate. It allows you to transform your structure into an array (or the opposite). + +> **[Serialization](https://en.wikipedia.org/wiki/Serialization)** is a process of transforming data structures into a format that can be easily stored or transmitted. Let's say you are running a program and would like to persist its state to be able to resume it later. To do this, you could take each of the objects your program is using and save their information, for example in a file. This is a simplified version of serialization. Now if you want to resume your program with this saved state, you would perform **deserialization**, which means loading the state of the objects from the saved source. + +For example: + +```rust +#[derive(Serde, Drop)] +struct A { + item_one: felt252, + item_two: felt252, +} + +fn main() { + let first_struct = A { item_one: 2, item_two: 99, }; + let mut output_array = array![]; + let serialized = first_struct.serialize(ref output_array); + panic(output_array); +} + +``` + +If you run the `main` function, the output will be: + +```shell +Run panicked with [2, 99 ('c'), ]. +``` + +We can see here that our struct `A` has been serialized into the output array. Note that the `serialize` function takes as argument a snapshot of the type you want to convert into an array. This is why deriving `Drop` for `A` is required here, as the `main` function keeps ownership of the `first_struct` struct. + +Also, we can use the `deserialize` function to convert the serialized array back into our `A` struct. + +Here is an example: + +```rust +#[derive(Serde, Drop)] +struct A { + item_one: felt252, + item_two: felt252, +} + +fn main() { + let first_struct = A { item_one: 2, item_two: 99, }; + let mut output_array = array![]; + let mut serialized = first_struct.serialize(ref output_array); + let mut span_array = output_array.span(); + let deserialized_struct: A = Serde::::deserialize(ref span_array).unwrap(); +} +``` + +Here we are converting a serialized array span back to the struct `A`. `deserialize` returns an `Option` so we need to unwrap it. When using `deserialize` we also need to specify the type we want to deserialize into. + +## Hashing with `Hash` + +It is possible to derive the `Hash` trait on structs and enums. This allows them to be hashed easily using any available hash function. For a struct or an enum to derive the `Hash` attribute, all fields or variants need to be hashable themselves. + +You can refer to the [Hashes section](ch11-04-hash.md) to get more information about how to hash complex data types. + +## Starknet Storage with `starknet::Store` + +The `starknet::Store` trait is relevant only when building on [Starknet](ch13-00-introduction-to-starknet-smart-contracts.md). It allows for a type to be used in smart contract storage by automatically implementing the necessary read and write functions. + +You can find detailed information about the inner workings of Starknet storage in the [Contract storage section](ch14-01-contract-storage.md). +# Appendix D - The Cairo Prelude + +## Prelude + +The Cairo prelude is a collection of commonly used modules, functions, data +types, and traits that are automatically brought into scope of every module in a +Cairo crate without needing explicit import statements. Cairo's prelude provides +the basic building blocks developers need to start Cairo programs and writing +smart contracts. + +The core library prelude is defined in the _[lib.cairo](https://github.com/starkware-libs/cairo/blob/main/corelib/src/lib.cairo)_ +file of the corelib crate and contains Cairo's primitive data types, traits, +operators, and utility functions. This includes: + +- Data types: integers, bools, arrays, dicts, etc. +- Traits: behaviors for arithmetic, comparison, and serialization operations +- Operators: arithmetic, logical, bitwise +- Utility functions - helpers for arrays, maps, boxing, etc. + +The core library prelude delivers the fundamental programming +constructs and operations needed for basic Cairo programs, without requiring the +explicit import of elements. Since the core library prelude is automatically +imported, its contents are available for use in any Cairo crate without explicit +imports. This prevents repetition and provides a better devX. This is what +allows you to use `ArrayTrait::append()` or the `Default` trait without bringing +them explicitly into scope. + +You can choose which prelude to use. For example, adding `edition = "2023_11"` in the _Scarb.toml_ configuration file will load the prelude from November 2023. Note that when you create a new project using `scarb new` command, the _Scarb.toml_ file will automatically include `edition = "2023_11"`. + +The compiler currently exposes 2 different versions of the prelude: + +- A general version, with a lot of traits that are made available, corresponding to `edition = "2023_01"`. +- A restricted version, including the most essential traits needed for general Cairo programming, corresponding to `edition = 2023_11`. +# Appendix E - Common Error Messages + +You might encounter error messages when writing Cairo code. Some of them occur very frequently, which is why we will be listing the most common error messages in this appendix to help you resolve common issues. + +- `Variable not dropped.`: this error message means that you are trying to make a variable with a type that do not implement the `Drop` trait go out of scope, withtout destroying it. Make sure that variables that need to be dropped at the end of the execution of a function implement the `Drop` trait or the `Destruct` trait. See [Ownership](ch04-01-what-is-ownership.md#destroying-values---example-with-feltdict) section. + +- `Variable was previously moved.`: this error message means that you are trying to use a variable whose ownership has already been transferred to another function. When a variable doesn't implement the `Copy` trait, it is passed by value to functions, and ownership of the variable is transferred to the function. Such a variable cannot be used anymore in the current context after its ownership has been transferred. It is often useful to use the `clone` method in this situation. + +- `error: Trait has no implementation in context: core::fmt::Display::`: this error message is encountered if you try to print an instance of a custom data type with `{}` placeholders in a `print!` or `println!` macro. To mitigate this issue, you need to either manually implement the `Display` trait for your type, or use the `Debug` trait by applying `derive(Debug)` to your type, allowing to print your instance by adding `:?` in `{}` placeholders. + +- `Got an exception while executing a hint: Hint Error: Failed to deserialize param #x.`: this error means that the execution failed because an entrypoint was called without the expected arguments. Make sure that the arguments you provide when calling an entrypoint are correct. There is a classic issue with `u256` variables, which are actually structs of 2 `u128`. Therefore, when calling a function that takes a `u256` as argument, you need to pass 2 values. + +- `Item path::item is not visible in this context.`: this error message lets us know that the path to bring an item into scope is correct, but there is a vibility issue. In cairo, all items are private to parent modules by default. To resolve this issue, make sure that all the modules on the path to items and items themselves are declared with `pub(crate)` or `pub` to have access to them. + +- `Identifier not found.`: this error message is a bit aspecific but might indicate that: + - A variable is being used before it has been declared. Make sure to declare variables with the `let` keyword. + - The path to bring an item into scope is wrongly defined. Make sure to use valid paths. + +## Starknet Components Related Error Messages + +You might encounter some errors when trying to implement components. +Unfortunately, some of them lack meaningful error messages to help debug. This +section aims to provide you with some pointers to help you debug your code. + +- `Trait not found. Not a trait.`: this error can occur when you're not importing the component's impl block + correctly in your contract. Make sure to respect the following syntax: + + ```rust,noplayground + #[abi(embed_v0)] + impl IMPL_NAME = PATH_TO_COMPONENT::EMBEDDED_NAME + ``` + +- `Plugin diagnostic: name is not a substorage member in the contract's Storage. Consider adding to Storage: (...)`: the compiler helps you a lot debugging this by giving you recommendation on the action to take. Basically, you forgot to add the component's storage to your contract's storage. Make sure to add the path to the component's storage annotated with the `#[substorage(v0)]` attribute to your contract's storage. + +- `Plugin diagnostic: name is not a nested event in the contract's Event enum. Consider adding to the Event enum:` similar to the previous error, the compiler tells you that you forgot to add the component's events to your contract's events. Make sure to add the path to the component's events to your contract's events. +# Appendix F - Useful Development Tools + +In this appendix, we talk about some useful development tools that the Cairo +project provides. We’ll look at automatic formatting, quick ways to apply +warning fixes, a linter, and integrating with IDEs. + +## Automatic Formatting with `scarb fmt` + +Scarb projects can be formatted using the `scarb fmt` command. +If you're using the Cairo binaries directly, you can run `cairo-format` instead. +Many collaborative projects use `scarb fmt` to prevent arguments about which +style to use when writing Cairo: everyone formats their code using the tool. + +To format any Cairo project, enter the following inside the project directory: + +```bash +scarb fmt +``` + +## IDE Integration Using `cairo-language-server` + +To help IDE integration, the Cairo community recommends using the +[`cairo-language-server`][cairo-language-server]. This tool is a set of +compiler-centric utilities that speaks the [Language Server Protocol][lsp], which is a specification for IDEs and programming languages to +communicate with each other. Different clients can use `cairo-language-server`, such as +[the Cairo extension for Visual Studio Code][vscode-cairo]. + +[lsp]: http://langserver.org/ +[vscode-cairo]: https://marketplace.visualstudio.com/items?itemName=starkware.cairo1 + +Visit the `vscode-cairo` [page][vscode-cairo] +to install it on VSCode. You will get abilities such as autocompletion, jump to +definition, and inline errors. + +[cairo-language-server]: https://github.com/starkware-libs/cairo/tree/main/crates/cairo-lang-language-server + +> Note: If you have Scarb installed, it should work out of the box with the Cairo VSCode extension, without a manual installation of the language server. +# Appendix G - Installing the Cairo Binaries + +If you want to have access to the Cairo binaries, for anything that you could not achieve by purely using Scarb you can install them by following the instructions below. + +### Prerequisites + +You will need to have [Rust](https://www.rust-lang.org) and [Git](https://git-scm.com/) installed. + +To install Rust, you first need the [`rustup`](https://www.rust-lang.org/tools/install) tool. It allows you to install Rust using the following command: +```bash +# Install stable Rust +rustup override set stable && rustup update +``` + +Follow the link for information on how to install [Git](https://git-scm.com/downloads). + +The next step is to install Cairo. We will download Cairo manually, using Cairo repository or with an installation script. You’ll need an internet connection for the download. + +## Installing Cairo with a Script ([Installer](https://github.com/franalgaba/cairo-installer) by [Fran](https://github.com/franalgaba)) + +### Install + +If you wish to install a specific release of Cairo rather than the latest head, set the `CAIRO_GIT_TAG` environment variable (e.g. `export CAIRO_GIT_TAG=v2.5.1`). + +```bash +curl -L https://github.com/franalgaba/cairo-installer/raw/main/bin/cairo-installer | bash +``` + +After installing, follow [these instructions](#set-up-your-shell-environment-for-cairo) to set up your shell environment. + +### Update + +``` +rm -fr ~/.cairo +curl -L https://github.com/franalgaba/cairo-installer/raw/main/bin/cairo-installer | bash +``` + +### Uninstall + +Cairo is installed within `$CAIRO_ROOT` (default: ~/.cairo). To uninstall, just remove it: + +```bash +rm -fr ~/.cairo +``` + +then remove these three lines from .bashrc: + +```bash +export PATH="$HOME/.cairo/target/release:$PATH" +``` + +and finally, restart your shell: + +```bash +exec $SHELL +``` + +### Set Up your Shell Environment for Cairo + +- Define environment variable `CAIRO_ROOT` to point to the path where + Cairo will store its data. `$HOME/.cairo` is the default. + If you installed Cairo via Git checkout, we recommend + to set it to the same location as where you cloned it. +- Add the `cairo-*` executables to your `PATH` if it's not already there + +The below setup should work for the vast majority of users for common use cases. + +- For **bash**: + + Stock Bash startup files vary widely between distributions in which of them source + which, under what circumstances, in what order and what additional configuration they perform. + As such, the most reliable way to get Cairo in all environments is to append Cairo + configuration commands to both `.bashrc` (for interactive shells) + and the profile file that Bash would use (for login shells). + + First, add the commands to `~/.bashrc` by running the following in your terminal: + + ```bash + echo 'export CAIRO_ROOT="$HOME/.cairo"' >> ~/.bashrc + echo 'command -v cairo-compile >/dev/null || export PATH="$CAIRO_ROOT/target/release:$PATH"' >> ~/.bashrc + ``` + + Then, if you have `~/.profile`, `~/.bash_profile` or `~/.bash_login`, add the commands there as well. + If you have none of these, add them to `~/.profile`. + + - to add to `~/.profile`: + + ```bash + echo 'export CAIRO_ROOT="$HOME/.cairo"' >> ~/.profile + echo 'command -v cairo-compile >/dev/null || export PATH="$CAIRO_ROOT/target/release:$PATH"' >> ~/.profile + ``` + + - to add to `~/.bash_profile`: + ```bash + echo 'export CAIRO_ROOT="$HOME/.cairo"' >> ~/.bash_profile + echo 'command -v cairo-compile >/dev/null || export PATH="$CAIRO_ROOT/target/release:$PATH"' >> ~/.bash_profile + ``` + +- For **Zsh**: + + ```zsh + echo 'export CAIRO_ROOT="$HOME/.cairo"' >> ~/.zshrc + echo 'command -v cairo-compile >/dev/null || export PATH="$CAIRO_ROOT/target/release:$PATH"' >> ~/.zshrc + ``` + + If you wish to get Cairo in non-interactive login shells as well, also add the commands to `~/.zprofile` or `~/.zlogin`. + +- For **Fish shell**: + + If you have Fish 3.2.0 or newer, execute this interactively: + + ```fish + set -Ux CAIRO_ROOT $HOME/.cairo + fish_add_path $CAIRO_ROOT/target/release + ``` + + Otherwise, execute the snippet below: + + ```fish + set -Ux CAIRO_ROOT $HOME/.cairo + set -U fish_user_paths $CAIRO_ROOT/target/release $fish_user_paths + ``` + +In MacOS, you might also want to install [Fig](https://fig.io/) which +provides alternative shell completions for many command line tools with an +IDE-like popup interface in the terminal window. +(Note that their completions are independent of Cairo's codebase +so they might be slightly out of sync for bleeding-edge interface changes.) + +### Restart your Shell + +for the `PATH` changes to take effect. + +```sh +exec "$SHELL" +``` + +## Installing Cairo Manually ([Guide](https://github.com/auditless/cairo-template) by [Abdel](https://github.com/abdelhamidbakhta)) + +### Step 1: Install Cairo 1.0 + +If you are using an x86 Linux system and can use the release binary, download Cairo here: . + +For everyone else, we recommend compiling Cairo from source as follows: + +```bash +# Start by defining environment variable CAIRO_ROOT +export CAIRO_ROOT="${HOME}/.cairo" + +# Create .cairo folder if it doesn't exist yet +mkdir $CAIRO_ROOT + +# Clone the Cairo compiler in $CAIRO_ROOT (default root) +cd $CAIRO_ROOT && git clone git@github.com:starkware-libs/cairo.git . + +# OPTIONAL/RECOMMENDED: If you want to install a specific version of the compiler +# Fetch all tags (versions) +git fetch --all --tags +# View tags (you can also do this in the Cairo compiler repository) +git describe --tags `git rev-list --tags` +# Checkout the version you want +git checkout tags/v2.5.1 + +# Generate release binaries +cargo build --all --release +``` + +. + +**NOTE: Keeping Cairo up to date** + +Now that your Cairo compiler is in a cloned repository, all you will need to do +is pull the latest changes and rebuild as follows: + +```bash +cd $CAIRO_ROOT && git fetch && git pull && cargo build --all --release +``` + +### Step 2: Add Cairo 1.0 Executables to Your Path + +```bash +export PATH="$CAIRO_ROOT/target/release:$PATH" +``` + +**NOTE: If installing from a Linux binary, adapt the destination path accordingly.** + +### Step 3: Setup Language Server + +#### VS Code Extension + +- If you have the previous Cairo 0 extension installed, you can disable/uninstall it. +- Install the Cairo 1 extension for proper syntax highlighting and code navigation. You can find the link to the extension [here](https://marketplace.visualstudio.com/items?itemName=starkware.cairo1&ssr=false), or just search for "Cairo 1.0" in the VS Code marketplace. +- The extension will work out of the box once you will have [Scarb](./ch01-03-hello-scarb.md) installed. + +#### Cairo Language Server without Scarb + +If you don't want to depend on Scarb, you can still use the Cairo Language Server with the compiler binary. +From [Step 1](#installing-cairo-with-a-script-installer-by-fran), the `cairo-language-server` binary should be built and executing this command will copy its path into your clipboard. + +```bash +which cairo-language-server | pbcopy +``` + +Update the `cairo1.languageServerPath` of the Cairo 1.0 extension by pasting the path. +# Appendix A - System Calls + +This chapter is based on the StarkNet documentation available at [StarkNet Docs](https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/system-calls-cairo1/). + +Writing smart contracts requires various associated operations, such as calling another contract or accessing the contract’s storage, that standalone programs do not require. + +The Starknet contract language supports these operations by using system calls. System calls enable a contract to require services from the Starknet OS. You can use system calls in a function to get information that depends on the broader state of Starknet, which would otherwise be inaccessible, rather than local variables that appear in the function’s scope. + +Here is a list of the system calls available in Cairo 1.0: + +- [get_block_hash](#get_block_hash) +- [get_execution_info](#get_execution_info) +- [call_contract](#call_contract) +- [deploy](#deploy) +- [emit_event](#emit_event) +- [library_call](#library_call) +- [send_message_to_L1](#send_message_to_l1) +- [replace_class](#replace_class) +- [storage_read](#storage_read) +- [storage_write](#storage_write) + +## `get_block_hash` + +#### Syntax + +```rust +extern fn get_block_hash_syscall( + block_number: u64 +) -> SyscallResult implicits(GasBuiltin, System) nopanic; +``` + +#### Description + +Gets the hash of a specific StarkNet block within the range of `[first_v0_12_0_block, current_block - 10]`. + +#### Return Values + +Returns the hash of the given block. + +#### Error Messages + +- `Block number out of range`: `block_number` is greater than _`current_block`_`- 10`. +- `0`: `block_number` is less than the first block number of v0.12.0. + +#### Common Library + +- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/0c882679fdb24a818cad19f2c18decbf6ef66153/corelib/src/starknet/syscalls.cairo#L37) + +## `get_execution_info` + +#### Syntax + +```rust +extern fn get_execution_info_syscall() -> SyscallResult> implicits( + GasBuiltin, System +) nopanic; +``` + +#### Description + +Gets information about the original transaction. + +In Cairo 1.0, all block/transaction/execution context getters are batched into this single system call. + +#### Arguments + +None. + +#### Return Values + +Returns a [struct](https://github.com/starkware-libs/cairo/blob/efbf69d4e93a60faa6e1363fd0152b8fcedbb00a/corelib/src/starknet/info.cairo#L8) containing the execution info. + +#### Common Library + +- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L35) + +## `call_contract` + +#### Syntax + +```rust +extern fn call_contract_syscall( + address: ContractAddress, entry_point_selector: felt252, calldata: Span +) -> SyscallResult> implicits(GasBuiltin, System) nopanic; +``` + +#### Description + +Calls a given contract. This system call expects the address of the called contract, a selector for a function within that contract, and call arguments. + +> **Note:** +> +> An internal call can’t return Err(\_) as this is not handled by the sequencer and the Starknet OS. +> +> If call_contract_syscall fails, this can’t be caught and will therefore result in the entire transaction being reverted. + +#### Arguments + +- _`address`_: The address of the contract you want to call. +- _`entry_point_selector`_: A selector for a function within that contract, can be computed with the `selector!` macro. +- _`calldata`_: The calldata array. + +#### Return Values + +The call response, of type `SyscallResult>`. + +#### Common Library + +- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L10) + +> **Note:** +> This is considered a lower-level syntax for calling contracts. +> If the interface of the called contract is available, then you can use a more straightforward syntax. + +## `deploy` + +#### Syntax + +```rust +extern fn deploy_syscall( + class_hash: ClassHash, + contract_address_salt: felt252, + calldata: Span, + deploy_from_zero: bool, +) -> SyscallResult<(ContractAddress, Span::)> implicits(GasBuiltin, System) nopanic; +``` + +#### Description + +Deploys a new instance of a previously declared class. + +#### Arguments + +- _`class_hash`_: The class hash of the contract to be deployed. +- _`contract_address_salt`_: The salt, an arbitrary value provided by the sender. It is used in the computation of the contract’s address. +- _`calldata`_: The constructor’s calldata. An array of felts. +- _`deploy_from_zero`_: A flag used for the contract address computation. If not set, the caller address will be used as the new contract’s deployer address, otherwise 0 is used. + +#### Return Values + +A tuple wrapped with SyscallResult where: + +- The first element is the address of the deployed contract, of type `ContractAddress`. + +- The second element is the response array from the contract’s constructor, of type `Span::`. + +#### Common Library + +- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/4821865770ac9e57442aef6f0ce82edc7020a4d6/corelib/src/starknet/syscalls.cairo#L22) + +## `emit_event` + +#### Syntax + +```rust +extern fn emit_event_syscall( + keys: Span, data: Span +) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; +``` + +#### Description + +Emits an event with a given set of keys and data. + +For more information and a higher-level syntax for emitting events, see [Starknet events](https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/starknet-events/). + +#### Arguments + +- _`keys`_: The event’s keys. These are analogous to Ethereum’s event topics, you can use the starknet_getEvents method to filter by these keys. + +- _`data`_: The event’s data. + +#### Return Values + +None. + +#### Example + +The following example emits an event with two keys, the strings `status` and `deposit` and three data elements: `1`, `2`, and `3`. + +```rust +let keys = ArrayTrait::new(); +keys.append('key'); +keys.append('deposit'); +let values = ArrayTrait::new(); +values.append(1); +values.append(2); +values.append(3); +emit_event_syscall(keys, values).unwrap_syscall(); +``` + +#### Common Library + +- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L30) + +## `library_call` + +#### Syntax + +```rust +extern fn library_call_syscall( + class_hash: ClassHash, function_selector: felt252, calldata: Span +) -> SyscallResult> implicits(GasBuiltin, System) nopanic; +``` + +#### Description + +Calls the requested function in any previously declared class. The class is only used for its logic. + +This system call replaces the known delegate call functionality from Ethereum, with the important difference that there is only one contract involved. + +#### Arguments + +- _`class_hash`_: The hash of the class you want to use. + +- _`function_selector`_: A selector for a function within that class, can be computed with the `selector!` macro. + +- _`calldata`_: The calldata. + +#### Return Values + +The call response, of type `SyscallResult>`. + +#### Common Library + +- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L43) + +## `send_message_to_L1` + +#### Syntax + +```rust +extern fn send_message_to_l1_syscall( + to_address: felt252, payload: Span +) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; +``` + +#### Description + +Sends a message to L1. + +This system call includes the message parameters as part of the proof’s output and exposes these parameters to the `StarknetCore` contract on L1 once the state update, including the transaction, is received. + +For more information, see Starknet’s [messaging mechanism](https://docs.starknet.io/documentation/architecture_and_concepts/Network_Architecture/messaging-mechanism/). + +#### Arguments + +- _`to_address`_: The recipient’s L1 address. + +- _`payload`_: The array containing the message payload. + +#### Return Values + +None. + +#### Example + +The following example sends a message whose content is `(1,2)` to the L1 contract whose address is `3423542542364363`. + +```rust +let payload = ArrayTrait::new(); +payload.append(1); +payload.append(2); +send_message_to_l1_syscall(payload).unwrap_syscall(); +``` + +#### Common Library + +- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L51) + +## `replace_class` + +#### Syntax + +```rust +extern fn replace_class_syscall( + class_hash: ClassHash +) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; +``` + +#### Description + +Once `replace_class` is called, the class of the calling contract (i.e. the contract whose address is returned by `get_contract_address` at the time the syscall is called) will be replaced by the class whose hash is given by the class_hash argument. + +> **Note:** +> +> After calling `replace_class`, the code currently executing from the old class will finish running. +> +> The new class will be used from the next transaction onwards or if the contract is called via the `call_contract` syscall in the same transaction (after the replacement). + +#### Arguments + +- _`class_hash`_: The hash of the class you want to use as a replacement. + +#### Return Values + +None. + +#### Common Library + +- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L77) + +## `storage_read` + +#### Syntax + +```rust +extern fn storage_read_syscall( + address_domain: u32, address: StorageAddress, +) -> SyscallResult implicits(GasBuiltin, System) nopanic; +``` + +#### Description + +Gets the value of a key in the storage of the calling contract. + +This system call provides direct access to any possible key in storage, in contrast with `var.read()`, which enables you to read storage variables that are defined explicitly in the contract. + +For information on accessing storage by using the storage variables, see [storage variables](https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/contract-storage/#storage_variables). + +#### Arguments + +- _`address_domain`_: The domain of the key, used to separate between different data availability modes. This separation is used in Starknet to offer different data availability modes. Currently, only the onchain mode (where all updates go to L1), indicated by domain `0`, is supported. Other address domains which will be introduced in the future will behave differently in terms of publication (in particular, they will not be posted on L1, creating a tradeoff between cost and security). + +- _`address`_: The requested storage address. + +#### Return Values + +The value of the key, of type `SyscallResult`. + +#### Example + +```rust +use starknet::storage_access::storage_base_address_from_felt252; + +... + +let storage_address = storage_base_address_from_felt252(3534535754756246375475423547453) +storage_read_syscall(0, storage_address).unwrap_syscall() +``` + +#### Common Library + +- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L60) + +## `storage_write` + +#### Syntax + +```rust +extern fn storage_write_syscall( + address_domain: u32, address: StorageAddress, value: felt252 +) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; +``` + +#### Description + +Sets the value of a key in the storage of the calling contract. + +This system call provides direct access to any possible key in storage, in contrast with `var.write()`, which enables you to write to storage variables that are defined explicitly in the contract. + +For information on accessing storage by using the storage variables, see [storage variables](https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/contract-storage/#storage_variables). + +#### Arguments + +- _`address_domain`_: The domain of the key, used to separate between different data availability modes. This separation is used in Starknet to offer different data availability modes. Currently, only the onchain mode (where all updates go to L1), indicated by domain `0`, is supported. Other address domains which will be introduced in the future will behave differently in terms of publication (in particular, they will not be posted on L1, creating a tradeoff between cost and security). + +- _`address`_: The requested storage address. + +- _`value`_: The value to write to the key. + +#### Return Values + +None. + +#### Common Library + +- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L70) +# Introduction + +## What is Cairo? + +Cairo is a programming language designed for a virtual CPU of the same name. The unique aspect of this processor is that it was not created for the physical constraints of our world but for cryptographic ones, making it capable of efficiently proving the execution of any program running on it. This means that you can perform time consuming operations on a machine you don't trust, and check the result very quickly on a cheaper machine. +While Cairo 0 used to be directly compiled to CASM, the Cairo CPU assembly, Cairo 1 is a higher level language. It first compiles to Sierra, an intermediate representation of Cairo which will compile later down to a safe subset of CASM. The point of Sierra is to ensure your CASM will always be provable, even when the computation fails. + +## What Can you Do with It? + +Cairo allows you to compute trustworthy values on untrusted machines. One major usecase is Starknet, a solution to Ethereum scaling. Ethereum is a decentralized blockchain platform that enables the creation of decentralized applications where every single interaction between a user and a d-app is verified by all the participants. Starknet is a Layer 2 built on top of Ethereum. Instead of having all the participants of the network to verify all user interactions, only one node, called the prover, executes the programs and generates proofs that the computations were done correctly. These proofs are then verified by an Ethereum smart contract, requiring significantly less computational power compared to executing the interactions themselves. This approach allows for increased throughput and reduced transaction costs while preserving Ethereum security. + +## What Are the Differences with Other Programming Languages? + +Cairo is quite different from traditional programming languages, especially when it comes to overhead costs and its primary advantages. Your program can be executed in two different ways: + +- When executed by the prover, it is similar to any other language. Because Cairo is virtualized, and because the operations were not specifically designed for maximum efficiency, this can lead to some performance overhead but it is not the most relevant part to optimize. + +- When the generated proof is verified by a verifier, it is a bit different. This has to be as cheap as possible since it could potentially be verified on many very small machines. Fortunately verifying is faster than computing and Cairo has some unique advantages to improve it even more. A notable one is non-determinism. This is a topic you will cover in more detail later in this book, but the idea is that you can theoretically use a different algorithm for verifying than for computing. Currently, writing custom non-deterministic code is not supported for the developers, but the standard library leverages non-determinism for improved performance. For example sorting an array in Cairo costs the same price as copying it. Because the verifier doesn't sort the array, it just checks that it is sorted, which is cheaper. + +Another aspect that sets the language apart is its memory model. In Cairo, memory access is immutable, meaning that once a value is written to memory, it cannot be changed. Cairo 1 provides abstractions that help developers work with these constraints, but it does not fully simulate mutability. Therefore, developers must think carefully about how they manage memory and data structures in their programs to optimize performance. + +## References + +- Cairo CPU Architecture: +- Cairo, Sierra and Casm: +- State of non determinism: +# Foreword + +In 2020, StarkWare released Cairo 0, a Turing-complete programming language supporting verifiable computation. Cairo started as an assembly language and gradually became more expressive. The learning curve was initially steep, as Cairo 0.x was a low-level language that did not entirely abstract the underlying cryptographic primitives required to build a proof for the execution of a program. + +With the release of Cairo 1, the developer experience has considerably improved, abstracting away the underlying immutable memory model of the Cairo architecture where possible. Strongly inspired by Rust, Cairo 1 has been built to help you create provable programs without specific knowledge of its underlying architecture so that you can focus on the program itself, increasing the overall security of Cairo programs. Powered by a Rust VM, the execution of Cairo programs is now _blazingly_ fast, allowing you to build an extensive test suite without compromising on performance. + +Blockchain developers that want to deploy contracts on Starknet will use the Cairo programming language to code their smart contracts. This allows the Starknet OS to generate execution traces for transactions to be proved by a prover, which is then verified on Ethereum L1 prior to updating the state root of Starknet. + +However, Cairo is not only for blockchain developers. As a general purpose programming language, it can be used for any computation that would benefit from being proved on one computer and verified on other machines with lower hardware requirements. + +This book is designed for developers with a basic understanding of programming concepts. It is a friendly and approachable text intended to help you level up your knowledge of Cairo, but also help you develop your programming skills in general. So, dive in and get ready to learn all there is to know about Cairo! + +## Acknowledgements + +This book would not have been possible without the help of the Cairo community. We would like to thank every contributor for their contributions to this book! + +We would like to thank the Rust community for the [Rust Book][doc rust], which has been a great source of inspiration for this book. Many examples and explanations have been adapted from the Rust Book to fit the Cairo programming language, as the two languages share many similarities. + +[doc rust]: https://doc.rust-lang.org/book/ +# Getting Started + +Let’s start your Cairo journey! There’s a lot to learn, but every journey starts somewhere. In this chapter, we’ll discuss: + +- Installing Scarb, which is Cairo's build toolchain and package manager, on Linux, macOS, and Windows. +- Writing a program that prints `Hello, world!`. +- Using basic Scarb commands to create a project and execute a program. + +## Getting Help + +If you have any questions about Starknet or Cairo, you can ask them in the [Starknet Discord server][discord]. The community is friendly and always willing to help. + +[discord]: https://discord.gg/starknet-community + +## Interacting with the Cairo Chatbot + +Cairo has its own chatbot, which can help you with Cairo-related questions. The chatbot is trained on the Cairo book, and uses RAG to efficiently retrieve information to provide help. You can find the chatbot on the [Cairo-Chatbot][cairo gpt] website. + +[cairo gpt]: https://cairo-chatbot.vercel.app/ +# Installation + +Cairo can be installed by simply downloading [Scarb][scarb doc]. Scarb bundles the Cairo compiler and the Cairo language server together in an easy-to-install package so that you can start writing Cairo code right away. + +Scarb is also Cairo's package manager and is heavily inspired by [Cargo][cargo doc], Rust’s build system and package manager. + +Scarb handles a lot of tasks for you, such as building your code (either pure Cairo or Starknet contracts), downloading the libraries your code depends on, building those libraries, and provides LSP support for the VSCode Cairo 1 extension. + +As you write more complex Cairo programs, you might add dependencies, and if you start a project using Scarb, managing external code and dependencies will be a lot easier to do. + +Let's start by installing Scarb. + +[scarb doc]: https://docs.swmansion.com/scarb/docs +[cargo doc]: https://doc.rust-lang.org/cargo/ + +## Installing Scarb + +### Requirements + +Scarb requires a Git executable to be available in the `PATH` environment variable. + +### Installation + +To install Scarb, please refer to the [installation instructions][scarb download]. We strongly recommend that you install +Scarb [via asdf][scarb asdf], a CLI tool that can manage multiple language runtime versions on a per-project basis. +This will ensure that the version of Scarb you use to work on a project always matches the one defined in the project settings, avoiding problems related to version mismatches. + +Please refer to the [asdf documentation][asdf doc] to install all prerequisites. + +Once you have asdf installed locally, you can download Scarb plugin with the following command: + +```bash +asdf plugin add scarb +``` + +This will allow you to download specific versions: + +```bash +asdf install scarb 2.6.3 +``` + +and set a global version: + +```bash +asdf global scarb 2.6.3 +``` + +Otherwise, you can simply run the following command in your terminal, and follow the onscreen instructions. This will install the latest stable release of Scarb. + +```bash +curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | sh +``` + +
+In both cases, you can verify installation by running the following command in a new terminal session, it should print both Scarb and Cairo language versions, e.g: + +```bash +$ scarb --version +scarb 2.6.3 (e6f921dfd 2024-03-13) +cairo: 2.6.3 (https://crates.io/crates/cairo-lang-compiler/2.6.3) +sierra: 1.5.0 +``` + +[scarb download]: https://docs.swmansion.com/scarb/download +[scarb asdf]: https://docs.swmansion.com/scarb/download.html#install-via-asdf +[asdf doc]: https://asdf-vm.com/guide/getting-started.html + +## Installing the VSCode Extension + +Cairo has a VSCode extension that provides syntax highlighting, code completion, and other useful features. You can install it from the [VSCode Marketplace][vsc extension]. +Once installed, go into the extension settings, and make sure to tick the `Enable Language Server` and `Enable Scarb` options. + +[vsc extension]: https://marketplace.visualstudio.com/items?itemName=starkware.cairo1 + +{{#quiz ../quizzes/ch01-01-installation.toml}} +# Hello, World + +Now that you’ve installed Cairo through Scarb, it’s time to write your first Cairo program. +It’s traditional when learning a new language to write a little program that +prints the text `Hello, world!` to the screen, so we’ll do the same here! + +> Note: This book assumes basic familiarity with the command line. Cairo makes +> no specific demands about your editing or tooling or where your code lives, so +> if you prefer to use an integrated development environment (IDE) instead of +> the command line, feel free to use your favorite IDE. The Cairo team has developed +> a VSCode extension for the Cairo language that you can use to get the features from +> the language server and code highlighting. See [Appendix F][devtools] +> for more details. + +[devtools]: ./appendix-06-useful-development-tools.md + +## Creating a Project Directory + +You’ll start by making a directory to store your Cairo code. It doesn’t matter +to Cairo where your code lives, but for the exercises and projects in this book, +we suggest making a _cairo_projects_ directory in your home directory and keeping all +your projects there. + +Open a terminal and enter the following commands to make a _cairo_projects_ directory. + +For Linux, macOS, and PowerShell on Windows, enter this: + +```shell +mkdir ~/cairo_projects +cd ~/cairo_projects +``` + +For Windows CMD, enter this: + +```cmd +> mkdir "%USERPROFILE%\cairo_projects" +> cd /d "%USERPROFILE%\cairo_projects" +``` + +> Note: From now on, for each example shown in the book, we assume that +> you will be working from a Scarb project directory. If you are not using Scarb, and try to run the examples from a different directory, you might need to adjust the commands accordingly or create a Scarb project. + +## Creating a Project with Scarb + +Let’s create a new project using Scarb. + +Navigate to your _cairo_projects_ directory (or wherever you decided to store your code). Then run the following: + +```bash +scarb new hello_world +``` + +It creates a new directory and project called _hello_world_. We’ve named our project _hello_world_, and Scarb creates its files in a directory of the same name. + +Go into the _hello_world_ directory with the command `cd hello_world`. You’ll see that Scarb has generated two files and one directory for us: a _Scarb.toml_ file and a _src_ directory with a _lib.cairo_ file inside. + +It has also initialized a new Git repository along with a `.gitignore` file + +> Note: Git is a common version control system. You can stop using version control system by using the `--no-vcs` flag. +> Run `scarb new --help` to see the available options. + +Open _Scarb.toml_ in your text editor of choice. It should look similar to the code in Listing 1-1. + +Filename: Scarb.toml + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2023_11" + +# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest + +[dependencies] +# foo = { path = "vendor/foo" } +``` + +Listing 1-1: Contents of _Scarb.toml_ generated by `scarb new` + +This file is in the [TOML][toml doc] (Tom’s Obvious, Minimal Language) format, which is Scarb’s configuration format. + +The first line, `[package]`, is a section heading that indicates that the following statements are configuring a package. As we add more information to this file, we’ll add other sections. + +The next three lines set the configuration information Scarb needs to compile your program: the name of the package and the version of Scarb to use, and the edition of the prelude to use. The prelude is the collection of the most commonly used items that are automatically imported into every Cairo program. You can learn more about the prelude in [Appendix D][prelude]. + +The last line, `[dependencies]`, is the start of a section for you to list any of your project’s dependencies. In Cairo, packages of code are referred to as crates. We won’t need any other crates for this project. + +> Note: If you're building contracts for Starknet, you will need to add the `starknet` dependency as mentioned in the [Scarb documentation][starknet package]. + +The other file created by Scarb is _src/lib.cairo_, let's delete all the content and put in the following content, we will explain the reason later. + +```rust,noplayground +mod hello_world; +``` + +Then create a new file called _src/hello_world.cairo_ and put the following code in it: + +Filename: src/hello_world.cairo + +```rust,file=hello_world.cairo +fn main() { + println!("Hello, World!"); +} +``` + +We have just created a file called _lib.cairo_, which contains a module declaration referencing another module named `hello_world`, as well as the file _hello_world.cairo_, containing the implementation details of the `hello_world` module. + +Scarb requires your source files to be located within the _src_ directory. + +The top-level project directory is reserved for README files, license information, configuration files, and any other non-code-related content. +Scarb ensures a designated location for all project components, maintaining a structured organization. + +If you started a project that doesn’t use Scarb, you can convert it to a project that does use Scarb. Move the project code into the _src_ directory and create an appropriate _Scarb.toml_ file. You can also use `scarb init` command to generate the _src_ folder and the _Scarb.toml_ it contains. + +```txt +├── Scarb.toml +├── src +│   ├── lib.cairo +│   └── hello_world.cairo +``` + + A sample Scarb project structure + +[toml doc]: https://toml.io/ +[prelude]: ./appendix-04-cairo-prelude.md +[starknet package]: https://docs.swmansion.com/scarb/docs/extensions/starknet/starknet-package.html + +## Building a Scarb Project + +From your _hello_world_ directory, build your project by entering the following command: + +```bash +$ scarb build + Compiling hello_world v0.1.0 (file:///projects/Scarb.toml) + Finished release target(s) in 0 seconds +``` + +This command creates a `sierra` file in _target/dev_, let's ignore the `sierra` file for now. + +If you have installed Cairo correctly, you should be able to run the `main` function of your program with the `scarb cairo-run` command and see the following output: + +```shell +$ scarb cairo-run +Running hello_world +Hello, World! +Run completed successfully, returning [] +``` + +Regardless of your operating system, the string `Hello, world!` should be printed to +the terminal. + +If `Hello, world!` did print, congratulations! You’ve officially written a Cairo +program. That makes you a Cairo programmer — welcome! + +## Anatomy of a Cairo Program + +Let’s review this “Hello, world!” program in detail. Here’s the first piece of +the puzzle: + +```rust,noplayground +fn main() { + +} +``` + +These lines define a function named `main`. The `main` function is special: it +is always the first code that runs in every executable Cairo program. Here, the +first line declares a function named `main` that has no parameters and returns +nothing. If there were parameters, they would go inside the parentheses `()`. + +The function body is wrapped in `{}`. Cairo requires curly brackets around all +function bodies. It’s good style to place the opening curly bracket on the same +line as the function declaration, adding one space in between. + +> Note: If you want to stick to a standard style across Cairo projects, you can +> use the automatic formatter tool available with `scarb fmt` to format your code in a +> particular style (more on `scarb fmt` in +> [Appendix F][devtools]). The Cairo team has included this tool +> with the standard Cairo distribution, as `cairo-run` is, so it should already be +> installed on your computer! + +The body of the `main` function holds the following code: + +```rust,noplayground + println!("Hello, World!"); +``` + +This line does all the work in this little program: it prints text to the +screen. There are four important details to notice here. + +First, Cairo style is to indent with four spaces, not a tab. + +Second, `println!` calls a Cairo macro. If it had called a function instead, it would be entered as `println` (without the `!`). +We’ll discuss Cairo macros in more detail in the ["Macros"][macros] chapter. For now, you just need to know that using a `!` means that you’re calling a macro instead of a normal function and that macros don’t always follow the same rules as functions. + +Third, you see the `"Hello, world!"` string. We pass this string as an argument to `println!`, and the string is printed to the screen. + +Fourth, we end the line with a semicolon (`;`), which indicates that this +expression is over and the next one is ready to begin. Most lines of Cairo code +end with a semicolon. + +[devtools]: ./appendix-06-useful-development-tools.md +[macros]: ./ch11-05-macros.md + +{{#quiz ../quizzes/ch01-02-hello-world.toml}} + +# Summary + +Let’s recap what we’ve learned so far about Scarb: + +- We can install one or multiple Scarb versions, either the latest stable or a specific one, using asdf. +- We can create a project using `scarb new`. +- We can build a project using `scarb build` to generate the compiled Sierra code. +- We can execute a Cairo program using the `scarb cairo-run` command. + +An additional advantage of using Scarb is that the commands are the same no matter which operating system you’re working on. So, at this point, we’ll no longer provide specific instructions for Linux and macOS versus Windows. + +You’re already off to a great start on your Cairo journey! This is a great time to build a more substantial program to get used to reading and writing Cairo code. +# Common Programming Concepts + +This chapter covers concepts that appear in almost every programming language and how they work in Cairo. Many programming languages have much in common at their core. None of the concepts presented in this chapter are unique to Cairo, but we’ll discuss them in the context of Cairo and explain the conventions around using these concepts. + +Specifically, you’ll learn about variables, basic types, functions, comments, and control flow. These foundations will be in every Cairo program, and learning them early will give you a strong core to start from. +# Variables and Mutability + +Cairo uses an immutable memory model, meaning that once a memory cell is written to, +it can't be overwritten but only read from. To reflect this immutable memory model, +variables in Cairo are immutable by default. +However, the language abstracts this model and gives you the option to make your +variables mutable. Let’s explore how and why Cairo enforces immutability, and how +you can make your variables mutable. + +When a variable is immutable, once a value is bound to a name, you can’t change +that value. To illustrate this, generate a new project called _variables_ in +your _cairo_projects_ directory by using `scarb new variables`. + +Then, in your new _variables_ directory, open _src/lib.cairo_ and replace its +code with the following code, which won’t compile just yet: + +Filename: src/lib.cairo + +```rust,does_not_compile +fn main() { + let x = 5; + println!("The value of x is: {}", x); + x = 6; + println!("The value of x is: {}", x); +} + +``` + +Save and run the program using `scarb cairo-run`. You should receive an error message +regarding an immutability error, as shown in this output: + +```shell +$ scarb cairo-run + Compiling no_listing_01_variables_are_immutable v0.1.0 (listings/ch02-common-programming-concepts/no_listing_01_variables_are_immutable/Scarb.toml) +error: Cannot assign to an immutable variable. + --> listings/ch02-common-programming-concepts/no_listing_01_variables_are_immutable/src/lib.cairo:6:5 + x = 6; + ^***^ + +error: could not compile `no_listing_01_variables_are_immutable` due to previous error +error: `scarb metadata` exited with error + +``` + +This example shows how the compiler helps you find errors in your programs. +Compiler errors can be frustrating, but they only mean your program +isn’t safely doing what you want it to do yet; they do _not_ mean that you’re +not a good programmer! Experienced Caironautes still get compiler errors. + +You received the error message `Cannot assign to an immutable variable.` +because you tried to assign a second value to the immutable `x` variable. + +It’s important that we get compile-time errors when we attempt to change a +value that’s designated as immutable because this specific situation can lead to +bugs. If one part of our code operates on the assumption that a value will +never change and another part of our code changes that value, it’s possible +that the first part of the code won’t do what it was designed to do. The cause +of this kind of bug can be difficult to track down after the fact, especially +when the second piece of code changes the value only _sometimes_. + +Cairo, unlike most other languages, has immutable memory. This makes a +whole class of bugs impossible, because values will never change unexpectedly. +This makes code easier to reason about. + +But mutability can be very useful, and can make code more convenient to write. +Although variables are immutable by default, you can make them mutable by +adding `mut` in front of the variable name. Adding `mut` also conveys +intent to future readers of the code by indicating that other parts of the code +will be changing the value associated to this variable. + + + +However, you might be wondering at this point what exactly happens when a variable +is declared as `mut`, as we previously mentioned that Cairo's memory is immutable. +The answer is that the _value_ is immutable, but the _variable_ isn't. The value +associated to the variable can be changed. Assigning to a mutable variable in Cairo +is essentially equivalent to redeclaring it to refer to another value in another memory cell, +but the compiler handles that for you, and the keyword `mut` makes it explicit. +Upon examining the low-level Cairo Assembly code, it becomes clear that +variable mutation is implemented as syntactic sugar, which translates mutation operations +into a series of steps equivalent to variable shadowing. The only difference is that at the Cairo +level, the variable is not redeclared so its type cannot change. + +For example, let’s change _src/lib.cairo_ to the following: + +```rust +fn main() { + let mut x = 5; + println!("The value of x is: {}", x); + x = 6; + println!("The value of x is: {}", x); +} +``` + +When we run the program now, we get this: + +```shell +$ scarb cairo-run + Compiling no_listing_02_adding_mut v0.1.0 (listings/ch02-common-programming-concepts/no_listing_02_adding_mut/Scarb.toml) + Finished release target(s) in 1 second + Running no_listing_02_adding_mut +The value of x is: 5 +The value of x is: 6 +Run completed successfully, returning [] + +``` + +We’re allowed to change the value bound to `x` from `5` to `6` when `mut` is +used. Ultimately, deciding whether to use mutability or not is up to you and +depends on what you think is clearest in that particular situation. + +## Constants + +Like immutable variables, _constants_ are values that are bound to a name and +are not allowed to change, but there are a few differences between constants +and variables. + +First, you aren’t allowed to use `mut` with constants. Constants aren’t just +immutable by default—they’re always immutable. You declare constants using the +`const` keyword instead of the `let` keyword, and the type of the value _must_ +be annotated. We’ll cover types and type annotations in the next section, +[“Data Types”][data-types], so don’t worry about the details +right now. Just know that you must always annotate the type. + +Constant variables can be declared with any usual data type, including structs, enums and fixed-size arrays. + +Constants can only be declared in the global scope, which makes +them useful for values that many parts of code need to know about. + +The last difference is that constants may natively be set only to a constant expression, +not the result of a value that could only be computed at runtime. + +Here’s an example of constants declaration: + +```rust,noplayground +struct AnyStruct { + a: u256, + b: u32 +} + +enum AnyEnum { + A: felt252, + B: (usize, u256) +} + +const ONE_HOUR_IN_SECONDS: u32 = 3600; +const STRUCT_INSTANCE: AnyStruct = AnyStruct { a: 0, b: 1 }; +const ENUM_INSTANCE: AnyEnum = AnyEnum::A('any enum'); +const BOOL_FIXED_SIZE_ARRAY: [bool; 2] = [true, false]; +``` + +Nonetheless, it is possible to use the `consteval_int!` macro to create a `const` variable that is the result of some computation: + +```rust, noplayground + const ONE_HOUR_IN_SECONDS: u32 = consteval_int!(60 * 60); +``` + +We will dive into more detail about macros in the [dedicated section](./ch11-05-macros.md). + +Cairo's naming convention for constants is to use all uppercase with underscores between words. + +Constants are valid for the entire time a program runs, within the scope in +which they were declared. This property makes constants useful for values in +your application domain that multiple parts of the program might need to know +about, such as the maximum number of points any player of a game is allowed to +earn, or the speed of light. + +Naming hardcoded values used throughout your program as constants is useful in +conveying the meaning of that value to future maintainers of the code. It also +helps to have only one place in your code you would need to change if the +hardcoded value needed to be updated in the future. + +[data-types]: ./ch02-02-data-types.md + +## Shadowing + +Variable shadowing refers to the declaration of a +new variable with the same name as a previous variable. Caironautes say that the +first variable is _shadowed_ by the second, which means that the second +variable is what the compiler will see when you use the name of the variable. +In effect, the second variable overshadows the first, taking any uses of the +variable name to itself until either it itself is shadowed or the scope ends. +We can shadow a variable by using the same variable’s name and repeating the +use of the `let` keyword as follows: + +```rust +fn main() { + let x = 5; + let x = x + 1; + { + let x = x * 2; + println!("Inner scope x value is: {}", x); + } + println!("Outer scope x value is: {}", x); +} +``` + +This program first binds `x` to a value of `5`. Then it creates a new variable +`x` by repeating `let x =`, taking the original value and adding `1` so the +value of `x` is then `6`. Then, within an inner scope created with the curly +brackets, the third `let` statement also shadows `x` and creates a new +variable, multiplying the previous value by `2` to give `x` a value of `12`. +When that scope is over, the inner shadowing ends and `x` returns to being `6`. +When we run this program, it will output the following: + +```shell +$ scarb cairo-run + Compiling no_listing_03_shadowing v0.1.0 (listings/ch02-common-programming-concepts/no_listing_03_shadowing/Scarb.toml) + Finished release target(s) in 1 second + Running no_listing_03_shadowing +Inner scope x value is: 12 +Outer scope x value is: 6 +Run completed successfully, returning [] + +``` + +Shadowing is different from marking a variable as `mut` because we’ll get a +compile-time error if we accidentally try to reassign to this variable without +using the `let` keyword. By using `let`, we can perform a few transformations +on a value but have the variable be immutable after those transformations have +been completed. + +Another distinction between `mut` and shadowing is that when we use the `let` keyword again, +we are effectively creating a new variable, which allows us to change the type of the +value while reusing the same name. As mentioned before, variable shadowing and mutable variables +are equivalent at the lower level. +The only difference is that by shadowing a variable, the compiler will not complain +if you change its type. For example, say our program performs a type conversion between the +`u64` and `felt252` types. + +```rust +fn main() { + let x: u64 = 2; + println!("The value of x is {} of type u64", x); + let x: felt252 = x.into(); // converts x to a felt, type annotation is required. + println!("The value of x is {} of type felt252", x); +} +``` + +The first `x` variable has a `u64` type while the second `x` variable has a `felt252` type. +Shadowing thus spares us from having to come up with different names, such as `x_u64` +and `x_felt252`; instead, we can reuse the simpler `x` name. However, if we try to use +`mut` for this, as shown here, we’ll get a compile-time error: + +```rust,does_not_compile +fn main() { + let mut x: u64 = 2; + println!("The value of x is: {}", x); + x = 'a short string'; + println!("The value of x is: {}", x); +} +``` + +The error says we were expecting a `u64` (the original type) but we got a different type: + +```shell +$ scarb cairo-run + Compiling no_listing_05_mut_cant_change_type v0.1.0 (listings/ch02-common-programming-concepts/no_listing_05_mut_cant_change_type/Scarb.toml) +error: The value does not fit within the range of type core::integer::u64. + --> listings/ch02-common-programming-concepts/no_listing_05_mut_cant_change_type/src/lib.cairo:6:9 + x = 'a short string'; + ^**************^ + +error: could not compile `no_listing_05_mut_cant_change_type` due to previous error +error: `scarb metadata` exited with error + +``` + +{{#quiz ../quizzes/ch02-01-variables-and-mutability.toml}} + +Now that we’ve explored how variables work, let’s look at more data types they can have. +# Data Types + +Every value in Cairo is of a certain _data type_, which tells Cairo what kind of +data is being specified so it knows how to work with that data. This section covers two subsets of data types: scalars and compounds. + +Keep in mind that Cairo is a _statically typed_ language, which means that it +must know the types of all variables at compile time. The compiler can usually infer the desired type based on the value and its usage. In cases when many types are possible, we can use a cast method where we specify the desired output type. + +```rust +fn main() { + let x: felt252 = 3; + let y: u32 = x.try_into().unwrap(); +} +``` + +You’ll see different type annotations for other data types. + +## Scalar Types + +A _scalar_ type represents a single value. Cairo has three primary scalar types: +felts, integers, and booleans. You may recognize +these from other programming languages. Let’s jump into how they work in Cairo. + +### Felt Type + +In Cairo, if you don't specify the type of a variable or argument, its type defaults to a field element, represented by the keyword `felt252`. In the context of Cairo, when we say “a field element” we mean an integer in the range \\( 0 \leq x < P \\), +where \\( P \\) is a very large prime number currently equal to \\( {2^{251}} + 17 \cdot {2^{192}} + 1 \\). When adding, subtracting, or multiplying, if the result falls outside the specified range of the prime number, an overflow (or underflow) occurs, and an appropriate multiple of \\( P \\) is added or subtracted to bring the result back within the range (i.e., the result is computed \\( \mod P \\) ). + +The most important difference between integers and field elements is division: Division of field elements (and therefore division in Cairo) is unlike regular CPUs division, where +integer division \\( \frac{x}{y} \\) is defined as \\( \left\lfloor \frac{x}{y} \right\rfloor \\) +where the integer part of the quotient is returned (so you get \\( \frac{7}{3} = 2 \\)) and it may or may not satisfy the equation \\( \frac{x}{y} \cdot y == x \\), +depending on the divisibility of `x` by `y`. + +In Cairo, the result of \\( \frac{x}{y} \\) is defined to always satisfy the equation \\( \frac{x}{y} \cdot y == x \\). If y divides x as integers, you will get the expected result in Cairo (for example \\( \frac{6}{2} \\) will indeed result in `3`). +But when y does not divide x, you may get a surprising result: for example, since \\( 2 \cdot \frac{P + 1}{2} = P + 1 \equiv 1 \mod P \\), the value of \\( \frac{1}{2} \\) in Cairo is \\( \frac{P + 1}{2} \\) (and not 0 or 0.5), as it satisfies the above equation. + +### Integer Types + +The felt252 type is a fundamental type that serves as the basis for creating all types in the core library. +However, it is highly recommended for programmers to use the integer types instead of the `felt252` type whenever possible, as the `integer` types come with added security features that provide extra protection against potential vulnerabilities in the code, such as overflow and underflow checks. By using these integer types, programmers can ensure that their programs are more secure and less susceptible to attacks or other security threats. +An `integer` is a number without a fractional component. This type declaration indicates the number of bits the programmer can use to store the integer. +Table 3-1 shows the built-in integer types in Cairo. We can use any of these variants to declare the type of an integer value. + +| Length | Unsigned | +| ------- | -------- | +| 8-bit | `u8` | +| 16-bit | `u16` | +| 32-bit | `u32` | +| 64-bit | `u64` | +| 128-bit | `u128` | +| 256-bit | `u256` | +| 32-bit | `usize` | + +
+
Table 3-1: Integer Types in Cairo.
+ +Each variant has an explicit size. Note that for now, the `usize` type is just an alias for `u32`; however, it might be useful when in the future Cairo can be compiled to MLIR. +As variables are unsigned, they can't contain a negative number. This code will cause the program to panic: + +```rust +fn sub_u8s(x: u8, y: u8) -> u8 { + x - y +} + +fn main() { + sub_u8s(1, 3); +} +``` + +All integer types previously mentioned fit into a `felt252`, except for `u256` which needs 4 more bits to be stored. Under the hood, `u256` is basically a struct with 2 fields: `u256 {low: u128, high: u128}`. + +Cairo also provides support for signed integers, starting with the prefix `i`. These integers can represent both positive and negative values, with sizes ranging from `i8` to `i128`. +Each signed variant can store numbers from \\( -({2^{n - 1}}) \\) to \\( {2^{n - 1}} - 1 \\) inclusive, where `n` is the number of bits that variant uses. So an i8 can store numbers from \\( -({2^7}) \\) to \\( {2^7} - 1 \\), which equals `-128` to `127`. + +You can write integer literals in any of the forms shown in Table 3-2. Note +that number literals that can be multiple numeric types allow a type suffix, +such as `57_u8`, to designate the type. +It is also possible to use a visual separator `_` for number literals, in order to improve code readability. + +| Numeric literals | Example | +| ---------------- | --------- | +| Decimal | `98222` | +| Hex | `0xff` | +| Octal | `0o04321` | +| Binary | `0b01` | + +
+
Table 3-2: Integer Literals in Cairo.
+ +So how do you know which type of integer to use? Try to estimate the max value your int can have and choose the good size. +The primary situation in which you’d use `usize` is when indexing some sort of collection. + +### Numeric Operations + +Cairo supports the basic mathematical operations you’d expect for all the integer +types: addition, subtraction, multiplication, division, and remainder. Integer +division truncates toward zero to the nearest integer. The following code shows +how you’d use each numeric operation in a `let` statement: + +```rust +fn main() { + // addition + let sum = 5_u128 + 10_u128; + + // subtraction + let difference = 95_u128 - 4_u128; + + // multiplication + let product = 4_u128 * 30_u128; + + // division + let quotient = 56_u128 / 32_u128; //result is 1 + let quotient = 64_u128 / 32_u128; //result is 2 + + // remainder + let remainder = 43_u128 % 5_u128; // result is 3 +} +``` + +Each expression in these statements uses a mathematical operator and evaluates +to a single value, which is then bound to a variable. + +[Appendix B][operators] contains a list of all operators that Cairo provides. + +[operators]: ./appendix-02-operators-and-symbols.md#operators + +### The Boolean Type + +As in most other programming languages, a Boolean type in Cairo has two possible +values: `true` and `false`. Booleans are one `felt252` in size. The Boolean type in +Cairo is specified using `bool`. For example: + +```rust +fn main() { + let t = true; + + let f: bool = false; // with explicit type annotation +} +``` + +When declaring a `bool` variable, it is mandatory to use either `true` or `false` literals as value. Hence, it is not allowed to use integer literals (i.e. `0` instead of false) for `bool` declarations. + +The main way to use Boolean values is through conditionals, such as an `if` +expression. We’ll cover how `if` expressions work in Cairo in the ["Control Flow"][control-flow] section. + +[control-flow]: ./ch02-05-control-flow.md + +### String Types + +Cairo doesn't have a native type for strings but provides two ways to handle them: short strings using simple quotes and ByteArray using double quotes. + +#### Short strings + +A short string is an ASCII string where each character is encoded on one byte (see the [ASCII table][ascii]). For example: + +- `'a'` is equivalent to `0x61` +- `'b'` is equivalent to `0x62` +- `'c'` is equivalent to `0x63` +- `0x616263` is equivalent to `'abc'`. + +Cairo uses the `felt252` for short strings. As the `felt252` is on 251 bits, a short string is limited to 31 characters (31 \* 8 = 248 bits, which is the maximum multiple of 8 that fits in 251 bits). + +You can choose to represent your short string with an hexadecimal value like `0x616263` or by directly writing the string using simple quotes like `'abc'`, which is more convenient. + +Here are some examples of declaring short strings in Cairo: + +```rust +# fn main() { + let my_first_char = 'C'; + let my_first_char_in_hex = 0x43; + + let my_first_string = 'Hello world'; + let my_first_string_in_hex = 0x48656C6C6F20776F726C64; +# +# let long_string: ByteArray = "this is a string which has more than 31 characters"; +# } +``` + +[ascii]: https://www.asciitable.com/ + +#### Byte Array Strings + +With the `ByteArray` struct added in Cairo 2.4.0, you are not limited to 31 characters anymore. These `ByteArray` strings are written in double quotes like in the following example: + +```rust +# fn main() { +# let my_first_char = 'C'; +# let my_first_char_in_hex = 0x43; +# +# let my_first_string = 'Hello world'; +# let my_first_string_in_hex = 0x48656C6C6F20776F726C64; +# + let long_string: ByteArray = "this is a string which has more than 31 characters"; +# } +``` + +## Type Casting + +In Cairo, you can convert scalar types from one type to another by using the `try_into` and `into` methods provided by the `TryInto` and `Into` traits from the core library. + +The `try_into` method allows for safe type casting when the target type might not fit the source value. Keep in mind that `try_into` returns an `Option` type, which you'll need to unwrap to access the new value. + +On the other hand, the `into` method can be used for type casting when success is guaranteed, such as when the source type is smaller than the destination type. + +To perform the conversion, call `var.into()` or `var.try_into()` on the source value to cast it to another type. The new variable's type must be explicitly defined, as demonstrated in the example below. + +```rust +fn main() { + let my_felt252 = 10; + // Since a felt252 might not fit in a u8, we need to unwrap the Option type + let my_u8: u8 = my_felt252.try_into().unwrap(); + let my_u16: u16 = my_u8.into(); + let my_u32: u32 = my_u16.into(); + let my_u64: u64 = my_u32.into(); + let my_u128: u128 = my_u64.into(); + // As a felt252 is smaller than a u256, we can use the into() method + let my_u256: u256 = my_felt252.into(); + let my_usize: usize = my_felt252.try_into().unwrap(); + let my_other_felt252: felt252 = my_u8.into(); + let my_third_felt252: felt252 = my_u16.into(); +} +``` + +## The Tuple Type + +A _tuple_ is a general way of grouping together a number of values with a +variety of types into one compound type. Tuples have a fixed length: once +declared, they cannot grow or shrink in size. + +We create a tuple by writing a comma-separated list of values inside +parentheses. Each position in the tuple has a type, and the types of the +different values in the tuple don’t have to be the same. We’ve added optional +type annotations in this example: + +```rust +fn main() { + let tup: (u32, u64, bool) = (10, 20, true); +} +``` + +The variable `tup` binds to the entire tuple because a tuple is considered a +single compound element. To get the individual values out of a tuple, we can +use pattern matching to destructure a tuple value, like this: + +```rust +fn main() { + let tup = (500, 6, true); + + let (x, y, z) = tup; + + if y == 6 { + println!("y is 6!"); + } +} +``` + +This program first creates a tuple and binds it to the variable `tup`. It then +uses a pattern with `let` to take `tup` and turn it into three separate +variables, `x`, `y`, and `z`. This is called _destructuring_ because it breaks +the single tuple into three parts. Finally, the program prints `y is 6!` as the value of +`y` is `6`. + +We can also declare the tuple with value and types, and destructure it at the same time. +For example: + +```rust +fn main() { + let (x, y): (felt252, felt252) = (2, 3); +} +``` + +## The Unit Type () + +A _unit type_ is a type which has only one value `()`. +It is represented by a tuple with no elements. +Its size is always zero, and it is guaranteed to not exist in the compiled code. + +You might be wondering why you would even need a unit type? In Cairo, everything is an expression, and an expression that returns nothing actually returns `()` implicitly. + +{{#quiz ../quizzes/ch02-02-data-types.toml}} +# Functions + +Functions are prevalent in Cairo code. You’ve already seen one of the most +important functions in the language: the `main` function, which is the entry +point of many programs. You’ve also seen the `fn` keyword, which allows you to +declare new functions. + +Cairo code uses _snake case_ as the conventional style for function and variable +names, in which all letters are lowercase and underscores separate words. +Here’s a program that contains an example function definition: + +```rust +fn another_function() { + println!("Another function."); +} + +fn main() { + println!("Hello, world!"); + another_function(); +} +``` + +We define a function in Cairo by entering `fn` followed by a function name and a +set of parentheses. The curly brackets tell the compiler where the function +body begins and ends. + +We can call any function we’ve defined by entering its name followed by a set +of parentheses. Because `another_function` is defined in the program, it can be +called from inside the `main` function. Note that we defined `another_function` +_before_ the `main` function in the source code; we could have defined it after +as well. Cairo doesn’t care where you define your functions, only that they’re +defined somewhere in a scope that can be seen by the caller. + +Let’s start a new project with Scarb named _functions_ to explore functions +further. Place the `another_function` example in _src/lib.cairo_ and run it. You +should see the following output: + +```shell +$ scarb cairo-run + Compiling no_listing_15_functions v0.1.0 (listings/ch02-common-programming-concepts/no_listing_15_functions/Scarb.toml) + Finished release target(s) in 1 second + Running no_listing_15_functions +Hello, world! +Another function. +Run completed successfully, returning [] + +``` + +The lines execute in the order in which they appear in the `main` function. +First the `Hello, world!` message prints, and then `another_function` is called +and its message is printed. + +## Parameters + +We can define functions to have _parameters_, which are special variables that +are part of a function’s signature. When a function has parameters, you can +provide it with concrete values for those parameters. Technically, the concrete +values are called _arguments_, but in casual conversation, people tend to use +the words _parameter_ and _argument_ interchangeably for either the variables +in a function’s definition or the concrete values passed in when you call a +function. + +In this version of `another_function` we add a parameter: + +```rust +fn main() { + another_function(5); +} + +fn another_function(x: felt252) { + println!("The value of x is: {}", x); +} +``` + +Try running this program; you should get the following output: + +```shell +$ scarb cairo-run + Compiling no_listing_16_single_param v0.1.0 (listings/ch02-common-programming-concepts/no_listing_16_single_param/Scarb.toml) + Finished release target(s) in 1 second + Running no_listing_16_single_param +The value of x is: 5 +Run completed successfully, returning [] + +``` + +The declaration of `another_function` has one parameter named `x`. The type of +`x` is specified as `felt252`. When we pass `5` in to `another_function`, the +`println!` macro puts `5` where the pair of curly brackets containing `x` was in the format string. + +In function signatures, you _must_ declare the type of each parameter. This is +a deliberate decision in Cairo’s design: requiring type annotations in function +definitions means the compiler almost never needs you to use them elsewhere in +the code to figure out what type you mean. The compiler is also able to give +more helpful error messages if it knows what types the function expects. + +When defining multiple parameters, separate the parameter declarations with +commas, like this: + +```rust +fn main() { + print_labeled_measurement(5, "h"); +} + +fn print_labeled_measurement(value: u128, unit_label: ByteArray) { + println!("The measurement is: {value}{unit_label}"); +} +``` + +This example creates a function named `print_labeled_measurement` with two +parameters. The first parameter is named `value` and is a `u128`. The second is +named `unit_label` and is of type `ByteArray` - Cairo's internal type to represent string literals. The function then prints text containing both the `value` and the `unit_label`. + +Let’s try running this code. Replace the program currently in your _functions_ +project’s _src/lib.cairo_ file with the preceding example and run it using `scarb cairo-run`: + +```shell +$ scarb cairo-run + Compiling no_listing_17_multiple_params v0.1.0 (listings/ch02-common-programming-concepts/no_listing_17_multiple_params/Scarb.toml) + Finished release target(s) in 1 second + Running no_listing_17_multiple_params +The measurement is: 5h +Run completed successfully, returning [] + +``` + +Because we called the function with `5` as the value for value and `"h"` as the value for `unit_label`, the program output contains those values. + +### Named Parameters + +In Cairo, named parameters allow you to specify the names of arguments when you call a function. This makes the function calls more readable and self-descriptive. +If you want to use named parameters, you need to specify the name of the parameter and the value you want to pass to it. The syntax is `parameter_name: value`. If you pass a variable that has the same name as the parameter, you can simply write `:parameter_name` instead of `parameter_name: variable_name`. + +Here is an example: + +```rust +fn foo(x: u8, y: u8) {} + +fn main() { + let first_arg = 3; + let second_arg = 4; + foo(x: first_arg, y: second_arg); + let x = 1; + let y = 2; + foo(:x, :y) +} +``` + +## Statements and Expressions + +Function bodies are made up of a series of statements optionally ending in an +expression. So far, the functions we’ve covered haven’t included an ending +expression, but you have seen an expression as part of a statement. Because +Cairo is an expression-based language, this is an important distinction to +understand. Other languages don’t have the same distinctions, so let’s look at +what statements and expressions are and how their differences affect the bodies +of functions. + +- **Statements** are instructions that perform some action and do not return + a value. +- **Expressions** evaluate to a resultant value. Let’s look at some examples. + +We’ve actually already used statements and expressions. Creating a variable and +assigning a value to it with the `let` keyword is a statement. In Listing 2-1, +`let y = 6;` is a statement. + +```rust +fn main() { + let y = 6; +} +``` + +Listing 2-1: A `main` function declaration containing one statement + +Function definitions are also statements; the entire preceding example is a statement in itself. + +Statements do not return values. Therefore, you can’t assign a `let` statement +to another variable, as the following code tries to do; you’ll get an error: + +```rust, noplayground +fn main() { + let x = (let y = 6); +} +``` + +When you run this program, the error you’ll get looks like this: + +```shell +$ scarb cairo-run + Compiling no_listing_18_statements_dont_return_values v0.1.0 (listings/ch02-common-programming-concepts/no_listing_20_statements_dont_return_values/Scarb.toml) +error: Missing token TerminalRParen. + --> listings/ch02-common-programming-concepts/no_listing_20_statements_dont_return_values/src/lib.cairo:3:14 + let x = (let y = 6); + ^ + +error: Missing token TerminalSemicolon. + --> listings/ch02-common-programming-concepts/no_listing_20_statements_dont_return_values/src/lib.cairo:3:14 + let x = (let y = 6); + ^ + +error: Missing token TerminalSemicolon. + --> listings/ch02-common-programming-concepts/no_listing_20_statements_dont_return_values/src/lib.cairo:3:23 + let x = (let y = 6); + ^ + +error: Skipped tokens. Expected: statement. + --> listings/ch02-common-programming-concepts/no_listing_20_statements_dont_return_values/src/lib.cairo:3:23 + let x = (let y = 6); + ^^ + +warn: Unused variable. Consider ignoring by prefixing with `_`. + --> listings/ch02-common-programming-concepts/no_listing_20_statements_dont_return_values/src/lib.cairo:3:9 + let x = (let y = 6); + ^ + +warn: Unused variable. Consider ignoring by prefixing with `_`. + --> listings/ch02-common-programming-concepts/no_listing_20_statements_dont_return_values/src/lib.cairo:3:18 + let x = (let y = 6); + ^ + +error: could not compile `no_listing_18_statements_dont_return_values` due to previous error +error: `scarb metadata` exited with error + +``` + +The `let y = 6` statement does not return a value, so there isn’t anything for +`x` to bind to. This is different from what happens in other languages, such as +C and Ruby, where the assignment returns the value of the assignment. In those +languages, you can write `x = y = 6` and have both `x` and `y` have the value +`6`; that is not the case in Cairo. + +Expressions evaluate to a value and make up most of the rest of the code that +you’ll write in Cairo. Consider a math operation, such as `5 + 6`, which is an +expression that evaluates to the value `11`. Expressions can be part of +statements: in Listing 2-1, the `6` in the statement `let y = 6;` is an +expression that evaluates to the value `6`. + +Calling a function is an expression since it always evaluates to a value: the function's explicit return value, if specified, or the 'unit' type `()` otherwise. + +A new scope block created with curly brackets is an expression, for example: + +```rust +fn main() { + let y = { + let x = 3; + x + 1 + }; + + println!("The value of y is: {}", y); +} +``` + +This expression: + +```rust, noplayground + let y = { + let x = 3; + x + 1 + }; +``` + +is a block that, in this case, evaluates to `4`. That value gets bound to `y` +as part of the `let` statement. Note that the `x + 1` line doesn’t have a +semicolon at the end, which is unlike most of the lines you’ve seen so far. +Expressions do not include ending semicolons. If you add a semicolon to the end +of an expression, you turn it into a statement, and it will then not return a +value. Keep this in mind as you explore function return values and expressions +next. + +## Functions with Return Values + +Functions can return values to the code that calls them. We don’t name return +values, but we must declare their type after an arrow (`->`). In Cairo, the +return value of the function is synonymous with the value of the final +expression in the block of the body of a function. You can return early from a +function by using the `return` keyword and specifying a value, but most +functions return the last expression implicitly. Here’s an example of a +function that returns a value: + +```rust +fn five() -> u32 { + 5 +} + +fn main() { + let x = five(); + println!("The value of x is: {}", x); +} +``` + +There are no function calls, or even `let` statements in the `five` +function—just the number `5` by itself. That’s a perfectly valid function in +Cairo. Note that the function’s return type is specified too, as `-> u32`. Try +running this code; the output should look like this: + +```shell +$ scarb cairo-run + Compiling no_listing_20_function_return_values v0.1.0 (listings/ch02-common-programming-concepts/no_listing_22_function_return_values/Scarb.toml) + Finished release target(s) in 1 second + Running no_listing_20_function_return_values +The value of x is: 5 +Run completed successfully, returning [] + +``` + +The `5` in `five` is the function’s return value, which is why the return type +is `u32`. Let’s examine this in more detail. There are two important bits: +first, the line `let x = five();` shows that we’re using the return value of a +function to initialize a variable. Because the function `five` returns a `5`, +that line is the same as the following: + +```rust, noplayground +let x = 5; +``` + +Second, the `five` function has no parameters and defines the type of the +return value, but the body of the function is a lonely `5` with no semicolon +because it’s an expression whose value we want to return. +Let’s look at another example: + +```rust +fn main() { + let x = plus_one(5); + + println!("The value of x is: {}", x); +} + +fn plus_one(x: u32) -> u32 { + x + 1 +} +``` + +Running this code will print `x = 6`. But if we place a +semicolon at the end of the line containing `x + 1`, changing it from an +expression to a statement, we’ll get an error: + +```rust,does_not_compile +fn main() { + let x = plus_one(5); + + println!("The value of x is: {}", x); +} + +fn plus_one(x: u32) -> u32 { + x + 1; +} +``` + +```shell +$ scarb cairo-run + Compiling no_listing_22_function_return_invalid v0.1.0 (listings/ch02-common-programming-concepts/no_listing_24_function_return_invalid/Scarb.toml) +error: Unexpected return type. Expected: "core::integer::u32", found: "()". + --> listings/ch02-common-programming-concepts/no_listing_24_function_return_invalid/src/lib.cairo:9:28 +fn plus_one(x: u32) -> u32 { + ^ + +error: could not compile `no_listing_22_function_return_invalid` due to previous error +error: `scarb metadata` exited with error + +``` + +The main error message, `Unexpected return type`, reveals the core issue with this +code. The definition of the function `plus_one` says that it will return an +`u32`, but statements don’t evaluate to a value, which is expressed by `()`, +the unit type. Therefore, nothing is returned, which contradicts the function +definition and results in an error. + +{{#quiz ../quizzes/ch02-03-functions.toml}} +# Comments + +All programmers strive to make their code easy to understand, but sometimes extra explanation is warranted. In these cases, programmers leave comments in their source code that the compiler will ignore but people reading the source code may find useful. + +Here’s a simple comment: + +```rust,noplayground +// hello, world +``` + +In Cairo, the idiomatic comment style starts a comment with two slashes, and the comment continues until the end of the line. For comments that extend beyond a single line, you’ll need to include `//` on each line, like this: + +```rust,noplayground +// So we’re doing something complicated here, long enough that we need +// multiple lines of comments to do it! Whew! Hopefully, this comment will +// explain what’s going on. +``` + +Comments can also be placed at the end of lines containing code: + +```rust +fn main() -> felt252 { + 1 + 4 // return the sum of 1 and 4 +} +``` + +But you’ll more often see them used in this format, with the comment on a separate line above the code it’s annotating: + +```rust +fn main() -> felt252 { + // this function performs a simple addition + 1 + 4 +} +``` + +### Item-level Documentation + +Item-level documentation comments refer to specific items such as functions, implementations, traits, etc. They are prefixed with three slashes (`///`). These comments provide a detailed description of the item, examples of usage, and any conditions that might cause a panic. In case of functions, the comments may also include separate sections for parameter and return value descriptions. + +```rust,noplayground +/// Returns the sum of `arg1` and `arg2`. +/// `arg1` cannot be zero. +/// +/// # Panics +/// +/// This function will panic if `arg1` is `0`. +/// +/// # Examples +/// +/// ``` +/// let a: felt252 = 2; +/// let b: felt252 = 3; +/// let c: felt252 = add(a, b); +/// assert(c == a + b, "Should equal a + b"); +/// ``` +fn add(arg1: felt252, arg2: felt252) -> felt252 { + assert(arg1 != 0, 'Cannot be zero'); + arg1 + arg2 +} +``` + +### Module Documentation + +Module documentation comments provide an overview of the entire module, including its purpose and examples of use. These comments are meant to be placed above the module they're describing and are prefixed with `//!`. This type of documentation gives a broad understanding of what the module does and how it can be used. + +```rust,noplayground +//! # my_module and implementation +//! +//! This is an example description of my_module and some of its features. +//! +//! # Examples +//! +//! ``` +//! mod my_other_module { +//! use path::to::my_module; +//! +//! fn foo() { +//! my_module.bar(); +//! } +//! } +//! ``` +mod my_module { // rest of implementation... +} +``` + +{{#quiz ../quizzes/ch02-04-comments.toml}} +# Control Flow + +The ability to run some code depending on whether a condition is true and to run some code repeatedly while a condition is true are basic building blocks in most programming languages. The most common constructs that let you control the flow of execution of Cairo code are if expressions and loops. + +## `if` Expressions + +An if expression allows you to branch your code depending on conditions. You provide a condition and then state, “If this condition is met, run this block of code. If the condition is not met, do not run this block of code.” + +Create a new project called _branches_ in your _cairo_projects_ directory to explore the `if` expression. In the _src/lib.cairo_ file, input the following: + +```rust +fn main() { + let number = 3; + + if number == 5 { + println!("condition was true and number = {}", number); + } else { + println!("condition was false and number = {}", number); + } +} +``` + +All `if` expressions start with the keyword `if`, followed by a condition. In this case, the condition checks whether or not the variable `number` has a value equal to 5. We place the block of code to execute if the condition is `true` immediately after the condition inside curly brackets. + +Optionally, we can also include an `else` expression, which we chose to do here, to give the program an alternative block of code to execute should the condition evaluate to `false`. If you don’t provide an `else` expression and the condition is `false`, the program will just skip the `if` block and move on to the next bit of code. + +Try running this code; you should see the following output: + +```shell +$ scarb cairo-run + Compiling no_listing_24_if v0.1.0 (listings/ch02-common-programming-concepts/no_listing_27_if/Scarb.toml) + Finished release target(s) in 1 second + Running no_listing_24_if +condition was false and number = 3 +Run completed successfully, returning [] + +``` + +Let’s try changing the value of `number` to a value that makes the condition `true` to see what happens: + +```rust, noplayground + let number = 5; +``` + +```shell +$ scarb cairo-run +condition was true and number = 5 +Run completed successfully, returning [] +``` + +It’s also worth noting that the condition in this code must be a `bool`. If the condition isn’t a `bool`, we’ll get an error. For example, try running the following code: + +```rust +fn main() { + let number = 3; + + if number { + println!("number was three"); + } +} +``` + +The `if` condition evaluates to a value of 3 this time, and Cairo throws an error: + +```shell +$ scarb build + Compiling no_listing_28_bis_if_not_bool v0.1.0 (listings/ch02-common-programming-concepts/no_listing_28_bis_if_not_bool/Scarb.toml) +error: Mismatched types. The type `core::bool` cannot be created from a numeric literal. + --> listings/ch02-common-programming-concepts/no_listing_28_bis_if_not_bool/src/lib.cairo:4:18 + let number = 3; + ^ + +error: could not compile `no_listing_28_bis_if_not_bool` due to previous error + +``` + +The error indicates that Cairo inferred the type of `number` to be a `bool` +based on its later use as a condition of the `if` statement. It tries to create +a `bool` from the value `3`, but Cairo doesn't support instantiating a `bool` +from a numeric literal anyway - you can only use `true` or `false` to create a +`bool`. Unlike languages such as Ruby and JavaScript, Cairo will not +automatically try to convert non-Boolean types to a Boolean. If we want the `if` +code block to run only when a number is not equal to 0, for example, we can +change the if expression to the following: + +```rust +fn main() { + let number = 3; + + if number != 0 { + println!("number was something other than zero"); + } +} + +``` + +Running this code will print `number was something other than zero`. + +## Handling Multiple Conditions with `else if` + +You can use multiple conditions by combining `if` and `else` in an `else if` expression. For example: + +```rust +fn main() { + let number = 3; + + if number == 12 { + println!("number is 12"); + } else if number == 3 { + println!("number is 3"); + } else if number - 2 == 1 { + println!("number minus 2 is 1"); + } else { + println!("number not found"); + } +} +``` + +This program has four possible paths it can take. After running it, you should see the following output: + +```shell +$ scarb cairo-run + Compiling no_listing_25_else_if v0.1.0 (listings/ch02-common-programming-concepts/no_listing_30_else_if/Scarb.toml) + Finished release target(s) in 1 second + Running no_listing_25_else_if +number is 3 +Run completed successfully, returning [] + +``` + +When this program executes, it checks each `if` expression in turn and executes the first body for which the condition evaluates to `true`. Note that even though `number - 2 == 1` is `true`, we don’t see the output `number minus 2 is 1` nor do we see the `number not found` text from the `else` block. That’s because Cairo only executes the block for the first true condition, and once it finds one, it doesn’t even check the rest. Using too many `else if` expressions can clutter your code, so if you have more than one, you might want to refactor your code. [Chapter 6][match] describes a powerful Cairo branching construct called `match` for these cases. + +[match]: ./ch06-02-the-match-control-flow-construct.md + +## Using `if` in a `let` Statement + +Because `if` is an expression, we can use it on the right side of a `let` statement to assign the outcome to a variable. + +```rust +fn main() { + let condition = true; + let number = if condition { + 5 + } else { + 6 + }; + + if number == 5 { + println!("condition was true and number is {}", number); + } +} +``` + +```shell +$ scarb cairo-run + Compiling no_listing_26_if_let v0.1.0 (listings/ch02-common-programming-concepts/no_listing_31_if_let/Scarb.toml) + Finished release target(s) in 1 second + Running no_listing_26_if_let +condition was true and number is 5 +Run completed successfully, returning [] + +``` + +The `number` variable will be bound to a value based on the outcome of the `if` expression, which will be 5 here. + +## Repetition with Loops + +It’s often useful to execute a block of code more than once. For this task, Cairo provides a simple loop syntax, which will run through the code inside the loop body to the end and then start immediately back at the beginning. To experiment with loops, let’s create a new project called _loops_. + +Cairo has two kinds of loops: `loop` and `while`. + +### Repeating Code with `loop` + +The `loop` keyword tells Cairo to execute a block of code over and over again forever or until you explicitly tell it to stop. + +As an example, change the _src/lib.cairo_ file in your _loops_ directory to look like this: + +```rust +fn main() { + loop { + println!("again!"); + if (false) { + break; + } + } +} +``` + +> Note: This program would not compile without a break condition. For the purpose of the example, we added a `break` statement that will never be reached, but satisfies the compiler. + +When we run this program, we’ll see `again!` printed over and over continuously until either the program runs out of gas or we stop the program manually. Most terminals support the keyboard shortcut ctrl-c to interrupt a program that is stuck in a continual loop. Give it a try: + +```shell +$ scarb cairo-run --available-gas=20000000 + Compiling loops v0.1.0 (file:///projects/loops) + Finished release target(s) in 0 seconds + Running loops +again! +again! +again! +^Cagain! +``` + +The symbol `^C` represents where you pressed ctrl-c. You may or may not see the word `again!` printed after the ^C, depending on where the code was in the loop when it received the interrupt signal. + +> Note: Cairo prevents us from running program with infinite loops by including a gas meter. The gas meter is a mechanism that limits the amount of computation that can be done in a program. By setting a value to the `--available-gas` flag, we can set the maximum amount of gas available to the program. Gas is a unit of measurement that expresses the computation cost of an instruction. When the gas meter runs out, the program will stop. In the previous case, we set the gas limit high enough for the program to run for quite some time. + +> It is particularly important in the context of smart contracts deployed on Starknet, as it prevents from running infinite loops on the network. +> If you're writing a program that needs to run a loop, you will need to execute it with the `--available-gas` flag set to a value that is large enough to run the program. + +Now, try running the same program again, but this time with the `--available-gas` flag set to `200000` instead of `2000000000000`. You will see the program only prints `again!` 3 times before it stops, as it ran out of gas to keep executing the loop. + +Fortunately, Cairo also provides a way to break out of a loop using code. You can place the `break` keyword within the loop to tell the program when to stop executing the loop. + +```rust +fn main() { + let mut i: usize = 0; + loop { + if i > 10 { + break; + } + println!("i = {}", i); + i += 1; + } +} +``` + +The `continue` keyword tells the program to go to the next iteration of the loop and to skip the rest of the code in this iteration. +Let's add a `continue` statement to our loop to skip the `println!` statement when `i` is equal to `5`. + +```rust +fn main() { + let mut i: usize = 0; + loop { + if i > 10 { + break; + } + if i == 5 { + i += 1; + continue; + } + println!("i = {}", i); + i += 1; + } +} +``` + +Executing this program will not print the value of `i` when it is equal to `5`. + +### Returning Values from Loops + +One of the uses of a `loop` is to retry an operation you know might fail, such +as checking whether an operation has succeeded. You might also need to pass +the result of that operation out of the loop to the rest of your code. To do +this, you can add the value you want returned after the `break` expression you +use to stop the loop; that value will be returned out of the loop so you can +use it, as shown here: + +```rust +fn main() { + let mut counter = 0; + + let result = loop { + if counter == 10 { + break counter * 2; + } + counter += 1; + }; + + println!("The result is {}", result); +} +``` + +Before the loop, we declare a variable named `counter` and initialize it to +`0`. Then we declare a variable named `result` to hold the value returned from +the loop. On every iteration of the loop, we check whether the `counter` is equal to `10`, and then add `1` to the `counter` variable. +When the condition is met, we use the `break` keyword with the value `counter * 2`. After the loop, we use a +semicolon to end the statement that assigns the value to `result`. Finally, we +print the value in `result`, which in this case is `20`. + +### Conditional Loops with `while` + +A program will often need to evaluate a condition within a loop. +While the condition is `true`, the loop runs. +When the condition ceases to be `true`, the program calls `break`, stopping the loop. +It’s possible to implement behavior like this using a combination of `loop`, `if`, `else`, and `break`; you could try that now in a program, if you’d like. +However, this pattern is so common that Cairo has a built-in language construct for it, called a `while` loop. + +In Listing 2-2, we use `while` to loop the program three times, counting down each time after printing the value of `number`, and then, after the loop, print a message and exit. + +```rust +fn main() { + let mut number = 3; + + while number != 0 { + println!("{number}!"); + number -= 1; + }; + + println!("LIFTOFF!!!"); +} +``` + +Listing 2-2: Using a `while` loop to run code while a condition holds `true`. + +This construct eliminates a lot of nesting that would be necessary if you used `loop`, `if`, `else`, and `break`, and it’s clearer. +While a condition evaluates to `true`, the code runs; otherwise, it exits the loop. + +{{#quiz ../quizzes/ch02-05-control-flow.toml}} + +## Summary + +You made it! This was a sizable chapter: you learned about variables, data types, functions, comments, +`if` expressions and loops! To practice with the concepts discussed in this chapter, +try building programs to do the following: + +- Generate the _n_-th Fibonacci number. +- Compute the factorial of a number _n_. + +Now, we’ll review the common collection types in Cairo in the next chapter. +# Common Collections + +Cairo provides a set of common collection types that can be used to store and manipulate data. These collections are designed to be efficient, flexible, and easy to use. This section introduces the primary collection types available in Cairo: Arrays and Dictionaries. +# Arrays + +An array is a collection of elements of the same type. You can create and use array methods by using the `ArrayTrait` trait from the core library. + +An important thing to note is that arrays have limited modification options. Arrays are, in fact, queues whose values can't be modified. +This has to do with the fact that once a memory slot is written to, it cannot be overwritten, but only read from it. You can only append items to the end of an array and remove items from the front. + +## Creating an Array + +Creating an array is done with the `ArrayTrait::new()` call. Here's an example of creating an array and appending 3 elements to it:: + +```rust +fn main() { + let mut a = ArrayTrait::new(); + a.append(0); + a.append(1); + a.append(2); +} +``` + +When required, you can pass the expected type of items inside the array when instantiating the array like this, or explicitly define the type of the variable. + +```rust, noplayground +let mut arr = ArrayTrait::::new(); +``` + +```rust, noplayground +let mut arr:Array = ArrayTrait::new(); +``` + +## Updating an Array + +### Adding Elements + +To add an element to the end of an array, you can use the `append()` method: + +```rust +# fn main() { +# let mut a = ArrayTrait::new(); +# a.append(0); +# a.append(1); + a.append(2); +# } +``` + +### Removing Elements + +You can only remove elements from the front of an array by using the `pop_front()` method. +This method returns an `Option` that can be unwrapped, containing the removed element, or `Option::None` if the array is empty. + +```rust +fn main() { + let mut a = ArrayTrait::new(); + a.append(10); + a.append(1); + a.append(2); + + let first_value = a.pop_front().unwrap(); + println!("The first value is {}", first_value); +} +``` + +The above code will print `The first value is 10` as we remove the first element that was added. + +In Cairo, memory is immutable, which means that it is not possible to modify the elements of an array once they've been added. You can only add elements to the end of an array and remove elements from the front of an array. These operations do not require memory mutation, as they involve updating pointers rather than directly modifying the memory cells. + +## Reading Elements from an Array + +To access array elements, you can use `get()` or `at()` array methods that return different types. Using `arr.at(index)` is equivalent to using the subscripting operator `arr[index]`. + +### `get()` Method + +The `get` function returns an `Option>`, which means it returns an option to a Box type (Cairo's smart-pointer type) containing a snapshot to the element at the specified index if that element exists in the array. If the element doesn't exist, `get` returns `None`. This method is useful when you expect to access indices that may not be within the array's bounds and want to handle such cases gracefully without panics. Snapshots will be explained in more detail in the ["References and Snapshots"][snapshots] chapter. + +Here is an example with the `get()` method: + +```rust +fn main() -> u128 { + let mut arr = ArrayTrait::::new(); + arr.append(100); + let index_to_access = + 1; // Change this value to see different results, what would happen if the index doesn't exist? + match arr.get(index_to_access) { + Option::Some(x) => { + *x + .unbox() // Don't worry about * for now, if you are curious see Chapter 4.2 #desnap operator + // It basically means "transform what get(idx) returned into a real value" + }, + Option::None => { panic!("out of bounds") } + } +} +``` + +[snapshots]: ./ch04-02-references-and-snapshots.md#snapshots + +### `at()` Method + +The `at` function, on the other hand, directly returns a snapshot to the element at the specified index using the `unbox()` operator to extract the value stored in a box. If the index is out of bounds, a panic error occurs. You should only use `at` when you want the program to panic if the provided index is out of the array's bounds, which can prevent unexpected behavior. + +Here is an example with the `at()` method: + +```rust +fn main() { + let mut a = ArrayTrait::new(); + a.append(0); + a.append(1); + + let first = *a.at(0); + let second = *a.at(1); +} +``` + +In this example, the variable named `first` will get the value `0` because that +is the value at index `0` in the array. The variable named `second` will get +the value `1` from index `1` in the array. + +If you want to use the subscripting operator `arr[index]`, you will need to explicitly define the type of the elements of the array, otherwise it will not compile. For example: + +```rust +fn main() { + let mut a: Array = ArrayTrait::new(); + a.append(0); + a.append(1); + + let first = a[0]; + let second = a[1]; +} +``` + +In summary, use `at` when you want to panic on out-of-bounds access attempts, and use `get` when you prefer to handle such cases gracefully without panicking. + +## Size-related Methods + +To determine the number of elements in an array, use the `len()` method. The return value is of type `usize`. + +If you want to check if an array is empty or not, you can use the `is_empty()` method, which returns `true` if the array is empty and `false` otherwise. + +## `array!` Macro + +Sometimes, we need to create arrays with values that are already known at compile time. The basic way of doing that is redundant. You would first declare the array and then append each value one by one. `array!` is a simpler way of doing this task by combining the two steps. +At compile-time, the compiler will expand the macro to generate the code that appends the items sequentially. + +Without `array!`: + +```rust + let mut arr = ArrayTrait::new(); + arr.append(1); + arr.append(2); + arr.append(3); + arr.append(4); + arr.append(5); +``` + +With `array!`: + +```rust + let arr = array![1, 2, 3, 4, 5]; +``` + +## Storing Multiple Types with Enums + +If you want to store elements of different types in an array, you can use an `Enum` to define a custom data type that can hold multiple types. Enums will be explained in more detail in the ["Enums and Pattern Matching"][enums] chapter. + +```rust +#[derive(Copy, Drop)] +enum Data { + Integer: u128, + Felt: felt252, + Tuple: (u32, u32), +} + +fn main() { + let mut messages: Array = array![]; + messages.append(Data::Integer(100)); + messages.append(Data::Felt('hello world')); + messages.append(Data::Tuple((10, 30))); +} +``` + +[enums]: ./ch06-00-enums-and-pattern-matching.md + +## Span + +`Span` is a struct that represents a snapshot of an `Array`. It is designed to provide safe and controlled access to the elements of an array without modifying the original array. Span is particularly useful for ensuring data integrity and avoiding borrowing issues when passing arrays between functions or when performing read-only operations, as introduced in ["References and Snapshots"][references]. + +All methods provided by `Array` can also be used with `Span`, except for the `append()` method. + +[references]: ./ch04-02-references-and-snapshots.md + +### Turning an Array into Span + +To create a `Span` of an `Array`, call the `span()` method: + +```rust +# fn main() { +# let mut array: Array = ArrayTrait::new(); + array.span(); +# } +``` + +{{#quiz ../quizzes/ch03-01-arrays.toml}} +# Dictionaries + +Cairo provides in its core library a dictionary-like type. The `Felt252Dict` data type represents a collection of key-value pairs where each key is unique and associated with a corresponding value. This type of data structure is known differently across different programming languages such as maps, hash tables, associative arrays and many others. + +The `Felt252Dict` type is useful when you want to organize your data in a certain way for which using an `Array` and indexing doesn't suffice. Cairo dictionaries also allow the programmer to easily simulate the existence of mutable memory when there is none. + +## Basic Use of Dictionaries + +It is normal in other languages when creating a new dictionary to define the data types of both key and value. In Cairo, the key type is restricted to `felt252`, leaving only the possibility to specify the value data type, represented by `T` in `Felt252Dict`. + +The core functionality of a `Felt252Dict` is implemented in the trait `Felt252DictTrait` which includes all basic operations. Among them we can find: + +1. `insert(felt252, T) -> ()` to write values to a dictionary instance and +2. `get(felt252) -> T` to read values from it. + +These functions allow us to manipulate dictionaries like in any other language. In the following example, we create a dictionary to represent a mapping between individuals and their balance: + +```rust +fn main() { + let mut balances: Felt252Dict = Default::default(); + + balances.insert('Alex', 100); + balances.insert('Maria', 200); + + let alex_balance = balances.get('Alex'); + assert!(alex_balance == 100, "Balance is not 100"); + + let maria_balance = balances.get('Maria'); + assert!(maria_balance == 200, "Balance is not 200"); +} +``` + +We can create a new instance of `Felt252Dict` by using the `default` method of the `Default` trait and add two individuals, each one with their own balance, using the `insert` method. Finally, we check the balance of our users with the `get` method. These methods are defined in the `Felt252DictTrait` trait in the core library. + +Throughout the book we have talked about how Cairo's memory is immutable, meaning you can only write to a memory cell once but the `Felt252Dict` type represents a way to overcome this obstacle. We will explain how this is implemented later on in ["Dictionaries Underneath"][dict underneath]. + +Building upon our previous example, let us show a code example where the balance of the same user changes: + +```rust +fn main() { + let mut balances: Felt252Dict = Default::default(); + + // Insert Alex with 100 balance + balances.insert('Alex', 100); + // Check that Alex has indeed 100 associated with him + let alex_balance = balances.get('Alex'); + assert!(alex_balance == 100, "Alex balance is not 100"); + + // Insert Alex again, this time with 200 balance + balances.insert('Alex', 200); + // Check the new balance is correct + let alex_balance_2 = balances.get('Alex'); + assert!(alex_balance_2 == 200, "Alex balance is not 200"); +} +``` + +Notice how in this example we added the 'Alex' individual twice, each time using a different balance and each time that we checked for its balance it had the last value inserted! `Felt252Dict` effectively allows us to "rewrite" the stored value for any given key. + +Before heading on and explaining how dictionaries are implemented it is worth mentioning that once you instantiate a `Felt252Dict`, behind the scenes all keys have their associated values initialized as zero. This means that if for example, you tried to get the balance of an inexistent user you will get 0 instead of an error or an undefined value. This also means there is no way to delete data from a dictionary. Something to take into account when incorporating this structure into your code. + +Until this point, we have seen all the basic features of `Felt252Dict` and how it mimics the same behavior as the corresponding data structures in any other language, that is, externally of course. Cairo is at its core a non-deterministic Turing-complete programming language, very different from any other popular language in existence, which as a consequence means that dictionaries are implemented very differently as well! + +In the following sections, we are going to give some insights about `Felt252Dict` inner mechanisms and the compromises that were taken to make them work. After that, we are going to take a look at how to use dictionaries with other data structures as well as use the `entry` method as another way to interact with them. + +[dict underneath]: ./ch03-02-dictionaries.md#dictionaries-underneath + +## Dictionaries Underneath + +One of the constraints of Cairo's non-deterministic design is that its memory system is immutable, so in order to simulate mutability, the language implements `Felt252Dict` as a list of entries. Each of the entries represents a time when a dictionary was accessed for reading/updating/writing purposes. An entry has three fields: + +1. A `key` field that identifies the key for this key-value pair of the dictionary. +2. A `previous_value` field that indicates which previous value was held at `key`. +3. A `new_value` field that indicates the new value that is held at `key`. + +If we try implementing `Felt252Dict` using high-level structures we would internally define it as `Array>` where each `Entry` has information about what key-value pair it represents and the previous and new values it holds. The definition of `Entry` would be: + +```rust,noplayground +struct Entry { + key: felt252, + previous_value: T, + new_value: T, +} +``` + +For each time we interact with a `Felt252Dict`, a new `Entry` will be registered: + +- A `get` would register an entry where there is no change in state, and previous and new values are stored with the same value. +- An `insert` would register a new `Entry` where the `new_value` would be the element being inserted, and the `previous_value` the last element inserted before this. In case it is the first entry for a certain key, then the previous value will be zero. + +The use of this entry list shows how there isn't any rewriting, just the creation of new memory cells per `Felt252Dict` interaction. Let's show an example of this using the `balances` dictionary from the previous section and inserting the users 'Alex' and 'Maria': + +```rust +# struct Entry { +# key: felt252, +# previous_value: T, +# new_value: T, +# } +# +# fn main() { +# let mut balances: Felt252Dict = Default::default(); + balances.insert('Alex', 100_u64); + balances.insert('Maria', 50_u64); + balances.insert('Alex', 200_u64); + balances.get('Maria'); +# } +``` + +These instructions would then produce the following list of entries: + +| key | previous | new | +| :---: | -------- | --- | +| Alex | 0 | 100 | +| Maria | 0 | 50 | +| Alex | 100 | 200 | +| Maria | 50 | 50 | + +Notice that since 'Alex' was inserted twice, it appears twice and the `previous` and `current` values are set properly. Also reading from 'Maria' registered an entry with no change from previous to current values. + +This approach to implementing `Felt252Dict` means that for each read/write operation, there is a scan for the whole entry list in search of the last entry with the same `key`. Once the entry has been found, its `new_value` is extracted and used on the new entry to be added as the `previous_value`. This means that interacting with `Felt252Dict` has a worst-case time complexity of `O(n)` where `n` is the number of entries in the list. + +If you pour some thought into alternate ways of implementing `Felt252Dict` you'd surely find them, probably even ditching completely the need for a `previous_value` field, nonetheless, since Cairo is not your normal language this won't work. +One of the purposes of Cairo is, with the STARK proof system, to generate proofs of computational integrity. This means that you need to verify that program execution is correct and inside the boundaries of Cairo restrictions. One of those boundary checks consists of "dictionary squashing" and that requires information on both previous and new values for every entry. + +## Squashing Dictionaries + +To verify that the proof generated by a Cairo program execution that used a `Felt252Dict` is correct, we need to check that there wasn't any illegal tampering with the dictionary. This is done through a method called `squash_dict` that reviews each entry of the entry list and checks that access to the dictionary remains coherent throughout the execution. + +The process of squashing is as follows: given all entries with certain key `k`, taken in the same order as they were inserted, verify that the ith entry `new_value` is equal to the ith + 1 entry `previous_value`. + +For example, given the following entry list: + +| key | previous | new | +| :-----: | -------- | --- | +| Alex | 0 | 150 | +| Maria | 0 | 100 | +| Charles | 0 | 70 | +| Maria | 100 | 250 | +| Alex | 150 | 40 | +| Alex | 40 | 300 | +| Maria | 250 | 190 | +| Alex | 300 | 90 | + +After squashing, the entry list would be reduced to: + +| key | previous | new | +| :-----: | -------- | --- | +| Alex | 0 | 90 | +| Maria | 0 | 190 | +| Charles | 0 | 70 | + +In case of a change on any of the values of the first table, squashing would have failed during runtime. + +## Dictionary Destruction + +If you run the examples from ["Basic Use of Dictionaries"][basic dictionaries] section, you'd notice that there was never a call to squash dictionary, but the program compiled successfully nonetheless. What happened behind the scene was that squash was called automatically via the `Felt252Dict` implementation of the `Destruct` trait. This call occurred just before the `balance` dictionary went out of scope. + +The `Destruct` trait represents another way of removing instances out of scope apart from `Drop`. The main difference between these two is that `Drop` is treated as a no-op operation, meaning it does not generate new CASM while `Destruct` does not have this restriction. The only type which actively uses the `Destruct` trait is `Felt252Dict`, for every other type `Destruct` and `Drop` are synonyms. You can read more about these traits in [Drop and Destruct][drop destruct] section of Appendix C. + +Later in ["Dictionaries as Struct Members"][dictionaries in structs] section, we will have a hands-on example where we implement the `Destruct` trait for a custom type. + +[basic dictionaries]: ./ch03-02-dictionaries.md#basic-use-of-dictionaries +[drop destruct]: ./appendix-03-derivable-traits.md#drop-and-destruct +[dictionaries in structs]: ./ch11-01-custom-data-structures.html#dictionaries-as-struct-members + +## More Dictionaries + +Up to this point, we have given a comprehensive overview of the functionality of `Felt252Dict` as well as how and why it is implemented in a certain way. If you haven't understood all of it, don't worry because in this section we will have some more examples using dictionaries. + +We will start by explaining the `entry` method which is part of a dictionary basic functionality included in `Felt252DictTrait` which we didn't mention at the beginning. Soon after, we will see examples of how to use `Felt252Dict` with other [complex types][nullable dictionaries values] such as `Array`. + +[nullable dictionaries values]: ./ch03-02-dictionaries.md#dictionaries-of-types-not-supported-natively + +## Entry and Finalize + +In the ["Dictionaries Underneath"][dict underneath] section, we explained how `Felt252Dict` internally worked. It was a list of entries for each time the dictionary was accessed in any manner. It would first find the last entry given a certain `key` and then update it accordingly to whatever operation it was executing. The Cairo language gives us the tools to replicate this ourselves through the `entry` and `finalize` methods. + +The `entry` method comes as part of `Felt252DictTrait` with the purpose of creating a new entry given a certain key. Once called, this method takes ownership of the dictionary and returns the entry to update. The method signature is as follows: + +```rust,noplayground +fn entry(self: Felt252Dict, key: felt252) -> (Felt252DictEntry, T) nopanic +``` + +The first input parameter takes ownership of the dictionary while the second one is used to create the appropriate entry. It returns a tuple containing a `Felt252DictEntry`, which is the type used by Cairo to represent dictionary entries, and a `T` representing the value held previously. +The `nopanic` notation simply indicates that the function is guaranteed to never panic. + +The next thing to do is to update the entry with the new value. For this, we use the `finalize` method which inserts the entry and returns ownership of the dictionary: + +```rust,noplayground +fn finalize(self: Felt252DictEntry, new_value: T) -> Felt252Dict +``` + +This method receives the entry and the new value as parameters, and returns the updated dictionary. + +Let us see an example using `entry` and `finalize`. Imagine we would like to implement our own version of the `get` method from a dictionary. We should then do the following: + +1. Create the new entry to add using the `entry` method. +2. Insert back the entry where the `new_value` equals the `previous_value`. +3. Return the value. + +Implementing our custom get would look like this: + +```rust,noplayground +use core::dict::Felt252DictEntryTrait; + +fn custom_get, +Drop, +Copy>( + ref dict: Felt252Dict, key: felt252 +) -> T { + // Get the new entry and the previous value held at `key` + let (entry, prev_value) = dict.entry(key); + + // Store the value to return + let return_value = prev_value; + + // Update the entry with `prev_value` and get back ownership of the dictionary + dict = entry.finalize(prev_value); + + // Return the read value + return_value +} +``` + +The `ref` keyword means that the ownership of the variable will be given back at the end of +the function. This concept will be explained in more detail in the ["References and Snapshots"][references] section. + +Implementing the `insert` method would follow a similar workflow, except for inserting a new value when finalizing. If we were to implement it, it would look like the following: + +```rust,noplayground +use core::dict::Felt252DictEntryTrait; + +fn custom_insert, +Destruct, +Drop>( + ref dict: Felt252Dict, key: felt252, value: T +) { + // Get the last entry associated with `key` + // Notice that if `key` does not exist, `_prev_value` will + // be the default value of T. + let (entry, _prev_value) = dict.entry(key); + + // Insert `entry` back in the dictionary with the updated value, + // and receive ownership of the dictionary + dict = entry.finalize(value); +} +``` + +As a finalizing note, these two methods are implemented in a similar way to how `insert` and `get` are implemented for `Felt252Dict`. This code shows some example usage: + +```rust +# use core::dict::Felt252DictEntryTrait; +# +# fn custom_get, +Drop, +Copy>( +# ref dict: Felt252Dict, key: felt252 +# ) -> T { +# // Get the new entry and the previous value held at `key` +# let (entry, prev_value) = dict.entry(key); +# +# // Store the value to return +# let return_value = prev_value; +# +# // Update the entry with `prev_value` and get back ownership of the dictionary +# dict = entry.finalize(prev_value); +# +# // Return the read value +# return_value +# } +# +# fn custom_insert, +Destruct, +Drop>( +# ref dict: Felt252Dict, key: felt252, value: T +# ) { +# // Get the last entry associated with `key` +# // Notice that if `key` does not exist, `_prev_value` will +# // be the default value of T. +# let (entry, _prev_value) = dict.entry(key); +# +# // Insert `entry` back in the dictionary with the updated value, +# // and receive ownership of the dictionary +# dict = entry.finalize(value); +# } +# +fn main() { + let mut dict: Felt252Dict = Default::default(); + + custom_insert(ref dict, '0', 100); + + let val = custom_get(ref dict, '0'); + + assert!(val == 100, "Expecting 100"); +} +# +# +``` + +[dict underneath]: ./ch03-02-dictionaries.md#dictionaries-underneath +[references]: ./ch04-02-references-and-snapshots.md + +## Dictionaries of Types not Supported Natively + +One restriction of `Felt252Dict` that we haven't talked about is the trait `Felt252DictValue`. +This trait defines the `zero_default` method which is the one that gets called when a value does not exist in the dictionary. +This is implemented by some common data types, such as most unsigned integers, `bool` and `felt252` - but it is not implemented for more complex types such as arrays, structs (including `u256`), and other types from the core library. +This means that making a dictionary of types not natively supported is not a straightforward task, because you would need to write a couple of trait implementations in order to make the data type a valid dictionary value type. +To compensate this, you can wrap your type inside a `Nullable`. + +`Nullable` is a smart pointer type that can either point to a value or be `null` in the absence of value. It is usually used in Object Oriented Programming Languages when a reference doesn't point anywhere. The difference with `Option` is that the wrapped value is stored inside a `Box` data type. The `Box` type is a smart pointer that allows us to use a dedicated `boxed_segment` memory segment for our data, and access this segment using a pointer that can only be manipulated in one place at a time. See [Smart Pointers Chapter](./ch11-02-smart-pointers.md) for more information. + +Let's show using an example. We will try to store a `Span` inside a dictionary. For that, we will use `Nullable` and `Box`. Also, we are storing a `Span` and not an `Array` because the latter does not implement the `Copy` trait which is required for reading from a dictionary. + +```rust,noplayground +use core::nullable::{NullableTrait, match_nullable, FromNullableResult}; + +fn main() { + // Create the dictionary + let mut d: Felt252Dict>> = Default::default(); + + // Create the array to insert + let a = array![8, 9, 10]; + + // Insert it as a `Span` + d.insert(0, NullableTrait::new(a.span())); + +//... +``` + +In this code snippet, the first thing we did was to create a new dictionary `d`. We want it to hold a `Nullable`. After that, we created an array and filled it with values. + +The last step is inserting the array as a span inside the dictionary. Notice that we do this using the `new` function of the `NullableTrait`. + +Once the element is inside the dictionary, and we want to get it, we follow the same steps but in reverse order. The following code shows how to achieve that: + +```rust,noplayground +//... + + // Get value back + let val = d.get(0); + + // Search the value and assert it is not null + let span = match match_nullable(val) { + FromNullableResult::Null => panic!("No value found"), + FromNullableResult::NotNull(val) => val.unbox(), + }; + + // Verify we are having the right values + assert!(*span.at(0) == 8, "Expecting 8"); + assert!(*span.at(1) == 9, "Expecting 9"); + assert!(*span.at(2) == 10, "Expecting 10"); +} +``` + +Here we: + +1. Read the value using `get`. +2. Verified it is non-null using the `match_nullable` function. +3. Unwrapped the value inside the box and asserted it was correct. + +The complete script would look like this: + +```rust +use core::nullable::{NullableTrait, match_nullable, FromNullableResult}; + +fn main() { + // Create the dictionary + let mut d: Felt252Dict>> = Default::default(); + + // Create the array to insert + let a = array![8, 9, 10]; + + // Insert it as a `Span` + d.insert(0, NullableTrait::new(a.span())); + + // Get value back + let val = d.get(0); + + // Search the value and assert it is not null + let span = match match_nullable(val) { + FromNullableResult::Null => panic!("No value found"), + FromNullableResult::NotNull(val) => val.unbox(), + }; + + // Verify we are having the right values + assert!(*span.at(0) == 8, "Expecting 8"); + assert!(*span.at(1) == 9, "Expecting 9"); + assert!(*span.at(2) == 10, "Expecting 10"); +} + +``` + +## Using Arrays inside Dictionaries + +In the previous section, we explored how to store and retrieve complex types inside a dictionary using `Nullable` and `Box`. Now, let's take a look at how to store an array inside a dictionary and dynamically modify its contents. + +Storing arrays in dictionaries in Cairo is slightly different from storing other types. This is because arrays are more complex data structures that require special handling to avoid issues with memory copying and references. + +First, let's look at how to create a dictionary and insert an array into it. This process is pretty straightforward and follows a similar pattern to inserting other types of data: + +```rust +fn main() { + let arr = array![20, 19, 26]; + let mut dict: Felt252Dict>> = Default::default(); + dict.insert(0, NullableTrait::new(arr)); + println!("Array inserted successfully."); +} +``` + +However, attempting to read an array from the dictionary using the `get` method will result in a compiler error. This is because `get` tries to copy the array in memory, which is not possible for arrays (as we've already mentioned in the [previous section][nullable dictionaries values], `Array` does not implement the `Copy` trait): + +```rust +use core::nullable::{match_nullable, FromNullableResult}; + +fn main() { + let arr = array![20, 19, 26]; + let mut dict: Felt252Dict>> = Default::default(); + dict.insert(0, NullableTrait::new(arr)); + println!("Array: {:?}", get_array_entry(ref dict, 0)); +} + +fn get_array_entry(ref dict: Felt252Dict>>, index: felt252) -> Span { + let val = dict.get(0); // This will cause a compiler error + let arr = match match_nullable(val) { + FromNullableResult::Null => panic!("No value!"), + FromNullableResult::NotNull(val) => val.unbox() + }; + arr.span() +} +``` + +```shell +$ scarb cairo-run + Compiling no_listing_15_dict_of_array_attempt_get v0.1.0 (listings/ch03-common-collections/no_listing_15_dict_of_array_attempt_get/Scarb.toml) +error: Trait has no implementation in context: core::traits::Copy::>> + --> listings/ch03-common-collections/no_listing_15_dict_of_array_attempt_get/src/lib.cairo:12:20 + let val = dict.get(0); // This will cause a compiler error + ^*^ + +error: could not compile `no_listing_15_dict_of_array_attempt_get` due to previous error +error: `scarb metadata` exited with error + +``` + +To correctly read an array from the dictionary, we need to use dictionary entries. This allows us to get a reference to the array value without copying it: + +```rust,noplayground +fn get_array_entry(ref dict: Felt252Dict>>, index: felt252) -> Span { + let (entry, _arr) = dict.entry(index); + let mut arr = _arr.deref_or(array![]); + let span = arr.span(); + dict = entry.finalize(NullableTrait::new(arr)); + span +} +``` + +> Note: We must convert the array to a `Span` before finalizing the entry, because calling `NullableTrait::new(arr)` moves the array, thus making it impossible to return it from the function. + +To modify the stored array, such as appending a new value, we can use a similar approach. The following `append_value` function demonstrates this: + +```rust,noplayground +fn append_value(ref dict: Felt252Dict>>, index: felt252, value: u8) { + let (entry, arr) = dict.entry(index); + let mut unboxed_val = arr.deref_or(array![]); + unboxed_val.append(value); + dict = entry.finalize(NullableTrait::new(unboxed_val)); +} +``` + +In the `append_value` function, we access the dictionary entry, dereference the array, append the new value, and finalize the entry with the updated array. + +> Note: Removing an item from a stored array can be implemented in a similar manner. + +Below is the complete example demonstrating the creation, insertion, reading, and modification of an array in a dictionary: + +```rust +use core::nullable::NullableTrait; +use core::dict::Felt252DictEntryTrait; + +fn append_value(ref dict: Felt252Dict>>, index: felt252, value: u8) { + let (entry, arr) = dict.entry(index); + let mut unboxed_val = arr.deref_or(array![]); + unboxed_val.append(value); + dict = entry.finalize(NullableTrait::new(unboxed_val)); +} + +fn get_array_entry(ref dict: Felt252Dict>>, index: felt252) -> Span { + let (entry, _arr) = dict.entry(index); + let mut arr = _arr.deref_or(array![]); + let span = arr.span(); + dict = entry.finalize(NullableTrait::new(arr)); + span +} + +fn main() { + let arr = array![20, 19, 26]; + let mut dict: Felt252Dict>> = Default::default(); + dict.insert(0, NullableTrait::new(arr)); + println!("Before insertion: {:?}", get_array_entry(ref dict, 0)); + + append_value(ref dict, 0, 30); + + println!("After insertion: {:?}", get_array_entry(ref dict, 0)); +} +``` + +{{#quiz ../quizzes/ch03-02-dictionaries.toml}} +# Understanding Cairo's Ownership system + +Cairo is a language built around a linear type system that allows us to +statically ensure that in every Cairo program, a value is used exactly once. +This linear type system helps prevent runtime errors by ensuring that operations that could cause such errors, such as writing twice to a memory cell, are detected at compile time. +This is achieved by implementing an ownership system +and forbidding copying and dropping values by default. In this chapter, we’ll +talk about Cairo's ownership system as well as references and snapshots. +# Ownership Using a Linear Type System + +Cairo uses a linear type system. In such a type system, any value (a basic type, a struct, an enum) must be used and must only be used once. 'Used' here means that the value is either _destroyed_ or _moved_. + +_Destruction_ can happen in several ways: + +- a variable goes out of scope. +- a struct is destructured. +- explicit destruction using `destruct()`. + +_Moving_ a value simply means passing that value to another function. + +This results in somewhat similar constraints to the Rust ownership model, but there are some differences. +In particular, the Rust ownership model exists (in part) to avoid data races and concurrent mutable access to a memory value. This is obviously impossible in Cairo since the memory is immutable. +Instead, Cairo leverages its linear type system for two main purposes: + +- Ensuring that all code is provable and thus verifiable. +- Abstracting away the immutable memory of the Cairo VM. + +### Ownership + +In Cairo, ownership applies to _variables_ and not to _values_. A value can safely be referred to by many different variables (even if they are mutable variables), as the value itself is always immutable. +Variables however can be mutable, so the compiler must ensure that constant variables aren't accidentally modified by the programmer. +This makes it possible to talk about ownership of a variable: the owner is the code that can read (and write if mutable) the variable. + +This means that variables (not values) follow similar rules to Rust values: + +- Each variable in Cairo has an owner. +- There can only be one owner at a time. +- When the owner goes out of scope, the variable is destroyed. + +Now that we’re past basic Cairo syntax, we won’t include all the `fn main() {` code in examples, so if you’re following along, make sure to put the following examples inside a main function manually. As a result, our examples will be a bit more concise, letting us focus on the actual details rather than boilerplate code. + +## Variable Scope + +As a first example of the linear type system, we’ll look at the _scope_ of some variables. A +scope is the range within a program for which an item is valid. Take the +following variable: + +```rust,noplayground +let s = 'hello'; +``` + +The variable `s` refers to a short string. The variable is valid from the point at +which it’s declared until the end of the current _scope_. Listing 4-1 shows a +program with comments annotating where the variable `s` would be valid. + +```rust +# //TAG: ignore_fmt +# fn main() { + { // s is not valid here, it’s not yet declared + let s = 'hello'; // s is valid from this point forward + // do stuff with s + } // this scope is now over, and s is no longer valid +# } +``` + +Listing 4-1: A variable and the scope in which it is valid + +In other words, there are two important points in time here: + +- When `s` comes _into_ scope, it is valid. +- It remains valid until it goes _out of_ scope. + +At this point, the relationship between scopes and when variables are valid is similar to that in other programming languages. Now we’ll build on top of this understanding by using the `Array` type we introduced in the previous ["Arrays"][array] section. + +[array]: ./ch03-01-arrays.md + +### Moving values + +As said earlier, _moving_ a value simply means passing that value to another function. When that happens, the variable referring to that value in the original scope is destroyed and can no longer be used, and a new variable is created to hold the same value. + +Arrays are an example of a complex type that is moved when passing it to another function. +Here is a short reminder of what an array looks like: + +```rust +# fn main() { + let mut arr: Array = array![]; + arr.append(1); + arr.append(2); +# } +``` + +How does the type system ensure that the Cairo program never tries to write to the same memory cell twice? +Consider the following code, where we try to remove the front of the array twice: + +```rust,does_not_compile +fn foo(mut arr: Array) { + arr.pop_front(); +} + +fn main() { + let mut arr: Array = array![]; + foo(arr); + foo(arr); +} +``` + +In this case, we try to pass the same value (the array in the `arr` variable) to both function calls. This means our code tries to remove the first element twice, which would try to write to the same memory cell twice - which is forbidden by the Cairo VM, leading to a runtime error. +Thankfully, this code does not actually compile. Once we have passed the array to the `foo` function, the variable `arr` is no longer usable. We get this compile-time error, telling us that we would need Array to implement the Copy Trait: + +```shell +$ scarb cairo-run + Compiling no_listing_02_pass_array_by_value v0.1.0 (listings/ch04-understanding-ownership/no_listing_02_pass_array_by_value/Scarb.toml) +warn: Unhandled `#[must_use]` type `core::option::Option::` + --> listings/ch04-understanding-ownership/no_listing_02_pass_array_by_value/src/lib.cairo:3:5 + arr.pop_front(); + ^*************^ + +error: Variable was previously moved. + --> listings/ch04-understanding-ownership/no_listing_02_pass_array_by_value/src/lib.cairo:9:9 + foo(arr); + ^*^ +note: variable was previously used here: + --> listings/ch04-understanding-ownership/no_listing_02_pass_array_by_value/src/lib.cairo:8:9 + foo(arr); + ^*^ +note: Trait has no implementation in context: core::traits::Copy::> + +error: could not compile `no_listing_02_pass_array_by_value` due to previous error +error: `scarb metadata` exited with error + +``` + +## The `Copy` Trait + +If a type implements the `Copy` trait, passing a value of that type to a function does not move the value. Instead, a new variable is created, referring to the same value. +The important thing to note here is that this is a completely free operation because variables are a Cairo abstraction only and because _values_ in Cairo are always immutable. This, in particular, conceptually differs from the Rust version of the `Copy` trait, where the value is potentially copied in memory. + +All basic types previously described in ["Data Types"][data types] implement by default the `Copy` trait. + +While Arrays and Dictionaries can't be copied, custom types that don't contain either of them can be. +You can implement the `Copy` trait on your type by adding the `#[derive(Copy)]` annotation to your type definition. However, Cairo won't allow a type to be annotated with Copy if the type itself or any of its components doesn't implement the Copy trait. + +```rust,ignore_format +#[derive(Copy, Drop)] +struct Point { + x: u128, + y: u128, +} + +fn main() { + let p1 = Point { x: 5, y: 10 }; + foo(p1); + foo(p1); +} + +fn foo(p: Point) { // do something with p +} +``` + +In this example, we can pass `p1` twice to the foo function because the `Point` type implements the `Copy` trait. This means that when we pass `p1` to `foo`, we are actually passing a copy of `p1`, so `p1` remains valid. In ownership terms, this means that the ownership of `p1` remains with the `main` function. +If you remove the `Copy` trait derivation from the `Point` type, you will get a compile-time error when trying to compile the code. + +_Don't worry about the `Struct` keyword. We will introduce this in [Chapter 5][structs]._ + +[data types]: ./ch02-02-data-types.md +[structs]: ./ch05-00-using-structs-to-structure-related-data.md + +## Destroying Values - Example with FeltDict + +The other way linear types can be _used_ is by being destroyed. Destruction must ensure that the 'resource' is now correctly released. In Rust, for example, this could be closing the access to a file, or locking a mutex. +In Cairo, one type that has such behaviour is `Felt252Dict`. For provability, dicts must be 'squashed' when they are destructed. +This would be very easy to forget, so it is enforced by the type system and the compiler. + +### No-op Destruction: the `Drop` Trait + +You may have noticed that the `Point` type in the previous example also implements the `Drop` trait. +For example, the following code will not compile, because the struct `A` is not moved or destroyed before it goes out of scope: + +```rust,does_not_compile +struct A {} + +fn main() { + A {}; // error: Variable not dropped. +} +``` + +However, types that implement the `Drop` trait are automatically destroyed when going out of scope. This destruction does nothing, it is a no-op - simply a hint to the compiler that this type can safely be destroyed once it's no longer useful. We call this "dropping" a value. + +At the moment, the `Drop` implementation can be derived for all types, allowing them to be dropped when going out of scope, except for dictionaries (`Felt252Dict`) and types containing dictionaries. +For example, the following code compiles: + +```rust +#[derive(Drop)] +struct A {} + +fn main() { + A {}; // Now there is no error. +} +``` + +### Destruction with a Side-effect: the `Destruct` Trait + +When a value is destroyed, the compiler first tries to call the `drop` method on that type. If it doesn't exist, then the compiler tries to call `destruct` instead. This method is provided by the `Destruct` trait. + +As said earlier, dictionaries in Cairo are types that must be "squashed" when destructed, so that the sequence of access can be proven. This is easy for developers to forget, so instead dictionaries implement the `Destruct` trait to ensure that all dictionaries are _squashed_ when going out of scope. +As such, the following example will not compile: + +```rust,does_not_compile +struct A { + dict: Felt252Dict +} + +fn main() { + A { dict: Default::default() }; +} +``` + +If you try to run this code, you will get a compile-time error: + +```shell +$ scarb cairo-run + Compiling no_listing_06_no_destruct_compile_fails v0.1.0 (listings/ch04-understanding-ownership/no_listing_06_no_destruct_compile_fails/Scarb.toml) +error: Variable not dropped. + --> listings/ch04-understanding-ownership/no_listing_06_no_destruct_compile_fails/src/lib.cairo:7:5 + A { dict: Default::default() }; + ^****************************^ +note: Trait has no implementation in context: core::traits::Drop:: +note: Trait has no implementation in context: core::traits::Destruct:: + +error: could not compile `no_listing_06_no_destruct_compile_fails` due to previous error +error: `scarb metadata` exited with error + +``` + +When `A` goes out of scope, it can't be dropped as it implements neither the `Drop` (as it contains a dictionary and can't `derive(Drop)`) nor the `Destruct` trait. To fix this, we can derive the `Destruct` trait implementation for the `A` type: + +```rust +#[derive(Destruct)] +struct A { + dict: Felt252Dict +} + +fn main() { + A { dict: Default::default() }; // No error here +} +``` + +Now, when `A` goes out of scope, its dictionary will be automatically `squashed`, and the program will compile. + +## Copy Array Data with `clone` + +If we _do_ want to deeply copy the data of an `Array`, we can use a common method called `clone`. We’ll discuss method syntax in a dedicated section in [Chapter 5][method syntax], but because methods are a common feature in many programming languages, you’ve probably seen them before. + +Here’s an example of the `clone` method in action. + +```rust +fn main() { + let arr1: Array = array![]; + let arr2 = arr1.clone(); +} +``` + +When you see a call to `clone`, you know that some arbitrary code is being executed and that code may be expensive. It’s a visual indicator that something different is going on. +In this case, the _value_ `arr1` refers to is being copied, resulting in new memory cells being used, and a new _variable_ `arr2` is created, referring to the new copied value. + +[method syntax]: ./ch05-03-method-syntax.md + +## Return Values and Scope + +Returning values is equivalent to _moving_ them. Listing 4-2 shows an example of a +function that returns some value, with similar annotations as those in Listing 4-1. + +Filename: src/lib.cairo + +```rust +#[derive(Drop)] +struct A {} + +fn main() { + let a1 = gives_ownership(); // gives_ownership moves its return + // value into a1 + + let a2 = A {}; // a2 comes into scope + + let a3 = takes_and_gives_back(a2); // a2 is moved into + // takes_and_gives_back, which also + // moves its return value into a3 + +} // Here, a3 goes out of scope and is dropped. a2 was moved, so nothing + // happens. a1 goes out of scope and is dropped. + +fn gives_ownership() -> A { // gives_ownership will move its + // return value into the function + // that calls it + + let some_a = A {}; // some_a comes into scope + + some_a // some_a is returned and + // moves ownership to the calling + // function +} + +// This function takes an instance some_a of A and returns it +fn takes_and_gives_back(some_a: A) -> A { // some_a comes into scope + + some_a // some_a is returned and + // moves ownership to the calling + // function +} +``` + +Listing 4-2: Moving return values + +While this works, moving into and out of every function is a bit tedious. What if we want to let a function use a value but not move the value? It’s quite annoying that anything we pass in also needs to be passed back if we want to use it again, in addition to any data resulting from the body of the function that we might want to return as well. + +Cairo does let us return multiple values using a tuple, as shown in Listing 4-3. + +Filename: src/lib.cairo + +```rust +fn main() { + let arr1: Array = array![]; + + let (arr2, len) = calculate_length(arr1); +} + +fn calculate_length(arr: Array) -> (Array, usize) { + let length = arr.len(); // len() returns the length of an array + + (arr, length) +} +``` + +Listing 4-3: Returning many values + +But this is too much ceremony and a lot of work for a concept that should be common. Luckily for us, Cairo has two features for passing a value without destroying or moving it, called _references_ and _snapshots_. +# References and Snapshots + +The issue with the tuple code in previous Listing 4-3 is that we have to return the +`Array` to the calling function so we can still use the `Array` after the +call to `calculate_length`, because the `Array` was moved into +`calculate_length`. + +## Snapshots + +In the previous chapter, we talked about how Cairo's ownership system prevents +us from using a variable after we've moved it, protecting us from potentially +writing twice to the same memory cell. However, it's not very convenient. +Let's see how we can retain ownership of the variable in the calling function using snapshots. + +In Cairo, a snapshot is an immutable view of a value at a certain point in time. +Recall that memory is immutable, so modifying a value actually creates a new memory cell. +The old memory cell still exists, and snapshots are variables that refer to that "old" value. +In this sense, snapshots are a view "into the past". + +Here is how you would define and use a `calculate_length` function that takes a +snapshot of an array as a parameter instead of taking ownership of the underlying value. In this example, +the `calculate_length` function returns the length of the array passed as a parameter. +As we're passing it as a snapshot, which is an immutable view of the array, we can be sure that +the `calculate_length` function will not mutate the array, and ownership of the array is kept in the `main` function. + +Filename: src/lib.cairo + +```rust +fn main() { + let mut arr1: Array = array![]; + let first_snapshot = @arr1; // Take a snapshot of `arr1` at this point in time + arr1.append(1); // Mutate `arr1` by appending a value + let first_length = calculate_length( + first_snapshot + ); // Calculate the length of the array when the snapshot was taken + let second_length = calculate_length(@arr1); // Calculate the current length of the array + println!("The length of the array when the snapshot was taken is {}", first_length); + println!("The current length of the array is {}", second_length); +} + +fn calculate_length(arr: @Array) -> usize { + arr.len() +} +``` + +> Note: it is only possible to call the `len()` method on an array snapshot because it is defined as such in the `ArrayTrait` trait. If you try to call a method that is not defined for snapshots on a snapshot, you will get a compilation error. However, you can call methods expecting a snapshot on non-snapshot types. + +The output of this program is: + +```shell +$ scarb cairo-run + Compiling no_listing_09_snapshots v0.1.0 (listings/ch04-understanding-ownership/no_listing_09_snapshots/Scarb.toml) + Finished release target(s) in 1 second + Running no_listing_09_snapshots +The length of the array when the snapshot was taken is 0 +The current length of the array is 1 +Run completed successfully, returning [] + +``` + +First, notice that all the tuple code in the variable declaration and the function return value is gone. Second, note +that we pass `@arr1` into `calculate_length` and, in its definition, we take `@Array` rather than `Array`. + +Let’s take a closer look at the function call here: + +```rust +let second_length = calculate_length(@arr1); // Calculate the current length of the array +``` + +The `@arr1` syntax lets us create a snapshot of the value in `arr1`. Because a snapshot is an immutable view of a value at a specific point in time, the usual rules of the linear type system are not enforced. In particular, snapshot variables always implement the `Drop` trait, never the `Destruct` trait, even dictionary snapshots. + +Similarly, the signature of the function uses `@` to indicate that the type of the parameter `arr` is a snapshot. Let’s add some explanatory annotations: + +```rust, noplayground +fn calculate_length( + array_snapshot: @Array // array_snapshot is a snapshot of an Array +) -> usize { + array_snapshot.len() +} // Here, array_snapshot goes out of scope and is dropped. +// However, because it is only a view of what the original array `arr` contains, the original `arr` can still be used. +``` + +The scope in which the variable `array_snapshot` is valid is the same as any function parameter’s scope, but the underlying value of the snapshot is not dropped when `array_snapshot` stops being used. When functions have snapshots as parameters instead of the actual values, we won’t need to return the values in order to give back ownership of the original value, because we never had it. + +### Desnap Operator + +To convert a snapshot back into a regular variable, you can use the `desnap` operator `*`, which serves as the opposite of the `@` operator. + +Only `Copy` types can be desnapped. However, in the general case, because the value is not modified, the new variable created by the `desnap` operator reuses the old value, and so desnapping is a completely free operation, just like `Copy`. + +In the following example, we want to calculate the area of a rectangle, but we don't want to take ownership of the rectangle in the `calculate_area` function, because we might want to use the rectangle again after the function call. Since our function doesn't mutate the rectangle instance, we can pass the snapshot of the rectangle to the function, and then transform the snapshots back into values using the `desnap` operator `*`. + +```rust +#[derive(Drop)] +struct Rectangle { + height: u64, + width: u64, +} + +fn main() { + let rec = Rectangle { height: 3, width: 10 }; + let area = calculate_area(@rec); + println!("Area: {}", area); +} + +fn calculate_area(rec: @Rectangle) -> u64 { + // As rec is a snapshot to a Rectangle, its fields are also snapshots of the fields types. + // We need to transform the snapshots back into values using the desnap operator `*`. + // This is only possible if the type is copyable, which is the case for u64. + // Here, `*` is used for both multiplying the height and width and for desnapping the snapshots. + *rec.height * *rec.width +} +``` + +But, what happens if we try to modify something we’re passing as a snapshot? Try the code in +Listing 4-4. Spoiler alert: it doesn’t work! + +Filename: src/lib.cairo + +```rust,does_not_compile +#[derive(Copy, Drop)] +struct Rectangle { + height: u64, + width: u64, +} + +fn main() { + let rec = Rectangle { height: 3, width: 10 }; + flip(@rec); +} + +fn flip(rec: @Rectangle) { + let temp = rec.height; + rec.height = rec.width; + rec.width = temp; +} +``` + + +Listing 4-4: Attempting to modify a snapshot value + +Here’s the error: + +```shell +$ scarb cairo-run + Compiling listing_04_04 v0.1.0 (listings/ch04-understanding-ownership/listing_04_attempt_modifying_snapshot/Scarb.toml) +error: Invalid left-hand side of assignment. + --> listings/ch04-understanding-ownership/listing_04_attempt_modifying_snapshot/src/lib.cairo:15:5 + rec.height = rec.width; + ^********^ + +error: Invalid left-hand side of assignment. + --> listings/ch04-understanding-ownership/listing_04_attempt_modifying_snapshot/src/lib.cairo:16:5 + rec.width = temp; + ^*******^ + +error: could not compile `listing_04_04` due to previous error +error: `scarb metadata` exited with error + +``` + +The compiler prevents us from modifying values associated to snapshots. + +## Mutable References + +We can achieve the behavior we want in Listing 4-4 by using a _mutable reference_ instead of a snapshot. Mutable references are actually mutable values passed to a function that are implicitly returned at the end of the function, returning ownership to the calling context. By doing so, they allow you to mutate the value passed while keeping ownership of it by returning it automatically at the end of the execution. +In Cairo, a parameter can be passed as _mutable reference_ using the `ref` modifier. + +> **Note**: In Cairo, a parameter can only be passed as _mutable reference_ using the `ref` modifier if the variable is declared as mutable with `mut`. + +In Listing 4-5, we use a mutable reference to modify the value of the `height` and `width` fields of the `Rectangle` instance in the `flip` function. + +```rust +#[derive(Drop)] +struct Rectangle { + height: u64, + width: u64, +} + +fn main() { + let mut rec = Rectangle { height: 3, width: 10 }; + flip(ref rec); + println!("height: {}, width: {}", rec.height, rec.width); +} + +fn flip(ref rec: Rectangle) { + let temp = rec.height; + rec.height = rec.width; + rec.width = temp; +} +``` + +Listing 4-5: Use of a mutable reference to modify a value + +First, we change `rec` to be `mut`. Then we pass a mutable reference of `rec` into `flip` with `ref rec`, and update the function signature to accept a mutable reference with `ref rec: Rectangle`. This makes it very clear that the `flip` function will mutate the value of the `Rectangle` instance passed as parameter. + +The output of the program is: + +```shell +$ scarb cairo-run + Compiling listing_04_05 v0.1.0 (listings/ch04-understanding-ownership/listing_05_mutable_reference/Scarb.toml) + Finished release target(s) in 1 second + Running listing_04_05 +height: 10, width: 3 +Run completed successfully, returning [] + +``` + +As expected, the `height` and `width` fields of the `rec` variable have been swapped. + +{{#quiz ../quizzes/ch04-02-references-and-snapshots.toml}} + +## Small Recap + +Let’s recap what we’ve discussed about the linear type system, ownership, snapshots, and references: + +- At any given time, a variable can only have one owner. +- You can pass a variable by-value, by-snapshot, or by-reference to a function. +- If you pass-by-value, ownership of the variable is transferred to the function. +- If you want to keep ownership of the variable and know that your function won’t mutate it, you can pass it as a snapshot with `@`. +- If you want to keep ownership of the variable and know that your function will mutate it, you can pass it as a mutable reference with `ref`. +# Using Structs to Structure Related Data + +A struct, or structure, is a custom data type that lets you package together and name multiple related values that make up a meaningful group. If you’re familiar with an object-oriented language, a struct is like an object’s data attributes. In this chapter, we’ll compare and contrast tuples with structs to build on what you already know and demonstrate when structs are a better way to group data. + +We’ll demonstrate how to define and instantiate structs. We’ll discuss how to define associated functions, especially the kind of associated functions called methods, to specify behavior associated with a struct type. Structs and enums (discussed in the [next chapter](ch06-01-enums.md)) are the building blocks for creating new types in your program’s domain to take full advantage of Cairo's compile-time type checking. +# Defining and Instantiating Structs + +Structs are similar to tuples, discussed in the [Data Types](ch02-02-data-types.md) section, in that both hold multiple related values. Like tuples, the pieces of a struct can be different types. Unlike with tuples, in a struct you’ll name each piece of data so it’s clear what the values mean. Adding these names means that structs are more flexible than tuples: you don’t have to rely on the order of the data to specify or access the values of an instance. + +To define a struct, we enter the keyword `struct` and name the entire struct. A struct’s name should describe the significance of the pieces of data being grouped together. Then, inside curly brackets, we define the names and types of the pieces of data, which we call fields. For example, Listing 5-1 shows a struct that stores information about a user account. + +Filename: src/lib.cairo + +```rust, noplayground +#[derive(Drop)] +struct User { + active: bool, + username: ByteArray, + email: ByteArray, + sign_in_count: u64, +} +``` + + +Listing 5-1: A `User` struct definition + +To use a struct after we’ve defined it, we create an _instance_ of that struct by specifying concrete values for each of the fields. +We create an instance by stating the name of the struct and then add curly brackets containing _key: value_ pairs, where the keys are the names of the fields and the values are the data we want to store in those fields. We don’t have to specify the fields in the same order in which we declared them in the struct. In other words, the struct definition is like a general template for the type, and instances fill in that template with particular data to create values of the type. + +For example, we can declare two particular users as shown in Listing 5-2. + +Filename: src/lib.cairo + +```rust +#[derive(Drop)] +struct User { + active: bool, + username: ByteArray, + email: ByteArray, + sign_in_count: u64, +} + +fn main() { + let user1 = User { + active: true, username: "someusername123", email: "someone@example.com", sign_in_count: 1 + }; + let user2 = User { + sign_in_count: 1, username: "someusername123", active: true, email: "someone@example.com" + }; +} + +``` + +Listing 5-2: Creating two instances of the `User` struct + +To get a specific value from a struct, we use dot notation. For example, to access `user1`'s email address, we use `user1.email`. If the instance is mutable, we can change a value by using the dot notation and assigning into a particular field. Listing 5-3 shows how to change the value in the `email` field of a mutable `User` instance. + +Filename: src/lib.cairo + +```rust +# #[derive(Drop)] +# struct User { +# active: bool, +# username: ByteArray, +# email: ByteArray, +# sign_in_count: u64, +# } +fn main() { + let mut user1 = User { + active: true, username: "someusername123", email: "someone@example.com", sign_in_count: 1 + }; + user1.email = "anotheremail@example.com"; +} +# +# fn build_user(email: ByteArray, username: ByteArray) -> User { +# User { active: true, username: username, email: email, sign_in_count: 1, } +# } +# +# fn build_user_short(email: ByteArray, username: ByteArray) -> User { +# User { active: true, username, email, sign_in_count: 1, } +# } +# +# +``` + +Listing 5-3: Changing the value in the email field of a `User` instance + +Note that the entire instance must be mutable; Cairo doesn’t allow us to mark only certain fields as mutable. + +As with any expression, we can construct a new instance of the struct as the last expression in the function body to implicitly return that new instance. + +Listing 5-4 shows a `build_user` function that returns a `User` instance with the given email and username. The `active` field gets the value of `true`, and the `sign_in_count` gets a value of `1`. + +Filename: src/lib.cairo + +```rust +# #[derive(Drop)] +# struct User { +# active: bool, +# username: ByteArray, +# email: ByteArray, +# sign_in_count: u64, +# } +# fn main() { +# let mut user1 = User { +# active: true, username: "someusername123", email: "someone@example.com", sign_in_count: 1 +# }; +# user1.email = "anotheremail@example.com"; +# } +# +fn build_user(email: ByteArray, username: ByteArray) -> User { + User { active: true, username: username, email: email, sign_in_count: 1, } +} +# +# fn build_user_short(email: ByteArray, username: ByteArray) -> User { +# User { active: true, username, email, sign_in_count: 1, } +# } +# +# +``` + +Listing 5-4: A `build_user` function that takes an email and username and returns a `User` instance. + +It makes sense to name the function parameters with the same name as the struct fields, but having to repeat the `email` and `username` field names and variables is a bit tedious. If the struct had more fields, repeating each name would get even more annoying. Luckily, there’s a convenient shorthand! + +## Using the Field Init Shorthand + +Because the parameter names and the struct field names are exactly the same in Listing 5-4, we can use the field init shorthand syntax to rewrite `build_user` so it behaves exactly the same but doesn’t have the repetition of `username` and `email`, as shown in Listing 5-5. + +Filename: src/lib.cairo + +```rust +# #[derive(Drop)] +# struct User { +# active: bool, +# username: ByteArray, +# email: ByteArray, +# sign_in_count: u64, +# } +# fn main() { +# let mut user1 = User { +# active: true, username: "someusername123", email: "someone@example.com", sign_in_count: 1 +# }; +# user1.email = "anotheremail@example.com"; +# } +# +# fn build_user(email: ByteArray, username: ByteArray) -> User { +# User { active: true, username: username, email: email, sign_in_count: 1, } +# } +# +fn build_user_short(email: ByteArray, username: ByteArray) -> User { + User { active: true, username, email, sign_in_count: 1, } +} +# +# +``` + +Listing 5-5: A `build_user` function that uses field init shorthand because the `username` and `email` parameters have the same name as struct fields. + +Here, we’re creating a new instance of the `User` struct, which has a field named `email`. We want to set the `email` field’s value to the value in the `email` parameter of the `build_user` function. Because the `email` field and the `email` parameter have the same name, we only need to write `email` rather than `email: email`. + +## Creating Instances from Other Instances with Struct Update Syntax + +It’s often useful to create a new instance of a struct that includes most of +the values from another instance, but changes some. You can do this using +_struct update syntax_. + +First, in Listing 5-6 we show how to create a new `User` instance in `user2` +regularly, without the update syntax. We set a new value for `email` but +otherwise use the same values from `user1` that we created in Listing 5-2. + +Filename: src/lib.cairo + +```rust +# #[derive(Drop)] +# struct User { +# active: bool, +# username: ByteArray, +# email: ByteArray, +# sign_in_count: u64, +# } +# +fn main() { + // --snip-- +# +# let user1 = User { +# email: "someone@example.com", username: "someusername123", active: true, sign_in_count: 1, +# }; + + let user2 = User { + active: user1.active, + username: user1.username, + email: "another@example.com", + sign_in_count: user1.sign_in_count, + }; +} +# +# +``` + + +Listing 5-6: Creating a new `User` instance using all but one of the values from `user1` + +Using struct update syntax, we can achieve the same effect with less code, as +shown in Listing 5-7. The syntax `..` specifies that the remaining fields not +explicitly set should have the same value as the fields in the given instance. + +Filename: src/lib.cairo + +```rust +# use core::byte_array; +# #[derive(Drop)] +# struct User { +# active: bool, +# username: ByteArray, +# email: ByteArray, +# sign_in_count: u64, +# } +# +fn main() { + // --snip-- +# +# let user1 = User { +# email: "someone@example.com", username: "someusername123", active: true, sign_in_count: 1, +# }; + + let user2 = User { email: "another@example.com", ..user1 }; +} +# +# +``` + + +Listing 5-7: Using struct update syntax to set a new +`email` value for a `User` instance but to use the rest of the values from `user1` + +The code in Listing 5-7 also creates an instance of `user2` that has a +different value for `email` but has the same values for the `username`, +`active`, and `sign_in_count` fields as `user1`. The `..user1` part must come last +to specify that any remaining fields should get their values from the +corresponding fields in `user1`, but we can choose to specify values for as +many fields as we want in any order, regardless of the order of the fields in +the struct’s definition. + +Note that the struct update syntax uses `=` like an assignment; this is because it moves the data, +just as we saw in the ["Moving Values"][move] section. In this example, we can no +longer use `user1` as a whole after creating `user2` because the `ByteArray` in the +`username` field of `user1` was moved into `user2`. If we had given `user2` new +`ByteArray` values for both `email` and `username`, and thus only used the +`active` and `sign_in_count` values from `user1`, then `user1` would still be +valid after creating `user2`. Both `active` and `sign_in_count` are types that +implement the `Copy` trait, so the behavior we discussed in the ["`Copy` Trait"][copy] section would apply. + +{{#quiz ../quizzes/ch05-01-defining-and-instantiating-structs.toml}} + +[move]: ch04-01-what-is-ownership.md#moving-values +[copy]: ch04-01-what-is-ownership.md#the-copy-trait +# An Example Program Using Structs + +To understand when we might want to use structs, let’s write a program that calculates the area of a rectangle. We’ll start by using single variables, and then refactor the program until we’re using structs instead. + +Let’s make a new project with Scarb called _rectangles_ that will take the width and height of a rectangle specified in pixels and calculate the area of the rectangle. Listing 5-8 shows a short program with one way of doing exactly that in our project’s _src/lib.cairo_. + +Filename: src/lib.cairo + +```rust +fn main() { + let width = 30; + let height = 10; + let area = area(width, height); + println!("Area is {}", area); +} + +fn area(width: u64, height: u64) -> u64 { + width * height +} +``` + +Listing 5-8: Calculating the area of a rectangle specified by separate width and height variables. + +Now run the program with `scarb cairo-run`: + +```shell +$ scarb cairo-run + Compiling listing_04_06_no_struct v0.1.0 (listings/ch05-using-structs-to-structure-related-data/listing_03_no_struct/Scarb.toml) + Finished release target(s) in 1 second + Running listing_04_06_no_struct +Area is 300 +Run completed successfully, returning [] + +``` + +This code succeeds in figuring out the area of the rectangle by calling the `area` function with each dimension, but we can do more to make this code clear and readable. + +The issue with this code is evident in the signature of `area`: + +```rust,noplayground +fn area(width: u64, height: u64) -> u64 { +``` + +The `area` function is supposed to calculate the area of one rectangle, but the function we wrote has two parameters, and it’s not clear anywhere in our program that the parameters are related. It would be more readable and more manageable to group width and height together. We’ve already discussed one way we might do that in the [Tuple Section of Chapter 2](ch02-02-data-types.html#the-tuple-type). + +## Refactoring with Tuples + +Listing 5-9 shows another version of our program that uses tuples. + +Filename: src/lib.cairo + +```rust +fn main() { + let rectangle = (30, 10); + let area = area(rectangle); + println!("Area is {}", area); +} + +fn area(dimension: (u64, u64)) -> u64 { + let (x, y) = dimension; + x * y +} +``` + +Listing 5-9: Specifying the width and height of the rectangle with a tuple. + +In one way, this program is better. Tuples let us add a bit of structure, and we’re now passing just one argument. But in another way, this version is less clear: tuples don’t name their elements, so we have to index into the parts of the tuple, making our calculation less obvious. + +Mixing up the width and height wouldn’t matter for the area calculation, but if we want to calculate the difference, it would matter! We would have to keep in mind that `width` is the tuple index `0` and `height` is the tuple index `1`. This would be even harder for someone else to figure out and keep in mind if they were to use our code. Because we haven’t conveyed the meaning of our data in our code, it’s now easier to introduce errors. + +## Refactoring with Structs: Adding More Meaning + +We use structs to add meaning by labeling the data. We can transform the tuple we’re using into a struct with a name for the whole as well as names for the parts. + +Filename: src/lib.cairo + +```rust +struct Rectangle { + width: u64, + height: u64, +} + +fn main() { + let rectangle = Rectangle { width: 30, height: 10, }; + let area = area(rectangle); + println!("Area is {}", area); +} + +fn area(rectangle: Rectangle) -> u64 { + rectangle.width * rectangle.height +} +``` + +Listing 5-10: Defining a `Rectangle` struct. + +Here we’ve defined a struct and named it `Rectangle`. Inside the curly brackets, we defined the fields as `width` and `height`, both of which have type `u64`. Then, in `main`, we created a particular instance of `Rectangle` that has a width of `30` and a height of `10`. Our `area` function is now defined with one parameter, which we’ve named `rectangle` which is of type `Rectangle` struct. We can then access the fields of the instance with dot notation, and it gives descriptive names to the values rather than using the tuple index values of `0` and `1`. + +{{#quiz ../quizzes/ch05-02-an-example-program-using-structs.toml}} +# Method Syntax + +_Methods_ are similar to functions: we declare them with the `fn` keyword and a name, they can have parameters and a return value, and they contain some code that’s run when the method is called from somewhere else. Unlike functions, methods are defined within the context of a struct (or an enum which we cover in [Chapter 6][enums]), and their first parameter is always `self`, which represents the instance of the type the method is being called on. + +## Defining Methods + +Let’s change the `area` function that has a `Rectangle` instance as a parameter and instead make an `area` method defined on the `Rectangle` struct, as shown in Listing 5-11 + +```rust, noplayground +#[derive(Copy, Drop)] +struct Rectangle { + width: u64, + height: u64, +} + +trait RectangleTrait { + fn area(self: @Rectangle) -> u64; +} + +impl RectangleImpl of RectangleTrait { + fn area(self: @Rectangle) -> u64 { + (*self.width) * (*self.height) + } +} + +fn main() { + let rect1 = Rectangle { width: 30, height: 50, }; + println!("Area is {}", rect1.area()); +} +``` + +Listing 5-11: Defining an `area` method on the `Rectangle` struct. + +To define the function within the context of `Rectangle`, we start an `impl` (implementation) block for a trait `RectangleTrait` that defines the methods that can be called on a `Rectangle` instance. As impl blocks can only be defined for traits and not types, we need to define this trait first - but it's not meant to be used for anything else. + +Everything within this `impl` block will be associated with the `Rectangle` type. Then we move the `area` function within the `impl` curly brackets and change the first (and in this case, only) parameter to be `self` in the signature and everywhere within the body. In `main`, where we called the `area` function and passed `rect1` as an argument, we can instead use _method syntax_ to call the `area` method on our `Rectangle` instance. The method syntax goes after an instance: we add a dot followed by the method name, parentheses, and any arguments. + +In the signature for `area`, we use `self: @Rectangle` instead of `rectangle: @Rectangle`. +Methods must have a parameter named `self`, for their first parameter, and the type of `self` indicates the type that method can be called on. Methods can take ownership of `self`, but `self` can also be passed by snapshot or by reference, just like any other parameter. + +> There is no direct link between a type and a trait. Only the type of the `self` parameter of a method defines the type from which this method can be called. That means, it is technically possible to define methods on multiple types in a same trait (mixing `Rectangle` and `Circle` methods, for example). But **this is not a recommended practice** as it can lead to confusion. + +The main reason for using methods instead of functions, in addition to providing method syntax, is for organization. We’ve put all the things we can do with an instance of a type in one `impl` block rather than making future users of our code search for capabilities of `Rectangle` in various places in the library we provide. + +## The `generate_trait` Attribute + +If you are familiar with Rust, you may find Cairo's approach confusing because methods cannot be defined directly on types. Instead, you must define a [trait](./ch08-02-traits-in-cairo.md) and an implementation of this trait associated with the type for which the method is intended. +However, defining a trait and then implementing it to define methods on a specific type is verbose, and unnecessary: the trait itself will not be reused. + +So, to avoid defining useless traits, Cairo provides the `#[generate_trait]` attribute to add above a trait implementation, which tells to the compiler to generate the corresponding trait definition for you, and let's you focus on the implementation only. Both approaches are equivalent, but it's considered a best practice to not explicitly define traits in this case. + +The previous example can also be written as follows: + +```rust +#[derive(Copy, Drop)] +struct Rectangle { + width: u64, + height: u64, +} + +#[generate_trait] +impl RectangleImpl of RectangleTrait { + fn area(self: @Rectangle) -> u64 { + (*self.width) * (*self.height) + } +} + +fn main() { + let rect1 = Rectangle { width: 30, height: 50, }; + println!("Area is {}", rect1.area()); +} + +``` + +Let's use this `#[generate_trait]` in the following chapters to make our code cleaner. + +## Snapshots and References + +As the `area` method does not modify the calling instance, `self` is declared as a snapshot of a `Rectangle` instance with the `@` snapshot operator. But, of course, we can also define some methods receiving a mutable reference of this instance, to be able to modify it. + +Let's write a new method `scale` which resizes a rectangle of a `factor` given as parameter: + +```rust +#[generate_trait] +impl RectangleImpl of RectangleTrait { + fn area(self: @Rectangle) -> u64 { + (*self.width) * (*self.height) + } + fn scale(ref self: Rectangle, factor: u64) { + self.width *= factor; + self.height *= factor; + } +} + +fn main() { + let mut rect2 = Rectangle { width: 10, height: 20 }; + rect2.scale(2); + println!("The new size is (width: {}, height: {})", rect2.width, rect2.height); +} +``` + +It is also possible to define a method which takes ownership of the instance by using just `self` as the first parameter but it is rare. This technique is usually used when the method transforms `self` into something else and you want to prevent the caller from using the original instance after the transformation. + +Look at the [Understanding Ownership](ch04-00-understanding-ownership.md) chapter for more details about these important notions. + +## Methods with Several Parameters + +Let’s practice using methods by implementing another method on the `Rectangle` struct. This time we want to write the method `can_hold` which accepts another instance of `Rectangle` and returns `true` if this rectangle can fit completely within self; otherwise, it should return false. + +```rust +#[generate_trait] +impl RectangleImpl of RectangleTrait { + fn area(self: @Rectangle) -> u64 { + *self.width * *self.height + } + + fn scale(ref self: Rectangle, factor: u64) { + self.width *= factor; + self.height *= factor; + } + + fn can_hold(self: @Rectangle, other: @Rectangle) -> bool { + *self.width > *other.width && *self.height > *other.height + } +} + +fn main() { + let rect1 = Rectangle { width: 30, height: 50, }; + let rect2 = Rectangle { width: 10, height: 40, }; + let rect3 = Rectangle { width: 60, height: 45, }; + + println!("Can rect1 hold rect2? {}", rect1.can_hold(@rect2)); + println!("Can rect1 hold rect3? {}", rect1.can_hold(@rect3)); +} +``` + +Here, we expect that `rect1` can hold `rect2` but not `rect3`. + +## Associated functions + +We call _associated functions_ all functions that are defined inside an `impl` block that are associated to a specific type. While this is not enforced by the compiler, it is a good practice to keep associated functions related to the same type in the same `impl` block - for example, all functions related to `Rectangle` will be grouped in the same `impl` block for `RectangleTrait`. + +Methods are a special kind of associated function, but we can also define associated functions that don’t have `self` as their first parameter (and thus are not methods) because they don’t need an instance of the type to work with, but are still associated with that type. + +Associated functions that aren’t methods are often used for constructors that +will return a new instance of the type. These are often called `new`, but +`new` isn’t a special name and isn’t built into the language. For example, we +could choose to provide an associated function named `square` that would have +one dimension parameter and use that as both width and height, thus making it +easier to create a square `Rectangle` rather than having to specify the same +value twice: + +Let's create the function `new` which creates a `Rectangle` from a `width` and a `height`, `square` which creates a square `Rectangle` from a `size` and `avg` which computes the average of two `Rectangle` instances: + +```rust +#[generate_trait] +impl RectangleImpl of RectangleTrait { + fn area(self: @Rectangle) -> u64 { + (*self.width) * (*self.height) + } + + fn new(width: u64, height: u64) -> Rectangle { + Rectangle { width, height } + } + + fn square(size: u64) -> Rectangle { + Rectangle { width: size, height: size } + } + + fn avg(lhs: @Rectangle, rhs: @Rectangle) -> Rectangle { + Rectangle { + width: ((*lhs.width) + (*rhs.width)) / 2, height: ((*lhs.height) + (*rhs.height)) / 2 + } + } +} + +fn main() { + let rect1 = RectangleTrait::new(30, 50); + let rect2 = RectangleTrait::square(10); + + println!( + "The average Rectangle of {:?} and {:?} is {:?}", + @rect1, + @rect2, + RectangleTrait::avg(@rect1, @rect2) + ); +} +``` + +To call the `square` associated function, we use the `::` syntax with the struct name; +`let sq = Rectangle::square(3);` is an example. This function is namespaced by +the struct: the `::` syntax is used for both associated functions and +namespaces created by modules. We’ll discuss modules in [Chapter +7][modules]. + +Note that the `avg` function could also be written as a method with `self` as the first rectangle. In this case, instead of using the method with `RectangleTrait::avg(@rect1, @rect2)`, it would be called with `rect1.avg(rect2)`. + +## Multiple Traits and `impl` Blocks + +Each struct is allowed to have multiple `trait` and `impl` blocks. For example, +the following code is equivalent to the code shown in the _Methods with several parameters_ section, which has each method in its own `trait` and `impl` blocks. + +```rust +#[generate_trait] +impl RectangleCalcImpl of RectangleCalc { + fn area(self: @Rectangle) -> u64 { + (*self.width) * (*self.height) + } +} + +#[generate_trait] +impl RectangleCmpImpl of RectangleCmp { + fn can_hold(self: @Rectangle, other: @Rectangle) -> bool { + *self.width > *other.width && *self.height > *other.height + } +} +``` + +There’s no strong reason to separate these methods into multiple `trait` and `impl` +blocks here, but this is valid syntax. + +{{#quiz ../quizzes/ch05-03-method-syntax.toml}} + +[enums]: ./ch06-01-enums.md +[modules]: ./ch07-02-defining-modules-to-control-scope.md +# Enums and Pattern Matching + +In this chapter, we’ll look at _enumerations_, also referred to as _enums_. +Enums allow you to define a type by enumerating its possible _variants_. First, +we’ll define and use an enum to show how an enum can encode meaning along with +data. Next, we’ll explore a particularly useful enum, called `Option`, which +expresses that a value can be either something or nothing. Finally, we’ll look at +how pattern matching in the `match` expression makes it easy to run different +code for different values of an enum. +# Enums + +Enums, short for "enumerations," are a way to define a custom data type that consists of a fixed set of named values, called _variants_. Enums are useful for representing a collection of related values where each value is distinct and has a specific meaning. + +## Enum Variants and Values + +Here's a simple example of an enum: + +```rust, noplayground +#[derive(Drop)] +enum Direction { + North, + East, + South, + West, +} +``` + +In this example, we've defined an enum called `Direction` with four variants: `North`, `East`, `South`, and `West`. The naming convention is to use PascalCase for enum variants. Each variant represents a distinct value of the `Direction` type. In this particular example, variants don't have any associated value. One variant can be instantiated using this syntax: + +```rust, noplayground +# #[derive(Drop)] +# enum Direction { +# North, +# East, +# South, +# West, +# } +# +# fn main() { + let direction = Direction::North; +# } +# +``` + +Now let's imagine that our variants have associated values, that store the exact degree of the direction. We can define a new `Direction` enum: + +```rust, noplayground +#[derive(Drop)] +enum Direction { + North: u128, + East: u128, + South: u128, + West: u128, +} +# +# fn main() { +# let direction = Direction::North(10); +# } +``` + +and instantiate it as follows: + +```rust, noplayground +# #[derive(Drop)] +# enum Direction { +# North: u128, +# East: u128, +# South: u128, +# West: u128, +# } +# +# fn main() { + let direction = Direction::North(10); +# } +``` + +In this code, each variant is associated with a `u128` value, representing the direction in degrees. In the next example, we will see that it is also possible to associate different data types with each variant. + +It's easy to write code that acts differently depending on the variant of an enum instance, in this example to run specific code according to a direction. You can learn more about it in the [Match Control Flow Construct][match] section. + +[match]: ./ch06-02-the-match-control-flow-construct.md + +## Enums Combined with Custom Types + +Enums can also be used to store more interesting custom data associated with each variant. For example: + +```rust, noplayground +#[derive(Drop)] +enum Message { + Quit, + Echo: felt252, + Move: (u128, u128), +} +``` + +In this example, the `Message` enum has three variants: `Quit`, `Echo`, and `Move`, all with different types: + +- `Quit` doesn't have any associated value. +- `Echo` is a single `felt252`. +- `Move` is a tuple of two `u128` values. + +You could even use a Struct or another enum you defined inside one of your enum variants. + +## Trait Implementations for Enums + +In Cairo, you can define traits and implement them for your custom enums. This allows you to define methods and behaviors associated with the enum. Here's an example of defining a trait and implementing it for the previous `Message` enum: + +```rust, noplayground +trait Processing { + fn process(self: Message); +} + +impl ProcessingImpl of Processing { + fn process(self: Message) { + match self { + Message::Quit => { println!("quitting") }, + Message::Echo(value) => { println!("echoing {}", value) }, + Message::Move((x, y)) => { println!("moving from {} to {}", x, y) }, + } + } +} +``` + +In this example, we implemented the `Processing` trait for `Message`. Here is how it could be used to process a Quit message: + +```rust, noplayground +# +# #[derive(Drop)] +# enum Message { +# Quit, +# Echo: felt252, +# Move: (u128, u128), +# } +# +# trait Processing { +# fn process(self: Message); +# } +# +# impl ProcessingImpl of Processing { +# fn process(self: Message) { +# match self { +# Message::Quit => { println!("quitting") }, +# Message::Echo(value) => { println!("echoing {}", value) }, +# Message::Move((x, y)) => { println!("moving from {} to {}", x, y) }, +# } +# } +# } +# fn main() { + let msg: Message = Message::Quit; + msg.process(); +# } +# +# +``` + +Running this code would print `quitting`. + +## The `Option` Enum and Its Advantages + +The `Option` enum is a standard Cairo enum that represents the concept of an optional value. It has two variants: `Some: T` and `None`. `Some: T` indicates that there's a value of type `T`, while `None` represents the absence of a value. + +```rust,noplayground +enum Option { + Some: T, + None, +} +``` + +The `Option` enum is helpful because it allows you to explicitly represent the possibility of a value being absent, making your code more expressive and easier to reason about. Using `Option` can also help prevent bugs caused by using uninitialized or unexpected `null` values. + +To give you an example, here is a function which returns the index of the first element of an array with a given value, or `None` if the element is not present. + +We are demonstrating two approaches for the above function: + +- Recursive approach with `find_value_recursive`. +- Iterative approach with `find_value_iterative`. + +```rust,noplayground +fn find_value_recursive(mut arr: Span, value: felt252, index: usize) -> Option { + match arr.pop_front() { + Option::Some(index_value) => { if (*index_value == value) { + return Option::Some(index); + } }, + Option::None => { return Option::None; }, + }; + + find_value_recursive(arr, value, index + 1) +} + +fn find_value_iterative(mut arr: Span, value: felt252) -> Option { + let mut result = Option::None; + let mut index = 0; + + while let Option::Some(array_value) = arr + .pop_front() { + if (*array_value == value) { + result = Option::Some(index); + break; + }; + + index += 1; + }; + + result +} +``` + +Enums can be useful in many situations, especially when using the `match` flow construct that we just used. We will describe it in the next section. + +Other enums are used very often, such as the `Result` enum, allowing to handle errors gracefully. We will explain the `Result` enum in detail in the ["Error Handling"][result enum] chapter. + +{{#quiz ../quizzes/ch06-01-enums.toml}} + +[result enum]: ./ch09-02-recoverable-errors.md#the-result-enum +# The Match Control Flow Construct + +Cairo has an extremely powerful control flow construct called `match` that allows you to compare a value against a series of patterns and then execute code based on which pattern matches. Patterns can be made up of literal values, variable names, wildcards, and many other things. The power of `match` comes from the expressiveness of the patterns and the fact that the compiler confirms that all possible cases are handled. + +Think of a `match` expression as being like a coin-sorting machine: coins slide down a track with variously sized holes along it, and each coin falls through the first hole it encounters that it fits into. In the same way, values go through each pattern in a match, and at the first pattern the value “fits”, the value falls into the associated code block to be used during execution. + +Speaking of coins, let’s use them as an example using `match`! We can write a function that takes an unknown US coin and, in a similar way as the counting machine, determines which coin it is and returns its value in cents, as shown in Listing 6-1. + +```rust,noplayground +enum Coin { + Penny, + Nickel, + Dime, + Quarter, +} + +fn value_in_cents(coin: Coin) -> felt252 { + match coin { + Coin::Penny => 1, + Coin::Nickel => 5, + Coin::Dime => 10, + Coin::Quarter => 25, + } +} +``` + +Listing 6-1: An enum and a `match` expression that has the variants of the enum as its patterns + +Let’s break down the `match` expression in the `value_in_cents` function. First, we list the `match` keyword followed by an expression, which in this case is the value `coin`. This seems very similar to a conditional expression used with the `if` statement, but there’s a big difference: with `if`, the condition needs to evaluate to a boolean value, but here it can be any type. The type of `coin` in this example is the `Coin` enum that we defined on the first line. + +Next are the `match` arms. An arm has two parts: a pattern and some code. The first arm here has a pattern that is the value `Coin::Penny` and then the `=>` operator that separates the pattern and the code to run. The code in this case is just the value `1`. Each arm is separated from the next with a comma. + +When the `match` expression executes, it compares the resultant value against the pattern of each arm, in the order they are given. If a pattern matches the value, the code associated with that pattern is executed. If that pattern doesn’t match the value, execution continues to the next arm, much as in a coin-sorting machine. We can have as many arms as we need: in the above example, our `match` has four arms. + +The code associated with each arm is an expression, and the resultant value of the expression in the matching arm is the value that gets returned for the entire match expression. + +We don’t typically use curly brackets if the `match` arm code is short, as it is in our example where each arm just returns a value. If you want to run multiple lines of code in a `match` arm, you must use curly brackets, with a comma following the arm. For example, the following code prints “Lucky penny!” every time the method is called with a `Coin::Penny`, but still returns the last value of the block, `1`: + +```rust,noplayground +fn value_in_cents(coin: Coin) -> felt252 { + match coin { + Coin::Penny => { + println!("Lucky penny!"); + 1 + }, + Coin::Nickel => 5, + Coin::Dime => 10, + Coin::Quarter => 25, + } +} +``` + +## Patterns That Bind to Values + +Another useful feature of `match` arms is that they can bind to the parts of the values that match the pattern. This is how we can extract values out of enum variants. + +As an example, let’s change one of our enum variants to hold data inside it. From 1999 through 2008, the United States minted quarters with different designs for each of the 50 states on one side. No other coins got state designs, so only quarters have this extra value. We can add this information to our `enum` by changing the `Quarter` variant to include a `UsState` value stored inside it, which we’ve done in Listing 6-2. + +```rust,noplayground + +#[derive(Drop, Debug)] // Debug so we can inspect the state in a minute +enum UsState { + Alabama, + Alaska, +} + +#[derive(Drop)] +enum Coin { + Penny, + Nickel, + Dime, + Quarter: UsState, +} +``` + +Listing 6-2: A `Coin` enum in which the `Quarter` variant also holds a `UsState` value + +Let’s imagine that a friend is trying to collect all 50 state quarters. While we sort our loose change by coin type, we’ll also call out the name of the state associated with each quarter so that if it’s one our friend doesn’t have, they can add it to their collection. + +In the `match` expression for this code, we add a variable called `state` to the pattern that matches values of the variant `Coin::Quarter`. When a `Coin::Quarter` matches, the `state` variable will bind to the value of that quarter’s state. Then we can use `state` in the code for that arm, like so: + +```rust,noplayground +fn value_in_cents(coin: Coin) -> felt252 { + match coin { + Coin::Penny => 1, + Coin::Nickel => 5, + Coin::Dime => 10, + Coin::Quarter(state) => { + println!("State quarter from {:?}!", state); + 25 + } + } +} +``` + +Because `state` is an `UsState` enum which implements the `Debug` trait, we can print `state` value with `println!` macro. + +> Note: `{:?}` is a special formatting syntax that allows to print a debug form of the parameter passed to the `println!` macro. You can find more information about it in [Appendix C][debug trait]. + +If we were to call `value_in_cents(Coin::Quarter(UsState::Alaska))`, `coin` would be `Coin::Quarter(UsState::Alaska)`. When we compare that value with each of the match arms, none of them match until we reach `Coin::Quarter(state)`. At that point, the binding for `state` will be the value `UsState::Alaska`. We can then use that binding in `println!` macro, thus getting the inner state value out of the `Coin` enum variant for `Quarter`. + +[debug trait]: ./appendix-03-derivable-traits.html#debug-for-printing-and-debugging + +## Matching with `Option` + +In the previous section, we wanted to get the inner `T` value out of the `Some` case when using `Option`; we can also handle `Option` using `match`, as we did with the `Coin` enum! Instead of comparing coins, we’ll compare the variants of `Option`, but the way the `match` expression works remains the same. + +Let’s say we want to write a function that takes an `Option` and, if there’s a value inside, adds `1` to that value. If there is no value inside, the function should return the `None` value and not attempt to perform any operations. + +This function is very easy to write, thanks to `match`, and will look like Listing 6-3. + +```rust +fn plus_one(x: Option) -> Option { + match x { + Option::Some(val) => Option::Some(val + 1), + Option::None => Option::None, + } +} + +fn main() { + let five: Option = Option::Some(5); + let six: Option = plus_one(five); + let none = plus_one(Option::None); +} +``` + +Listing 6-3: A function that uses a `match` expression on an `Option` + +Let’s examine the first execution of `plus_one` in more detail. When we call `plus_one(five)`, the variable `x` in the body of `plus_one` will have the value `Some(5)`. We then compare that against each `match` arm: + +```rust,noplayground + Option::Some(val) => Option::Some(val + 1), +``` + +Does `Option::Some(5)` value match the pattern `Option::Some(val)`? It does! We have the same variant. The `val` binds to the value contained in `Option::Some`, so `val` takes the value `5`. The code in the `match` arm is then executed, so we add `1` to the value of `val` and create a new `Option::Some` value with our total `6` inside. Because the first arm matched, no other arms are compared. + +Now let’s consider the second call of `plus_one` in our main function, where `x` is `Option::None`. We enter the `match` and compare to the first arm: + +```rust,noplayground + Option::Some(val) => Option::Some(val + 1), +``` + +The `Option::Some(val)` value doesn’t match the pattern `Option::None`, so we continue to the next arm: + +```rust + Option::None => Option::None, +``` + +It matches! There’s no value to add to, so the matching construct ends and returns the `Option::None` value on the right side of `=>`. + +Combining `match` and enums is useful in many situations. You’ll see this pattern a lot in Cairo code: `match` against an enum, bind a variable to the data inside, and then execute code based on it. It’s a bit tricky at first, but once you get used to it, you’ll wish you had it in all languages. It’s consistently a user favorite. + +## Matches Are Exhaustive + +There’s one other aspect of `match` we need to discuss: the arms’ patterns must cover all possibilities. Consider this version of our `plus_one` function, which has a bug and won’t compile: + +```rust,noplayground +fn plus_one(x: Option) -> Option { + match x { + Option::Some(val) => Option::Some(val + 1), + } +} +``` + +We didn’t handle the `None` case, so this code will cause a bug. +Luckily, it’s a bug Cairo knows how to catch. If we try to compile this code, we’ll get this error: + +```shell +$ scarb cairo-run + Compiling no_listing_08_missing_match_arm v0.1.0 (listings/ch06-enums-and-pattern-matching/no_listing_09_missing_match_arm/Scarb.toml) +error: Missing match arm: `None` not covered. + --> listings/ch06-enums-and-pattern-matching/no_listing_09_missing_match_arm/src/lib.cairo:5:5 + match x { + ^*******^ + +error: could not compile `no_listing_08_missing_match_arm` due to previous error +error: `scarb metadata` exited with error + +``` + +Cairo knows that we didn’t cover every possible case, and even knows which pattern we forgot! Matches in Cairo are exhaustive: we must exhaust every last possibility in order for the code to be valid. Especially in the case of `Option`, when Cairo prevents us from forgetting to explicitly handle the `None` case, it protects us from assuming that we have a value when we might have null, thus making the [billion-dollar mistake][null pointer] discussed earlier impossible. + +[null pointer]: https://en.wikipedia.org/wiki/Null_pointer#History + +## Catch-all with the `_` Placeholder + +Using enums, we can also take special actions for a few particular values, but for all other values take one default action. +`_` is a special pattern that matches any value and does not bind to that value. +You can use it by simply adding a new arm with `_` as the pattern for the last arm of the `match` expression. + +Imagine we have a vending machine that only accepts Dime coins. +We want to have a function that processes inserted coins and returns `true` only if the coin is accepted. + +Here's a `vending_machine_accept` function that implements this logic: + +```rust,noplayground +fn vending_machine_accept(coin: Coin) -> bool { + match coin { + Coin::Dime => true, + _ => false, + } +} +``` + +This example also meets the exhaustiveness requirement because we’re explicitly ignoring all other values in the last arm; we haven’t forgotten anything. + +> There's no catch-all pattern in Cairo that allows you to use the value of the pattern. + + + +## Multiple Patterns with the `|` Operator + +In `match` expressions, you can match multiple patterns using the `|` syntax, which is the pattern _or_ operator. + +For example, in the following code we modified the `vending_machine_accept` function to accept both `Dime` and `Quarter` coins in a single arm: + +```rust,noplayground +fn vending_machine_accept(coin: Coin) -> bool { + match coin { + Coin::Dime | Coin::Quarter => true, + _ => false, + } +} +``` + +## Matching Tuples + +It is possible to match tuples. +Let's introduce a new `DayType` enum: + +```rust,noplayground +#[derive(Drop)] +enum DayType { + Week, + Weekend, + Holiday +} +``` + +Now, let's suppose that our vending machine accepts any coin on weekdays, but only accepts quarters and dimes on weekends and holidays. +We can modify the `vending_machine_accept` function to accept a tuple of a `Coin` and a `Weekday` and return `true` only if the given coin is accepted on the specified day: + +```rust,noplayground +fn vending_machine_accept(c: (DayType, Coin)) -> bool { + match c { + (DayType::Week, _) => true, + (_, Coin::Dime) | (_, Coin::Quarter) => true, + (_, _) => false, + } +} +``` + +Writing `(_, _)` for the last arm of a tuple matching pattern might feel superfluous. Hence, we can use the `_ =>` syntax if we want, for example, that our vending machine only accepts quarters on weekdays: + +```rust,noplayground +fn vending_week_machine(c: (DayType, Coin)) -> bool { + match c { + (DayType::Week, Coin::Quarter) => true, + _ => false, + } +} +``` + +## Matching `felt252` and Integer Variables + +You can also match `felt252` and integer variables. This is useful when you want to match against a range of values. +However, there are some restrictions: + +- Only integers that fit into a single `felt252` are supported (i.e. `u256` is not supported). +- The first arm must be 0. +- Each arm must cover a sequential segment, contiguously with other arms. + +Imagine we’re implementing a game where you roll a six-sided die to get a number between 0 and 5. +If you have 0, 1 or 2 you win. If you have 3, you can roll again. For all other values you lose. + +Here's a match that implements that logic: + +```rust,noplayground +fn roll(value: u8) { + match value { + 0 | 1 | 2 => println!("you won!"), + 3 => println!("you can roll again!"), + _ => println!("you lost...") + } +} +``` + +{{#quiz ../quizzes/ch06-02-match.toml}} + +> These restrictions are planned to be relaxed in future versions of Cairo. +# Concise Control Flow with `if let` and `while let` + +## `if let` + +The `if let` syntax lets you combine `if` and `let` into a less verbose way to handle values that match one pattern while ignoring the rest. Consider the program in Listing 6-4 that matches on an `Option::Some` value in the `config_max` variable but only wants to execute code if the value is `Option::Some` variant. + +```rust +# fn main() { + let config_max = Option::Some(5); + match config_max { + Option::Some(max) => println!("The maximum is configured to be {}", max), + _ => (), + } +# } +``` + +Listing 6-4: A `match` that only cares about executing +code when the value is `Option::Some` + +If the value is `Option::Some`, we print out the value in the `Option::Some` variant by binding +the value to the variable `max` in the pattern. We don’t want to do anything +with the `None` value. To satisfy the `match` expression, we have to add `_ => +()` after processing just one variant, which is annoying boilerplate code to +add. + +Instead, we could write this in a shorter way using `if let`. The following +code behaves the same as the `match` in Listing 6-4: + +```rust +# fn main() { + let number = Option::Some(5); + if let Option::Some(max) = number { + println!("The maximum is configured to be {}", max); + } +# } +# +``` + +The syntax `if let` takes a pattern and an expression separated by an equal +sign. It works the same way as a `match`, where the expression is given to the +`match` and the pattern is its first arm. In this case, the pattern is +`Option::Some(max)`, and `max` binds to the value inside `Option::Some`. We can then +use `max` in the body of the `if let` block in the same way we used `max` in +the corresponding `match` arm. The code in the `if let` block isn’t run if the +value doesn’t match the pattern. + +Using `if let` means less typing, less indentation, and less boilerplate code. +However, you lose the exhaustive checking that `match` enforces. Choosing +between `match` and `if let` depends on what you’re doing in your particular +situation and whether gaining conciseness is an appropriate trade-off for +losing exhaustive checking. + +In other words, you can think of `if let` as syntactic sugar for a `match` that +runs code when the value matches one pattern and then ignores all other values. + +We can include an `else` with an `if let`. The block of code that goes with `else` +is the same as the block of code that would go with the `_` case in the `match` +expression. Recall the `Coin` enum definition in Listing 6-2, +where the `Quarter` variant also held a `UsState` value. If we wanted to count +all non-quarter coins we see while also announcing the state of the quarters, +we could do that with a `match` expression, like this: + +```rust +# #[derive(Drop)] +# enum Coin { +# Penny, +# Nickel, +# Dime, +# Quarter, +# } +# +# fn main() { + let coin = Coin::Quarter; + let mut count = 0; + match coin { + Coin::Quarter => println!("You got a quarter!"), + _ => count += 1, + } +# } +``` + +Or we could use an `if let` and `else` expression, like this: + +```rust +# #[derive(Drop)] +# enum Coin { +# Penny, +# Nickel, +# Dime, +# Quarter, +# } +# +# fn main() { + let coin = Coin::Quarter; + let mut count = 0; + if let Coin::Quarter = coin { + println!("You got a quarter!"); + } else { + count += 1; + } +# println!("{}", count); +# } +# +``` + +If you have a situation in which your program has logic that is too verbose to +express using `match`, remember that `if let` is in your Cairo toolbox as well. + +## `while let` + +The `while let` syntax is similar to the `if let` syntax, but it allows you to loop over a collection of values and execute a block of code for each value that matches a specified pattern. In the case below, the pattern is `Option::Some(x)`, which matches any `Some` variant of the `Option` enum. + +```rust +fn main() { + let mut arr = array![1, 2, 3, 4, 5, 6, 7, 8, 9]; + let mut sum = 0; + while let Option::Some(value) = arr.pop_front() { + sum += value; + }; + println!("{}", sum); +} +``` + +Using `while let` provides a more concise and idiomatic way of writing this loop compared to a traditional `while` loop with explicit pattern matching or handling of the `Option` type. However, as with `if let`, you lose the exhaustive checking that a `match` expression provides, so you need to be careful to handle any remaining cases outside the `while let` loop if necessary. +# Managing Cairo Projects with Packages, Crates and Modules + +As you write large programs, organizing your code will become increasingly +important. By grouping related functionality and separating code with distinct +features, you’ll clarify where to find code that implements a particular +feature and where to go to change how a feature works. + +The programs we’ve written so far have been in one module in one file. As a +project grows, you should organize code by splitting it into multiple modules +and then multiple files. As a package grows, you can extract parts into +separate crates that become external dependencies. This chapter covers all +these techniques. + +We’ll also discuss encapsulating implementation details, which lets you reuse +code at a higher level: once you’ve implemented an operation, other code can +call your code without having to know how the +implementation works. + +A related concept is scope: the nested context in which code is written has a +set of names that are defined as “in scope”. When reading, writing, and +compiling code, programmers and compilers need to know whether a particular +name at a particular spot refers to a variable, function, struct, enum, module, +constant, or other item and what that item means. You can create scopes and +change which names are in or out of scope. You can’t have two items with the +same name in the same scope. + +Cairo has a number of features that allow you to manage your code’s +organization. These features, sometimes +collectively referred to as the _module system_, include: + +- **Packages:** A Scarb feature that lets you build, test, and share crates. +- **Crates:** A tree of modules that corresponds to a single compilation unit. + It has a root directory, and a root module defined at the _lib.cairo_ file under this directory. +- **Modules** and **use:** Let you control the organization and scope of items. +- **Paths:** A way of naming an item, such as a struct, function, or module. + +In this chapter, we’ll cover all these features, discuss how they interact, and +explain how to use them to manage scope. By the end, you should have a solid +understanding of the module system and be able to work with scopes like a pro! +# Packages and Crates + +## What is a Crate? + +A crate is a subset of a package that is used in the actual Cairo compilation. This includes: + +- The package source code, identified by the package name and the crate root, which is the main entry point of the package. +- A subset of the package metadata that identifies crate-level settings of the Cairo compiler, for example, the `edition` field in the _Scarb.toml_ file. + +Crates can contain modules, and the modules may be defined in other files that get compiled with the crate, as will be discussed in the subsequent sections. + +## What is the Crate Root? + +The crate root is the _lib.cairo_ source file that the Cairo compiler starts from and makes up the root module of your crate. We’ll explain modules in depth in the ["Defining Modules to Control Scope"][modules] chapter. + +[modules]: ./ch07-02-defining-modules-to-control-scope.md + +## What is a Package? + +A Cairo package is a directory (or equivalent) containing: + +- A _Scarb.toml_ manifest file with a `[package]` section. +- Associated source code. + +This definition implies that a package might contain other packages, with a corresponding _Scarb.toml_ file for each package. + +## Creating a Package with Scarb + +You can create a new Cairo package using the Scarb command-line tool. To create a new package, run the following command: + +```bash +scarb new my_package +``` + +This command will generate a new package directory named _my_package_ with the following structure: + +``` +my_package/ +├── Scarb.toml +└── src + └── lib.cairo +``` + +- _src/_ is the main directory where all the Cairo source files for the package will be stored. +- _lib.cairo_ is the default root module of the crate, which is also the main entry point of the package. +- _Scarb.toml_ is the package manifest file, which contains metadata and configuration options for the package, such as dependencies, package name, version, and authors. You can find documentation about it on the [Scarb reference][manifest]. + +```toml +[package] +name = "my_package" +version = "0.1.0" +edition = "2023_11" + +[dependencies] +# foo = { path = "vendor/foo" } +``` + +As you develop your package, you may want to organize your code into multiple Cairo source files. You can do this by creating additional _.cairo_ files within the _src_ directory or its subdirectories. + +{{#quiz ../quizzes/ch07-01-packages-crates.toml}} + +[manifest]: https://docs.swmansion.com/scarb/docs/reference/manifest.html +# Defining Modules to Control Scope + +In this section, we’ll talk about modules and other parts of the module system, +namely _paths_ that allow you to name items and the `use` keyword that brings a +path into scope. + +First, we’re going to start with a list of rules for easy reference when you’re +organizing your code in the future. Then we’ll explain each of the rules in +detail. + +## Modules Cheat Sheet + +Here we provide a quick reference on how modules, paths and the `use` keyword +work in the compiler, and how most developers organize their +code. We’ll be going through examples of each of these rules throughout this +chapter, but this is a great place to refer to as a reminder of how modules +work. You can create a new Scarb project with `scarb new backyard` to follow along. + +- **Start from the crate root**: When compiling a crate, the compiler first + looks in the crate root file (_src/lib.cairo_) for code to compile. +- **Declaring modules**: In the crate root file, you can declare new modules; + say, you declare a “garden” module with `mod garden;`. The compiler will look + for the module’s code in these places: + + - Inline, within curly brackets that replace the semicolon following `mod garden`. + + ```rust,noplayground + // crate root file (src/lib.cairo) + mod garden { + // code defining the garden module goes here + } + ``` + + - In the file _src/garden.cairo_. + +- **Declaring submodules**: In any file other than the crate root, you can + declare submodules. For example, you might declare `mod vegetables;` in + _src/garden.cairo_. The compiler will look for the submodule’s code within the + directory named for the parent module in these places: + + - Inline, directly following `mod vegetables`, within curly brackets instead + of the semicolon. + + ```rust,noplayground + // src/garden.cairo file + mod vegetables { + // code defining the vegetables submodule goes here + } + ``` + + - In the file _src/garden/vegetables.cairo_. + +- **Paths to code in modules**: Once a module is part of your crate, you can + refer to code in that module from anywhere else in that same crate, using the path + to the code. For example, an `Asparagus` type in the `vegetables` submodule would be found at + `backyard::garden::vegetables::Asparagus`. +- **Private vs public**: Code within a module is private from its parent modules by default. This means that it may only be + accessed by the current module and its descendants. To make a module public, declare it with `pub mod` instead of `mod`. To make items within a public module public as well, use `pub` before their declarations. Cairo also provides the `pub(crate)` keyword, allowing an item or module to be only visible within the crate in which the definition is included. +- **The `use` keyword**: Within a scope, the `use` keyword creates shortcuts to + items to reduce repetition of long paths. In any scope that can refer to + `backyard::garden::vegetables::Asparagus`, you can create a shortcut with + `use backyard::garden::vegetables::Asparagus;` and from then on you only need to + write `Asparagus` to make use of that type in the scope. + +Here we create a crate named `backyard` that illustrates these rules. The +crate’s directory, also named `backyard`, contains these files and directories: + +```text +backyard/ +├── Scarb.toml +└── src + ├── garden + │   └── vegetables.cairo + ├── garden.cairo + └── lib.cairo +``` + +The crate root file in this case is _src/lib.cairo_, and it contains: + +Filename: src/lib.cairo + +```rust +pub mod garden; +use garden::vegetables::Asparagus; + +fn main() { + let plant = Asparagus {}; + println!("I'm growing {:?}!", plant); +} +``` + +The `pub mod garden;` line imports the `garden` module. Using `pub` to make `garden` publicly accessible, or `pub(crate)` if you really want to make `garden` only available for your crate, is optional to run our program here, as the `main` function resides in the same module as `pub mod garden;` declaration. Nevertheless, not declaring `garden` as `pub` will make it not accessible from any other package. +This line tells the compiler to include the code it finds in _src/garden.cairo_, which is: + +Filename: src/garden.cairo + +```rust,noplayground +pub mod vegetables; +``` + +Here, `pub mod vegetables;` means the code in *src/garden/vegetables.cairo* is included too. That code is: + +```rust,noplayground +#[derive(Drop, Debug)] +pub struct Asparagus {} +``` + +The line `use garden::vegetables::Asparagus;` lets us bring the `Asparagus` type into scope, +so we can use it in the `main` function. + +Now let’s get into the details of these rules and demonstrate them in action! + +## Grouping Related Code in Modules + +_Modules_ let us organize code within a crate for readability and easy reuse. +Modules also allow us to control the privacy of items, because code within a module +is private by default. Private items are internal implementation details not +available for outside use. We can choose to make modules and the items within +them public, which exposes them to allow external code to use and depend on them. + +As an example, let’s write a library crate that provides the functionality of a +restaurant. We’ll define the signatures of functions but leave their bodies +empty to concentrate on the organization of the code, rather than the +implementation of a restaurant. + +In the restaurant industry, some parts of a restaurant are referred to as +_front of house_ and others as _back of house_. Front of house is where +customers are; this encompasses where the hosts seat customers, servers take +orders and payment, and bartenders make drinks. Back of house is where the +chefs and cooks work in the kitchen, dishwashers clean up, and managers do +administrative work. + +To structure our crate in this way, we can organize its functions into nested +modules. Create a new package named _restaurant_ by running `scarb new restaurant`; then enter the code in Listing 7-1 into _src/lib.cairo_ to +define some modules and function signatures. Here’s the front of house section: + +Filename: src/lib.cairo + +```rust,noplayground +mod front_of_house { + mod hosting { + fn add_to_waitlist() {} + + fn seat_at_table() {} + } + + mod serving { + fn take_order() {} + + fn serve_order() {} + + fn take_payment() {} + } +} +``` + +Listing 7-1: A `front_of_house` module containing other modules that then contain functions + +We define a module with the `mod` keyword followed by the name of the module +(in this case, `front_of_house`). The body of the module then goes inside curly +brackets. Inside modules, we can place other modules, as in this case with the +modules `hosting` and `serving`. Modules can also hold definitions for other +items, such as structs, enums, constants, traits, and functions. + +By using modules, we can group related definitions together and name why +they’re related. Programmers using this code can navigate the code based on the +groups rather than having to read through all the definitions, making it easier +to find the definitions relevant to them. Programmers adding new functionality +to this code would know where to place the code to keep the program organized. + +Earlier, we mentioned that _src/lib.cairo_ is called the crate +root. The reason for this name is that the content of this file forms a module named after the crate name at the root of the crate’s module structure, known as the _module tree_. + +Listing 7-2 shows the module tree for the structure in Listing 7-1. + +```text +restaurant + └── front_of_house + ├── hosting + │ ├── add_to_waitlist + │ └── seat_at_table + └── serving + ├── take_order + ├── serve_order + └── take_payment +``` + +Listing 7-2: The module tree for the code in Listing 7-1 + +This tree shows how some of the modules nest inside one another; for example, +`hosting` nests inside `front_of_house`. The tree also shows that some modules +are _siblings_ to each other, meaning they’re defined in the same module; +`hosting` and `serving` are siblings defined within `front_of_house`. If module +A is contained inside module B, we say that module A is the _child_ of module B +and that module B is the _parent_ of module A. Notice that the entire module +tree is rooted under the explicit name of the crate _restaurant_. + +The module tree might remind you of the filesystem’s directory tree on your +computer; this is a very apt comparison! Just like directories in a filesystem, +you use modules to organize your code. And just like files in a directory, we +need a way to find our modules. + +{{#quiz ../quizzes/ch07-02-defining-modules-to-control-scope.toml}} +# Paths for Referring to an Item in the Module Tree + +To show Cairo where to find an item in a module tree, we use a path in the same way we use a path when navigating a filesystem. To call a function, we need to know its path. + +A path can take two forms: + +- An _absolute path_ is the full path starting from a crate root. The absolute path begins with the crate name. +- A _relative path_ starts from the current module. + +Both absolute and relative paths are followed by one or more identifiers separated by double colons (`::`). + +To illustrate this notion let's take back our example Listing 7-1 for the restaurant we used in the last chapter. We have a crate named _restaurant_ in which we have a module named `front_of_house` that contains a module named `hosting`. The `hosting` module contains a function named `add_to_waitlist`. We want to call the `add_to_waitlist` function from the `eat_at_restaurant` function. We need to tell Cairo the path to the `add_to_waitlist` function so it can find it. + +Filename: src/lib.cairo + +```rust,noplayground +mod front_of_house { + mod hosting { + fn add_to_waitlist() {} + + fn seat_at_table() {} + } + + mod serving { + fn take_order() {} + + fn serve_order() {} + + fn take_payment() {} + } +} + + +pub fn eat_at_restaurant() { + // Absolute path + restaurant::front_of_house::hosting::add_to_waitlist(); + + // Relative path + front_of_house::hosting::add_to_waitlist(); +} +``` + +Listing 7-3: Calling the `add_to_waitlist` function using absolute and relative paths + +The `eat_at_restaurant` function is part of our library's public API, so we mark it with the `pub` keyword. We’ll go into more detail about `pub` in the ["Exposing Paths with the `pub` Keyword"][pub] section. + +The first time we call the `add_to_waitlist` function in `eat_at_restaurant`, +we use an absolute path. The `add_to_waitlist` function is defined in the same +crate as `eat_at_restaurant`. In Cairo, absolute paths start from the crate root, which you need to refer to by using the crate name. You can imagine a filesystem with the same structure: we’d specify the path _/front_of_house/hosting/add_to_waitlist_ to run the _add_to_waitlist_ program; using the crate name to start from the crate root is like using a slash (`/`) to start from the filesystem root in your shell. + +The second time we call `add_to_waitlist`, we use a relative path. The path starts with `front_of_house`, the name of the module defined at the same level of the module tree as `eat_at_restaurant`. Here the filesystem equivalent would be using the path _./front_of_house/hosting/add_to_waitlist_. Starting with a module name means that the path is relative to the current module. + +Let’s try to compile Listing 7-3 and find out why it won’t compile yet! We get the following error: + +```shell +$ scarb cairo-run + Compiling listing_07_02 v0.1.0 (listings/ch07-managing-cairo-projects-with-packages-crates-and-modules/listing_02_paths/Scarb.toml) +error: Identifier not found. + --> listings/ch07-managing-cairo-projects-with-packages-crates-and-modules/listing_02_paths/src/lib.cairo:22:5 + restaurant::front_of_house::hosting::add_to_waitlist(); + ^********^ + +error: Item `listing_07_02::front_of_house::hosting` is not visible in this context. + --> listings/ch07-managing-cairo-projects-with-packages-crates-and-modules/listing_02_paths/src/lib.cairo:25:21 + front_of_house::hosting::add_to_waitlist(); + ^*****^ + +error: Item `listing_07_02::front_of_house::hosting::add_to_waitlist` is not visible in this context. + --> listings/ch07-managing-cairo-projects-with-packages-crates-and-modules/listing_02_paths/src/lib.cairo:25:30 + front_of_house::hosting::add_to_waitlist(); + ^*************^ + +error: could not compile `listing_07_02` due to previous error +error: `scarb metadata` exited with error + +``` + +The error messages say that module `hosting` and the `add_to_waitlist` function are not visible. In other words, we have the correct paths for the `hosting` module and the `add_to_waitlist` function, but Cairo won’t let us use them because it doesn’t have access to them. In Cairo, all items (functions, methods, structs, enums, modules, and constants) are private to parent modules by default. If you want to make an item like a function or struct private, you put it in a module. + +Items in a parent module can’t use the private items inside child modules, but items in child modules can use the items in their ancestor modules. This is because child modules wrap and hide their implementation details, but the child modules can see the context in which they’re defined. To continue with our metaphor, think of the privacy rules as being like the back office of a restaurant: what goes on in there is private to restaurant customers, but office managers can see and do everything in the restaurant they operate. + +Cairo chose to have the module system function this way so that hiding inner implementation details is the default. That way, you know which parts of the inner code you can change without breaking outer code. However, Cairo does give you the option to expose inner parts of child modules’ code to outer ancestor modules by using the `pub` keyword to make an item public. + +[pub]: ./ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md#exposing-paths-with-the-pub-keyword + +## Exposing Paths with the `pub` Keyword + +Let’s return to the previous error that told us the `hosting` module and the `add_to_waitlist` function are not visible. We want the `eat_at_restaurant` function in the parent module to have access to the `add_to_waitlist` function in the child module, so we mark the `hosting` module with the `pub` keyword, as shown in Listing 7-4. + +Filename: src/lib.cairo + +```rust,noplayground +mod front_of_house { + pub mod hosting { + fn add_to_waitlist() {} + } +} + +pub fn eat_at_restaurant() { + // Absolute path + restaurant::front_of_house::hosting::add_to_waitlist(); + + // Relative path + front_of_house::hosting::add_to_waitlist(); +} +``` + +Listing 7-4: Declaring the `hosting` module as `pub` to use it from `eat_at_restaurant` + +Unfortunately, the code in Listing 7-4 still results in an error. + +What happened? Adding the `pub` keyword in front of `mod hosting;` makes the module public. With this change, if we can access `front_of_house`, we can access `hosting`. But the contents of `hosting` are still private; making the module public doesn’t make its contents public. The `pub` keyword on a module only lets code in its ancestor modules refer to it, not access its inner code. Because modules are containers, there’s not much we can do by only making the module public; we need to go further and choose to make one or more of the items within the module public as well. + +Let’s also make the `add_to_waitlist` function public by adding the `pub` keyword before its definition, as in Listing 7-5. + +Filename: src/lib.cairo + +```rust,noplayground +mod front_of_house { + pub mod hosting { + pub fn add_to_waitlist() {} + } +} + +pub fn eat_at_restaurant() { + // Absolute path + restaurant::front_of_house::hosting::add_to_waitlist(); // ✅ Compiles + + // Relative path + front_of_house::hosting::add_to_waitlist(); // ✅ Compiles +} +``` + +Listing 7-5: Declaring the `hosting` module as `pub` to use it from `eat_at_restaurant` + +Now the code will compile! To see why adding the `pub` keyword lets us use these paths in `add_to_waitlist` with respect to the privacy rules, let’s look at the absolute and the relative paths. + +In the absolute path, we start with the crate root, the root of our crate’s module tree. The `front_of_house` module is defined in the crate root. While `front_of_house` isn’t public, because the `eat_at_restaurant` function is defined in the same module as `front_of_house` (that is, `front_of_house` and `eat_at_restaurant` are siblings), we can refer to `front_of_house` from `eat_at_restaurant`. Next is the `hosting` module marked with `pub`. We can access the parent module of `hosting`, so we can access `hosting` itself. Finally, the `add_to_waitlist` function is marked with `pub` and we can access its parent module, so this function call works! + +In the relative path, the logic is the same as the absolute path except for the first step: rather than starting from the crate root, the path starts from `front_of_house`. The `front_of_house` module is defined within the same module as `eat_at_restaurant`, so the relative path starting from the module in which `eat_at_restaurant` is defined works. Then, because `hosting` and `add_to_waitlist` are marked with `pub`, the rest of the path works, and this function call is valid! + +{{#quiz ../quizzes/ch07-03-paths-in-module-tree-1.toml}} + +## Starting Relative Paths with `super` + +We can construct relative paths that begin in the parent module, rather than the current module or the crate root, by using `super` at the start of the path. This is like starting a filesystem path with the `..` syntax. Using `super` allows us to reference an item that we know is in the parent module, which can make rearranging the module tree easier when the module is closely related to the parent, but the parent might be moved elsewhere in the module tree someday. + +Consider the code in Listing 7-6 that models the situation in which a chef fixes an incorrect order and personally brings it out to the customer. The function `fix_incorrect_order` defined in the `back_of_house` module calls the function `deliver_order` defined in the parent module by specifying the path to `deliver_order` starting with `super`: + +Filename: src/lib.cairo + +```rust,noplayground +fn deliver_order() {} + +mod back_of_house { + fn fix_incorrect_order() { + cook_order(); + super::deliver_order(); + } + + fn cook_order() {} +} +``` + +Listing 7-6: Calling a function using a relative path starting with `super` + +Here you can see directly that you access a parent's module easily using `super`, which wasn't the case previously. +Note that the `back_of_house` is kept private, as external users are not supposed to interact with the back of house directly. + +## Making Structs and Enums Public + +We can also use `pub` to designate structs and enums as public, but there are a few extra details to consider when using `pub` with structs and enums. + +- If we use `pub` before a struct definition, we make the struct public, but the struct’s fields will still be private. We can make each field public or not on a case-by-case basis. +- In contrast, if we make an enum public, all of its variants are then public. We only need the `pub` before the `enum` keyword. + +There’s one more situation involving `pub` that we haven’t covered, and that is our last module system feature: the `use` keyword. We’ll cover `use` by itself first, and then we’ll show how to combine `pub` and `use`. + +{{#quiz ../quizzes/ch07-03-paths-in-module-tree-2.toml}} +# Bringing Paths into Scope with the `use` Keyword + +Having to write out the paths to call functions can feel inconvenient and repetitive. Fortunately, there’s a way to simplify this process: we can create a shortcut to a path with the `use` keyword once, and then use the shorter name everywhere else in the scope. + +In Listing 7-7, we bring the `restaurant::front_of_house::hosting` module into the +scope of the `eat_at_restaurant` function so we only have to specify +`hosting::add_to_waitlist` to call the `add_to_waitlist` function in +`eat_at_restaurant`. + +Filename: src/lib.cairo + +```rust +// Assuming "front_of_house" module is contained in a crate called "restaurant", as mentioned in the section "Defining Modules to Control Scope" +// If the path is created in the same crate, "restaurant" is optional in the use statement + +mod front_of_house { + pub mod hosting { + pub fn add_to_waitlist() {} + } +} + +use restaurant::front_of_house::hosting; + +pub fn eat_at_restaurant() { + hosting::add_to_waitlist(); // ✅ Shorter path +} +``` + +Listing 7-7: Bringing a module into scope with `use` + +Adding `use` and a path in a scope is similar to creating a symbolic link in the filesystem. By adding `use restaurant::front_of_house::hosting;` in the crate root, `hosting` is now a valid name in that scope, just as though the `hosting` module had been defined in the crate root. + +Note that `use` only creates the shortcut for the particular scope in which the `use` occurs. Listing 7-8 moves the `eat_at_restaurant` function into a new child module named `customer`, which is then a different scope than the `use` +statement, so the function body won’t compile: + +Filename: src/lib.cairo + +```rust +mod front_of_house { + pub mod hosting { + pub fn add_to_waitlist() {} + } +} + +use restaurant::front_of_house::hosting; + +mod customer { + pub fn eat_at_restaurant() { + hosting::add_to_waitlist(); + } +} +``` + +Listing 7-8: A `use` statement only applies in the scope it’s in. + +The compiler error shows that the shortcut no longer applies within the `customer` module: + +```shell +$ scarb build + Compiling listing_07_05 v0.1.0 (listings/ch07-managing-cairo-projects-with-packages-crates-and-modules/listing_07_use_and_scope/Scarb.toml) +error: Identifier not found. + --> listings/ch07-managing-cairo-projects-with-packages-crates-and-modules/listing_07_use_and_scope/src/lib.cairo:10:5 +use restaurant::front_of_house::hosting; + ^********^ + +error: Identifier not found. + --> listings/ch07-managing-cairo-projects-with-packages-crates-and-modules/listing_07_use_and_scope/src/lib.cairo:14:9 + hosting::add_to_waitlist(); + ^*****^ + +error: could not compile `listing_07_05` due to previous error + +``` + +## Creating Idiomatic `use` Paths + +In Listing 7-7, you might have wondered why we specified `use restaurant::front_of_house::hosting` +and then called `hosting::add_to_waitlist` in `eat_at_restaurant` rather than specifying the `use` path all the way out to +the `add_to_waitlist` function to achieve the same result, as in Listing 7-9. + +Filename: src/lib.cairo + +```rust +mod front_of_house { + pub mod hosting { + pub fn add_to_waitlist() {} + } +} + +use restaurant::front_of_house::hosting::add_to_waitlist; + +pub fn eat_at_restaurant() { + add_to_waitlist(); +} +``` + +Listing 7-9: Bringing the `add_to_waitlist` function into scope with `use`, which is unidiomatic + +Although both Listing 7-7 and 7-9 accomplish the same task, Listing 7-7 is +the idiomatic way to bring a function into scope with `use`. Bringing the +function’s parent module into scope with `use` means we have to specify the +parent module when calling the function. Specifying the parent module when +calling the function makes it clear that the function isn’t locally defined +while still minimizing repetition of the full path. The code in Listing 7-9 is +unclear as to where `add_to_waitlist` is defined. + +On the other hand, when bringing in structs, enums, traits, and other items with `use`, it’s idiomatic to specify the full path. Listing 7-10 shows the idiomatic way to bring the core library’s `BitSize` trait into the scope, allowing to call `bits` method to retrieve the size in bits of a type. + +```rust +use core::num::traits::BitSize; + +fn main() { + let u8_size: usize = BitSize::::bits(); + println!("A u8 variable has {} bits", u8_size) +} +``` + +Listing 7-10: Bringing `BitSize` trait into scope in an idiomatic way + +There’s no strong reason behind this idiom: it’s just the convention that has +emerged in the Rust community, and folks have gotten used to reading and writing Rust code this way. +As Cairo shares many idioms with Rust, we follow this convention as well. + +The exception to this idiom is if we’re bringing two items with the same name +into scope with `use` statements, because Cairo doesn’t allow that. + +### Providing New Names with the `as` Keyword + +There’s another solution to the problem of bringing two types of the same name +into the same scope with `use`: after the path, we can specify `as` and a new +local name, or _alias_, for the type. Listing 7-11 shows how you can rename an import with `as`: + +Filename: src/lib.cairo + +```rust +use core::array::ArrayTrait as Arr; + +fn main() { + let mut arr = Arr::new(); // ArrayTrait was renamed to Arr + arr.append(1); +} +``` + +Listing 7-11: Renaming a trait when it’s brought into scope with the `as` keyword + +Here, we brought `ArrayTrait` into scope with the alias `Arr`. We can now access the trait's methods with the `Arr` identifier. + +### Importing Multiple Items from the Same Module + +When you want to import multiple items (like functions, structs or enums) +from the same module in Cairo, you can use curly braces `{}` to list all of +the items that you want to import. This helps to keep your code clean and easy +to read by avoiding a long list of individual `use` statements. + +The general syntax for importing multiple items from the same module is: + +```rust +use module::{item1, item2, item3}; +``` + +Here is an example where we import three structures from the same module: + +```rust +// Assuming we have a module called `shapes` with the structures `Square`, `Circle`, and `Triangle`. +mod shapes { + #[derive(Drop)] + pub struct Square { + pub side: u32 + } + + #[derive(Drop)] + pub struct Circle { + pub radius: u32 + } + + #[derive(Drop)] + pub struct Triangle { + pub base: u32, + pub height: u32, + } +} + +// We can import the structures `Square`, `Circle`, and `Triangle` from the `shapes` module like this: +use shapes::{Square, Circle, Triangle}; + +// Now we can directly use `Square`, `Circle`, and `Triangle` in our code. +fn main() { + let sq = Square { side: 5 }; + let cr = Circle { radius: 3 }; + let tr = Triangle { base: 5, height: 2 }; +// ... +} +``` + +Listing 7-12: Importing multiple items from the same module + +## Re-exporting Names in Module Files + +When we bring a name into scope with the `use` keyword, the name available in +the new scope can be imported as if it had been defined in that code’s scope. +This technique is called _re-exporting_ because we’re bringing an item into scope, +but also making that item available for others to bring into their scope, with the `pub` keyword. + +For example, let's re-export the `add_to_waitlist` function in the restaurant example: + +Filename: src/lib.cairo + +```rust +mod front_of_house { + pub mod hosting { + pub fn add_to_waitlist() {} + } +} + +pub use restaurant::front_of_house::hosting; + +fn eat_at_restaurant() { + hosting::add_to_waitlist(); +} +``` + +Listing 7-13: Making a name available for any code to use from a new scope with `pub use` + +Before this change, external code would have to call the `add_to_waitlist` +function by using the path `restaurant::front_of_house::hosting::add_to_waitlist()`. +Now that this `pub use` has re-exported the `hosting` module from the root module, external code +can now use the path `restaurant::hosting::add_to_waitlist()` instead. + +Re-exporting is useful when the internal structure of your code is different +from how programmers calling your code would think about the domain. For +example, in this restaurant metaphor, the people running the restaurant think +about “front of house” and “back of house.” But customers visiting a restaurant +probably won’t think about the parts of the restaurant in those terms. With +`pub use`, we can write our code with one structure but expose a different +structure. Doing so makes our library well organized for programmers working on +the library and programmers calling the library. + +## Using External Packages in Cairo with Scarb + +You might need to use external packages to leverage the functionality provided by the community. Scarb allows you to use dependencies by cloning packages from their Git repositories. To use an external package in your project with Scarb, simply declare the Git repository URL of the dependency you want to add in a dedicated `[dependencies]` section in your _Scarb.toml_ configuration file. Note that the URL might correspond to the main branch, or any specific commit, branch or tag. For this, you will have to pass an extra `rev`, `branch`, or `tag` field, respectively. For example, the following code imports the main branch of _alexandria_math_ crate from _alexandria_ package: + +```rust +[dependencies] +alexandria_math = { git = "https://github.com/keep-starknet-strange/alexandria.git" } +``` + +while the following code imports a specific branch (which is deprecated and should not be used): + +```rust +[dependencies] +alexandria_math = { git = "https://github.com/keep-starknet-strange/alexandria.git", branch = "cairo-v2.3.0-rc0" } +``` + +If you want to import multiple packages in your project, you need to create only one `[dependencies]` section and list all the desired packages beneath it. You can also specify development dependencies by declaring a `[dev-dependencies]` section. + +After that, simply run `scarb build` to fetch all external dependencies and compile your package with all the dependencies included. + +Note that it is also possible to add dependencies with the `scarb add` command, which will automatically edit the _Scarb.toml_ file for you. For development dependencies, just use the `scarb add --dev` command. + +To remove a dependency, simply remove the corresponding line from your _Scarb.toml_ file, or use the `scarb rm` command. + +{{#quiz ../quizzes/ch07-04-bringing-paths-into-scope.toml}} +# Separating Modules into Different Files + +So far, all the examples in this chapter defined multiple modules in one file. +When modules get large, you might want to move their definitions to a separate +file to make the code easier to navigate. + +For example, let’s start from the code in Listing 7-7 that had multiple +restaurant modules. We’ll extract modules into files instead of having all the +modules defined in the crate root file. In this case, the crate root file is +_src/lib.cairo_. + +First, we’ll extract the `front_of_house` module to its own file. Remove the +code inside the curly brackets for the `front_of_house` module, leaving only +the `mod front_of_house;` declaration, so that _src/lib.cairo_ contains the code +shown in Listing 7-14. Note that this won’t compile until we create the +_src/front_of_house.cairo_ file. + +Filename: src/lib.cairo + +```rust,noplayground +mod front_of_house; + +use restaurant::front_of_house::hosting; + +fn eat_at_restaurant() { + hosting::add_to_waitlist(); +} +``` + +Listing 7-14: Declaring the `front_of_house` module whose body will be in _src/front_of_house.cairo_ + +Next, place the code that was in the curly brackets into a new file named +_src/front_of_house.cairo_, as shown in Listing 7-15. The compiler knows to look +in this file because it came across the module declaration in the crate root +with the name `front_of_house`. + +Filename: src/front_of_house.cairo + +```rust,noplayground +pub mod hosting { + pub fn add_to_waitlist() {} +} +``` + +Listing 7-15: Definitions inside the `front_of_house` module in _src/front_of_house.cairo_ + +Note that you only need to load a file using a `mod` declaration _once_ in your +module tree. Once the compiler knows the file is part of the project (and knows +where in the module tree the code resides because of where you’ve put the `mod` +statement), other files in your project should refer to the loaded file’s code +using a path to where it was declared, as covered in the ["Paths for Referring to an Item in the Module Tree"][path] chapter. +In other words, `mod` is _not_ an “include” operation that you may have seen in other +programming languages. + +Next, we’ll extract the `hosting` module to its own file. The process is a bit +different because `hosting` is a child module of `front_of_house`, not of the +root module. We’ll place the file for `hosting` in a new directory that will be +named for its ancestors in the module tree, in this case _src/front_of_house/_. + +To start moving `hosting`, we change _src/front_of_house.cairo_ to contain only the +declaration of the `hosting` module: + +Filename: src/front_of_house.cairo + +```rust,noplayground +pub mod hosting; +``` + +Then we create a _src/front_of_house_ directory and a file _hosting.cairo_ to +contain the definitions made in the `hosting` module: + +Filename: src/front_of_house/hosting.cairo + +```rust,noplayground +pub fn add_to_waitlist() {} +``` + +If we instead put _hosting.cairo_ in the _src_ directory, the compiler would +expect the _hosting.cairo_ code to be in a `hosting` module declared in the crate +root, and not declared as a child of the `front_of_house` module. The +compiler’s rules for which files to check for which modules’ code means the +directories and files more closely match the module tree. + +We’ve moved each module’s code to a separate file, and the module tree remains +the same. The function calls in `eat_at_restaurant` will work without any +modification, even though the definitions live in different files. This +technique lets you move modules to new files as they grow in size. + +Note that the `use restaurant::front_of_house::hosting;` statement in +_src/lib.cairo_ also hasn’t changed, nor does `use` have any impact on what files +are compiled as part of the crate. The `mod` keyword declares modules, and Cairo +looks in a file with the same name as the module for the code that goes into +that module. + +[path]: ./ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md + +## Summary + +Cairo lets you split a package into multiple crates and a crate into modules +so you can refer to items defined in one module from another module. You can do +this by specifying absolute or relative paths. These paths can be brought into +scope with a `use` statement so you can use a shorter path for multiple uses of +the item in that scope. Module code is **private** by default. + +{{#quiz ../quizzes/ch07-05-separate-modules.toml}} +# Generic Types and Traits + +Every programming language has tools for effectively handling the duplication of concepts. In Cairo, one such tool is generics: abstract stand-ins for concrete types or other properties. We can express the behavior of generics or how they relate to other generics without knowing what will be in their place when compiling and running the code. + +Functions can take parameters of some generic type, instead of a concrete type like `u32` or `bool`, in the same way a function takes parameters with unknown values to run the same code on multiple concrete values. In fact, we’ve already used generics in [Chapter 6][option enum] with `Option`. + +In this chapter, you’ll explore how to define your own types, functions, and traits with generics. + +Generics allow us to replace specific types with a placeholder that represents multiple types to remove code duplication. Upon compilation, the compiler creates a new definition for each concrete type that replaces a generic type, reducing development time for the programmer, but code duplication at compile level still exists. This may be of importance if you are writing Starknet contracts and using a generic for multiple types which will cause contract size to increment. + +Then you’ll learn how to use traits to define behavior in a generic way. You can combine traits with generic types to constrain a generic type to accept only those types that have a particular behavior, as opposed to just any type. + +[option enum]: ./ch06-01-enums.html#the-option-enum-and-its-advantages + +## Removing Duplication by Extracting a Function + +Generics allow us to replace specific types with a placeholder that represents multiple types to remove code duplication. Before diving into generics syntax, let’s first look at how to remove duplication in a way that doesn’t involve generic types by extracting a function that replaces specific values with a placeholder that represents multiple values. Then we’ll apply the same technique to extract a generic function! By learning how to identify duplicated code that can be extracted into a function, you'll start to recognize instances where generics can be used to reduce duplication. + +We begin with a short program that finds the largest number in an array of `u8`: + +```rust +fn main() { + let mut number_list: Array = array![34, 50, 25, 100, 65]; + + let mut largest = number_list.pop_front().unwrap(); + + while let Option::Some(number) = number_list + .pop_front() { + if number > largest { + largest = number; + } + }; + + println!("The largest number is {}", largest); +} +``` + +We store an array of `u8` in the variable `number_list` and extract the first number in the array in a variable named `largest`. We then iterate through all the numbers in the array, and if the current number is greater than the number stored in `largest`, we update the value of `largest`. However, if the current number is less than or equal to the largest number seen so far, the variable doesn’t change, and the code moves on to the next number in the list. After considering all the numbers in the array, `largest` should contain the largest number, which in this case is 100. + +We've now been tasked with finding the largest number in two different arrays of numbers. To do so, we can choose to duplicate the previous code and use the same logic at two different places in the program, as follows: + +```rust +fn main() { + let mut number_list: Array = array![34, 50, 25, 100, 65]; + + let mut largest = number_list.pop_front().unwrap(); + + while let Option::Some(number) = number_list + .pop_front() { + if number > largest { + largest = number; + } + }; + + println!("The largest number is {}", largest); + + let mut number_list: Array = array![102, 34, 255, 89, 54, 2, 43, 8]; + + let mut largest = number_list.pop_front().unwrap(); + + while let Option::Some(number) = number_list + .pop_front() { + if number > largest { + largest = number; + } + }; + + println!("The largest number is {}", largest); +} +``` + +Although this code works, duplicating code is tedious and error-prone. We also have to remember to update the code in multiple places when we want to change it. + +To eliminate this duplication, we’ll create an abstraction by defining a function that operates on any array of `u8` passed in a parameter. This solution makes our code clearer and lets us express the concept of finding the largest number in an array abstractly. + +To do that, we extract the code that finds the largest number into a function named `largest`. Then we call the function to find the largest number in the two arrays. We could also use the function on any other array of `u8` values we might have in the future. + +```rust +fn largest(ref number_list: Array) -> u8 { + let mut largest = number_list.pop_front().unwrap(); + + while let Option::Some(number) = number_list + .pop_front() { + if number > largest { + largest = number; + } + }; + + largest +} + +fn main() { + let mut number_list = array![34, 50, 25, 100, 65]; + + let result = largest(ref number_list); + println!("The largest number is {}", result); + + let mut number_list = array![102, 34, 255, 89, 54, 2, 43, 8]; + + let result = largest(ref number_list); + println!("The largest number is {}", result); +} +``` + +The largest function has a parameter called `number_list`, passed by reference, which represents any concrete array of `u8` values we might pass into the function. As a result, when we call the function, the code runs on the specific values that we pass in. + +In summary, here are the steps we took to change the code: + +- Identify duplicate code. +- Extract the duplicate code into the body of the function and specify the inputs and return values of that code in the function signature. +- Update the two instances of duplicated code to call the function instead. + +Next, we’ll use these same steps with generics to reduce code duplication. In the same way that the function body can operate on an abstract `Array` instead of specific `u8` values, generics allow code to operate on abstract types. +# Generic Data Types + +We use generics to create definitions for item declarations, such as structs and functions, which we can then use with many different concrete data types. In Cairo, we can use generics when defining functions, structs, enums, traits, implementations and methods. In this chapter, we are going to take a look at how to effectively use generic types with all of them. + +Generics allow us to write reusable code that works with many types, thus avoiding code duplication, while enhancing code maintainability. + +## Generic Functions + +Making a function generic means it can operate on different types, avoiding the need for multiple, type-specific implementations. This leads to significant code reduction and increases the flexibility of the code. + +When defining a function that uses generics, we place the generics in the function signature, where we would usually specify the data types of the parameter and return value. For example, imagine we want to create a function which given two `Array` of items, will return the largest one. If we need to perform this operation for lists of different types, then we would have to redefine the function each time. Luckily we can implement the function once using generics and move on to other tasks. + +```rust +// Specify generic type T between the angulars +fn largest_list(l1: Array, l2: Array) -> Array { + if l1.len() > l2.len() { + l1 + } else { + l2 + } +} + +fn main() { + let mut l1 = array![1, 2]; + let mut l2 = array![3, 4, 5]; + + // There is no need to specify the concrete type of T because + // it is inferred by the compiler + let l3 = largest_list(l1, l2); +} +``` + +The `largest_list` function compares two lists of the same type and returns the one with more elements and drops the other. If you compile the previous code, you will notice that it will fail with an error saying that there are no traits defined for dropping an array of a generic type. This happens because the compiler has no way to guarantee that an `Array` is droppable when executing the `main` function. In order to drop an array of `T`, the compiler must first know how to drop `T`. This can be fixed by specifying in the function signature of `largest_list` that `T` must implement the `Drop` trait. The correct function definition of `largest_list` is as follows: + +```rust +fn largest_list>(l1: Array, l2: Array) -> Array { + if l1.len() > l2.len() { + l1 + } else { + l2 + } +} +``` + +The new `largest_list` function includes in its definition the requirement that whatever generic type is placed there, it must be droppable. This is what we call _trait bounds_. The `main` function remains unchanged, the compiler is smart enough to deduce which concrete type is being used and if it implements the `Drop` trait. + +### Constraints for Generic Types + +When defining generic types, it is useful to have information about them. Knowing which traits a generic type implements allows us to use it more effectively in a function's logic at the cost of constraining the generic types that can be used with the function. We saw an example of this previously by adding the `TDrop` implementation as part of the generic arguments of `largest_list`. While `TDrop` was added to satisfy the compiler's requirements, we can also add constraints to benefit our function logic. + +Imagine that we want, given a list of elements of some generic type `T`, to find the smallest element among them. Initially, we know that for an element of type `T` to be comparable, it must implement the `PartialOrd` trait. The resulting function would be: + +```rust +// Given a list of T get the smallest one +// The PartialOrd trait implements comparison operations for T +fn smallest_element>(list: @Array) -> T { + // This represents the smallest element through the iteration + // Notice that we use the desnap (*) operator + let mut smallest = *list[0]; + + // The index we will use to move through the list + let mut index = 1; + + // Iterate through the whole list storing the smallest + while index < list + .len() { + if *list[index] < smallest { + smallest = *list[index]; + } + index = index + 1; + }; + + smallest +} + +fn main() { + let list: Array = array![5, 3, 10]; + + // We need to specify that we are passing a snapshot of `list` as an argument + let s = smallest_element(@list); + assert!(s == 3); +} +``` + +The `smallest_element` function uses a generic type `T` that implements the `PartialOrd` trait, takes a snapshot of an `Array` as a parameter and returns a copy of the smallest element. Because the parameter is of type `@Array`, we no longer need to drop it at the end of the execution and so we are not required to implement the `Drop` trait for `T` as well. Why does it not compile then? + +When indexing on `list`, the value results in a snap of the indexed element, and unless `PartialOrd` is implemented for `@T` we need to desnap the element using `*`. The `*` operation requires a copy from `@T` to `T`, which means that `T` needs to implement the `Copy` trait. After copying an element of type `@T` to `T`, there are now variables with type `T` that need to be dropped, requiring `T` to implement the `Drop` trait as well. We must then add both `Drop` and `Copy` traits implementation for the function to be correct. After updating the `smallest_element` function the resulting code would be: + +```rust +fn smallest_element, impl TCopy: Copy, impl TDrop: Drop>( + list: @Array +) -> T { + let mut smallest = *list[0]; + let mut index = 1; + + while index < list + .len() { + if *list[index] < smallest { + smallest = *list[index]; + } + index = index + 1; + }; + + smallest +} +``` + +### Anonymous Generic Implementation Parameter (`+` Operator) + +Until now, we have always specified a name for each implementation of the required generic trait: `TPartialOrd` for `PartialOrd`, `TDrop` for `Drop`, and `TCopy` for `Copy`. + +However, most of the time, we don't use the implementation in the function body; we only use it as a constraint. In these cases, we can use the `+` operator to specify that the generic type must implement a trait without naming the implementation. This is referred to as an _anonymous generic implementation parameter_. + +For example, `+PartialOrd` is equivalent to `impl TPartialOrd: PartialOrd`. + +We can rewrite the `smallest_element` function signature as follows: + +```rust +fn smallest_element, +Copy, +Drop>(list: @Array) -> T { +# let mut smallest = *list[0]; +# let mut index = 1; +# loop { +# if index >= list.len() { +# break smallest; +# } +# if *list[index] < smallest { +# smallest = *list[index]; +# } +# index = index + 1; +# } +# } +``` + +## Structs + +We can also define structs to use a generic type parameter for one or more fields using the `<>` syntax, similar to function definitions. First, we declare the name of the type parameter inside the angle brackets just after the name of the struct. Then we use the generic type in the struct definition where we would otherwise specify concrete data types. The next code example shows the definition `Wallet` which has a `balance` field of type `T`. + +```rust +#[derive(Drop)] +struct Wallet { + balance: T +} + +fn main() { + let w = Wallet { balance: 3 }; +} +``` + +The above code derives the `Drop` trait for the `Wallet` type automatically. It is equivalent to writing the following code: + +```rust +struct Wallet { + balance: T +} + +impl WalletDrop> of Drop>; + +fn main() { + let w = Wallet { balance: 3 }; +} +``` + +We avoid using the `derive` macro for `Drop` implementation of `Wallet` and instead define our own `WalletDrop` implementation. Notice that we must define, just like functions, an additional generic type for `WalletDrop` saying that `T` implements the `Drop` trait as well. We are basically saying that the struct `Wallet` is droppable as long as `T` is also droppable. + +Finally, if we want to add a field to `Wallet` representing its address and we want that field to be different than `T` but generic as well, we can simply add another generic type between the `<>`: + +```rust +#[derive(Drop)] +struct Wallet { + balance: T, + address: U, +} + +fn main() { + let w = Wallet { balance: 3, address: 14 }; +} +``` + +We add to the `Wallet` struct definition a new generic type `U` and then assign this type to the new field member `address`. Notice that the `derive` attribute for the `Drop` trait works for `U` as well. + +## Enums + +As we did with structs, we can define enums to hold generic data types in their variants. For example the `Option` enum provided by the Cairo core library: + +```rust,noplayground +enum Option { + Some: T, + None, +} +``` + +The `Option` enum is generic over a type `T` and has two variants: `Some`, which holds one value of type `T` and `None` that doesn't hold any value. By using the `Option` enum, it is possible for us to express the abstract concept of an optional value and because the value has a generic type `T` we can use this abstraction with any type. + +Enums can use multiple generic types as well, like the definition of the `Result` enum that the core library provides: + +```rust,noplayground +enum Result { + Ok: T, + Err: E, +} +``` + +The `Result` enum has two generic types, `T` and `E`, and two variants: `Ok` which holds the value of type `T` and `Err` which holds the value of type `E`. This definition makes it convenient to use the `Result` enum anywhere we have an operation that might succeed (by returning a value of type `T`) or fail (by returning a value of type `E`). + +## Generic Methods + +We can implement methods on structs and enums, and use the generic types in their definitions, too. Using our previous definition of `Wallet` struct, we define a `balance` method for it: + +```rust +#[derive(Copy, Drop)] +struct Wallet { + balance: T +} + +trait WalletTrait { + fn balance(self: @Wallet) -> T; +} + +impl WalletImpl> of WalletTrait { + fn balance(self: @Wallet) -> T { + return *self.balance; + } +} + +fn main() { + let w = Wallet { balance: 50 }; + assert!(w.balance() == 50); +} +``` + +We first define `WalletTrait` trait using a generic type `T` which defines a method that returns the value of the field `balance` from `Wallet`. Then we give an implementation for the trait in `WalletImpl`. Note that you need to include a generic type in both definitions of the trait and the implementation. + +We can also specify constraints on generic types when defining methods on the type. We could, for example, implement methods only for `Wallet` instances rather than `Wallet`. In the code example, we define an implementation for wallets which have a concrete type of `u128` for the `balance` field. + +```rust +#[derive(Copy, Drop)] +struct Wallet { + balance: T +} + +/// Generic trait for wallets +trait WalletTrait { + fn balance(self: @Wallet) -> T; +} + +impl WalletImpl> of WalletTrait { + fn balance(self: @Wallet) -> T { + return *self.balance; + } +} + +/// Trait for wallets of type u128 +trait WalletReceiveTrait { + fn receive(ref self: Wallet, value: u128); +} + +impl WalletReceiveImpl of WalletReceiveTrait { + fn receive(ref self: Wallet, value: u128) { + self.balance += value; + } +} + +fn main() { + let mut w = Wallet { balance: 50 }; + assert!(w.balance() == 50); + + w.receive(100); + assert!(w.balance() == 150); +} +``` + +The new method `receive` increments the size of `balance` of any instance of a `Wallet`. Notice that we changed the `main` function making `w` a mutable variable in order for it to be able to update its balance. If we were to change the initialization of `w` by changing the type of `balance` the previous code wouldn't compile. + +Cairo allows us to define generic methods inside generic traits as well. Using the past implementation from `Wallet` we are going to define a trait that picks two wallets of different generic types and creates a new one with a generic type of each. First, let's rewrite the struct definition: + +```rust,noplayground +struct Wallet { + balance: T, + address: U, +} +``` + +Next, we are going to naively define the mixup trait and implementation: + +```rust,noplayground +// This does not compile! +trait WalletMixTrait { + fn mixup(self: Wallet, other: Wallet) -> Wallet; +} + +impl WalletMixImpl of WalletMixTrait { + fn mixup(self: Wallet, other: Wallet) -> Wallet { + Wallet { balance: self.balance, address: other.address } + } +} + +``` + +We are creating a trait `WalletMixTrait` with the `mixup` method which given an instance of `Wallet` and `Wallet` creates a new `Wallet`. As `mixup` signature specifies, both `self` and `other` are getting dropped at the end of the function, which is why this code does not compile. If you have been following from the start until now you would know that we must add a requirement for all the generic types specifying that they will implement the `Drop` trait for the compiler to know how to drop instances of `Wallet`. The updated implementation is as follows: + +```rust +trait WalletMixTrait { + fn mixup, U2, +Drop>( + self: Wallet, other: Wallet + ) -> Wallet; +} + +impl WalletMixImpl, U1, +Drop> of WalletMixTrait { + fn mixup, U2, +Drop>( + self: Wallet, other: Wallet + ) -> Wallet { + Wallet { balance: self.balance, address: other.address } + } +} +``` + +We add the requirements for `T1` and `U1` to be droppable on `WalletMixImpl` declaration. Then we do the same for `T2` and `U2`, this time as part of `mixup` signature. We can now try the `mixup` function: + +```rust,noplayground +fn main() { + let w1: Wallet = Wallet { balance: true, address: 10 }; + let w2: Wallet = Wallet { balance: 32, address: 100 }; + + let w3 = w1.mixup(w2); + + assert!(w3.balance); + assert!(w3.address == 100); +} +``` + +We first create two instances: one of `Wallet` and the other of `Wallet`. Then, we call `mixup` and create a new `Wallet` instance. +# Traits in Cairo + +A trait defines a set of methods that can be implemented by a type. These methods can be called on instances of the type when this trait is implemented. +A trait combined with a generic type defines functionality a particular type has and can share with other types. We can use traits to define shared behavior in an abstract way. +We can use _trait bounds_ to specify that a generic type can be any type that has certain behavior. + +> Note: Traits are similar to a feature often called interfaces in other languages, although with some differences. + +While traits can be written to not accept generic types, they are most useful when used with generic types. We already covered generics in the [previous chapter][generics], and we will use them in this chapter to demonstrate how traits can be used to define shared behavior for generic types. + +[generics]: ./ch08-01-generic-data-types.md + +## Defining a Trait + +A type’s behavior consists of the methods we can call on that type. Different types share the same behavior if we can call the same methods on all of those types. Trait definitions are a way to group method signatures together to define a set of behaviors necessary to accomplish some purpose. + +For example, let’s say we have a struct `NewsArticle` that holds a news story in a particular location. We can define a trait `Summary` that describes the behavior of something that can summarize the `NewsArticle` type. + +```rust,noplayground +# #[derive(Drop, Clone)] +# struct NewsArticle { +# headline: ByteArray, +# location: ByteArray, +# author: ByteArray, +# content: ByteArray, +# } +# +pub trait Summary { + fn summarize(self: @NewsArticle) -> ByteArray; +} +# +# impl NewsArticleSummary of Summary { +# fn summarize(self: @NewsArticle) -> ByteArray { +# format!("{:?} by {:?} ({:?})", self.headline, self.author, self.location) +# } +# } +# +# +``` + +Here, we declare a trait using the `trait` keyword and then the trait’s name, which is `Summary` in this case. +We’ve also declared the trait as `pub` so that crates depending on this crate can make use of this trait too, as we’ll see in a few examples. + +Inside the curly brackets, we declare the method signatures that describe the behaviors of the types that implement this trait, which in this case is `fn summarize(self: @NewsArticle) -> ByteArray;`. After the method signature, instead of providing an implementation within curly brackets, we use a semicolon. + +> Note: the `ByteArray` type is the type used to represent strings in Cairo. + +As the trait is not generic, the `self` parameter is not generic either and is of type `@NewsArticle`. This means that the `summarize` method can only be called on instances of `NewsArticle`. + +Now, consider that we want to make a media aggregator library crate named _aggregator_ that can display summaries of data that might be stored in a `NewsArticle` or `Tweet` instance. To do this, we need a summary from each type, and we’ll request that summary by calling a summarize method on an instance of that type. By defining the `Summary` trait on generic type `T`, we can implement the `summarize` method on any type we want to be able to summarize. + +```rust,noplayground +# mod aggregator { + pub trait Summary { + fn summarize(self: @T) -> ByteArray; + } +# +# #[derive(Drop)] +# pub struct NewsArticle { +# pub headline: ByteArray, +# pub location: ByteArray, +# pub author: ByteArray, +# pub content: ByteArray, +# } +# +# impl NewsArticleSummary of Summary { +# fn summarize(self: @NewsArticle) -> ByteArray { +# format!("{} by {} ({})", self.headline, self.author, self.location) +# } +# } +# +# #[derive(Drop)] +# pub struct Tweet { +# pub username: ByteArray, +# pub content: ByteArray, +# pub reply: bool, +# pub retweet: bool, +# } +# +# impl TweetSummary of Summary { +# fn summarize(self: @Tweet) -> ByteArray { +# format!("{}: {}", self.username, self.content) +# } +# } +# } +# +# use aggregator::{Summary, NewsArticle, Tweet}; +# +# fn main() { +# let news = NewsArticle { +# headline: "Cairo has become the most popular language for developers", +# location: "Worldwide", +# author: "Cairo Digger", +# content: "Cairo is a new programming language for zero-knowledge proofs", +# }; +# +# let tweet = Tweet { +# username: "EliBenSasson", +# content: "Crypto is full of short-term maximizing projects. \n @Starknet and @StarkWareLtd are about long-term vision maximization.", +# reply: false, +# retweet: false +# }; // Tweet instantiation +# +# println!("New article available! {}", news.summarize()); +# println!("New tweet! {}", tweet.summarize()); +# } +# +# +``` + +A `Summary` trait that consists of the behavior provided by a `summarize` method + +Each type implementing this trait must provide its own custom behavior for the body of the method. The compiler will enforce that any type that implements the `Summary` trait will have the method `summarize` defined with this signature exactly. + +A trait can have multiple methods in its body: the method signatures are listed one per line and each line ends in a semicolon. + +## Implementing a Trait on a Type + +Now that we’ve defined the desired signatures of the `Summary` trait’s methods, +we can implement it on the types in our media aggregator. The following code shows +an implementation of the `Summary` trait on the `NewsArticle` struct that uses +the headline, the author, and the location to create the return value of +`summarize`. For the `Tweet` struct, we define `summarize` as the username +followed by the entire text of the tweet, assuming that tweet content is +already limited to 280 characters. + + + +```rust,noplayground +# mod aggregator { +# pub trait Summary { +# fn summarize(self: @T) -> ByteArray; +# } +# + #[derive(Drop)] + pub struct NewsArticle { + pub headline: ByteArray, + pub location: ByteArray, + pub author: ByteArray, + pub content: ByteArray, + } + + impl NewsArticleSummary of Summary { + fn summarize(self: @NewsArticle) -> ByteArray { + format!("{} by {} ({})", self.headline, self.author, self.location) + } + } + + #[derive(Drop)] + pub struct Tweet { + pub username: ByteArray, + pub content: ByteArray, + pub reply: bool, + pub retweet: bool, + } + + impl TweetSummary of Summary { + fn summarize(self: @Tweet) -> ByteArray { + format!("{}: {}", self.username, self.content) + } + } +# } +# +# use aggregator::{Summary, NewsArticle, Tweet}; +# +# fn main() { +# let news = NewsArticle { +# headline: "Cairo has become the most popular language for developers", +# location: "Worldwide", +# author: "Cairo Digger", +# content: "Cairo is a new programming language for zero-knowledge proofs", +# }; +# +# let tweet = Tweet { +# username: "EliBenSasson", +# content: "Crypto is full of short-term maximizing projects. \n @Starknet and @StarkWareLtd are about long-term vision maximization.", +# reply: false, +# retweet: false +# }; // Tweet instantiation +# +# println!("New article available! {}", news.summarize()); +# println!("New tweet! {}", tweet.summarize()); +# } +# +# +``` + +Implementing a trait on a type is similar to implementing regular methods. The +difference is that after `impl`, we put a name for the implementation, +then use the `of` keyword, and then specify the name of the trait we are writing the implementation for. +If the implementation is for a generic type, we place the generic type name in the angle brackets after the trait name. + +Note that for the trait method to be accessible, there must be an implementation of that trait visible from the scope where the method is called. If the trait is `pub` and the implementation is not, and the implementation is not visible in the scope where the trait method is called, this will cause a compilation error. + +Within the `impl` block, we put the method signatures +that the trait definition has defined. Instead of adding a semicolon after each +signature, we use curly brackets and fill in the method body with the specific +behavior that we want the methods of the trait to have for the particular type. + +Now that the library has implemented the `Summary` trait on `NewsArticle` and +`Tweet`, users of the crate can call the trait methods on instances of +`NewsArticle` and `Tweet` in the same way we call regular methods. The only +difference is that the user must bring the trait into scope as well as the +types. Here’s an example of how a crate could use our `aggregator` crate: + +```rust +# mod aggregator { +# pub trait Summary { +# fn summarize(self: @T) -> ByteArray; +# } +# +# #[derive(Drop)] +# pub struct NewsArticle { +# pub headline: ByteArray, +# pub location: ByteArray, +# pub author: ByteArray, +# pub content: ByteArray, +# } +# +# impl NewsArticleSummary of Summary { +# fn summarize(self: @NewsArticle) -> ByteArray { +# format!("{} by {} ({})", self.headline, self.author, self.location) +# } +# } +# +# #[derive(Drop)] +# pub struct Tweet { +# pub username: ByteArray, +# pub content: ByteArray, +# pub reply: bool, +# pub retweet: bool, +# } +# +# impl TweetSummary of Summary { +# fn summarize(self: @Tweet) -> ByteArray { +# format!("{}: {}", self.username, self.content) +# } +# } +# } +# +use aggregator::{Summary, NewsArticle, Tweet}; + +fn main() { + let news = NewsArticle { + headline: "Cairo has become the most popular language for developers", + location: "Worldwide", + author: "Cairo Digger", + content: "Cairo is a new programming language for zero-knowledge proofs", + }; + + let tweet = Tweet { + username: "EliBenSasson", + content: "Crypto is full of short-term maximizing projects. \n @Starknet and @StarkWareLtd are about long-term vision maximization.", + reply: false, + retweet: false + }; // Tweet instantiation + + println!("New article available! {}", news.summarize()); + println!("New tweet! {}", tweet.summarize()); +} +# +# +``` + +This code prints the following: + +```shell +$ scarb cairo-run + Compiling no_listing_15_traits v0.1.0 (listings/ch08-generic-types-and-traits/no_listing_15_traits/Scarb.toml) + Finished release target(s) in 1 second + Running no_listing_15_traits +New article available! Cairo has become the most popular language for developers by Cairo Digger (Worldwide) +New tweet! EliBenSasson: Crypto is full of short-term maximizing projects. + @Starknet and @StarkWareLtd are about long-term vision maximization. +Run completed successfully, returning [] + +``` + +Other crates that depend on the _aggregator_ crate can also bring the `Summary` trait into scope to implement `Summary` on their own types. + + + + + + +## Managing and Using External Trait + +To use traits methods, you need to make sure the correct traits/implementation(s) are imported. In some cases you might need to import not only the trait but also the implementation if they are declared in separate modules. +If `CircleGeometry` implementation was in a separate module/file named _circle_, then to define `boundary` method on `Circle` struct, we'd need to import `ShapeGeometry` trait in the _circle_ module. + +If the code was organized into modules like this, where the implementation of a trait was defined in a different module than the trait itself, explicitly importing the relevant trait or implementation is required. + +```rust,noplayground +// Here T is an alias type which will be provided during implementation +pub trait ShapeGeometry { + fn boundary(self: T) -> u64; + fn area(self: T) -> u64; +} + +mod rectangle { + // Importing ShapeGeometry is required to implement this trait for Rectangle + use super::ShapeGeometry; + + #[derive(Copy, Drop)] + pub struct Rectangle { + pub height: u64, + pub width: u64, + } + + // Implementation RectangleGeometry passes in + // to implement the trait for that type + impl RectangleGeometry of ShapeGeometry { + fn boundary(self: Rectangle) -> u64 { + 2 * (self.height + self.width) + } + fn area(self: Rectangle) -> u64 { + self.height * self.width + } + } +} + +mod circle { + // Importing ShapeGeometry is required to implement this trait for Circle + use super::ShapeGeometry; + + #[derive(Copy, Drop)] + pub struct Circle { + pub radius: u64 + } + + // Implementation CircleGeometry passes in + // to implement the imported trait for that type + impl CircleGeometry of ShapeGeometry { + fn boundary(self: Circle) -> u64 { + (2 * 314 * self.radius) / 100 + } + fn area(self: Circle) -> u64 { + (314 * self.radius * self.radius) / 100 + } + } +} + +use rectangle::Rectangle; +use circle::Circle; + +fn main() { + let rect = Rectangle { height: 5, width: 7 }; + println!("Rectangle area: {}", ShapeGeometry::area(rect)); //35 + println!("Rectangle boundary: {}", ShapeGeometry::boundary(rect)); //24 + + let circ = Circle { radius: 5 }; + println!("Circle area: {}", ShapeGeometry::area(circ)); //78 + println!("Circle boundary: {}", ShapeGeometry::boundary(circ)); //31 +} +``` + +Note that in this example, `CircleGeometry` and `RectangleGeometry` implementations don't need to be declared as `pub`. Indeed, `ShapeGeometry` trait, which is public, is used to print the result in the `main` function. The compiler will find the appropriate implementation for the `ShapeGeometry` public trait, regardless of the implementation visibility. + +## Impl Aliases + +Implementations can be aliased when imported. This is most useful when you want to instantiate generic implementations with concrete types. For example, let's say we define a trait `Two` that is used to return the value `2` for a type `T`. We can write a trivial generic implementation of `Two` for all types that implement the `One` trait, simply by adding twice the value of `one` and returning it. However, in our public API, we may only want to expose the `Two` implementation for the `u8` and `u128` types. + +```rust,noplayground +trait Two { + fn two() -> T; +} + +mod one_based { + pub impl TwoImpl< + T, +Copy, +Drop, +Add, impl One: core::num::traits::One + > of super::Two { + fn two() -> T { + One::one() + One::one() + } + } +} + +pub impl U8Two = one_based::TwoImpl; +pub impl U128Two = one_based::TwoImpl; +``` + + Listing 8-1: Using impl aliases to instantiate generic impls with concrete types + +We can define the generic implementation in a private module, use an impl alias to instantiate the generic implementation for these two concrete types, and make these two implementations public, while keeping the generic implementation private and unexposed. This way, we can avoid code duplication using the generic implementation, while keeping the public API clean and simple. + +## Negative Impls + +> Note: This is still an experimental feature and can only be used if `experimental-features = ["negative_impls"]` is enabled in your _Scarb.toml_ file, under the `[package]` section. + +Negative implementations, also known as negative traits or negative bounds, are a mechanism that allows you to express that a type does not implement a certain trait when defining the implementation of a trait over a generic type. Negative impls enable you to write implementations that are applicable only when another implementation does not exist in the current scope. + +For example, let's say we have a trait `Producer` and a trait `Consumer`, and we want to define a generic behavior where all types implement the `Consumer` trait by default. However, we want to ensure that no type can be both a `Consumer` and a `Producer`. We can use negative impls to express this restriction. + +In Listing 8-2, we define a `ProducerType` that implements the `Producer` trait, and two other types, `AnotherType` and `AThirdType`, which do not implement the `Producer` trait. We then use negative impls to create a default implementation of the `Consumer` trait for all types that do not implement the `Producer` trait. + +```rust +#[derive(Drop)] +struct ProducerType {} + +#[derive(Drop, Debug)] +struct AnotherType {} + +#[derive(Drop, Debug)] +struct AThirdType {} + +trait Producer { + fn produce(self: T) -> u32; +} + +trait Consumer { + fn consume(self: T, input: u32); +} + +impl ProducerImpl of Producer { + fn produce(self: ProducerType) -> u32 { + 42 + } +} + +impl TConsumerImpl, +Drop, -Producer> of Consumer { + fn consume(self: T, input: u32) { + println!("{:?} consumed value: {}", self, input); + } +} + +fn main() { + let producer = ProducerType {}; + let another_type = AnotherType {}; + let third_type = AThirdType {}; + let production = producer.produce(); + + // producer.consumer(production); Invalid: ProducerType does not implement Consumer + another_type.consume(production); + third_type.consume(production); +} +``` + + Listing 8-2: Using negative impls to enforce that a type cannot implement both `Producer` and `Consumer` traits simultaneously + +In the `main` function, we create instances of `ProducerType`, `AnotherType`, and `AThirdType`. We then call the `produce` method on the `producer` instance and pass the result to the `consume` method on the `another_type` and `third_type` instances. Finally, we try to call the `consume` method on the `producer` instance, which results in a compile-time error because `ProducerType` does not implement the `Consumer` trait. + +{{#quiz ../quizzes/ch08-02-traits.toml}} +# Error handling + +In this chapter, we will explore various error handling techniques provided by Cairo, which not only allow you to address potential issues in your code, but also make it easier to create programs that are adaptable and maintainable. By examining different approaches to managing errors, such as pattern matching with the `Result` enum, using the `?` operator for more ergonomic error propagation, and employing the `unwrap` or `expect` methods for handling recoverable errors, you'll gain a deeper understanding of Cairo's error handling features. These concepts are crucial for building robust applications that can effectively handle unexpected situations, ensuring your code is ready for production. +# Unrecoverable Errors with `panic` + +In Cairo, unexpected issues may arise during program execution, resulting in runtime errors. While the `panic` function from the core library doesn't provide a resolution for these errors, it does acknowledge their occurrence and terminates the program. There are two primary ways that a panic can be triggered in Cairo: inadvertently, through actions causing the code to panic (e.g., accessing an array beyond its bounds), or deliberately, by invoking the `panic` function. + +When a panic occurs, it leads to an abrupt termination of the program. The `panic` function takes an array as an argument, which can be used to provide an error message and performs an unwind process where all variables are dropped and dictionaries squashed to ensure the soundness of the program to safely terminate the execution. + +Here is how we can call `panic` from inside a program and return the error code `2`: + +Filename: src/lib.cairo + +```rust +fn main() { + let mut data = array![2]; + + if true { + panic(data); + } + println!("This line isn't reached"); +} +``` + +Running the program will produce the following output: + +```shell +$ scarb cairo-run + Compiling no_listing_01_panic v0.1.0 (listings/ch09-error-handling/no_listing_01_panic/Scarb.toml) + Finished release target(s) in 1 second + Running no_listing_01_panic +Run panicked with [2, ]. + +``` + +As you can notice in the output, the call to `println!` macro is never reached, as the program terminates after encountering the `panic` statement. + +An alternative and more idiomatic approach to panic in Cairo would be to use the `panic_with_felt252` function. This function serves as an abstraction of the array-defining process and is often preferred due to its clearer and more concise expression of intent. By using `panic_with_felt252`, developers can panic in a one-liner by providing a `felt252` error message as an argument, making the code more readable and maintainable. + +Let's consider an example: + +```rust +use core::panic_with_felt252; + +fn main() { + panic_with_felt252(2); +} +``` + +Executing this program will yield the same error message as before. In that case, if there is no need for an array and multiple values to be returned within the error, `panic_with_felt252` is a more succinct alternative. + +## `panic!` Macro + +`panic!` macro can be really helpful. The previous example returning the error code `2` shows how convenient `panic!` macro is. There is no need to create an array and pass it as an argument like with the `panic` function. + +```rust +fn main() { + if true { + panic!("2"); + } + println!("This line isn't reached"); +} +``` + +Unlike the `panic_with_felt252` function, using `panic!` allows the input, which is ultimately the panic error, to be a literal longer than 31 bytes. This is because `panic!` takes a string as a parameter. For example, the following line of code will successfully compile: + +```rust, noplayground +panic!("the error for panic! macro is not limited to 31 characters anymore"); +``` + +## `nopanic` Notation + +You can use the `nopanic` notation to indicate that a function will never panic. Only `nopanic` functions can be called in a function annotated as `nopanic`. + +Here is an example: + +```rust,noplayground +fn function_never_panic() -> felt252 nopanic { + 42 +} +``` + +This function will always return `42` and is guaranteed to never panic. Conversely, the following function is not guaranteed to never panic: + +```rust,noplayground +fn function_never_panic() nopanic { + assert(1 == 1, 'what'); +} +``` + +If you try to compile this function that includes code that may panic, you will get the following error: + +```shell +$ scarb cairo-run + Compiling no_listing_04_nopanic_wrong v0.1.0 (listings/ch09-error-handling/no_listing_05_nopanic_wrong/Scarb.toml) +error: Function is declared as nopanic but calls a function that may panic. + --> listings/ch09-error-handling/no_listing_05_nopanic_wrong/src/lib.cairo:4:12 + assert(1 == 1, 'what'); + ^****^ + +error: Function is declared as nopanic but calls a function that may panic. + --> listings/ch09-error-handling/no_listing_05_nopanic_wrong/src/lib.cairo:4:5 + assert(1 == 1, 'what'); + ^********************^ + +error: could not compile `no_listing_04_nopanic_wrong` due to previous error +error: `scarb metadata` exited with error + +``` + +Note that there are two functions that may panic here, `assert` and equality with `==`. We usually don't use `assert` function in practice and use `assert!` macro instead. We will discuss `assert!` macro in more detail in the [Testing Cairo Programs][assert macro] chapter. + +[assert macro]: ./ch10-01-how-to-write-tests.md#checking-results-with-the-assert-macro + +## `panic_with` Attribute + +You can use the `panic_with` attribute to mark a function that returns an `Option` or `Result`. This attribute takes two arguments, which are the data that is passed as the panic reason as well as the name for a wrapping function. It will create a wrapper for your annotated function which will panic if the function returns `None` or `Err`, with the given data as the panic error. + +Example: + +```rust +#[panic_with('value is 0', wrap_not_zero)] +fn wrap_if_not_zero(value: u128) -> Option { + if value == 0 { + Option::None + } else { + Option::Some(value) + } +} + +fn main() { + wrap_if_not_zero(0); // this returns None + wrap_not_zero(0); // this panics with 'value is 0' +} +``` + +{{#quiz ../quizzes/ch09-01-unrecoverable-errors-with-panic.toml}} +# Recoverable Errors with `Result` + +Most errors aren’t serious enough to require the program to stop entirely. Sometimes, when a function fails, it’s for a reason that you can easily interpret and respond to. For example, if you try to add two large integers and the operation overflows because the sum exceeds the maximum representable value, you might want to return an error or a wrapped result instead of causing undefined behavior or terminating the process. + +## The `Result` Enum + +Recall from [Generic data types][generic enums] section in Chapter 8 that the `Result` enum is defined as having two variants, `Ok` and `Err`, as follows: + +```rust,noplayground +enum Result { + Ok: T, + Err: E, +} +``` + +The `Result` enum has two generic types, `T` and `E`, and two variants: `Ok` which holds the value of type `T` and `Err` which holds the value of type `E`. This definition makes it convenient to use the `Result` enum anywhere we have an operation that might succeed (by returning a value of type `T`) or fail (by returning a value of type `E`). + +[generic enums]: ./ch08-01-generic-data-types.md#enums + +## The `ResultTrait` + +The `ResultTrait` trait provides methods for working with the `Result` enum, such as unwrapping values, checking whether the `Result` is `Ok` or `Err`, and panicking with a custom message. The `ResultTraitImpl` implementation defines the logic of these methods. + +```rust,noplayground +trait ResultTrait { + fn expect<+Drop>(self: Result, err: felt252) -> T; + + fn unwrap<+Drop>(self: Result) -> T; + + fn expect_err<+Drop>(self: Result, err: felt252) -> E; + + fn unwrap_err<+Drop>(self: Result) -> E; + + fn is_ok(self: @Result) -> bool; + + fn is_err(self: @Result) -> bool; +} +``` + +The `expect` and `unwrap` methods are similar in that they both attempt to extract the value of type `T` from a `Result` when it is in the `Ok` variant. If the `Result` is `Ok(x)`, both methods return the value `x`. However, the key difference between the two methods lies in their behavior when the `Result` is in the `Err` variant. The `expect` method allows you to provide a custom error message (as a `felt252` value) that will be used when panicking, giving you more control and context over the panic. On the other hand, the `unwrap` method panics with a default error message, providing less information about the cause of the panic. + +The `expect_err` and `unwrap_err` methods have the exact opposite behavior. If the `Result` is `Err(x)`, both methods return the value `x`. However, the key difference between the two methods is in case of `Result::Ok()`. The `expect_err` method allows you to provide a custom error message (as a `felt252` value) that will be used when panicking, giving you more control and context over the panic. On the other hand, the `unwrap_err` method panics with a default error message, providing less information about the cause of the panic. + +A careful reader may have noticed the `<+Drop>` and `<+Drop>` in the first four methods signatures. This syntax represents generic type constraints in the Cairo language, as seen in the previous chapter. These constraints indicate that the associated functions require an implementation of the `Drop` trait for the generic types `T` and `E`, respectively. + +Finally, the `is_ok` and `is_err` methods are utility functions provided by the `ResultTrait` trait to check the variant of a `Result` enum value. + +- `is_ok` takes a snapshot of a `Result` value and returns `true` if the `Result` is the `Ok` variant, meaning the operation was successful. If the `Result` is the `Err` variant, it returns `false`. +- `is_err` takes a snapshot of a `Result` value and returns `true` if the `Result` is the `Err` variant, meaning the operation encountered an error. If the `Result` is the `Ok` variant, it returns `false`. + +These methods are helpful when you want to check the success or failure of an operation without consuming the `Result` value, allowing you to perform additional operations or make decisions based on the variant without unwrapping it. + +You can find the implementation of the `ResultTrait` [here][result corelib]. + +It is always easier to understand with examples. Have a look at this function signature: + +```rust,noplayground +fn u128_overflowing_add(a: u128, b: u128) -> Result; +``` + +It takes two `u128` integers, `a` and `b`, and returns a `Result` where the `Ok` variant holds the sum if the addition does not overflow, and the `Err` variant holds the overflowed value if the addition does overflow. + +Now, we can use this function elsewhere. For instance: + +```rust,noplayground +fn u128_checked_add(a: u128, b: u128) -> Option { + match u128_overflowing_add(a, b) { + Result::Ok(r) => Option::Some(r), + Result::Err(r) => Option::None, + } +} + +``` + +Here, it accepts two `u128` integers, `a` and `b`, and returns an `Option`. It uses the `Result` returned by `u128_overflowing_add` to determine the success or failure of the addition operation. The `match` expression checks the `Result` from `u128_overflowing_add`. If the result is `Ok(r)`, it returns `Option::Some(r)` containing the sum. If the result is `Err(r)`, it returns `Option::None` to indicate that the operation has failed due to overflow. The function does not panic in case of an overflow. + +Let's take another example: + +```rust,noplayground +fn parse_u8(s: felt252) -> Result { + match s.try_into() { + Option::Some(value) => Result::Ok(value), + Option::None => Result::Err('Invalid integer'), + } +} +``` + +In this example, the `parse_u8` function takes a `felt252` and tries to convert it into a `u8` integer using the `try_into` method. If successful, it returns `Result::Ok(value)`, otherwise it returns `Result::Err('Invalid integer')`. + +Our two test cases are: + +```rust,noplayground +# fn parse_u8(s: felt252) -> Result { +# match s.try_into() { +# Option::Some(value) => Result::Ok(value), +# Option::None => Result::Err('Invalid integer'), +# } +# } +# +#[cfg(test)] +mod tests { + use super::parse_u8; + + #[test] + fn test_felt252_to_u8() { + let number: felt252 = 5; + // should not panic + let res = parse_u8(number).unwrap(); + } + + #[test] + #[should_panic] + fn test_felt252_to_u8_panic() { + let number: felt252 = 256; + // should panic + let res = parse_u8(number).unwrap(); + } +} +# +# +``` + +Don't worry about the `#[cfg(test)]` attribute for now. We'll explain in more detail its meaning in the next [Testing Cairo Programs][tests] chapter. + +`#[test]` attribute means the function is a test function, and `#[should_panic]` attribute means this test will pass if the test execution panics. + +The first one tests a valid conversion from `felt252` to `u8`, expecting the `unwrap` method not to panic. The second test function attempts to convert a value that is out of the `u8` range, expecting the `unwrap` method to panic with the error message `Invalid integer`. + +[result corelib]: https://github.com/starkware-libs/cairo/blob/main/corelib/src/result.cairo#L20 +[tests]: ./ch10-01-how-to-write-tests.md + +### The `?` Operator + +The last operator we will talk about is the `?` operator. The `?` operator is used for more idiomatic and concise error handling. When you use the `?` operator on a `Result` or `Option` type, it will do the following: + +- If the value is `Result::Ok(x)` or `Option::Some(x)`, it will return the inner value `x` directly. +- If the value is `Result::Err(e)` or `Option::None`, it will propagate the error or `None` by immediately returning from the function. + +The `?` operator is useful when you want to handle errors implicitly and let the calling function deal with them. + +Here is an example: + +```rust,noplayground +fn do_something_with_parse_u8(input: felt252) -> Result { + let input_to_u8: u8 = parse_u8(input)?; + // DO SOMETHING + let res = input_to_u8 - 1; + Result::Ok(res) +} +``` + +We can see that `do_something_with_parse_u8` function takes a `felt252` value as input and calls `parse_u8` function. The `?` operator is used to propagate the error, if any, or unwrap the successful value. + +And with a little test case: + +```rust,noplayground +# fn parse_u8(s: felt252) -> Result { +# match s.try_into() { +# Option::Some(value) => Result::Ok(value), +# Option::None => Result::Err('Invalid integer'), +# } +# } +# +# fn do_something_with_parse_u8(input: felt252) -> Result { +# let input_to_u8: u8 = parse_u8(input)?; +# // DO SOMETHING +# let res = input_to_u8 - 1; +# Result::Ok(res) +# } +# +# #[cfg(test)] +# mod tests { +# use super::do_something_with_parse_u8; + #[test] + fn test_function_2() { + let number: felt252 = 258; + match do_something_with_parse_u8(number) { + Result::Ok(value) => println!("Result: {}", value), + Result::Err(e) => println!("Error: {}", e), + } + } +# } +# +``` + +The console will print the error `Invalid Integer`. + +### Summary + +We saw that recoverable errors can be handled in Cairo using the `Result` enum, which has two variants: `Ok` and `Err`. The `Result` enum is generic, with types `T` and `E` representing the successful and error values, respectively. The `ResultTrait` provides methods for working with `Result`, such as unwrapping values, checking if the result is `Ok` or `Err`, and panicking with custom messages. + +To handle recoverable errors, a function can return a `Result` type and use pattern matching to handle the success or failure of an operation. The `?` operator can be used to implicitly handle errors by propagating the error or unwrapping the successful value. This allows for more concise and clear error handling, where the caller is responsible for managing errors raised by the called function. + +{{#quiz ../quizzes/ch09-02-error-handling-result.toml}} +# Testing Cairo Programs + +Correctness in our programs is the extent to which our code does what we intend it to do. Cairo is designed with a high degree of concern about the correctness of programs, but correctness is complex and not easy to prove. Cairo's linear type system shoulders a huge part of this burden, but the type system cannot catch everything. As such, Cairo includes support for writing tests. + +Testing is a complex skill: although we can’t cover every detail about how to write good tests in one chapter, we’ll discuss the mechanics of Cairo's testing facilities. We’ll talk about the annotations and macros available to you when writing your tests, the default behavior and options provided for running your tests, and how to organize tests into unit tests and integration tests. +# How To Write Tests + +## The Anatomy of a Test Function + +Tests are Cairo functions that verify that the non-test code is functioning in the expected manner. The bodies of test functions typically perform these three actions: + +- Set up any needed data or state. +- Run the code you want to test. +- Assert the results are what you expect. + +Let’s look at the features Cairo provides for writing tests that take these actions, which include: + +- `#[test]` attribute. +- `assert!`, `assert_eq!`, `assert_ne!`, `assert_lt!`, `assert_le!`, `assert_gt!` and `assert_ge!` macros. +- `#[should_panic]` attribute. + +### The Anatomy of a Test Function + +At its simplest, a test in Cairo is a function that’s annotated with the `#[test]` attribute. Attributes are metadata about pieces of Cairo code; one example is the `#[derive()]` attribute we used with structs in [Chapter 5](ch05-01-defining-and-instantiating-structs.md). To change a function into a test function, add `#[test]` on the line before `fn`. When you run your tests with the `scarb cairo-test` command, Scarb runs Cairo's test runner binary that runs the annotated functions and reports on whether each test function passes or fails. + +Let's create a new project called _adder_ using Scarb with the command `scarb new adder`: + +```shell +adder +├── Scarb.toml +└── src + └── lib.cairo +``` + +In _lib.cairo_, let's remove the existing content and add a `tests` module containing the first test, as shown in Listing 10-1. + +Filename: src/lib.cairo + +```rust +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + let result = 2 + 2; + assert!(result == 4, "result is not 4"); + } +} +``` + +Listing 10-1: A simple test function + +Note the `#[test]` annotation: this attribute indicates this is a test function, so the test runner knows to treat this function as a test. We might also have non-test functions to help set up common scenarios or perform common operations, so we always need to indicate which functions are tests. + +We use the `#[cfg(test)]` attribute for the `tests` module, so that the compiler knows the code it contains needs to be compiled only when running tests. This is actually not an option: if you put a simple test with the `#[test]` attribute in a _lib.cairo_ file, it will not compile. We will talk more about the `#[cfg(test)]` attribute in the next [Testing Organization](ch10-02-test-organization.md) section. + +The example function body uses the `assert!` macro, which contains the result of adding 2 and 2, which equals 4. This assertion serves as an example of the format for a typical test. We'll explain in more detail how `assert!` works later in this chapter. Let’s run it to see that this test passes. + +The `scarb cairo-test` command runs all tests found in our project, and shows the following output: + +```shell +$ scarb cairo-test +testing adder ... +running 1 test +test adder::tests::it_works ... ok (gas usage est.: 22540) +test result: ok. 1 passed; 0 failed; 0 ignored; 0 filtered out; +``` + +`scarb cairo-test` compiled and ran the test. We see the line `running 1 test`. The next line shows the name of the test function, called `it_works`, and that the result of running that test is `ok`. The test runner also provides an estimation of the gas consumption. The overall summary `test result: ok.` means that all the tests passed, and the portion that reads `1 passed; 0 failed` totals the number of tests that passed or failed. + +It’s possible to mark a test as ignored so it doesn’t run in a particular instance; we’ll cover that in the [Ignoring Some Tests Unless Specifically Requested](#ignoring-some-tests-unless-specifically-requested) section later in this chapter. Because we haven’t done that here, the summary shows `0 ignored`. We can also pass an argument to the `scarb cairo-test` command to run only a test whose name matches a string; this is called filtering and we’ll cover that in the [Running Single Tests](#running-single-tests) section. Since we haven’t filtered the tests being run, the end of the summary shows `0 filtered out`. + +Let’s start to customize the test to our own needs. First change the name of the `it_works` function to a different name, such as `exploration`, like so: + +```rust, noplayground +#[test] +fn exploration() { + let result = 2 + 2; + assert!(result == 4, "result is not 4"); +} +``` + +Then run `scarb cairo-test` again. The output now shows `exploration` instead of `it_works`: + +```shell +$ scarb cairo-test +testing adder ... +running 1 test +test adder::tests::exploration ... ok (gas usage est.: 22540) +test result: ok. 1 passed; 0 failed; 0 ignored; 0 filtered out; +``` + +Now we’ll add another test, but this time we’ll make a test that fails! Tests fail when something in the test function panics. Each test is run in a new thread, and when the main thread sees that a test thread has died, the test is marked as failed. Enter the new test as a function named `another`, so your _src/lib.cairo_ file looks like in Listing 10-2. + +Filename: src/lib.cairo + +```rust +#[cfg(test)] +mod tests { + #[test] + fn exploration() { + let result = 2 + 2; + assert!(result == 4, "result is not 4"); + } + + #[test] + fn another() { + let result = 2 + 2; + assert!(result == 6, "Make this test fail"); + } +} + +``` + +Listing 10-2: Adding a second test in _lib.cairo_ that will fail + +Run `scarb cairo-test` and you will see the following output: + +```shell +$ scarb cairo-test + Running cairo-test listing_08_03 + Compiling test(listings/ch10-testing-cairo-programs/listing_10_02/Scarb.toml) + Finished release target(s) in 1 second +testing listing_08_03 ... +running 2 tests +test listing_08_03::tests::exploration ... ok (gas usage est.: 22540) +test listing_08_03::tests::another ... fail (gas usage est.: 24810) +failures: + listing_08_03::tests::another - Panicked with "Make this test fail". + + +``` + +Instead of `ok`, the line `adder::another` shows `fail`. A new section appears between the individual results and the summary. It displays the detailed reason for each test failure. In this case, we get the details that `another` failed because it panicked with `"Make this test fail"` error. + +The summary line is displayed at the end: overall, our test result is `FAILED`. We had one test pass and one test fail. + +Now that you’ve seen what the test results look like in different scenarios, let’s look at some functions that are useful in tests. + +## Checking Results with the `assert!` Macro + +The `assert!` macro, provided by Cairo, is useful when you want to ensure that some condition in a test evaluates to `true`. We give the `assert!` macro the first argument that evaluates to a boolean. If the value is `true`, nothing happens and the test passes. If the value is `false`, the `assert!` macro calls `panic()` to cause the test to fail with a message we defined as the second argument. Using the `assert!` macro helps us check that our code is functioning in the way we intended. + +Remember in [Chapter 5][method syntax], we used a `Rectangle` struct and a `can_hold` method, which are repeated here in Listing 10-3. Let’s put this code in the _src/lib.cairo_ file, then write some tests for it using the `assert!` macro. + +Filename: src/lib.cairo + +```rust +#[derive(Drop)] +struct Rectangle { + width: u64, + height: u64, +} + +trait RectangleTrait { + fn can_hold(self: @Rectangle, other: @Rectangle) -> bool; +} + +impl RectangleImpl of RectangleTrait { + fn can_hold(self: @Rectangle, other: @Rectangle) -> bool { + *self.width > *other.width && *self.height > *other.height + } +} +``` + +Listing 10-3: Using the `Rectangle` struct and its `can_hold` method from Chapter 5 + +The `can_hold` method returns a `bool`, which means it’s a perfect use case for the `assert!` macro. We can write a test that exercises the `can_hold` method by creating a `Rectangle` instance that has a width of `8` and a height of `7` and asserting that it can hold another `Rectangle` instance that has a width of `5` and a height of `1`. + +```rust +# #[derive(Drop)] +# struct Rectangle { +# width: u64, +# height: u64, +# } +# +# trait RectangleTrait { +# fn can_hold(self: @Rectangle, other: @Rectangle) -> bool; +# } +# +# impl RectangleImpl of RectangleTrait { +# fn can_hold(self: @Rectangle, other: @Rectangle) -> bool { +# *self.width > *other.width && *self.height > *other.height +# } +# } +# +#[cfg(test)] +mod tests { + use super::Rectangle; + use super::RectangleTrait; + + #[test] + fn larger_can_hold_smaller() { + let larger = Rectangle { height: 7, width: 8, }; + let smaller = Rectangle { height: 1, width: 5, }; + + assert!(larger.can_hold(@smaller), "rectangle cannot hold"); + } +} +# #[cfg(test)] +# mod tests2 { +# use super::Rectangle; +# use super::RectangleTrait; +# +# #[test] +# fn smaller_cannot_hold_larger() { +# let larger = Rectangle { height: 7, width: 8, }; +# let smaller = Rectangle { height: 1, width: 5, }; +# +# assert!(!smaller.can_hold(@larger), "rectangle cannot hold"); +# } +# } +# +``` + +We’ve named our test `larger_can_hold_smaller`, and we’ve created the two `Rectangle` instances that we need. Then we called the `assert!` macro and passed it the result of calling `larger.can_hold(@smaller)`. This expression is supposed to return `true`, so our test should pass. Let’s find out! + +```shell +$ scarb cairo-test +testing adder ... +running 1 test +test adder::tests::larger_can_hold_smaller ... ok (gas usage est.: 54940) +test result: ok. 1 passed; 0 failed; 0 ignored; 0 filtered out; +``` + +It does pass! Let’s add another test, this time asserting that a smaller rectangle cannot hold a larger rectangle: + +Filename: src/lib.cairo + +```rust +# #[derive(Drop)] +# struct Rectangle { +# width: u64, +# height: u64, +# } +# +# trait RectangleTrait { +# fn can_hold(self: @Rectangle, other: @Rectangle) -> bool; +# } +# +# impl RectangleImpl of RectangleTrait { +# fn can_hold(self: @Rectangle, other: @Rectangle) -> bool { +# *self.width > *other.width && *self.height > *other.height +# } +# } +# +# #[cfg(test)] +# mod tests { +# use super::Rectangle; +# use super::RectangleTrait; +# +# #[test] +# fn larger_can_hold_smaller() { +# let larger = Rectangle { height: 7, width: 8, }; +# let smaller = Rectangle { height: 1, width: 5, }; +# +# assert!(larger.can_hold(@smaller), "rectangle cannot hold"); +# } +# } +# #[cfg(test)] +# mod tests2 { +# use super::Rectangle; +# use super::RectangleTrait; +# + #[test] + fn smaller_cannot_hold_larger() { + let larger = Rectangle { height: 7, width: 8, }; + let smaller = Rectangle { height: 1, width: 5, }; + + assert!(!smaller.can_hold(@larger), "rectangle cannot hold"); + } +# } +# +``` + +Listing 10-4: Adding another test in _lib.cairo_ that will pass + +Because the correct result of the `can_hold` method, in this case, is `false`, we need to negate that result before we pass it to the `assert!` macro. As a result, our test will pass if `can_hold` returns `false`: + +```shell +$ scarb cairo-test + Running cairo-test listing_08_06 + Compiling test(listings/ch10-testing-cairo-programs/listing_10_03/Scarb.toml) + Finished release target(s) in 1 second +testing listing_08_06 ... +running 2 tests +test listing_08_06::tests2::smaller_cannot_hold_larger ... ok (gas usage est.: 24180) +test listing_08_06::tests::larger_can_hold_smaller ... ok (gas usage est.: 23580) +test result: ok. 2 passed; 0 failed; 0 ignored; 0 filtered out; + + +``` + +Two tests that pass! Now let’s see what happens to our test results when we introduce a bug in our code. We’ll change the implementation of the `can_hold` method by replacing the `>` sign with a `<` sign when it compares the widths: + +```rust +impl RectangleImpl of RectangleTrait { + fn can_hold(self: @Rectangle, other: @Rectangle) -> bool { + *self.width < *other.width && *self.height > *other.height + } +} +``` + +Running the tests now produces the following: + +```shell +$ scarb cairo-test +testing adder ... +running 2 tests +test adder::tests::larger_can_hold_smaller ... fail (gas usage est.: 57610) +test adder::tests::smaller_cannot_hold_larger ... ok (gas usage est.: 55140) +failures: + adder::larger_can_hold_smaller - Panicked with "rectangle cannot hold". + +Error: test result: FAILED. 1 passed; 1 failed; 0 ignored +``` + +Our tests caught the bug! Because `larger.width` is `8` and `smaller.width` is `5`, the comparison of the widths in `can_hold` now returns `false` (`8` is not less than `5`) in the `larger_can_hold_smaller` test. Notice that the `smaller_cannot_hold_larger` test still passes: to make this test fail, the height comparison should also be modified in `can_hold` method, replacing the `>` sign with a `<` sign. + +[method syntax]: ./ch05-03-method-syntax.md + +## Testing Equality and Comparisons with the `assert_xx!` Macros + +### `assert_eq!` and `assert_ne!` Macros + +A common way to verify functionality is to test for equality between the result +of the code under test and the value you expect the code to return. You could +do this using the `assert!` macro and passing it an expression using the `==` +operator. However, this is such a common test that the standard library +provides a pair of macros — `assert_eq!` and `assert_ne!` — to perform this test +more conveniently. These macros compare two arguments for equality or +inequality, respectively. They’ll also print the two values if the assertion +fails, which makes it easier to see _why_ the test failed; conversely, the +`assert!` macro only indicates that it got a `false` value for the `==` +expression, without printing the values that led to the `false` value. + +In Listing 10-5, we write a function named `add_two` that adds `2` to its +parameter, then we test this function using `assert_eq!` and `assert_ne!` macros. + +Filename: src/lib.cairo + +```rust, noplayground +fn add_two(a: u32) -> u32 { + a + 2 +} + +#[cfg(test)] +mod tests { + use super::add_two; + + #[test] + fn it_adds_two() { + assert_eq!(4, add_two(2)); + } + + #[test] + fn wrong_check() { + assert_ne!(0, add_two(2)); + } +} +``` + +Listing 10-5: Testing the function `add_two` using `assert_eq!` and `assert_ne!` macros + +Let’s check that it passes! + +```shell +$ scarb cairo-test +testing adder ... +running 2 tests +test adder::tests::wrong_check ... ok (gas usage est.: 132000) +test adder::tests::it_adds_two ... ok (gas usage est.: 131500) +test result: ok. 2 passed; 0 failed; 0 ignored; 0 filtered out; +``` + +In the `it_adds_two` test, we pass `4` as argument to `assert_eq!` macro, which is equal to the result of +calling `add_two(2)`. The line for this test is `test adder::tests::it_adds_two ... ok`, and the `ok` text indicates that our test passed. + +In the `wrong_check` test, we pass `0` as argument to `assert_ne!` macro, which is not equal to the result of +calling `add_two(2)`. Tests that use the `assert_ne!` macro will pass if the two values we give it are _not_ equal and +fail if they’re equal. This macro is most useful for cases when we’re not sure +what a value _will_ be, but we know what the value definitely _shouldn’t_ be. +For example, if we’re testing a function that is guaranteed to change its input +in some way, but how the input is changed depends on the day of +the week that we run our tests, the best thing to assert might be that the +output of the function is not equal to the input. + +Let’s introduce a bug into our code to see what `assert_eq!` looks like when it +fails. Change the implementation of the `add_two` function to instead add `3`: + +```rust, noplayground +fn add_two(a: u32) -> u32 { + a + 3 +} +``` + +Run the tests again: + +```shell +$ scarb cairo-test +testing adder ... +running 2 tests +test adder::tests::wrong_check ... ok (gas usage est.: 132000) +test adder::tests::it_adds_two ... fail (gas usage est.: 166800) +failures: + adder::tests::it_adds_two - Panicked with "assertion `4 == add_two(2)` failed. +4: 4 +add_two(2): 5". + +Error: test result: FAILED. 1 passed; 1 failed; 0 ignored +``` + +Our test caught the bug! The `it_adds_two` test failed with the following +message: `` Panicked with "assertion `4 == add_two(2)` failed ``. +It tells us that the assertion that failed was `` "assertion `left == right` failed`` and the `left` +and `right` values are printed on the next lines as `left: left_value` and `right: right_value`. +This helps us start debugging: the `left` argument was `4` but the `right` argument, where we had +`add_two(2)`, was `5`. You can imagine that this would be especially helpful +when we have a lot of tests going on. + +Note that in some languages and test frameworks, the parameters for equality +assertion functions are called `expected` and `actual`, and the order in which +we specify the arguments matters. However, in Cairo, they’re called `left` and +`right`, and the order in which we specify the value we expect and the value +the code produces doesn’t matter. We could write the assertion in this test as +`assert_eq!(add_two(2), 4)`, which would result in the same failure message +that displays `` assertion failed: `(left == right)` ``. + +Here is a simple example comparing two structs, showing how to use `assert_eq!` and `assert_ne!` macros: + +```rust, noplayground +#[derive(Drop, Debug, PartialEq)] +struct MyStruct { + var1: u8, + var2: u8 +} + +#[cfg(test)] +#[test] +fn test_struct_equality() { + let first = MyStruct { var1: 1, var2: 2 }; + let second = MyStruct { var1: 1, var2: 2 }; + let third = MyStruct { var1: 1, var2: 3 }; + + assert_eq!(first, second); + assert_eq!(first, second, "{:?},{:?} should be equal", first, second); + assert_ne!(first, third); + assert_ne!(first, third, "{:?},{:?} should not be equal", first, third); +} +``` + +Under the surface, `assert_eq!` and `assert_ne!` macros use the operators +`==` and `!=`, respectively. They both take snapshots of values as arguments. When the assertions fail, these macros print their +arguments using debug formatting (`{:?}` syntax), which means the values being compared must +implement `PartialEq` and `Debug` traits. All primitive types and most of +the core library types implement these traits. For structs and enums that +you define yourself, you’ll need to implement `PartialEq` to assert equality of +those types. You’ll also need to implement `Debug` to print the values when the +assertion fails. Because both traits are derivable, this is usually as straightforward as adding the +`#[derive(Drop, Debug, PartialEq)]` annotation to your struct or enum definition. See +[Appendix C](./appendix-03-derivable-traits.md) for more details about these and other derivable traits. + +### `assert_lt!`, `assert_le!`, `assert_gt!` and `assert_ge!` Macros + +Comparisons in tests can be done using the `assert_xx!` macros: + +- `assert_lt!` checks if a given value is lower than another value, and reverts otherwise. +- `assert_le!` checks if a given value is lower or equal than another value, and reverts otherwise. +- `assert_gt!` checks if a given value is greater than another value, and reverts otherwise. +- `assert_ge!` checks if a given value is greater or equal than another value, and reverts otherwise. + +Listing 10-6 demonstrates how to use these macros: + +```rust, noplayground +#[derive(Drop, Copy, Debug, PartialEq)] +struct Dice { + number: u8, +} + +impl DicePartialOrd of PartialOrd { + fn lt(lhs: Dice, rhs: Dice) -> bool { + lhs.number < rhs.number + } + + fn le(lhs: Dice, rhs: Dice) -> bool { + lhs.number <= rhs.number + } + + fn gt(lhs: Dice, rhs: Dice) -> bool { + lhs.number > rhs.number + } + + fn ge(lhs: Dice, rhs: Dice) -> bool { + lhs.number >= rhs.number + } +} + +#[cfg(test)] +#[test] +fn test_struct_equality() { + let first_throw = Dice { number: 5 }; + let second_throw = Dice { number: 2 }; + let third_throw = Dice { number: 6 }; + let fourth_throw = Dice { number: 5 }; + + assert_gt!(first_throw, second_throw); + assert_ge!(first_throw, fourth_throw); + assert_lt!(second_throw, third_throw); + assert_le!( + first_throw, fourth_throw, "{:?},{:?} should be lower or equal", first_throw, fourth_throw + ); +} +``` + +Listing 10-6: Example of tests that use the `assert_xx!` macros for comparisons + +In this example, we roll a `Dice` struct multiple times and compare the results. We need to manually implement the `PartialOrd` trait for our struct so that we can compare `Dice` instances with `lt`, `le`, `gt` and `ge` functions, which are used by `assert_lt!`, `assert_le!`, `assert_gt!` and `assert_ge!` macros, respectively. We also need to derive the `Copy` trait on our `Dice` struct to use the instantiated structs multiple times, as the comparison functions take ownership of the variables. + +## Adding Custom Failure Messages + +You can also add a custom message to be printed with the failure message as +optional arguments to `assert!`, `assert_eq!`, and `assert_ne!` macros. Any +arguments specified after the required arguments are passed along to the +`format!` macro (discussed in the [Printing][formatting] chapter), so you can pass a format string that contains `{}` placeholders and +values to go in those placeholders. Custom messages are useful for documenting +what an assertion means; when a test fails, you’ll have a better idea of what +the problem is with the code. + +Let’s add a custom failure message composed of a format +string with a placeholder filled in with the actual value we got from the +`add_two` function: + +```rust, noplayground + #[test] + fn it_adds_two() { + assert_eq!(4, add_two(2), "Expected {}, got add_two(2)={}", 4, add_two(2)); + } +``` + +Now when we run the test, we’ll get a more informative error message: + +```shell +$ scarb cairo-test +testing adder ... +running 1 test +test adder::tests::it_adds_two ... fail (gas usage est.: 590230) +failures: + adder::tests::it_adds_two - Panicked with "assertion `4 == add_two(2)` failed: Expected 4, got add_two(2)=5 +4: 4 +add_two(2): 5". + +Error: test result: FAILED. 0 passed; 1 failed; 0 ignored +``` + +We can see the value we actually got in the test output, which would help us +debug what happened instead of what we were expecting to happen. + +[formatting]: ./ch11-08-printing.md#formatting + +## Checking for panics with `should_panic` + +In addition to checking return values, it’s important to check that our code handles error conditions as we expect. For example, consider the `Guess` type in Listing 10-7: + +Filename: src/lib.cairo + +```rust, noplayground +#[derive(Drop)] +struct Guess { + value: u64, +} + +pub trait GuessTrait { + fn new(value: u64) -> Guess; +} + +impl GuessImpl of GuessTrait { + fn new(value: u64) -> Guess { + if value < 1 || value > 100 { + panic!("Guess must be >= 1 and <= 100"); + } + + Guess { value, } + } +} +``` + +Listing 10-7: `Guess` struct and its `new` method + +Other code that uses `Guess` depends on the guarantee that `Guess` instances will contain only values between `1` and `100`. We can write a test that ensures that attempting to create a `Guess` instance with a value outside that range panics. + +We do this by adding the attribute `should_panic` to our test function. The test passes if the code inside the function panics; the test fails if the code inside the function doesn’t panic. + +```rust, noplayground +#[cfg(test)] +mod tests { + use super::GuessTrait; + + #[test] + #[should_panic] + fn greater_than_100() { + GuessTrait::new(200); + } +} +``` + +We place the `#[should_panic]` attribute after the `#[test]` attribute and before the test function it applies to. Let’s look at the result to see that this test passes: + +```shell +$ scarb cairo-test +testing guess ... +running 1 test +test guess::tests::greater_than_100 ... ok (gas usage est.: 26850) +test result: ok. 1 passed; 0 failed; 0 ignored; 0 filtered out; +``` + +Looks good! Now let’s introduce a bug in our code by removing the condition that the `new` function will panic if the value is greater than `100`: + +```rust, noplayground +# #[derive(Drop)] +# struct Guess { +# value: u64, +# } +# +# trait GuessTrait { +# fn new(value: u64) -> Guess; +# } +# +impl GuessImpl of GuessTrait { + fn new(value: u64) -> Guess { + if value < 1 { + panic!("Guess must be >= 1 and <= 100"); + } + + Guess { value, } + } +} +# +# +``` + +When we run the test, it will fail: + +```shell +$ scarb cairo-test +testing guess ... +running 1 test +test guess::tests::greater_than_100 ... fail (gas usage est.: 23910) +failures: + guess::tests::greater_than_100 - expected panic but finished successfully. + +Error: test result: FAILED. 0 passed; 1 failed; 0 ignored +``` + +We don’t get a very helpful message in this case, but when we look at the test function, we see that it’s annotated with `#[should_panic]` attribute. The failure we got means that the code in the test function did not cause a panic. + +Tests that use `should_panic` can be imprecise. A `should_panic` test would pass even if the test panics for a different reason from the one we were expecting. To make `should_panic` tests more precise, we can add an optional `expected` parameter to the `#[should_panic]` attribute. The test harness will make sure that the failure message contains the provided text. For example, consider the modified code for `GuessImpl` in Listing 10-8 where the `new` function panics with different messages depending on whether the value is too small or too large: + +Filename: src/lib.cairo + +```rust, noplayground +# #[derive(Drop)] +# struct Guess { +# value: u64, +# } +# +# trait GuessTrait { +# fn new(value: u64) -> Guess; +# } +# +impl GuessImpl of GuessTrait { + fn new(value: u64) -> Guess { + if value < 1 { + panic!("Guess must be >= 1"); + } else if value > 100 { + panic!("Guess must be <= 100"); + } + + Guess { value, } + } +} + +#[cfg(test)] +mod tests { + use super::GuessTrait; + + #[test] + #[should_panic(expected: ("Guess must be <= 100",))] + fn greater_than_100() { + GuessTrait::new(200); + } +} +# +# +``` + +Listing 10-8: `new` implementation that panics with different error messages + +The test will pass because the value we put in the `should_panic` attribute’s `expected` parameter is the string that the `Guess::new` method panics with. We need to specify the entire panic message that we expect. + +To see what happens when a `should_panic` test with an expected message fails, let’s again introduce a bug into our code by swapping the bodies of the `if value < 1` and the `else if value > 100` blocks: + +```rust, noplayground +impl GuessImpl of GuessTrait { + fn new(value: u64) -> Guess { + if value < 1 { + panic!("Guess must be <= 100"); + } else if value > 100 { + panic!("Guess must be >= 1"); + } + + Guess { value, } + } +} + +#[cfg(test)] +mod tests { + use super::GuessTrait; + + #[test] + #[should_panic(expected: ("Guess must be <= 100",))] + fn greater_than_100() { + GuessTrait::new(200); + } +} +``` + +This time when we run the `should_panic` test, it will fail: + +```shell +$ scarb cairo-test +testing guess ... +running 1 test +test guess::tests::greater_than_100 ... fail (gas usage est.: 26690) +failures: + guess::tests::greater_than_100 - Panicked with "Guess must be >= 1". +Error: test result: FAILED. 0 passed; 1 failed; 0 ignored +``` + +The failure message indicates that this test did indeed panic as we expected, but the panic message did not include the expected string. The panic message that we did get in this case was `Guess must be >= 1`. Now we can start figuring out where our bug is! + +## Running Single Tests + +Sometimes, running a full test suite can take a long time. If you’re working on code in a particular area, you might want to run only the tests pertaining to that code. You can choose which tests to run by passing `scarb cairo-test` an option `-f` (for "filter"), followed by the name of the test you want to run as an argument. + +To demonstrate how to run a single test, we’ll first create two test functions, as shown in Listing 10-9, and choose which ones to run. + +Filename: src/lib.cairo + +```rust, noplayground +#[cfg(test)] +mod tests { + #[test] + fn add_two_and_two() { + let result = 2 + 2; + assert!(result == 4, "result is not 4"); + } + + #[test] + fn add_three_and_two() { + let result = 3 + 2; + assert!(result == 5, "result is not 5"); + } +} +``` + +Listing 10-9: Two tests with two different names + +We can pass the name of any test function to `cairo-test` to run only that test using the `-f` flag: + +```shell +$ scarb cairo-test -f add_two_and_two +testing adder ... +running 1 test +test adder::tests::add_two_and_two ... ok (gas usage est.: 22540) +test result: ok. 1 passed; 0 failed; 0 ignored; 1 filtered out; +``` + +Only the test with the name `add_two_and_two` ran; the other test didn’t match that name. The test output lets us know we had one more test that didn’t run by displaying `1 filtered out;` at the end. + +We can also specify part of a test name, and any test whose name contains that value will be run. + +## Ignoring Some Tests Unless Specifically Requested + +Sometimes a few specific tests can be very time-consuming to execute, so you might want to exclude them during most runs of `scarb cairo-test`. Rather than listing as arguments all tests you do want to run, you can instead annotate the time-consuming tests using the `#[ignore]` attribute to exclude them, as shown here: + +```rust, noplayground +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + let result = 2 + 2; + assert!(result == 4, "result is not 4"); + } + + #[test] + #[ignore] + fn expensive_test() { // code that takes an hour to run + } +} +``` + +After `#[test]` we add the `#[ignore]` line to the test we want to exclude. Now when we run our tests, `it_works` runs, but `expensive_test` doesn’t: + +```shell +$ scarb cairo-test +testing adder ... +running 2 tests +test adder::tests::expensive_test ... ignored +test adder::tests::it_works ... ok (gas usage est.: 22540) +test result: ok. 1 passed; 0 failed; 1 ignored; 0 filtered out; +``` + +The `expensive_test` function is listed as ignored. + +When you’re at a point where it makes sense to check the results of the ignored tests and you have time to wait for the results, you can run `scarb cairo-test --include-ignored` to run all tests, whether they’re ignored or not. + +## Testing Recursive Functions or Loops + +When testing recursive functions or loops, the test is instantiated by default with a maximum amount of gas that it can consume. This prevents running infinite loops or consuming too much gas, and can help you benchmark the efficiency of your implementations. This value is assumed reasonably large enough, but you can override it by adding the `#[available_gas()]` attribute to the test function. The following example shows how to use it: + +```rust, noplayground +fn sum_n(n: usize) -> usize { + let mut i = 0; + let mut sum = 0; + while i <= n { + sum += i; + i += 1; + }; + sum +} + +#[cfg(test)] +mod tests { + use super::sum_n; + + #[test] + #[available_gas(2000000)] + fn test_sum_n() { + let result = sum_n(10); + assert!(result == 55, "result is not 55"); + } +} +``` + +## Benchmarking the Gas Usage of a Specific Operation + +When you want to benchmark the gas usage of a specific operation, you can use the following pattern in your test function. + +```rust, noplayground +let initial = testing::get_available_gas(); +gas::withdraw_gas().unwrap(); + /// code we want to bench. +println!("{}\n", initial - testing::get_available_gas()); +``` + +The following example shows how to use it to test the gas function of the `sum_n` function above. + +```rust +fn sum_n(n: usize) -> usize { + let mut i = 0; + let mut sum = 0; + while i <= n { + sum += i; + i += 1; + }; + sum +} + +#[cfg(test)] +mod tests { + use super::sum_n; + use core::testing; + use core::gas; + + #[test] + fn benchmark_sum_n_gas() { + let initial = testing::get_available_gas(); + gas::withdraw_gas().unwrap(); + /// code we want to bench. + let _result = sum_n(10); + println!("consumed gas: {}\n", initial - testing::get_available_gas()); + } +} +``` + +The value printed when running `scarb cairo-test` is the amount of gas that was consumed by the benchmarked operation. + +```shell +$ scarb cairo-test +testing adder ... +running 1 test +consumed gas: 80690 + +test adder::tests::benchmark_sum_n_gas ... ok (gas usage est.: 140100) +test result: ok. 1 passed; 0 failed; 0 ignored; 0 filtered out; +``` + +Here, the gas usage of the `sum_n` function is `80690` (decimal representation of the hex number). The total amount consumed by the test is slightly higher at `140100`, due to some extra steps required to run the entire test function. + +{{#quiz ../quizzes/ch10-01-how_to_write_tests.toml}} +# Testing Organization + +We'll think about tests in terms of two main categories: unit tests and integration tests. Unit tests are small and more focused, testing one module in isolation at a time, and can test private functions. Integration tests use your code in the same way any other external code would, using only the public interface and potentially exercising multiple modules per test. + +Writing both kinds of tests is important to ensure that the pieces of your library are doing what you expect them to, separately and together. + +## Unit Tests + +The purpose of unit tests is to test each unit of code in isolation from the rest of the code to quickly pinpoint where code is and isn’t working as expected. You’ll put unit tests in the `src` directory in each file with the code that they’re testing. + +The convention is to create a module named `tests` in each file to contain the test functions and to annotate the module with `#[cfg(test)]` attribute. + +### The Tests Module and `#[cfg(test)]` + +The `#[cfg(test)]` annotation on the tests module tells Cairo to compile and run the test code only when you run `scarb cairo-test`, not when you run `scarb cairo-run`. This saves compile time when you only want to build the library and saves space in the resulting compiled artifact because the tests are not included. You’ll see that because integration tests go in a different directory, they don’t need the `#[cfg(test)]` annotation. However, because unit tests go in the same files as the code, you’ll use `#[cfg(test)]` to specify that they shouldn’t be included in the compiled result. + +Recall that when we created the new _adder_ project in the first section of this chapter, we wrote this first test: + +```rust +#[cfg(test)] +mod tests { + #[test] + fn it_works() { + let result = 2 + 2; + assert!(result == 4, "result is not 4"); + } +} +``` + +The attribute `cfg` stands for configuration and tells Cairo that the following item should only be included given a certain configuration option. In this case, the configuration option is `test`, which is provided by Cairo for compiling and running tests. By using the `cfg` attribute, Cairo compiles our test code only if we actively run the tests with `scarb cairo-test`. This includes any helper functions that might be within this module, in addition to the functions annotated with `#[test]`. + +## Integration Tests + +Integration tests use your library in the same way any other code would. Their purpose is to test whether many parts of your library work together correctly. Units of code that work correctly on their own could have problems when integrated, so test coverage of the integrated code is important as well. To create integration tests, you first need a `tests` directory. + +### The _tests_ Directory + +```shell +adder +├── Scarb.toml +├── src +│   ├── lib.cairo +│   ├── tests +│   │   └── integration_tests.cairo +│   └── tests.cairo +``` + +First of all, add the following code in your _lib.cairo_ file: + +Filename: src/lib.cairo + +```rust, noplayground +fn it_adds_two(a: u8, b: u8) -> u8 { + a + b +} + +#[cfg(test)] +mod tests; +``` + +Note that we still need to use the `#[cfg(test)]` attribute here, because we are in the _lib.cairo_ file of the _src_ directory. +Then, create a _tests.cairo_ file and fill it as follows: + +Filename: src/tests.cairo + +```rust, noplayground +mod integration_tests; +``` + +Finally, enter this code into the _src/tests/integration_tests.cairo_ file: + +Filename: src/tests/integration_tests.cairo + +```rust, noplayground +use adder::it_adds_two; + +#[test] +fn internal() { + assert!(it_adds_two(2, 2) == 4, "internal_adder failed"); +} +``` + +We need to bring our tested functions into each test file scope. For that reason we add `use adder::it_adds_two` at the top of the code, which we didn’t need in the unit tests. + +Then, to run all of our integration tests, we can just add a filter to only run tests whose path contains "integration_tests". + +```shell +$ scarb test -f integration_tests + Running cairo-test adder + Compiling test(listings/ch10-testing-cairo-programs/no_listing_09_integration_test/Scarb.toml) + Finished release target(s) in 1 second +testing adder ... +running 1 test +test adder::tests::integration_tests::internal ... ok (gas usage est.: 23110) +test result: ok. 1 passed; 0 failed; 0 ignored; 0 filtered out; + + +``` + +The result of the tests is the same as what we've been seeing: one line for each test. + +{{#quiz ../quizzes/ch10-02-testing-organization.toml}} +# Advanced Features + +Now, let's learn about more advanced features offered by Cairo. +# Custom Data Structures + +When you first start programming in Cairo, you'll likely want to use arrays +(`Array`) to store collections of data. However, you will quickly realize +that arrays have one big limitation - the data stored in them is immutable. Once +you append a value to an array, you can't modify it. + +This can be frustrating when you want to use a mutable data structure. For +example, say you're making a game where the players have a level, and they can +level up. You might try to store the level of the players in an array: + +```rust,noplayground + let mut level_players = array![5, 1, 10]; +``` + +But then you realize you can't increase the level at a specific index once it's +set. If a player dies, you cannot remove it from the array unless he happens to +be in the first position. + +Fortunately, Cairo provides a handy built-in [dictionary type](./ch03-02-dictionaries.md) called `Felt252Dict` that allows us to +simulate the behavior of mutable data structures. Let's first explore how to create a struct that contains, among others, a `Felt252Dict`. + +> Note: Several concepts used in this chapter were already presented earlier in the book. We recommend checking out the following chapters if you need to revise them: +> [Structs](ch05-00-using-structs-to-structure-related-data.md), +> [Methods](./ch05-03-method-syntax.md), +> [Generic types](./ch08-00-generic-types-and-traits.md), +> [Traits](./ch08-02-traits-in-cairo.md). + +## Dictionaries as Struct Members + +Defining dictionaries as struct members is possible in Cairo but correctly interacting with them may not be entirely seamless. Let's try implementing a custom _user database_ that will allow us to add users and query them. We will need to define a struct to represent the new type and a trait to define its functionality: + +```rust,noplayground +struct UserDatabase { + users_updates: u64, + balances: Felt252Dict, +} + +trait UserDatabaseTrait { + fn new() -> UserDatabase; + fn update_user<+Drop>(ref self: UserDatabase, name: felt252, balance: T); + fn get_balance<+Copy>(ref self: UserDatabase, name: felt252) -> T; +} +``` + +Our new type `UserDatabase` represents a database of users. It is generic over the balances of the users, giving major flexibility to whoever uses our data type. Its two members are: + +- `users_updates`, the number of users updates in the dictionary. +- `balances`, a mapping of each user to its balance. + +The database core functionality is defined by `UserDatabaseTrait`. The following methods are defined: + +- `new` for easily creating new `UserDatabase` types. +- `update_user` to update the balance of users in the database. +- `get_balance` to find user's balance in the database. + +The only remaining step is to implement each of the methods in `UserDatabaseTrait`, but since we are working with [Generic types](./ch08-00-generic-types-and-traits.md) we also need to correctly establish the requirements of `T` so it can be a valid `Felt252Dict` value type: + +1. `T` should implement the `Copy` since it's required for getting values from a `Felt252Dict`. +2. All value types of a dictionary implement the `Felt252DictValue`, our generic type should do as well. +3. To insert values, `Felt252DictTrait` requires all value types to be droppable (implement the `Drop` trait). + +The implementation, with all restrictions in place, would be as follows: + +```rust,noplayground +impl UserDatabaseImpl> of UserDatabaseTrait { + // Creates a database + fn new() -> UserDatabase { + UserDatabase { users_updates: 0, balances: Default::default() } + } + + // Get the user's balance + fn get_balance<+Copy>(ref self: UserDatabase, name: felt252) -> T { + self.balances.get(name) + } + + // Add a user + fn update_user<+Drop>(ref self: UserDatabase, name: felt252, balance: T) { + self.balances.insert(name, balance); + self.users_updates += 1; + } +} +``` + +Our database implementation is almost complete, except for one thing: the compiler doesn't know how to make a `UserDatabase` go out of scope, since it doesn't implement the `Drop` trait, nor the `Destruct` trait. +Since it has a `Felt252Dict` as a member, it cannot be dropped, so we are forced to implement the `Destruct` trait manually (refer to the [Ownership](ch04-01-what-is-ownership.md#the-drop-trait) chapter for more information). +Using `#[derive(Destruct)]` on top of the `UserDatabase` definition won't work because of the use of [Generic types][generics] in the struct definition. We need to code the `Destruct` trait implementation by ourselves: + +```rust,noplayground +impl UserDatabaseDestruct, +Felt252DictValue> of Destruct> { + fn destruct(self: UserDatabase) nopanic { + self.balances.squash(); + } +} +``` + +Implementing `Destruct` for `UserDatabase` was our last step to get a fully functional database. We can now try it out: + +```rust +# struct UserDatabase { +# users_updates: u64, +# balances: Felt252Dict, +# } +# +# trait UserDatabaseTrait { +# fn new() -> UserDatabase; +# fn update_user<+Drop>(ref self: UserDatabase, name: felt252, balance: T); +# fn get_balance<+Copy>(ref self: UserDatabase, name: felt252) -> T; +# } +# +# impl UserDatabaseImpl> of UserDatabaseTrait { +# // Creates a database +# fn new() -> UserDatabase { +# UserDatabase { users_updates: 0, balances: Default::default() } +# } +# +# // Get the user's balance +# fn get_balance<+Copy>(ref self: UserDatabase, name: felt252) -> T { +# self.balances.get(name) +# } +# +# // Add a user +# fn update_user<+Drop>(ref self: UserDatabase, name: felt252, balance: T) { +# self.balances.insert(name, balance); +# self.users_updates += 1; +# } +# } +# +# impl UserDatabaseDestruct, +Felt252DictValue> of Destruct> { +# fn destruct(self: UserDatabase) nopanic { +# self.balances.squash(); +# } +# } +# +fn main() { + let mut db = UserDatabaseTrait::::new(); + + db.update_user('Alex', 100); + db.update_user('Maria', 80); + + db.update_user('Alex', 40); + db.update_user('Maria', 0); + + let alex_latest_balance = db.get_balance('Alex'); + let maria_latest_balance = db.get_balance('Maria'); + + assert!(alex_latest_balance == 40, "Expected 40"); + assert!(maria_latest_balance == 0, "Expected 0"); +} +# +# +``` + +[generics]: ./ch08-00-generic-types-and-traits.md + +## Simulating a Dynamic Array with Dicts + +First, let's think about how we want our mutable dynamic array to behave. What +operations should it support? + +It should: + +- Allow us to append items at the end. +- Let us access any item by index. +- Allow setting the value of an item at a specific index. +- Return the current length. + +We can define this interface in Cairo like: + +```rust,noplayground +trait VecTrait { + fn new() -> V; + fn get(ref self: V, index: usize) -> Option; + fn at(ref self: V, index: usize) -> T; + fn push(ref self: V, value: T) -> (); + fn set(ref self: V, index: usize, value: T); + fn len(self: @V) -> usize; +} +``` + +This provides a blueprint for the implementation of our dynamic array. We named +it _Vec_ as it is similar to the `Vec` data structure in Rust. + +### Implementing a Dynamic Array in Cairo + +To store our data, we'll use a `Felt252Dict` which maps index numbers (felts) +to values. We'll also store a separate `len` field to track the length. + +Here is what our struct looks like. We wrap the type `T` inside `Nullable` +pointer to allow using any type `T` in our data structure, as explained in the +[Dictionaries][nullable] section: + +```rust,noplayground +struct NullableVec { + data: Felt252Dict>, + len: usize +} +``` + +Since we again have `Felt252Dict` as a struct member, we need to implement the `Destruct` trait to tell the compiler how to make `NullableVec` go out of scope. + +```rust,noplayground +impl DestructNullableVec> of Destruct> { + fn destruct(self: NullableVec) nopanic { + self.data.squash(); + } +} +``` + +The key thing that makes this vector mutable is that we can insert values into +the dictionary to set or update values in our data structure. For example, to +update a value at a specific index, we do: + +```rust,noplayground + fn set(ref self: NullableVec, index: usize, value: T) { + assert!(index < self.len(), "Index out of bounds"); + self.data.insert(index.into(), NullableTrait::new(value)); + } +``` + +This overwrites the previously existing value at that index in the dictionary. + +While arrays are immutable, dictionaries provide the flexibility we need for +modifiable data structures like vectors. + +The implementation of the rest of the interface is straightforward. The +implementation of all the methods defined in our interface can be done as follow +: + +```rust,noplayground +impl NullableVecImpl, +Copy> of VecTrait, T> { + fn new() -> NullableVec { + NullableVec { data: Default::default(), len: 0 } + } + + fn get(ref self: NullableVec, index: usize) -> Option { + if index < self.len() { + Option::Some(self.data.get(index.into()).deref()) + } else { + Option::None + } + } + + fn at(ref self: NullableVec, index: usize) -> T { + assert!(index < self.len(), "Index out of bounds"); + self.data.get(index.into()).deref() + } + + fn push(ref self: NullableVec, value: T) -> () { + self.data.insert(self.len.into(), NullableTrait::new(value)); + self.len = core::integer::u32_wrapping_add(self.len, 1_usize); + } + fn set(ref self: NullableVec, index: usize, value: T) { + assert!(index < self.len(), "Index out of bounds"); + self.data.insert(index.into(), NullableTrait::new(value)); + } + fn len(self: @NullableVec) -> usize { + *self.len + } +} +``` + +The full implementation of the `Vec` structure can be found in the +community-maintained library [Alexandria](https://github.com/keep-starknet-strange/alexandria/tree/main/packages/data_structures/src). + +[nullable]: ./ch03-02-dictionaries.md#dictionaries-of-types-not-supported-natively + +## Simulating a Stack with Dicts + +We will now look at a second example and its implementation details: a Stack. + +A Stack is a LIFO (Last-In, First-Out) collection. The insertion of a new +element and removal of an existing element takes place at the same end, +represented as the top of the stack. + +Let us define what operations we need to create a stack: + +- Push an item to the top of the stack. +- Pop an item from the top of the stack. +- Check whether there are still any elements in the stack. + +From these specifications we can define the following interface : + +```rust,noplayground +trait StackTrait { + fn push(ref self: S, value: T); + fn pop(ref self: S) -> Option; + fn is_empty(self: @S) -> bool; +} +``` + +### Implementing a Mutable Stack in Cairo + +To create a stack data structure in Cairo, we can again use a `Felt252Dict` +to store the values of the stack along with a `usize` field to keep track of the +length of the stack to iterate over it. + +The Stack struct is defined as: + +```rust,noplayground +struct NullableStack { + data: Felt252Dict>, + len: usize, +} +``` + +Next, let's see how our main functions `push` and `pop` are implemented. + +```rust,noplayground +impl NullableStackImpl, +Copy> of StackTrait, T> { + fn push(ref self: NullableStack, value: T) { + self.data.insert(self.len.into(), NullableTrait::new(value)); + self.len += 1; + } + + fn pop(ref self: NullableStack) -> Option { + if self.is_empty() { + return Option::None; + } + self.len -= 1; + Option::Some(self.data.get(self.len.into()).deref()) + } + + fn is_empty(self: @NullableStack) -> bool { + *self.len == 0 + } +} +``` + +The code uses the `insert` and `get` methods to access the values in the +`Felt252Dict`. To push an element to the top of the stack, the `push` +function inserts the element in the dict at index `len` and increases the +`len` field of the stack to keep track of the position of the stack top. To +remove a value, the `pop` function decreases the value of `len` to update the +position of the stack top and then retrieves the last value at position `len`. + +The full implementation of the Stack, along with more data structures that you +can use in your code, can be found in the community-maintained +[Alexandria][alexandria data structures] library, in the "data_structures" crate. + +[alexandria data structures]: https://github.com/keep-starknet-strange/alexandria/tree/main/packages/data_structures/src + +{{#quiz ../quizzes/ch11-01-custom-structs.toml}} + +## Summary + +Well done! Now you have knowledge of arrays, dictionaries and even custom data structures. +While Cairo's memory model is immutable and can make it difficult to implement +mutable data structures, we can fortunately use the `Felt252Dict` type to +simulate mutable data structures. This allows us to implement a wide range of +data structures that are useful for many applications, effectively hiding the +complexity of the underlying memory model. +# Smart Pointers + +A pointer is a general concept for a variable that contains a memory address. This address refers to, or “points at,” some other data. While pointers are a powerful feature, they can also be a source of bugs and security vulnerabilities. For example, a pointer can reference an unassigned memory cell, which means that attempting to access the data at that address would cause the program to crash, making it unprovable. To prevent such issues, Cairo uses _Smart Pointers_. + +Smart pointers are data structures that act like a pointer, but also have additional metadata and capabilities. The concept of smart pointers isn’t unique to Cairo: smart pointers originated in C++ and exist in other languages like Rust as well. In the specific case of Cairo, smart pointers ensure that memory is not addressed in an unsafe way that could cause a program to be unprovable, by providing a safe way to access memory through strict type checking and ownership rules. + +Though we didn’t call them as such at the time, we’ve already encountered a few smart pointers in this book, including `Felt252Dict` and `Array` in Chapter 3. Both these types count as smart pointers because they own a memory segment and allow you to manipulate it. They also have metadata and extra capabilities or guarantees. Arrays keep track of their current length to ensure that existing elements are not overwritten, and that new elements are only appended to the end. + +The Cairo VM memory is composed by multiple segments that can store data, each identified by a unique index. When you create an array, you allocate a new segment in the memory to store the future elements. The array itself is just a pointer to that segment where the elements are stored. + +## The `Box` Type to Manipulate Pointers + +The principal smart pointer type in Cairo is a _box_, denoted as `Box`. Manually defining boxes allow you to store data in a specific memory segment of the Cairo VM called the _boxed segment_. This segment is dedicated to store all boxed values, and what remains in the execution segment is only a pointer to the boxed segment. Whenever you instantiate a new pointer variable of type `Box`, you append the data of type `T` to the boxed segment. + +Boxes have very little performance overhead, other than writing their inner values to the boxed segment. But they don’t have many extra capabilities either. You’ll use them most often in these situations: + +- When you have a type whose size can’t be known at compile time and you want to use a value of that type in a context that requires an exact size +- When you have a large amount of data and you want to transfer ownership but ensure the data won’t be copied when you do so + +We’ll demonstrate the first situation in the [“Enabling Recursive Types with Boxes”][nullable recursive types] section. +In the second case, transferring ownership of a large amount of data can take a long time because the data is copied around in memory. To improve performance in this situation, we can store the large amount of data in the boxed segment using a box type. Then, only the small amount of pointer data is copied around in memory, while the data it references stays in one place on the boxed segment. + +[nullable recursive types]: ./ch11-02-smart-pointers.md#enabling-recursive-types-with-nullable-boxes + +### Using a `Box` to Store Data in the Boxed Segment + +Before we discuss the boxed segment storage use cases for `Box`, we’ll cover the syntax and how to interact with values stored within a `Box`. + +Listing 11-1 shows how to use a box to store a value in the boxed segment: + +```rust +fn main() { + let b = BoxTrait::new(5_u128); + println!("b = {}", b.unbox()) +} +``` + +Listing 11-1: Storing a `u128` value in the boxed segment using a box + +We define the variable `b` to have the value of a `Box` that points to the value `5`, which is stored in the boxed segment. This program will print `b = 5`; in this case, we can access the data in the box similar to how we would if this data was simply in the execution memory. Putting a single value in a box isn’t very useful, so you won’t use boxes by themselves in this way very often. Having values like a single `u128` in the execution memory, where they’re stored by default, is more appropriate in the majority of situations. Let’s look at a case where boxes allow us to define types that we wouldn’t be allowed to if we didn’t have boxes. + +### Enabling Recursive Types with Nullable Boxes + + + +### Using Boxes to Improve Performance + +Passing pointers between functions allows you to reference data without copying the data itself. Using boxes can improve performance as it allows you to pass a pointer to some data from one function to another, without the need to copy the entire data in memory before performing the function call. Instead of having to write `n` values into memory before calling a function, only a single value is written, corresponding to the pointer to the data. If the data stored in the box is very large, the performance improvement can be significant, as you would save `n-1` memory operations before each function call. + +Let's take a look at the code in Listing 11-2, which shows two ways of passing data to a function: by value and by pointer. + +```rust +#[derive(Drop)] +struct Cart { + paid: bool, + items: u256, + buyer: ByteArray +} + +fn pass_data(cart: Cart) { + println!("{} is shopping today and bought {} items", cart.buyer, cart.items); +} + +fn pass_pointer(cart: Box) { + let cart = cart.unbox(); + println!("{} is shopping today and bought {} items", cart.buyer, cart.items); +} + +fn main() { + let new_struct = Cart { paid: true, items: 1, buyer: "Eli" }; + pass_data(new_struct); + + let new_box = BoxTrait::new(Cart { paid: false, items: 2, buyer: "Uri" }); + pass_pointer(new_box); +} +``` + +Listing 11-2: Storing large amounts of data in a box for performance. + +The `main` function includes 2 function calls: + +- `pass_data` that takes a variable of type `Cart`. +- `pass_pointer` that takes a pointer of type `Box`. + +When passing data to a function, the entire data is copied into the last available memory cells right before the function call. Calling `pass_data` will copy all 3 fields of `Cart` to memory, while `pass_pointer` only requires the copy of the `new_box` pointer which is of size 1. + +
+ box memory +
+
+ CairoVM Memory layout when using boxes +
+ +The illustration above demonstrates how the memory behaves in both cases. The first instance of `Cart` is stored in the execution segment, and we need to copy all its fields to memory before calling the `pass_data` function. The second instance of `Cart` is stored in the boxed segment, and the pointer to it is stored in the execution segment. When calling the `pass_pointer` function, only the pointer to the struct is copied to memory right before the function call. In both cases, however, instantiating the struct will store all its values in the execution segment: the boxed segment can only be filled with data taken from the execution segment. + +## The `Nullable` Type for Dictionaries + +`Nullable` is another type of smart pointer that can either point to a value or be `null` in the absence of value. It is defined at the Sierra level. This type is mainly used in dictionaries that contain types that don't implement the `zero_default` method of the `Felt252DictValue` trait (i.e., arrays and structs). + +If we try to access an element that does not exist in a dictionary, the code will fail if the `zero_default` method cannot be called. + +[Chapter 3.2][dictionary nullable span] about dictionaries thoroughly explains how to store a `Span` variable inside a dictionary using the `Nullable` type. Please refer to it for further information. + +[dictionary nullable span]: /ch03-02-dictionaries.md#dictionaries-of-types-not-supported-natively + +{{#quiz ../quizzes/ch11-02-smart_pointers.toml}} +# Operator Overloading + +Operator overloading is a feature in some programming languages that allows the redefinition of standard operators, such as addition (`+`), subtraction (`-`), multiplication (`*`), and division (`/`), to work with user-defined types. This can make the syntax of the code more intuitive, by enabling operations on user-defined types to be expressed in the same way as operations on primitive types. + +In Cairo, operator overloading is achieved through the implementation of specific traits. Each operator has an associated trait, and overloading that operator involves providing an implementation of that trait for a custom type. +However, it's essential to use operator overloading judiciously. Misuse can lead to confusion, making the code more difficult to maintain, for example when there is no semantic meaning to the operator being overloaded. + +Consider an example where two `Potions` need to be combined. `Potions` have two data fields, mana and health. Combining two `Potions` should add their respective fields. + +```rust +struct Potion { + health: felt252, + mana: felt252 +} + +impl PotionAdd of Add { + fn add(lhs: Potion, rhs: Potion) -> Potion { + Potion { health: lhs.health + rhs.health, mana: lhs.mana + rhs.mana, } + } +} + +fn main() { + let health_potion: Potion = Potion { health: 100, mana: 0 }; + let mana_potion: Potion = Potion { health: 0, mana: 100 }; + let super_potion: Potion = health_potion + mana_potion; + // Both potions were combined with the `+` operator. + assert(super_potion.health == 100, ''); + assert(super_potion.mana == 100, ''); +} +``` + +In the code above, we're implementing the `Add` trait for the `Potion` type. The add function takes two arguments: `lhs` and `rhs` (left and right-hand side). The function body returns a new `Potion` instance, its field values being a combination of `lhs` and `rhs`. + +As illustrated in the example, overloading an operator requires specification of the concrete type being overloaded. The overloaded generic trait is `Add`, and we define a concrete implementation for the type `Potion` with `Add`. + +{{#quiz ../quizzes/ch11-03-operator-overloading.toml}} +# Hashes + +At its essence, hashing is a process of converting input data (often called a message) of any length into a fixed-size value, typically referred to as a "hash." This transformation is deterministic, meaning that the same input will always produce the same hash value. Hash functions are a fundamental component in various fields, including data storage, cryptography and data integrity verification. They are very often used when developing smart contracts, especially when working with [Merkle trees][merkle tree wiki]. + +In this chapter, we will present the two hash functions implemented natively in the Cairo core library: `Poseidon` and `Pedersen`. We will discuss when and how to use them, and see examples with Cairo programs. + +[merkle tree wiki]: https://en.wikipedia.org/wiki/Merkle_tree#Uses + +### Hash Functions in Cairo + +The Cairo core library provides two hash functions: Pedersen and Poseidon. + +Pedersen hash functions are cryptographic algorithms that rely on [elliptic curve cryptography][ec wiki]. These functions perform operations on points along an elliptic curve — essentially, doing math with the locations of these points — which are easy to do in one direction and hard to undo. This one-way difficulty is based on the Elliptic Curve Discrete Logarithm Problem (ECDLP), which is a problem so hard to solve that it ensures the security of the hash function. The difficulty of reversing these operations is what makes the Pedersen hash function secure and reliable for cryptographic purposes. + +Poseidon is a family of hash functions designed to be very efficient as algebraic circuits. Its design is particularly efficient for Zero-Knowledge proof systems, including STARKs (so, Cairo). Poseidon uses a method called a 'sponge construction,' which soaks up data and transforms it securely using a process known as the Hades permutation. Cairo's version of Poseidon is based on a three-element state permutation with [specific parameters][poseidon parameters]. + +[ec wiki]: https://en.wikipedia.org/wiki/Elliptic-curve_cryptography +[poseidon parameters]: https://github.com/starkware-industries/poseidon/blob/main/poseidon3.txt + +#### When to Use Them? + +Pedersen was the first hash function used on Starknet, and is still used to compute the addresses of variables in storage (for example, `LegacyMap` uses Pedersen to hash the keys of a storage mapping on Starknet). However, as Poseidon is cheaper and faster than Pedersen when working with STARK proofs system, it's now the recommended hash function to use in Cairo programs. + +### Working with Hashes + +The core library makes it easy to work with hashes. The `Hash` trait is implemented for all types that can be converted to `felt252`, including `felt252` itself. For more complex types like structs, deriving `Hash` allows them to be hashed easily using the hash function of your choice - given that all of the struct's fields are themselves hashable. You cannot derive the `Hash` trait on a struct that contains un-hashable values, such as `Array` or `Felt252Dict`, even if `T` itself is hashable. + +The `Hash` trait is accompanied by the `HashStateTrait` and `HashStateExTrait` that define the basic methods to work with hashes. They allow you to initialize a hash state that will contain the temporary values of the hash after each application of the hash function, update the hash state and finalize it when the computation is completed. `HashStateTrait` and `HashStateExTrait` are defined as follows: + +```rust,noplayground +/// A trait for hash state accumulators. +trait HashStateTrait { + fn update(self: S, value: felt252) -> S; + fn finalize(self: S) -> felt252; +} + +/// Extension trait for hash state accumulators. +trait HashStateExTrait { + /// Updates the hash state with the given value. + fn update_with(self: S, value: T) -> S; +} + +/// A trait for values that can be hashed. +trait Hash> { + /// Updates the hash state with the given value. + fn update_state(state: S, value: T) -> S; +} +``` + +To use hashes in your code, you must first import the relevant traits and functions. In the following example, we will demonstrate how to hash a struct using both the Pedersen and Poseidon hash functions. + +The first step is to initialize the hash with either `PoseidonTrait::new() -> HashState` or `PedersenTrait::new(base: felt252) -> HashState` depending on which hash function we want to work with. Then the hash state can be updated with the `update(self: HashState, value: felt252) -> HashState` or `update_with(self: S, value: T) -> S` functions as many times as required. Then the function `finalize(self: HashState) -> felt252` is called on the hash state and it returns the value of the hash as a `felt252`. + +```rust +use core::poseidon::PoseidonTrait; +use core::hash::{HashStateTrait, HashStateExTrait}; + +#[derive(Drop, Hash)] +struct StructForHash { + first: felt252, + second: felt252, + third: (u32, u32), + last: bool, +} + +fn main() -> felt252 { + let struct_to_hash = StructForHash { first: 0, second: 1, third: (1, 2), last: false }; + + let hash = PoseidonTrait::new().update_with(struct_to_hash).finalize(); + hash +} +``` + +Pedersen is different from Poseidon, as it starts with a base state. This base state must be of `felt252` type, which forces us to either hash the struct with an arbitrary base state using the `update_with` method, or serialize the struct into an array to loop through all of its fields and hash its elements together. + +Here is a short example of Pedersen hashing: + +```rust +# use core::pedersen::PedersenTrait; +# use core::hash::{HashStateTrait, HashStateExTrait}; +# +# #[derive(Drop, Hash, Serde, Copy)] +# struct StructForHash { +# first: felt252, +# second: felt252, +# third: (u32, u32), +# last: bool, +# } +# +fn main() -> (felt252, felt252) { + let struct_to_hash = StructForHash { first: 0, second: 1, third: (1, 2), last: false }; + + // hash1 is the result of hashing a struct with a base state of 0 + let hash1 = PedersenTrait::new(0).update_with(struct_to_hash).finalize(); + + let mut serialized_struct: Array = ArrayTrait::new(); + Serde::serialize(@struct_to_hash, ref serialized_struct); + let first_element = serialized_struct.pop_front().unwrap(); + let mut state = PedersenTrait::new(first_element); + + while let Option::Some(value) = serialized_struct.pop_front() { + state = state.update(value); + }; + + // hash2 is the result of hashing only the fields of the struct + let hash2 = state.finalize(); + + (hash1, hash2) +} +# +# +``` + +### Advanced Hashing: Hashing Arrays with Poseidon + +Let us look at an example of hashing a struct that contains a `Span`. +To hash a `Span` or a struct that contains a `Span` you can use the built-in function `poseidon_hash_span(mut span: Span) -> felt252`. Similarly, you can hash `Array` by calling `poseidon_hash_span` on its span. + +First, let us import the following traits and function: + +```rust,noplayground +use core::poseidon::PoseidonTrait; +use core::poseidon::poseidon_hash_span; +use core::hash::{HashStateTrait, HashStateExTrait}; +``` + +Now we define the struct. As you might have noticed, we didn't derive the `Hash` trait. If you attempt to derive the `Hash` trait for this struct, it will result in an error because the structure contains a field that is not hashable. + +```rust, noplayground +#[derive(Drop)] +struct StructForHashArray { + first: felt252, + second: felt252, + third: Array, +} +``` + +In this example, we initialized a `HashState` (`hash`), updated it and then called the function `finalize()` on the +`HashState` to get the computed hash `hash_felt252`. We used `poseidon_hash_span` on the `Span` of the `Array` to compute its hash. + +```rust +# use core::poseidon::PoseidonTrait; +# use core::poseidon::poseidon_hash_span; +# use core::hash::{HashStateTrait, HashStateExTrait}; +# +# #[derive(Drop)] +# struct StructForHashArray { +# first: felt252, +# second: felt252, +# third: Array, +# } +# +fn main() { + let struct_to_hash = StructForHashArray { first: 0, second: 1, third: array![1, 2, 3, 4, 5] }; + + let mut hash = PoseidonTrait::new().update(struct_to_hash.first).update(struct_to_hash.second); + let hash_felt252 = hash.update(poseidon_hash_span(struct_to_hash.third.span())).finalize(); +} +# +# +``` +# Macros + +The Cairo language has some plugins that allow developers to simplify their code. They are called `inline_macros` and are a way of writing code that generates other code. + +## `consteval_int!` Macro + +In some situations, a developer might need to declare a constant that is the result of a computation of integers. To compute a constant expression and use its result at compile time, it is required to use the `consteval_int!` macro. + +Here is an example of `consteval_int!`: + +```rust,noplayground +const a: felt252 = consteval_int!(2 * 2 * 2); +``` + +This will be interpreted as `const a: felt252 = 8;` by the compiler. + +## `selector!` Macro + +See [Entry Point Selector](./ch15-02-contract-dispatchers-library-dispatchers-and-system-calls.md#entry-point-selector). + +## `print!` and `println!` Macros + +Please refer to the [Printing](./ch11-08-printing.md) page. + +## `array!` Macro + +Please refer to the [Arrays](./ch03-01-arrays.md) page. + +## `panic!` Macro + +See [Unrecoverable Errors with panic](./ch09-01-unrecoverable-errors-with-panic.html#panic-macro) page. + +## `assert!` and `assert_xx!` Macros + +See [How to Write Tests](./ch10-01-how-to-write-tests.md) page. + +## `format!` Macro + +See [Printing](./ch11-08-printing.html#formatting) page. + +## `write!` and `writeln!` Macros + +See [Printing](./ch11-08-printing.html#printing-custom-data-types) page. + +## `get_dep_component!`, `get_dep_component_mut` and `component!` Macros + +Please refer to the [Composability and Components](./ch16-02-00-composability-and-components.md) chapter. +# Inlining in Cairo + +Inlining is a common code optimization technique supported by most compilers. It involves replacing a function call at the call site with the actual code of the called function, eliminating the overhead associated with the function call itself. This can improve performance by reducing the number of instructions executed, but may increase the total size of the program. When you're thinking about whether to inline a function, take into account things like how big it is, what parameters it has, how often it gets called, and how it might affect the size of your compiled code. + +## The `inline` Attribute + +In Cairo, the `inline` attribute suggests whether or not the Sierra code corresponding to the attributed function should be directly injected in the caller function's context, rather than using a `function_call` libfunc to execute that code. + +There are three variants of the `inline` attribute that one can use: + +- `#[inline]` suggests performing an inline expansion. +- `#[inline(always)]` suggests that an inline expansion should always be performed. +- `#[inline(never)]` suggests that an inline expansion should never be performed. + +> Note: the `inline` attribute in every form is a hint, with no requirements on the language to place a copy of the attributed function in the caller. This means that the attribute may be ignored by the compiler. In practice, `#[inline(always)]` will cause inlining in all but the most exceptional cases. + +Many of the Cairo corelib functions are inlined. User-defined functions may also be annotated with the `inline` attribute. Annoting functions with the `#[inline(always)]` attribute reduces the total number of steps required when calling these attributed functions. Indeed, injecting the Sierra code at the caller site avoids the step-cost involved in calling functions and obtaining their arguments. + +However, inlining can also lead to increased code size. Whenever a function is inlined, the call site contains a copy of the function's Sierra code, potentially leading to duplication of code across the compiled code. + +Therefore, inlining should be applied with caution. Using `#[inline]` or `#[inline(always)]` indiscriminately will lead to increased compile time. It is particularly useful to inline small functions, ideally with many arguments. This is because inlining large functions will increase the code length of the program, and handling many arguments will increase the number of steps to execute these functions. + +The more frequently a function is called, the more beneficial inlining becomes in terms of performance. By doing so, the number of steps for the execution will be lower, while the code length will not grow that much or might even decrease in terms of total number of instructions. + +> Inlining is often a tradeoff between number of steps and code length. Use the `inline` attribute cautiously where it is appropriate. + +## Inlining Example + +Let's introduce a short example to illustrate the mechanisms of inlining in Cairo. Listing 11-3 shows a basic program allowing comparison between inlined and non-inlined functions. + +```rust +fn main() -> felt252 { + inlined() + not_inlined() +} + +#[inline(always)] +fn inlined() -> felt252 { + 1 +} + +#[inline(never)] +fn not_inlined() -> felt252 { + 2 +} +``` + +Listing 11-3: A small Cairo program that adds the return value of 2 functions, with one of them being inlined + +Let's take a look at the corresponding Sierra code to see how inlining works under the hood: + +```rust,noplayground +// type declarations +type felt252 = felt252 [storable: true, drop: true, dup: true, zero_sized: false] + +// libfunc declarations +libfunc function_call = function_call +libfunc felt252_const<1> = felt252_const<1> +libfunc store_temp = store_temp +libfunc felt252_add = felt252_add +libfunc felt252_const<2> = felt252_const<2> + +// statements +00 function_call() -> ([0]) +01 felt252_const<1>() -> ([1]) +02 store_temp([1]) -> ([1]) +03 felt252_add([1], [0]) -> ([2]) +04 store_temp([2]) -> ([2]) +05 return([2]) +06 felt252_const<1>() -> ([0]) +07 store_temp([0]) -> ([0]) +08 return([0]) +09 felt252_const<2>() -> ([0]) +10 store_temp([0]) -> ([0]) +11 return([0]) + +// funcs +main::main::main@0() -> (felt252) +main::main::inlined@6() -> (felt252) +main::main::not_inlined@9() -> (felt252) +``` + +The Sierra file is structured in three parts: + +- Type and libfunc declarations. +- Statements that constitute the program. +- Declaration of the functions of the program. + +The Sierra code statements always match the order of function declarations in the Cairo program. Indeed, the declaration of the functions of the program tells us that: + +- `main` function starts at line 0, and returns a `felt252` on line 5. +- `inlined` function starts at line 6, and returns a `felt252` on line 8. +- `not_inlined` function starts at line 9, and returns a `felt252` on line 11. + +All statements corresponding to the `main` function are located between lines 0 and 5: + +```rust,noplayground +00 function_call() -> ([0]) +01 felt252_const<1>() -> ([1]) +02 store_temp([1]) -> ([1]) +03 felt252_add([1], [0]) -> ([2]) +04 store_temp([2]) -> ([2]) +05 return([2]) +``` + +The `function_call` libfunc is called on line 0 to execute the `not_inlined` function. This will execute the code from lines 9 to 10 and store the return value in the variable with id `0`. + +```rust,noplayground +09 felt252_const<2>() -> ([0]) +10 store_temp([0]) -> ([0]) +``` + +This code uses a single data type, `felt252`. It uses two library functions - `felt_const<2>`, which returns the constant `felt252` 2, and `store_temp`, which pushes a constant value to memory. The first line calls the `felt_const<2>` libfunc to create a variable with id `0`. Then, the second line pushes this variable to memory for later use. + +After that, Sierra statements from line 1 to 2 are the actual body of the `inlined` function: + +```rust,noplayground +06 felt252_const<1>() -> ([0]) +07 store_temp([0]) -> ([0]) +``` + +The only difference is that the inlined code will store the `felt252_const` value in a variable with id `1`, because `[0]` refers to a variable previously assigned: + +```rust,noplayground +01 felt252_const<1>() -> ([1]) +02 store_temp([1]) -> ([1]) +``` + +> Note: in both cases (inlined or not), the `return` instruction of the function being called is not executed, as this would lead to prematurely end the execution of the `main` function. Instead, return values of `inlined` and `not_inlined` will be added and the result will be returned. + +Lines 3 to 5 contain the Sierra statements that will add the values contained in variables with ids `0` and `1`, store the result in memory and return it: + +```rust,noplayground +03 felt252_add([1], [0]) -> ([2]) +04 store_temp([2]) -> ([2]) +05 return([2]) +``` + +Now, let's take a look at the Casm code corresponding to this program to really understand the benefits of inlining. + +## Casm Code Explanations + +Here is the Casm code for our previous program example: + +```rust,noplayground +1 call rel 3 +2 ret +3 call rel 9 +4 [ap + 0] = 1, ap++ +5 [ap + 0] = [ap + -1] + [ap + -2], ap++ +6 ret +7 [ap + 0] = 1, ap++ +8 ret +9 [ap + 0] = 2, ap++ +10 ret +11 ret +``` + +Don't hesitate to use [cairovm.codes](https://cairovm.codes/) playground to follow along and see all the execution trace. + +Each instruction and each argument for any instruction increment the Program Counter (known as PC) by 1. This means that `ret` on line 2 is actually the instruction at `PC = 3`, as the argument `3` corresponds to `PC = 2`. + +The `call` and `ret` instructions allow implementation of a function stack: + +- `call` instruction acts like a jump instruction, updating the PC to a given value, whether relatively to the current value using `rel` or absolutely using `abs`. +- `ret` instruction jumps back right after the `call` instruction and continues the execution of the code. + +We can now decompose how these instructions are executed to understand what this code does: + +- `call rel 3`: this instruction increments the PC by 3 and executes the instruction at this location, which is `call rel 9` at `PC = 4`. +- `call rel 9` increments the PC by 9 and executes the instruction at `PC = 13`, which is actually line 9. +- `[ap + 0] = 2, ap++`: `ap` stands for Allocation Pointer, which points to the first memory cell that has not been used by the program so far. This means we store the value `2` in the next free memory cell indicated by the current value of `ap`, after which we increment `ap` by 1. Then, we go to the next line which is `ret`. +- `ret`: jumps back to the line after `call rel 9`, so we go to line 4. +- `[ap + 0] = 1, ap++` : we store the value `1` in `[ap]` and we apply `ap++` so that `[ap - 1] = 1`. This means we now have `[ap-1] = 1, [ap-2] = 2` and we go to the next line. +- `[ap + 0] = [ap + -1] + [ap + -2], ap++`: we sum the values `1` and `2` and store the result in `[ap]`, and we apply `ap++` so the result is `[ap-1] = 3, [ap-2] = 1, [ap-3]=2`. +- `ret`: jumps back to the line after `call rel 3`, so we go to line 2. +- `ret`: last instruction executed as there is no more `call` instruction where to jump right after. This is the actual return instruction of the Cairo `main` function. + +To summarize: + +- `call rel 3` corresponds to the `main` function, which is obviously not inlined. +- `call rel 9` triggers the call the `not_inlined` function, which returns `2` and stores it at the final location `[ap-3]`. +- The line 4 is the inlined code of the `inlined` function, which returns `1` and stores it at the final location `[ap-2]`. We clearly see that there is no `call` instruction in this case, because the body of the function is inserted and directly executed. +- After that, the sum is computed and we ultimately go back to the line 2 which contains the final `ret` instruction that returns the sum, corresponding to the return value of the `main` function. + +It is interesting to note that in both Sierra code and Casm code, the `not_inlined` function will be called and executed before the body of the `inlined` function, even though the Cairo program executes `inlined() + not_inlined()`. + +> The Casm code of our program clearly shows that there is a function call for the `not_inlined` function, while the `inlined` function is correctly inlined. + +## Additional Optimizations + +Let's study another program that shows other benefits that inlining may sometimes provide. Listing 11-4 shows a Cairo program that calls 2 functions and doesn't return anything: + +```rust +fn main() { + inlined(); + not_inlined(); +} + +#[inline(always)] +fn inlined() -> felt252 { + 'inlined' +} + +#[inline(never)] +fn not_inlined() -> felt252 { + 'not inlined' +} +``` + +Listing 11-4: A small Cairo program that calls `inlined` and `not_inlined` and doesn't return any value. + +Here is the corresponding Sierra code: + +```rust,noplayground +// type declarations +type felt252 = felt252 [storable: true, drop: true, dup: true, zero_sized: false] +type Unit = Struct [storable: true, drop: true, dup: true, zero_sized: true] + +// libfunc declarations +libfunc function_call = function_call +libfunc drop = drop +libfunc struct_construct = struct_construct +libfunc felt252_const<29676284458984804> = felt252_const<29676284458984804> +libfunc store_temp = store_temp +libfunc felt252_const<133508164995039583817065828> = felt252_const<133508164995039583817065828> + +// statements +00 function_call() -> ([0]) +01 drop([0]) -> () +02 struct_construct() -> ([1]) +03 return([1]) +04 felt252_const<29676284458984804>() -> ([0]) +05 store_temp([0]) -> ([0]) +06 return([0]) +07 felt252_const<133508164995039583817065828>() -> ([0]) +08 store_temp([0]) -> ([0]) +09 return([0]) + +// funcs +main::main::main@0() -> (Unit) +main::main::inlined@4() -> (felt252) +main::main::not_inlined@7() -> (felt252) +``` + +In this specific case, we can observe that the compiler has applied additional optimizations to the `main` function of our code : the code of the `inlined` function, which is annotated with the `#[inline(always)]` attribute, is actually not copied in the `main` function. Instead, the `main` function starts with the `function_call` libfunc to call the `not_inlined` function, entirely omitting the code of the `inlined` function. + +> Because `inlined` return value is never used, the compiler optimizes the `main` function by skipping the `inlined` function code. This will actually reduce the code length while reducing the number of steps required to execute `main`. + +In contrast, line 0 uses the `function_call` libfunc to execute the `not_inlined` function normally. This means that all the code from lines 7 to 8 will be executed: + +```rust,noplayground +07 felt252_const<133508164995039583817065828>() -> ([0]) +08 store_temp([0]) -> ([0]) +``` + +This value stored in the variable with id `0` is then dropped on line 1, as it is not used in the `main` function: + +```rust,noplayground +01 drop([0]) -> () +``` + +Finally, as the `main` function doesn't return any value, a variable of unit type `()` is created and returned: + +```rust,noplayground +02 struct_construct() -> ([1]) +03 return([1]) +``` + +## Summary + +Inlining is a compiler optimization technique that can be very useful in various situations. Inlining a function allows to get rid of the overhead of calling a function with the `function_call` libfunc by injecting the Sierra code directly in the caller function's context, while potentially optimizing the Sierra code executed to reduce the number of steps. If used effectively, inlining can even reduce code length as shown in the previous example. + +Nevertheless, applying the `inline` attribute to a function with a lot of code and few parameters might result in an increased code size, especially if the inlined function is used many times in the codebase. Use inlining only where it makes sense, and be aware that the compiler handles inlining by default. Therefore, manually applying inlining is not recommended in most situations, but can help improve and fine-tune your code's behavior. +# Printing + +When writing a program, it is quite common to print some data to the console, either for the normal process of the program or for debugging purpose. In this chapter, we describe the options you have to print simple and complex data types. + +## Printing Standard Data Types + +Cairo provides two macros to print standard data types: + +- `println!` which prints on a new line +- `print!` with inline printing + +Both take a `ByteArray` string as first parameter (see [Data Types][byte array]), which can be a simple string to print a message or a string with placeholders to format the way values are printed. + +There are two ways to use these placeholders and both can be mixed: + +- empty curly brackets `{}` are replaced by values given as parameters to the `print!` macro, in the same order. +- curly brackets with variable names are directly replaced by the variable value. + +Here are some examples: + +```rust +fn main() { + let a = 10; + let b = 20; + let c = 30; + + println!("Hello world!"); + println!("{} {} {}", a, b, c); // 10 20 30 + println!("{c} {a} {}", b); // 30 10 20 +} +``` + +> `print!` and `println!` macros use the `Display` trait under the hood, and are therefore used to print the value of types that implement it. This is the case for basic data types, but not for more complex ones. If you try to print complex data type values with these macros, e.g. for debugging purposes, you will get an error. In that case, you can either [manually implement][print with display] the `Display` trait for your type or use the `Debug` trait (see [below][print with debug]). + +[byte array]: ./ch02-02-data-types.md#byte-array-strings +[print with display]: ./ch11-08-printing.md#printing-custom-data-types +[print with debug]: ./ch11-08-printing.md#print-debug-traces + +## Formatting + +Cairo also provides a useful macro to handle string formatting: `format!`. This macro works like `println!`, but instead of printing the output to the screen, it returns a `ByteArray` with the contents. In the following example, we perform string concatenation using either the `+` operator or the +`format!` macro. The version of the code using `format!` is much easier to read, and the code generated by the `format!` macro uses snapshots, so that this call doesn’t take ownership of any of its parameters. + +```rust +fn main() { + let s1: ByteArray = "tic"; + let s2: ByteArray = "tac"; + let s3: ByteArray = "toe"; + let s = s1 + "-" + s2 + "-" + s3; + // using + operator consumes the strings, so they can't be used again! + + let s1: ByteArray = "tic"; + let s2: ByteArray = "tac"; + let s3: ByteArray = "toe"; + let s = format!("{s1}-{s2}-{s3}"); // s1, s2, s3 are not consumed by format! + // or + let s = format!("{}-{}-{}", s1, s2, s3); + + println!("{}", s); +} +``` + +## Printing Custom Data Types + +As previously explained, if you try to print the value of a custom data type with `print!` or `println!` macros, you'll get an error telling you that the `Display` trait is not implemented for your custom type: + +```shell +error: Trait has no implementation in context: core::fmt::Display:: +``` + +The `println!` macro can do many kinds of formatting, and by default, the curly brackets tell `println!` to use formatting known as `Display` - output intended for direct end user consumption. The primitive types we’ve seen so far implement `Display` by default because there’s only one way you’d want to show a `1` or any other primitive type to a user. But with structs, the way `println!` should format the output is less clear because there are more display possibilities: Do we want commas or not? Do we want to print the curly brackets? Should all the fields be shown? Due to this ambiguity, Cairo doesn’t try to guess what we want, and structs don’t have a provided implementation of `Display` to use with `println!` and the `{}` placeholder. + +Here is the `Display` trait to implement: + +```rust,noplayground +trait Display { + fn fmt(self: @T, ref f: Formatter) -> Result<(), Error>; +} +``` + +The second parameter `f` is of type `Formatter`, which is just a struct containing a `ByteArray`, representing the pending result of formatting: + +```rust,noplayground +#[derive(Default, Drop)] +pub struct Formatter { + /// The pending result of formatting. + pub buffer: ByteArray, +} +``` + +Knowing this, here is an example of how to implement the `Display` trait for a custom `Point` struct: + +```rust +use core::fmt::{Display, Formatter, Error}; + +#[derive(Copy, Drop)] +struct Point { + x: u8, + y: u8 +} + +impl PointDisplay of Display { + fn fmt(self: @Point, ref f: Formatter) -> Result<(), Error> { + let str: ByteArray = format!("Point ({}, {})", *self.x, *self.y); + f.buffer.append(@str); + Result::Ok(()) + } +} + +fn main() { + let p = Point { x: 1, y: 3 }; + println!("{}", p); // Point: (1, 3) +} +``` + +Cairo also provides the `write!` and `writeln!` macros to write formatted strings in a formatter. +Here is a short example using `write!` macro to concatenate multiple strings on the same line and then print the result: + +```rust +use core::fmt::Formatter; + +fn main() { + let mut formatter: Formatter = Default::default(); + let a = 10; + let b = 20; + write!(formatter, "hello"); + write!(formatter, "world"); + write!(formatter, " {a} {b}"); + + println!("{}", formatter.buffer); // helloworld 10 20 +} +``` + +It is also possible to implement the `Display` trait for the `Point` struct using these macros, as shown here: + +```rust +use core::fmt::{Display, Formatter, Error}; + +#[derive(Copy, Drop)] +struct Point { + x: u8, + y: u8 +} + +impl PointDisplay of Display { + fn fmt(self: @Point, ref f: Formatter) -> Result<(), Error> { + let x = *self.x; + let y = *self.y; + + writeln!(f, "Point ({x}, {y})") + } +} + +fn main() { + let p = Point { x: 1, y: 3 }; + println!("{}", p); // Point: (1, 3) +} +``` + +> Printing complex data types this way might not be ideal as it requires additional steps to use the `print!` and `println!` macros. If you need to print complex data types, especially when debugging, use the `Debug` trait described below instead. + +## Print Debug Traces + +Cairo provides the `Debug` trait, which can be derived to print the value of variables when debugging. Simply add `:?` within the curly brackets `{}` placeholders in a `print!` or `println!` macro string. + +This trait is very useful and is implemented by default for basic data types. It can also be simply derived for complex data types using the `#[derive(Debug)]` attribute, as long as all types they contain implement it. This eliminates the need to manually implement extra code to print complex data types. + +Note that `assert_xx!` macros used in tests require the provided values to implement the `Debug` trait, as they also print the result in case of assertion failure. + +For more details about the `Debug` trait and its usage for printing values when debugging, please refer to the [Derivable Traits][debug trait] appendix. + +[debug trait]: ./appendix-03-derivable-traits.md#debug-trait-for-printing-and-debugging +# Introduction to Starknet Smart Contracts + +All through the previous sections, you've mostly written programs with a `main` entrypoint. In the coming sections, you will learn to write and deploy Starknet contracts. + +One of the key applications of the Cairo language is writing smart contracts for the Starknet network. Starknet is a permissionless decentralized network that leverages zk-STARKs technology for scalability. As a Layer 2 (L2) scalability solution for Ethereum, Starknet aims to provide fast, secure, and low-cost transactions. It operates as a validity rollup, commonly known as a zero-knowledge rollup, and is built on top of the Cairo VM. + +Starknet contracts are programs specifically designed to run within the Starknet OS. The Starknet OS is a Cairo program itself, which means that any operation executed by the Starknet OS can be proven and succinctly verified. Smart contracts can access Starknet's persistent state through the OS, enabling them to read or modify variables in Starknet’s state, communicate with other contracts, and interact seamlessly with the underlying Layer 1 (L1) network. + +If you want to learn more about the Starknet network itself, its architecture and the tooling available, you should read the [Starknet Book][starknet book]. In this book, we will only focus on writing smart contracts in Cairo. + +[starknet book]: https://book.starknet.io/ + +## Scarb + +Scarb facilitates smart contract development for Starknet. To enable this feature, you'll need to make some configurations in your _Scarb.toml_ file (see [Installation][scarb installation] for how to install Scarb). + +First, add the `starknet` dependency to your _Scarb.toml_ file. Next, enable the Starknet contract compilation of the package by adding a `[[target.starknet-contract]]` section. By default, specifying this target will build a Sierra Contract Class file, which can be deployed on Starknet. If you omit to specify the target, your package will compile but will not produce an output that you can use with Starknet. + +Below is the minimal _Scarb.toml_ file required to compile a crate containing Starknet contracts: + +```toml +[package] +name = "package_name" +version = "0.1.0" + +[dependencies] +starknet = ">=2.6.3" + +[[target.starknet-contract]] +``` + +To compile contracts defined in your package's dependencies, please refer to the [Scarb documentation][compile dep contract]. + +[scarb installation]: ./ch01-01-installation.md +[compile dep contract]: https://docs.swmansion.com/scarb/docs/extensions/starknet/contract-target.html#compiling-external-contracts + +## Starknet Foundry + +Starknet Foundry is a tool chain for Starknet smart contract development. It supports many features, including writing and running tests with advanced features, deploying contracts, interacting with the Starknet network, and more. + +We'll describe Starknet Foundry in more detail in [Chapter 17][testing with snfoundry] when discussing Starknet smart contract testing and security. + +[testing with snfoundry]: ./ch17-02-testing-smart-contracts.md#testing-smart-contracts-with-starknet-foundry +# General Introduction to Smart Contracts + +This chapter will give you a high level introduction to what smart contracts are, what they are used for, and why blockchain developers would use Cairo and Starknet. +If you are already familiar with blockchain programming, feel free to skip this chapter. The last part might still be interesting though. + +## Smart Contracts + +Smart contracts gained popularity and became more widespread with the birth of Ethereum. Smart contracts are essentially programs deployed on a blockchain. The term "smart contract" is somewhat misleading, as they are neither "smart" nor "contracts" but rather code and instructions that are executed based on specific inputs. They primarily consist of two components: storage and functions. Once deployed, users can interact with smart contracts by initiating blockchain transactions containing execution data (which function to call and with what input). Smart contracts can modify and read the storage of the underlying blockchain. A smart contract has its own address and is considered a blockchain account, meaning it can hold tokens. + +The programming language used to write smart contracts varies depending on the blockchain. For example, on Ethereum and the [EVM-compatible ecosystem][evm], the most commonly used language is Solidity, while on Starknet, it is Cairo. The way the code is compiled also differs based on the blockchain. On Ethereum, Solidity is compiled into bytecode. On Starknet, Cairo is compiled into Sierra and then into Cairo Assembly (CASM). + +Smart contracts possess several unique characteristics. They are **permissionless**, meaning anyone can deploy a smart contract on the network (within the context of a decentralized blockchain, of course). Smart contracts are also **transparent**; the data stored by the smart contract is accessible to anyone. The code that composes the contract can also be transparent, enabling **composability**. This allows developers to write smart contracts that use other smart contracts. Smart contracts can only access and interact with data from the blockchain they are deployed on. They require third-party software (called _oracles_) to access external data (the price of a token for instance). + +For developers to build smart contracts that can interact with each other, it is required to know what the other contracts look like. Hence, Ethereum developers started to build standards for smart contract development, the `ERCxx`. The two most used and famous standards are the `ERC20`, used to build tokens like `USDC`, `DAI` or `STARK`, and the `ERC721`, for NFTs (Non-Fungible Tokens) like `CryptoPunks` or `Everai`. + +[evm]: https://ethereum.org/en/developers/docs/evm/ + +## Use Cases + +There are many possible use cases for smart contracts. The only limits are the technical constraints of the blockchain and the creativity of developers. + +### DeFi + +For now, the principal use case for smart contracts is similar to that of Ethereum or Bitcoin, which is essentially handling money. In the context of the alternative payment system promised by Bitcoin, smart contracts on Ethereum enable the creation of decentralized financial applications that no longer rely on traditional financial intermediaries. This is what we call DeFi (decentralized finance). DeFi consists of various projects such as lending/borrowing applications, decentralized exchanges (DEX), on-chain derivatives, stablecoins, decentralized hedge funds, insurance, and many more. + +### Tokenization + +Smart contracts can facilitate the tokenization of real-world assets, such as real estate, art, or precious metals. Tokenization divides an asset into digital tokens, which can be easily traded and managed on blockchain platforms. This can increase liquidity, enable fractional ownership, and simplify the buying and selling process. + +### Voting + +Smart contracts can be used to create secure and transparent voting systems. Votes can be recorded on the blockchain, ensuring immutability and transparency. The smart contract can then automatically tally the votes and declare the results, minimizing the potential for fraud or manipulation. + +### Royalties + +Smart contracts can automate royalty payments for artists, musicians, and other content creators. When a piece of content is consumed or sold, the smart contract can automatically calculate and distribute the royalties to the rightful owners, ensuring fair compensation and reducing the need for intermediaries. + +### Decentralized Identities DIDs + +Smart contracts can be used to create and manage digital identities, allowing individuals to control their personal information and share it with third parties securely. The smart contract could verify the authenticity of a user's identity and automatically grant or revoke access to specific services based on the user's credentials. + +
+
+As Ethereum continues to mature, we can expect the use cases and applications of smart contracts to expand further, bringing about exciting new opportunities and reshaping traditional systems for the better. + +## The Rise of Starknet and Cairo + +Ethereum, being the most widely used and resilient smart contract platform, became a victim of its own success. With the rapid adoption of some previously mentioned use cases, mainly DeFi, the cost of performing transactions became extremely high, rendering the network almost unusable. Engineers and researchers in the ecosystem began working on solutions to address this scalability issue. + +A famous trilemma called The Blockchain Trilemma in the blockchain space states that it is hard to achieve a high level of scalability, decentralization, and security simultaneously; trade-offs must be made. Ethereum is at the intersection of decentralization and security. Eventually, it was decided that Ethereum's purpose would be to serve as a secure settlement layer, while complex computations would be offloaded to other networks built on top of Ethereum. These are called Layer 2s (L2s). + +The two primary types of L2s are optimistic rollups and validity rollups. Both approaches involve compressing and batching numerous transactions together, computing the new state, and settling the result on Ethereum (L1). The difference lies in the way the result is settled on L1. For optimistic rollups, the new state is considered valid by default, but there is a 7-day window for nodes to identify malicious transactions. + +In contrast, validity rollups, such as Starknet, use cryptography to prove that the new state has been correctly computed. This is the purpose of STARKs, this cryptographic technology could permit validity rollups to scale significantly more than optimistic rollups. You can learn more about STARKs from Starkware's Medium [article][starks article], which serves as a good primer. + +> Starknet's architecture is thoroughly described in the [Starknet Book][starknet architecture], which is a great resource to learn more about the Starknet network. + +Remember Cairo? It is, in fact, a language developed specifically to work with STARKs and make them general-purpose. With Cairo, we can write **provable code**. In the context of Starknet, this allows proving the correctness of computations from one state to another. + +Unlike most (if not all) of Starknet's competitors that chose to use the EVM (either as-is or adapted) as a base layer, Starknet employs its own VM. This frees developers from the constraints of the EVM, opening up a broader range of possibilities. Coupled with decreased transaction costs, the combination of Starknet and Cairo creates an exciting playground for developers. Native account abstraction enables more complex logic for accounts, that we call "Smart Accounts", and transaction flows. Emerging use cases include **transparent AI** and machine learning applications. Finally, **blockchain games** can be developed entirely **on-chain**. Starknet has been specifically designed to maximize the capabilities of STARK proofs for optimal scalability. + +> Learn more about Account Abstraction in the [Starknet Book][account abstraction chapter]. + +[starks article]: https://medium.com/starkware/starks-starkex-and-starknet-9a426680745a +[starknet architecture]: https://book.starknet.io/ch03-00-architecture.html +[account abstraction chapter]: https://book.starknet.io/ch04-00-account-abstraction.html + +## Cairo Programs and Starknet Contracts: What Is the Difference? + +Starknet contracts are a special superset of Cairo programs, so the concepts previously learned in this book are still applicable to write Starknet contracts. +As you may have already noticed, a Cairo program must always have a `main` function that serves as the entry point for this program: + +```rust +fn main() {} +``` + +Contracts deployed on the Starknet network are essentially programs that are run by the sequencer, and as such, have access to Starknet's state. Contracts do not have a `main` function but one or multiple functions that can serve as entry points. + +Starknet contracts are defined within [modules][module chapter]. For a module to be handled as a contract by the compiler, it must be annotated with the `#[starknet::contract]` attribute. + +[module chapter]: ./ch07-02-defining-modules-to-control-scope.md +# Anatomy of a Simple Contract + +This chapter will introduce you to the basics of Starknet contracts using a very simple smart contract as example. You will learn how to write a contract that allows anyone to store a single number on the Starknet blockchain. + +Let's consider the following contract for the whole chapter. It might not be easy to understand it all at once, but we will go through it step by step: + +```rust,noplayground +#[starknet::interface] +trait ISimpleStorage { + fn set(ref self: TContractState, x: u128); + fn get(self: @TContractState) -> u128; +} + +#[starknet::contract] +mod SimpleStorage { + #[storage] + struct Storage { + stored_data: u128 + } + + #[abi(embed_v0)] + impl SimpleStorage of super::ISimpleStorage { + fn set(ref self: ContractState, x: u128) { + self.stored_data.write(x); + } + + fn get(self: @ContractState) -> u128 { + self.stored_data.read() + } + } +} +``` + +Listing 13-1: A simple storage contract + +## What Is this Contract? + +Contracts are defined by encapsulating state and logic within a module annotated with the `#[starknet::contract]` attribute. + +The state is defined within the `Storage` struct, and is always initialized empty. Here, our struct contains a single a field called `stored_data` of type `u128` (unsigned integer of 128 bits), indicating that our contract can store any number between 0 and \\( {2^{128}} - 1 \\). + +The logic is defined by functions that interact with the state. Here, our contract defines and publicly exposes the functions `set` and `get` that can be used to modify or retrieve the value of the stored variable. +You can think of it as a single slot in a database that you can query and modify by calling functions of the code that manages the database. + +## The Interface: the Contract's Blueprint + +```rust,noplayground +#[starknet::interface] +trait ISimpleStorage { + fn set(ref self: TContractState, x: u128); + fn get(self: @TContractState) -> u128; +} +``` + +Listing 13-2: A basic contract interface + + +Interfaces represent the blueprint of the contract. They define the functions that the contract exposes to the outside world. In Cairo, they're defined by annotating a trait with the `#[starknet::interface]` attribute. All functions of the trait are considered public functions of any contract that implements this trait, and are callable from the outside world. + +All contract interfaces use a generic type for the `self` parameter, representing the contract state. We chose to name this generic parameter `TContractState` in our interface, but this is not enforced and any name can be chosen. + +In our interface, note the generic type `TContractState` of the `self` argument which is passed by reference to the `set` function. Seeing the `self` argument passed in a contract function tells us that this function can access the state of the contract. The `ref` modifier implies that `self` may be modified, meaning that the storage variables of the contract may be modified inside the `set` function. + +On the other hand, the `get` function takes a snapshot of `TContractState`, which immediately tells us that it does not modify the state (and indeed, the compiler will complain if we try to modify storage inside the `get` function). + +By leveraging the [traits & impls](./ch08-02-traits-in-cairo.md) mechanism from Cairo, we can make sure that the actual implementation of the contract matches its interface. In fact, you will get a compilation error if your contract doesn’t conform with the declared interface. For example, Listing 13-3 shows a wrong implementation of the `ISimpleStorage` interface, containing a slightly different `set` function that doesn't have the same signature. + +```rust,noplayground + #[abi(embed_v0)] + impl SimpleStorage of super::ISimpleStorage { + fn set(ref self: ContractState) {} + fn get(self: @ContractState) -> u128 { + self.stored_data.read() + } + } +``` + +Listing 13-3: A wrong implementation of the interface of the contract. This does not compile, as the signature of `set` doesn't match the trait's. + +Trying to compile a contract using this implementation will result in the following error: + +```shell +$ scarb cairo-run + Compiling listing_99_02 v0.1.0 (listings/ch13-introduction-to-starknet-smart-contracts/listing_02_wrong_impl/Scarb.toml) +error: The number of parameters in the impl function `SimpleStorage::set` is incompatible with `ISimpleStorage::set`. Expected: 2, actual: 1. + --> listings/ch13-introduction-to-starknet-smart-contracts/listing_02_wrong_impl/src/lib.cairo:24:16 + fn set(ref self: ContractState) {} + ^*********************^ + +error: Wrong number of arguments. Expected 2, found: 1 + --> listings/ch13-introduction-to-starknet-smart-contracts/listing_02_wrong_impl/src/lib.cairo[contract]:80:5 + SimpleStorage::set(ref contract_state, ); + ^**************************************^ + +error: could not compile `listing_99_02` due to previous error +error: `scarb metadata` exited with error + +``` + +## Public Functions Defined in an Implementation Block + +Before we explore things further down, let's define some terminology. + +- In the context of Starknet, a _public function_ is a function that is exposed to the outside world. A public function can be called by anyone, either from outside the contract or from within the contract itself. In the example above, `set` and `get` are public functions. + +- What we call an _external_ function is a public function that can be directly invoked through a Starknet transaction and that can mutate the state of the contract. `set` is an external function. + +- A _view_ function is a public function that is typically read-only and cannot mutate the state of the contract. However, this limitation is only enforced by the compiler, and not by Starknet itself. We will discuss the implications of this in a later section. `get` is a view function. + +```rust,noplayground + #[abi(embed_v0)] + impl SimpleStorage of super::ISimpleStorage { + fn set(ref self: ContractState, x: u128) { + self.stored_data.write(x); + } + + fn get(self: @ContractState) -> u128 { + self.stored_data.read() + } + } +``` + +Listing 13-4: `SimpleStorage` implementation + +Since the contract interface is defined as the `ISimpleStorage` trait, in order to match the interface, the public functions of the contract must be defined in an implementation of this trait — which allows us to make sure that the implementation of the contract matches its interface. + +However, simply defining the functions in the implementation block is not enough. The implementation block must be annotated with the `#[abi(embed_v0)]` attribute. This attribute exposes the functions defined in this implementation to the outside world — forget to add it and your functions will not be callable from the outside. All functions defined in a block marked as `#[abi(embed_v0)]` are consequently _public functions_. + +Because the `SimpleStorage` contract is defined as a module, we need to access the interface defined in the parent module. We can either bring it to the current scope with the `use` keyword, or refer to it directly using `super`. + +When writing the implementation of an interface, the `self` parameter in the trait methods **must** be of type `ContractState`. The `ContractState` type is generated by the compiler, and gives access to the storage variables defined in the `Storage` struct. +Additionally, `ContractState` gives us the ability to emit events. The name `ContractState` is not surprising, as it’s a representation of the contract’s state, which is what we think of `self` in the contract interface trait. +When `self` is a snapshot of `ContractState`, only read access is allowed, and emitting events is not possible. + +## Accessing and Modifying the Contract's State + +Two methods are commonly used to access or modify the state of a contract: +- `read`, which returns the value of a storage variable. This method is called on the variable itself and does not take any argument. + +```rust,noplayground + self.stored_data.read() +``` + +- `write`, which allows to write a new value in a storage slot. This method is also called on the variable itself and takes one argument, which is the value to be written. Note that `write` may take more than one argument, depending on the type of the storage variable. For example, writing on a mapping requires 2 arguments: the key and the value to be written. + +```rust,noplayground + self.stored_data.write(x); +``` + +> Reminder: if the contract state is passed as a snapshot with `@` instead of passed by reference with `ref`, attempting to modify the contract state will result in a compilation error. + +This contract does not do much apart from allowing anyone to store a single number that is accessible by anyone in the world. Anyone could call `set` again with a different value and overwrite the current number. Nevertheless, each value stored in the storage of the contract will still be stored in the history of the blockchain. Later in this book, you will see how you can impose access restrictions so that only you can alter the number. +# Building Starknet Smart Contracts + +In the previous section, we gave an introductory example of a smart contract written in Cairo, describing the basic blocks to build smart contracts on Starknet. In this section, we'll be taking a deeper look at all the components of a smart contract, step by step. + +When we discussed [_interfaces_][contract interface], we specified the difference between the two types of _public functions_, i.e., _external functions_ and _view functions_, and we mentioned how to interact with the _storage_ of a contract. + +At this point, you should have multiple questions that come to mind: + +- How can I store more complex data types? +- How do I define internal/private functions? +- How can I emit events? How can I index them? +- Is there a way to reduce the boilerplate? + +Luckily, we'll be answering all these questions in this chapter. Let's consider the `NameRegistry` contract in Listing 14-1 that we'll be using throughout this chapter: + +```rust,noplayground +use starknet::ContractAddress; + +#[starknet::interface] +pub trait INameRegistry { + fn store_name( + ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType + ); + fn get_name(self: @TContractState, address: ContractAddress) -> felt252; + fn get_owner(self: @TContractState) -> NameRegistry::Person; +} + +#[starknet::contract] +mod NameRegistry { + use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; + + #[storage] + struct Storage { + names: LegacyMap::, + owner: Person, + registration_type: LegacyMap::, + total_names: u128, + } + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + StoredName: StoredName, + } + #[derive(Drop, starknet::Event)] + struct StoredName { + #[key] + user: ContractAddress, + name: felt252, + } + + #[derive(Drop, Serde, starknet::Store)] + pub struct Person { + address: ContractAddress, + name: felt252, + } + + #[derive(Drop, Serde, starknet::Store)] + pub enum RegistrationType { + finite: u64, + infinite + } + + #[constructor] + fn constructor(ref self: ContractState, owner: Person) { + self.names.write(owner.address, owner.name); + self.total_names.write(1); + self.owner.write(owner); + } + + // Public functions inside an impl block + #[abi(embed_v0)] + impl NameRegistry of super::INameRegistry { + fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { + let caller = get_caller_address(); + self._store_name(caller, name, registration_type); + } + + fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { + self.names.read(address) + } + + fn get_owner(self: @ContractState) -> Person { + self.owner.read() + } + } + + // Standalone public function + #[external(v0)] + fn get_contract_name(self: @ContractState) -> felt252 { + 'Name Registry' + } + + // Could be a group of functions about a same topic + #[generate_trait] + impl InternalFunctions of InternalFunctionsTrait { + fn _store_name( + ref self: ContractState, + user: ContractAddress, + name: felt252, + registration_type: RegistrationType + ) { + let total_names = self.total_names.read(); + self.names.write(user, name); + self.registration_type.write(user, registration_type); + self.total_names.write(total_names + 1); + self.emit(StoredName { user: user, name: name }); + } + } + + // Free function + fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { + self.owner.address() + } +} +``` + +Listing 14-1: Our reference contract for this chapter + +[contract interface]: ./ch13-02-anatomy-of-a-simple-contract.md#the-interface-the-contracts-blueprint +# Contract Storage + +The most common way for interacting with a contract’s storage is through storage variables. As stated previously, storage variables allow you to store data that will be stored in the contract's storage that is itself stored on the blockchain. These data are persistent and can be accessed and potentially modified anytime once the contract is deployed. + +Storage variables in Starknet contracts are stored in a special struct called `Storage`: + +```rust, noplayground +# use starknet::ContractAddress; +# +# #[starknet::interface] +# pub trait INameRegistry { +# fn store_name( +# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType +# ); +# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; +# fn get_owner(self: @TContractState) -> NameRegistry::Person; +# } +# +# #[starknet::contract] +# mod NameRegistry { +# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; +# + #[storage] + struct Storage { + names: LegacyMap::, + owner: Person, + registration_type: LegacyMap::, + total_names: u128, + } +# +# #[event] +# #[derive(Drop, starknet::Event)] +# enum Event { +# StoredName: StoredName, +# } +# #[derive(Drop, starknet::Event)] +# struct StoredName { +# #[key] +# user: ContractAddress, +# name: felt252, +# } +# +# #[derive(Drop, Serde, starknet::Store)] +# pub struct Person { +# address: ContractAddress, +# name: felt252, +# } +# +# #[derive(Drop, Serde, starknet::Store)] +# pub enum RegistrationType { +# finite: u64, +# infinite +# } +# +# #[constructor] +# fn constructor(ref self: ContractState, owner: Person) { +# self.names.write(owner.address, owner.name); +# self.total_names.write(1); +# self.owner.write(owner); +# } +# +# // Public functions inside an impl block +# #[abi(embed_v0)] +# impl NameRegistry of super::INameRegistry { +# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { +# let caller = get_caller_address(); +# self._store_name(caller, name, registration_type); +# } +# +# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { +# self.names.read(address) +# } +# +# fn get_owner(self: @ContractState) -> Person { +# self.owner.read() +# } +# } +# +# // Standalone public function +# #[external(v0)] +# fn get_contract_name(self: @ContractState) -> felt252 { +# 'Name Registry' +# } +# +# // Could be a group of functions about a same topic +# #[generate_trait] +# impl InternalFunctions of InternalFunctionsTrait { +# fn _store_name( +# ref self: ContractState, +# user: ContractAddress, +# name: felt252, +# registration_type: RegistrationType +# ) { +# let total_names = self.total_names.read(); +# self.names.write(user, name); +# self.registration_type.write(user, registration_type); +# self.total_names.write(total_names + 1); +# self.emit(StoredName { user: user, name: name }); +# } +# } +# +# // Free function +# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { +# self.owner.address() +# } +# } +# +# +``` + +The `Storage` struct is a [struct][structs chapter] like any other, except that it **must** be annotated with the `#[storage]` attribute. This annotation tells the compiler to generate the required code to interact with the blockchain state, and allows you to read and write data from and to storage. Moreover, this allows you to define storage mappings using the dedicated `LegacyMap` type. + +Variables declared in the `Storage` struct are not stored contiguously but in different locations in the contract's storage. The storage address of a particular variable is determined by the variable's name, and the eventual keys of the variable if it is a mapping. + +[structs chapter]: ./ch05-00-using-structs-to-structure-related-data.md + +## Addresses of Storage Variables + +The address of a storage variable is computed as follows: + +- If the variable is a single value, the address is the `sn_keccak` hash of the ASCII encoding of the variable's name. `sn_keccak` is Starknet's version of the Keccak256 hash function, whose output is truncated to 250 bits. + +- If the variable is composed of multiple values (i.e., a tuple, a struct or an enum), we also use the `sn_keccak` hash of the ASCII encoding of the variable's name to determine the base address in storage. Then, depending on the type, the storage layout will differ. See the ["Storing Custom Types"][custom types storage layout] section. + +- If the variable is a [mapping][storage mappings] with a key `k`, the address of the value at key `k` is `h(sn_keccak(variable_name),k)`, where ℎ is the Pedersen hash and the final value is taken modulo \\( {2^{251}} - 256\\). If the key is composed of more than one `felt252`, the address of the value will be `h(...h(h(sn_keccak(variable_name),k_1),k_2),...,k_n)`, with `k_1,...,k_n` being all `felt252` that constitute the key. In the case of mappings to complex values (e.g., tuples or structs), then this complex value lies in a continuous segment starting from the address calculated with the previous formula. Note that 256 field elements is the current limitation on the maximal size of a complex storage value. + +You can access the address of a storage variable by calling the `address` function on the variable, which returns a `StorageBaseAddress` value. + +```rust, noplayground +# use starknet::ContractAddress; +# +# #[starknet::interface] +# pub trait INameRegistry { +# fn store_name( +# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType +# ); +# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; +# fn get_owner(self: @TContractState) -> NameRegistry::Person; +# } +# +# #[starknet::contract] +# mod NameRegistry { +# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; +# +# #[storage] +# struct Storage { +# names: LegacyMap::, +# owner: Person, +# registration_type: LegacyMap::, +# total_names: u128, +# } +# +# #[event] +# #[derive(Drop, starknet::Event)] +# enum Event { +# StoredName: StoredName, +# } +# #[derive(Drop, starknet::Event)] +# struct StoredName { +# #[key] +# user: ContractAddress, +# name: felt252, +# } +# +# #[derive(Drop, Serde, starknet::Store)] +# pub struct Person { +# address: ContractAddress, +# name: felt252, +# } +# +# #[derive(Drop, Serde, starknet::Store)] +# pub enum RegistrationType { +# finite: u64, +# infinite +# } +# +# #[constructor] +# fn constructor(ref self: ContractState, owner: Person) { +# self.names.write(owner.address, owner.name); +# self.total_names.write(1); +# self.owner.write(owner); +# } +# +# // Public functions inside an impl block +# #[abi(embed_v0)] +# impl NameRegistry of super::INameRegistry { +# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { +# let caller = get_caller_address(); +# self._store_name(caller, name, registration_type); +# } +# +# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { +# self.names.read(address) +# } +# +# fn get_owner(self: @ContractState) -> Person { +# self.owner.read() +# } +# } +# +# // Standalone public function +# #[external(v0)] +# fn get_contract_name(self: @ContractState) -> felt252 { +# 'Name Registry' +# } +# +# // Could be a group of functions about a same topic +# #[generate_trait] +# impl InternalFunctions of InternalFunctionsTrait { +# fn _store_name( +# ref self: ContractState, +# user: ContractAddress, +# name: felt252, +# registration_type: RegistrationType +# ) { +# let total_names = self.total_names.read(); +# self.names.write(user, name); +# self.registration_type.write(user, registration_type); +# self.total_names.write(total_names + 1); +# self.emit(StoredName { user: user, name: name }); +# } +# } +# +# // Free function +# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { + self.owner.address() +# } +# } +# +# +``` + +[custom types storage layout]: ./ch14-01-contract-storage.md#storing-custom-types +[storage mappings]: ./ch14-01-contract-storage.html#storage-mappings + +## Interacting with Storage Variables + +Variables stored in the `Storage` struct can be accessed and modified using the `read` and `write` functions, respectively. As previously mentioned, you can get their address in storage using the `address` function. All these functions are automatically generated by the compiler for each storage variable. + +To read the value of the `owner` storage variable, which is a single value, we call the `read` function on the `owner` variable, passing in no parameters. + +```rust, noplayground +# use starknet::ContractAddress; +# +# #[starknet::interface] +# pub trait INameRegistry { +# fn store_name( +# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType +# ); +# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; +# fn get_owner(self: @TContractState) -> NameRegistry::Person; +# } +# +# #[starknet::contract] +# mod NameRegistry { +# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; +# +# #[storage] +# struct Storage { +# names: LegacyMap::, +# owner: Person, +# registration_type: LegacyMap::, +# total_names: u128, +# } +# +# #[event] +# #[derive(Drop, starknet::Event)] +# enum Event { +# StoredName: StoredName, +# } +# #[derive(Drop, starknet::Event)] +# struct StoredName { +# #[key] +# user: ContractAddress, +# name: felt252, +# } +# +# #[derive(Drop, Serde, starknet::Store)] +# pub struct Person { +# address: ContractAddress, +# name: felt252, +# } +# +# #[derive(Drop, Serde, starknet::Store)] +# pub enum RegistrationType { +# finite: u64, +# infinite +# } +# +# #[constructor] +# fn constructor(ref self: ContractState, owner: Person) { +# self.names.write(owner.address, owner.name); +# self.total_names.write(1); +# self.owner.write(owner); +# } +# +# // Public functions inside an impl block +# #[abi(embed_v0)] +# impl NameRegistry of super::INameRegistry { +# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { +# let caller = get_caller_address(); +# self._store_name(caller, name, registration_type); +# } +# +# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { +# self.names.read(address) +# } +# +# fn get_owner(self: @ContractState) -> Person { + self.owner.read() +# } +# } +# +# // Standalone public function +# #[external(v0)] +# fn get_contract_name(self: @ContractState) -> felt252 { +# 'Name Registry' +# } +# +# // Could be a group of functions about a same topic +# #[generate_trait] +# impl InternalFunctions of InternalFunctionsTrait { +# fn _store_name( +# ref self: ContractState, +# user: ContractAddress, +# name: felt252, +# registration_type: RegistrationType +# ) { +# let total_names = self.total_names.read(); +# self.names.write(user, name); +# self.registration_type.write(user, registration_type); +# self.total_names.write(total_names + 1); +# self.emit(StoredName { user: user, name: name }); +# } +# } +# +# // Free function +# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { +# self.owner.address() +# } +# } +# +# +``` + +To read the value of the storage variable `names`, which is a mapping from `ContractAddress` to `felt252`, we call the `read` function on the `names` variable, passing in the key `address` as a parameter. If the mapping had more than one key, we would pass in the other keys as parameters as well. + +```rust, noplayground +# use starknet::ContractAddress; +# +# #[starknet::interface] +# pub trait INameRegistry { +# fn store_name( +# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType +# ); +# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; +# fn get_owner(self: @TContractState) -> NameRegistry::Person; +# } +# +# #[starknet::contract] +# mod NameRegistry { +# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; +# +# #[storage] +# struct Storage { +# names: LegacyMap::, +# owner: Person, +# registration_type: LegacyMap::, +# total_names: u128, +# } +# +# #[event] +# #[derive(Drop, starknet::Event)] +# enum Event { +# StoredName: StoredName, +# } +# #[derive(Drop, starknet::Event)] +# struct StoredName { +# #[key] +# user: ContractAddress, +# name: felt252, +# } +# +# #[derive(Drop, Serde, starknet::Store)] +# pub struct Person { +# address: ContractAddress, +# name: felt252, +# } +# +# #[derive(Drop, Serde, starknet::Store)] +# pub enum RegistrationType { +# finite: u64, +# infinite +# } +# +# #[constructor] +# fn constructor(ref self: ContractState, owner: Person) { +# self.names.write(owner.address, owner.name); +# self.total_names.write(1); +# self.owner.write(owner); +# } +# +# // Public functions inside an impl block +# #[abi(embed_v0)] +# impl NameRegistry of super::INameRegistry { +# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { +# let caller = get_caller_address(); +# self._store_name(caller, name, registration_type); +# } +# +# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { + self.names.read(address) +# } +# +# fn get_owner(self: @ContractState) -> Person { +# self.owner.read() +# } +# } +# +# // Standalone public function +# #[external(v0)] +# fn get_contract_name(self: @ContractState) -> felt252 { +# 'Name Registry' +# } +# +# // Could be a group of functions about a same topic +# #[generate_trait] +# impl InternalFunctions of InternalFunctionsTrait { +# fn _store_name( +# ref self: ContractState, +# user: ContractAddress, +# name: felt252, +# registration_type: RegistrationType +# ) { +# let total_names = self.total_names.read(); +# self.names.write(user, name); +# self.registration_type.write(user, registration_type); +# self.total_names.write(total_names + 1); +# self.emit(StoredName { user: user, name: name }); +# } +# } +# +# // Free function +# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { +# self.owner.address() +# } +# } +# +# +``` + +To write a new value to the storage slot of a storage variable, we call the `write` function passing in the eventual keys and the value as arguments. As with the `read` function, the number of arguments depends on the storage variable type. Here, we only pass in the value to write to the `owner` variable as it is a simple variable. + +```rust, noplayground +# use starknet::ContractAddress; +# +# #[starknet::interface] +# pub trait INameRegistry { +# fn store_name( +# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType +# ); +# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; +# fn get_owner(self: @TContractState) -> NameRegistry::Person; +# } +# +# #[starknet::contract] +# mod NameRegistry { +# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; +# +# #[storage] +# struct Storage { +# names: LegacyMap::, +# owner: Person, +# registration_type: LegacyMap::, +# total_names: u128, +# } +# +# #[event] +# #[derive(Drop, starknet::Event)] +# enum Event { +# StoredName: StoredName, +# } +# #[derive(Drop, starknet::Event)] +# struct StoredName { +# #[key] +# user: ContractAddress, +# name: felt252, +# } +# +# #[derive(Drop, Serde, starknet::Store)] +# pub struct Person { +# address: ContractAddress, +# name: felt252, +# } +# +# #[derive(Drop, Serde, starknet::Store)] +# pub enum RegistrationType { +# finite: u64, +# infinite +# } +# +# #[constructor] +# fn constructor(ref self: ContractState, owner: Person) { +# self.names.write(owner.address, owner.name); +# self.total_names.write(1); + self.owner.write(owner); +# } +# +# // Public functions inside an impl block +# #[abi(embed_v0)] +# impl NameRegistry of super::INameRegistry { +# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { +# let caller = get_caller_address(); +# self._store_name(caller, name, registration_type); +# } +# +# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { +# self.names.read(address) +# } +# +# fn get_owner(self: @ContractState) -> Person { +# self.owner.read() +# } +# } +# +# // Standalone public function +# #[external(v0)] +# fn get_contract_name(self: @ContractState) -> felt252 { +# 'Name Registry' +# } +# +# // Could be a group of functions about a same topic +# #[generate_trait] +# impl InternalFunctions of InternalFunctionsTrait { +# fn _store_name( +# ref self: ContractState, +# user: ContractAddress, +# name: felt252, +# registration_type: RegistrationType +# ) { +# let total_names = self.total_names.read(); +# self.names.write(user, name); +# self.registration_type.write(user, registration_type); +# self.total_names.write(total_names + 1); +# self.emit(StoredName { user: user, name: name }); +# } +# } +# +# // Free function +# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { +# self.owner.address() +# } +# } +# +# +``` + +In this second example, we need to pass `user` and `name` as arguments, because `names` is a mapping, with `user` as key and `name` as value. + +```rust, noplayground +# use starknet::ContractAddress; +# +# #[starknet::interface] +# pub trait INameRegistry { +# fn store_name( +# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType +# ); +# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; +# fn get_owner(self: @TContractState) -> NameRegistry::Person; +# } +# +# #[starknet::contract] +# mod NameRegistry { +# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; +# +# #[storage] +# struct Storage { +# names: LegacyMap::, +# owner: Person, +# registration_type: LegacyMap::, +# total_names: u128, +# } +# +# #[event] +# #[derive(Drop, starknet::Event)] +# enum Event { +# StoredName: StoredName, +# } +# #[derive(Drop, starknet::Event)] +# struct StoredName { +# #[key] +# user: ContractAddress, +# name: felt252, +# } +# +# #[derive(Drop, Serde, starknet::Store)] +# pub struct Person { +# address: ContractAddress, +# name: felt252, +# } +# +# #[derive(Drop, Serde, starknet::Store)] +# pub enum RegistrationType { +# finite: u64, +# infinite +# } +# +# #[constructor] +# fn constructor(ref self: ContractState, owner: Person) { +# self.names.write(owner.address, owner.name); +# self.total_names.write(1); +# self.owner.write(owner); +# } +# +# // Public functions inside an impl block +# #[abi(embed_v0)] +# impl NameRegistry of super::INameRegistry { +# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { +# let caller = get_caller_address(); +# self._store_name(caller, name, registration_type); +# } +# +# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { +# self.names.read(address) +# } +# +# fn get_owner(self: @ContractState) -> Person { +# self.owner.read() +# } +# } +# +# // Standalone public function +# #[external(v0)] +# fn get_contract_name(self: @ContractState) -> felt252 { +# 'Name Registry' +# } +# +# // Could be a group of functions about a same topic +# #[generate_trait] +# impl InternalFunctions of InternalFunctionsTrait { +# fn _store_name( +# ref self: ContractState, +# user: ContractAddress, +# name: felt252, +# registration_type: RegistrationType +# ) { +# let total_names = self.total_names.read(); + self.names.write(user, name); +# self.registration_type.write(user, registration_type); +# self.total_names.write(total_names + 1); +# self.emit(StoredName { user: user, name: name }); +# } +# } +# +# // Free function +# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { +# self.owner.address() +# } +# } +# +# +``` + +## Storing Custom Types + +The `Store` trait, defined in the `starknet::storage_access` module, is used to specify how a type should be stored in storage. In order for a type to be stored in storage, it **must** implement the `Store` trait. Most types from the core library, such as unsigned integers (`u8`, `u128`, `u256`...), `felt252`, `bool`, `ByteArray`, `ContractAddress`, etc. implement the `Store` trait and can thus be stored without further action. + +But what if you wanted to store a type that you defined yourself, such as an enum or a struct? In that case, you have to explicitly tell the compiler how to store this type. + +In our example, we want to store a `Person` struct in storage, which is only possible by implementing the `Store` trait for the `Person` type. This can be simply achieved by adding a `#[derive(starknet::Store)]` attribute on top of our struct definition. Note that all the members of the struct need to implement the `Store` trait. + +```rust, noplayground +# use starknet::ContractAddress; +# +# #[starknet::interface] +# pub trait INameRegistry { +# fn store_name( +# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType +# ); +# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; +# fn get_owner(self: @TContractState) -> NameRegistry::Person; +# } +# +# #[starknet::contract] +# mod NameRegistry { +# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; +# +# #[storage] +# struct Storage { +# names: LegacyMap::, +# owner: Person, +# registration_type: LegacyMap::, +# total_names: u128, +# } +# +# #[event] +# #[derive(Drop, starknet::Event)] +# enum Event { +# StoredName: StoredName, +# } +# #[derive(Drop, starknet::Event)] +# struct StoredName { +# #[key] +# user: ContractAddress, +# name: felt252, +# } +# + #[derive(Drop, Serde, starknet::Store)] + pub struct Person { + address: ContractAddress, + name: felt252, + } +# +# #[derive(Drop, Serde, starknet::Store)] +# pub enum RegistrationType { +# finite: u64, +# infinite +# } +# +# #[constructor] +# fn constructor(ref self: ContractState, owner: Person) { +# self.names.write(owner.address, owner.name); +# self.total_names.write(1); +# self.owner.write(owner); +# } +# +# // Public functions inside an impl block +# #[abi(embed_v0)] +# impl NameRegistry of super::INameRegistry { +# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { +# let caller = get_caller_address(); +# self._store_name(caller, name, registration_type); +# } +# +# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { +# self.names.read(address) +# } +# +# fn get_owner(self: @ContractState) -> Person { +# self.owner.read() +# } +# } +# +# // Standalone public function +# #[external(v0)] +# fn get_contract_name(self: @ContractState) -> felt252 { +# 'Name Registry' +# } +# +# // Could be a group of functions about a same topic +# #[generate_trait] +# impl InternalFunctions of InternalFunctionsTrait { +# fn _store_name( +# ref self: ContractState, +# user: ContractAddress, +# name: felt252, +# registration_type: RegistrationType +# ) { +# let total_names = self.total_names.read(); +# self.names.write(user, name); +# self.registration_type.write(user, registration_type); +# self.total_names.write(total_names + 1); +# self.emit(StoredName { user: user, name: name }); +# } +# } +# +# // Free function +# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { +# self.owner.address() +# } +# } +# +# +``` + +Similarly, Enums can only be written to storage if they implement the `Store` trait, which can be trivially derived as long as all associated types implement the `Store` trait. + +```rust, noplayground +# use starknet::ContractAddress; +# +# #[starknet::interface] +# pub trait INameRegistry { +# fn store_name( +# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType +# ); +# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; +# fn get_owner(self: @TContractState) -> NameRegistry::Person; +# } +# +# #[starknet::contract] +# mod NameRegistry { +# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; +# +# #[storage] +# struct Storage { +# names: LegacyMap::, +# owner: Person, +# registration_type: LegacyMap::, +# total_names: u128, +# } +# +# #[event] +# #[derive(Drop, starknet::Event)] +# enum Event { +# StoredName: StoredName, +# } +# #[derive(Drop, starknet::Event)] +# struct StoredName { +# #[key] +# user: ContractAddress, +# name: felt252, +# } +# +# #[derive(Drop, Serde, starknet::Store)] +# pub struct Person { +# address: ContractAddress, +# name: felt252, +# } +# + #[derive(Drop, Serde, starknet::Store)] + pub enum RegistrationType { + finite: u64, + infinite + } +# +# #[constructor] +# fn constructor(ref self: ContractState, owner: Person) { +# self.names.write(owner.address, owner.name); +# self.total_names.write(1); +# self.owner.write(owner); +# } +# +# // Public functions inside an impl block +# #[abi(embed_v0)] +# impl NameRegistry of super::INameRegistry { +# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { +# let caller = get_caller_address(); +# self._store_name(caller, name, registration_type); +# } +# +# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { +# self.names.read(address) +# } +# +# fn get_owner(self: @ContractState) -> Person { +# self.owner.read() +# } +# } +# +# // Standalone public function +# #[external(v0)] +# fn get_contract_name(self: @ContractState) -> felt252 { +# 'Name Registry' +# } +# +# // Could be a group of functions about a same topic +# #[generate_trait] +# impl InternalFunctions of InternalFunctionsTrait { +# fn _store_name( +# ref self: ContractState, +# user: ContractAddress, +# name: felt252, +# registration_type: RegistrationType +# ) { +# let total_names = self.total_names.read(); +# self.names.write(user, name); +# self.registration_type.write(user, registration_type); +# self.total_names.write(total_names + 1); +# self.emit(StoredName { user: user, name: name }); +# } +# } +# +# // Free function +# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { +# self.owner.address() +# } +# } +# +# +``` + +You might have noticed that we also derived `Drop` and `Serde` on our custom types. Both of them are required for properly serializing arguments passed to entrypoints and deserializing their outputs. + +### Structs Storage Layout + +On Starknet, structs are stored in storage as a sequence of primitive types. +The elements of the struct are stored in the same order as they are defined in the struct definition. The first element of the struct is stored at the base address of the struct, which is computed as specified in ["Addresses of Storage Variables"][storage addresses] section and can be obtained by calling `var.address()`, and subsequent elements are stored at addresses contiguous to the first element. +For example, the storage layout for the `owner` variable of type `Person` will result in the following layout: + +| Fields | Address | +| ------- | ------------------ | +| name | owner.address() | +| address | owner.address() +1 | + +Note that tuples are similarly stored in contract's storage, with the first element of the tuple being stored at the base address, and subsequent elements stored contiguously. + +[storage addresses]: ./ch14-01-contract-storage.html#addresses-of-storage-variables + +### Enums Storage Layout + +When you store an enum variant, what you're essentially storing is the variant's index and eventual associated values. This index starts at 0 for the first variant of your enum and increments by 1 for each subsequent variant. +If your variant has an associated value, this value is stored starting from the address immediately following the address of the index of the variant. +For example, suppose we have the `RegistrationType` enum with the `finite` variant that carries an associated limit date, and the `infinite` variant without associated data. The storage layout for the `finite` variant would look like this: + +| Element | Address | +| ----------------------------------- | ------------------------------- | +| Variant index (0 for finite) | registration_type.address() | +| Associated limit date | registration_type.address() + 1 | + +while the storage layout for the `infinite` would be as follows: + +| Element | Address | +| ----------------------------------- | ------------------------------- | +| Variant index (1 for infinite) | registration_type.address() | + +## Storage Mappings + +Storage mappings are similar to hash tables in that they allow mapping keys to values. However, unlike a typical hash table, the key data itself is not stored - only its hash is used to look up the associated value in the contract's storage. +Mappings do not have a concept of length or whether a key/value pair is set. All values are by default set to 0. The only way to remove an entry from a mapping is to set its value to the default zero value. + +Mappings are only used to compute the location of data in the storage of a +contract given certain keys. They are thus **only allowed as storage variables**. +They cannot be used as parameters or return parameters of contract functions, +and cannot be used as types inside structs. + +
+ mappings +
+
+ Mapping keys to storage values +
+ +To declare a mapping, use the `LegacyMap` type enclosed in angle brackets `<>`, +specifying the key and value types. + +You can also create more complex mappings with multiple keys. You can find in Listing 14-2 the popular `allowances` storage variable of the ERC20 Standard which maps an `owner` and an allowed `spender` to their `allowance` amount using multiple keys passed inside a tuple: + +```rust,noplayground + #[storage] + struct Storage { + allowances: LegacyMap::<(ContractAddress, ContractAddress), u256> + } +``` + +Listing 14-2: Storing a mapping with multiple keys inside a tuple + +The address in storage of a variable stored in a mapping is computed according to the description in the ["Addresses of Storage Variables"][storage addresses] section. + +If the key of a mapping is a struct, each element of the struct constitutes a key. Moreover, the struct should implement the `Hash` trait, which can be derived with the `#[derive(Hash)]` attribute. For example, if you have a struct with two fields, the address will be `h(h(sn_keccak(variable_name),k_1),k_2)` modulo \\( {2^{251}} - 256\\), where `k_1` and `k_2` are the values of the two fields of the struct. + +Similarly, in the case of a nested mapping using a tuple as key, such as `LegacyMap::<(ContractAddress, ContractAddress), u8>`, the address will be computed in the same way, with each element of the tuple being a key: `h(h(sn_keccak(variable_name),k_1),k_2)`. + +[storage addresses]: ./ch14-01-contract-storage.html#addresses-of-storage-variables +# Contract Functions + +In this section, we are going to be looking at the different types of functions you could encounter in Starknet smart contracts. + +Functions can access the contract's state easily via `self: ContractState`, which abstracts away the complexity of underlying system calls (`storage_read_syscall` and `storage_write_syscall`). The compiler provides two modifiers: `ref` and `@` to decorate `self`, which intends to distinguish view and external functions. + +## 1. Constructors + +Constructors are a special type of function that only runs once when deploying a contract, and can be used to initialize the state of a contract. + +```rust,noplayground + #[constructor] + fn constructor(ref self: ContractState, owner: Person) { + self.names.write(owner.address, owner.name); + self.total_names.write(1); + self.owner.write(owner); + } +``` + +Some important rules to note: + +1. A contract can't have more than one constructor. +2. The constructor function must be named `constructor`, and must be annotated with the `#[constructor]` attribute. + +The `constructor` function might take arguments, which are passed when deploying the contract. In our example, we pass some value corresponding to a `Person` type as argument in order to store the `owner` information (address and name) in the contract. + +Note that the `constructor` function **must** take `self` as a first argument, corresponding to the state of the contract, generally passed by reference with the `ref` keyword to be able to modify the contract's state. We will explain `self` and its type shortly. + +## 2. Public Functions + +As stated previously, public functions are accessible from outside of the contract. They are usually defined inside an implementation block annotated with the `#[abi(embed_v0)]` attribute, but might also be defined independently under the `#[external(v0)]` attribute. + +The `#[abi(embed_v0)]` attribute means that all functions embedded inside it are implementations of the Starknet interface of the contract, and therefore potential entry points. + +Annotating an impl block with the `#[abi(embed_v0)]` attribute only affects the visibility (i.e., public vs private/internal) of the functions it contains, but it doesn't inform us on the ability of these functions to modify the state of the contract. + +```rust,noplayground + // Public functions inside an impl block + #[abi(embed_v0)] + impl NameRegistry of super::INameRegistry { + fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { + let caller = get_caller_address(); + self._store_name(caller, name, registration_type); + } + + fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { + self.names.read(address) + } + + fn get_owner(self: @ContractState) -> Person { + self.owner.read() + } + } +``` + +> Similarly to the `constructor` function, all public functions, either standalone functions annotated with the `#[external(v0)]` or functions within an impl block annotated with the `#[abi(embed_v0)]` attribute, **must** take `self` as a first argument. This is not the case for private functions. + +### External Functions + +External functions are _public_ functions where the `self: ContractState` argument is passed by reference with the `ref` keyword, which exposes both the `read` and `write` access to storage variables. This allows modifying the state of the contract via `self` directly. + +```rust,noplayground + fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { + let caller = get_caller_address(); + self._store_name(caller, name, registration_type); + } +``` + +### View Functions + +View functions are _public_ functions where the `self: ContractState` argument is passed as snapshot, which only allows the `read` access to storage variables, and restricts writes to storage made via `self` by causing compilation errors. The compiler will mark their `state_mutability` to `view`, preventing any state modification through `self` directly. + +```rust,noplayground + fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { + self.names.read(address) + } + +``` + +### State Mutability of Public Functions + +However, as you may have noticed, passing `self` as a snapshot only restricts the storage write access via `self` at compile time. It does not prevent state modification via direct system calls, nor calling another contract that would modify the state. + +The read-only property of view functions is not enforced on Starknet, and sending a transaction targeting a view function _could_ change the state. + +In conclusion, even though external and view functions are distinguished by the Cairo compiler, **all public functions** can be called through an invoke transaction and have the potential to modify states on Starknet. Also, all public functions can be queried via `starknet_call` on Starknet, which will not create a transaction and hence will not change the state. + +> **Warning:** This is different from the EVM where a `staticcall` opcode is provided, which prevents storage modifications in the current context and subcontexts. Hence developers **should not** have the assumption that calling a view function on another contract cannot modify the state. + +### Standalone Public Functions + +It is also possible to define public functions outside of an implementation of a trait, using the `#[external(v0)]` attribute. Doing this will automatically generate the corresponding ABI, allowing these standalone public functions to be callable by anyone from the outside. These functions can also be called from within the contract just like any function in Starknet contracts. The first parameter must be `self`. + +Here, we define a standalone `get_contract_name` function outside of an impl block: + +```rust,noplayground + // Standalone public function + #[external(v0)] + fn get_contract_name(self: @ContractState) -> felt252 { + 'Name Registry' + } +``` + +## 3. Private Functions + +Functions that are not defined with the `#[external(v0)]` attribute or inside a block annotated with the `#[abi(embed_v0)]` attribute are private functions (also called internal functions). They can only be called from within the contract. + +They can be grouped in a dedicated impl block (e.g., in components, to easily import internal functions all at once in the embedding contracts) or just be added as free functions inside the contract module. +Note that these 2 methods are equivalent. Just choose the one that makes your code more readable and easy to use. + +```rust,noplayground + // Could be a group of functions about a same topic + #[generate_trait] + impl InternalFunctions of InternalFunctionsTrait { + fn _store_name( + ref self: ContractState, + user: ContractAddress, + name: felt252, + registration_type: RegistrationType + ) { + let total_names = self.total_names.read(); + self.names.write(user, name); + self.registration_type.write(user, registration_type); + self.total_names.write(total_names + 1); + self.emit(StoredName { user: user, name: name }); + } + } + + // Free function + fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { + self.owner.address() + } +``` + +> Wait, what is this `#[generate_trait]` attribute? Where is the trait definition for this implementation? Well, the `#[generate_trait]` attribute is a special attribute that tells the compiler to generate a trait definition for the implementation block. This allows you to get rid of the boilerplate code of defining a trait with generic parameters and implementing it for the implementation block. With this attribute, we can simply define the implementation block directly, without any generic parameter, and use `self: ContractState` in our functions. + +The `#[generate_trait]` attribute is mostly used to define private impl blocks. It might also be used in addition to `#[abi(per_item)]` to define the various entrypoints of a contract (see [next section][abi per item section]). + +> Note: using `#[generate_trait]` in addition to the `#[abi(embed_v0)]` attribute for a public impl block is not recommended, as it will result in a failure to generate the corresponding ABI. Public functions should only be defined in an impl block annotated with `#[generate_trait]` if this block is also annotated with the `#[abi(per_item)]` attribute. + +[abi per item section]: ./ch14-02-contract-functions.md#4-abiper_item-attribute + + +## `[abi(per_item)]` Attribute + +You can also define the entrypoint type of functions individually inside an impl block using the`#[abi(per_item)]` attribute on top of your impl. It is often used with the `#[generate_trait]` attribute, as it allows you to define entrypoints without an explicit interface. In this case, the functions will not be grouped under an impl in the ABI. Note that when using `#[abi(per_item)]` attribute, public functions need to be annotated with the `#[external(v0)]` attribute - otherwise, they will not be exposed and will be considered as private functions. + +Here is a short example: + +```rust,noplayground +#[starknet::contract] +mod AbiAttribute { + #[storage] + struct Storage {} + + #[abi(per_item)] + #[generate_trait] + impl SomeImpl of SomeTrait { + #[constructor] + // this is a constructor function + fn constructor(ref self: ContractState) {} + + #[external(v0)] + // this is a public function + fn external_function(ref self: ContractState, arg1: felt252) {} + + #[l1_handler] + // this is a l1_handler function + fn handle_message(ref self: ContractState, from_address: felt252, arg: felt252) {} + + // this is an internal function + fn internal_function(self: @ContractState) {} + } +} +``` + +In the case of `#[abi(per_item)]` attribute usage without `#[generate_trait]`, it will only be possible to include `constructor`, `l1-handler` and `internal` functions in the trait implementation. Indeed, `#[abi(per_item)]` only works with a trait that is not defined as a Starknet interface. Hence, it will be mandatory to create another trait defined as interface to implement public functions. +# Contract Events + +Events are custom data structures that are emitted by smart contracts during execution. They provide a way for smart contracts to communicate with the external world by logging information about specific occurrences in a contract. + +Events play a crucial role in the integration of smart contracts in real-world applications. Take, for instance, the Non-Fungible Tokens (NFTs) minted on Starknet. An event is emitted each time a token is minted. This event is indexed and stored in some database, allowing applications to display almost instantaneously useful information to users. If the contract doesn't emit an event when minting a new token, it would be less practical, with the need of querying the state of the blockchain to get the data needed. + +## Defining Events + +All the different events in a contract are defined under the `Event` enum, which must implement the `starknet::Event` trait. This trait is defined in the core library as follows: + +```rust,noplayground +trait Event { + fn append_keys_and_data(self: T, ref keys: Array, ref data: Array); + fn deserialize(ref keys: Span, ref data: Span) -> Option; +} +``` + +The `#[derive(starknet::Event)]` attribute causes the compiler to generate an implementation for the above trait, +instantiated with the `Event` type, which in our example is the following enum: + +```rust,noplayground + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + StoredName: StoredName, + } +``` + +Each variant of the `Event` enum has to be a struct or an enum, and each variant needs to implement the `starknet::Event` trait itself. Moreover, the members of these variants must implement the `Serde` trait (_c.f._ [Appendix C: Serializing with Serde][serde appendix]), as keys/data are added to the event using a serialization process. + +The auto-implementation of the `starknet::Event` trait will implement the `append_keys_and_data` function for each variant of our `Event` enum. The generated implementation will append a single key based on the variant name (`StoredName`), and then recursively call `append_keys_and_data` in the impl of the `Event` trait for the variant’s type. + +In our example, the `Event` enum contains only one variant, which is a struct named `StoredName`. We chose to name our variant with the same name as the struct name, but this is not enforced. + +```rust,noplayground + #[derive(Drop, starknet::Event)] + struct StoredName { + #[key] + user: ContractAddress, + name: felt252, + } +``` + +Whenever an enum that derives the `starknet::Event` trait has an enum variant, this enum is nested by default. Therefore, the list of keys corresponding to the variant’s name will include the `sn_keccak` hash of the variant's name itself. This can be superfluous, typically when using embedded components in contracts. Indeed, in such cases, we might want the events defined in the components to be emitted without any additional data, and it could be useful to annotate the enum variant with the `#[flat]` attribute. By doing so, we allow to opt out of the nested behavior and ignore the variant name in the serialization process. On the other hand, nested events have the benefit of distinguishing between the main contract event and different components events, which might be helpful. + +In our contract, we defined an event named `StoredName` that emits the contract address of the caller and the name stored within the contract, where the `user` field is serialized as a key and the `name` field is serialized as data. + +Indexing events fields allows for more efficient queries and filtering of events. To index a field as a key of an event, simply annotate it with the `#[key]` attribute as demonstrated in the example for the `user` key. By doing so, any indexed field will allow queries of events that contain a given value for that field with \\( O(log(n)) \\) time complexity, while non indexed fields require any query to iterate over all events, providing \\( O(n) \\) time complexity. + +When emitting the event with `self.emit(StoredName { user: user, name: name })`, a key corresponding to the name ` StoredName`, specifically `sn_keccak(StoredName)`, is appended to the keys list. `user`is serialized as key, thanks to the `#[key]` attribute, while address is serialized as data. After everything is processed, we end up with the following keys and data: `keys = [sn_keccak("StoredName"),user]` and `data = [name]`. + +[serde appendix]: ./appendix-03-derivable-traits.html#serializing-with-serde + +## Emitting Events + +After defining events, we can emit them using `self.emit`, with the following syntax: + +```rust,noplayground + self.emit(StoredName { user: user, name: name }); +``` + +The `emit` function is called on `self` and takes a reference to `self`, i.e., state modification capabilities are required. Therefore, it is not possible to emit events in view functions. +# Starknet Cross-Contract Interactions + +Interactions between smart contracts are an important feature when creating complex decentralized applications, as it allows for composability and separation of concerns. This chapter sheds light on how to make contracts interact with each other. + +Specifically, you'll learn about ABIs, contract interfaces, the contract and library dispatchers and their low-level system call equivalents! +# ABIs and Contract Interfaces + +Cross-contract interactions between smart contracts on a blockchain is a common practice which enables us to build flexible contracts that can speak with each other. + +Achieving this on Starknet requires something we call an interface. + +## ABI - Application Binary Interface + +On Starknet, the ABI of a contract is a JSON representation of the contract's functions and structures, giving anyone (or any other contract) the ability to form encoded calls to it. It is a blueprint that instructs how functions should be called, what input parameters they expect, and in what format. + +While we write our smart contract logics in high-level Cairo, they are stored on the VM as executable bytecodes which are in binary formats. Since this bytecode is not human readable, it requires interpretation to be understood. This is where ABIs come into play, defining specific methods which can be called to a smart contract for execution. Without an ABI, it becomes practically impossible for external actors to understand how to interact with a contract. + +ABIs are typically used in dApps frontends, allowing it to format data correctly, making it understandable by the smart contract and vice versa. When you interact with a smart contract through a block explorer like [Voyager](https://voyager.online/) or [Starkscan](https://starkscan.co/), they use the contract's ABI to format the data you send to the contract and the data it returns. + +## Interface + +The interface of a contract is a list of the functions it exposes publicly. +It specifies the function signatures (name, parameters, visibility and return value) contained in a smart contract without including the function body. + +Contract interfaces in Cairo are traits annotated with the `#[starknet::interface]` attribute. If you are new to traits, check out the dedicated chapter on [traits](./ch08-02-traits-in-cairo.md). + +One important specification is that this trait must be generic over the `TContractState` type. This is required for functions to access the contract's storage, so that they can read and write to it. + +> Note: The contract constructor is not part of the interface. Nor are internal functions part of the interface. + +Here's a sample interface for an ERC20 token contract. As you can see, it's a generic trait over the `TContractState` type. `view` functions have a self parameter of type `@TContractState`, while `external` functions have a self parameter of type passed by reference `ref self: TContractState`. + +```rust,noplayground +use starknet::ContractAddress; + +#[starknet::interface] +trait IERC20 { + fn name(self: @TContractState) -> felt252; + + fn symbol(self: @TContractState) -> felt252; + + fn decimals(self: @TContractState) -> u8; + + fn total_supply(self: @TContractState) -> u256; + + fn balance_of(self: @TContractState, account: ContractAddress) -> u256; + + fn allowance(self: @TContractState, owner: ContractAddress, spender: ContractAddress) -> u256; + + fn transfer(ref self: TContractState, recipient: ContractAddress, amount: u256) -> bool; + + fn transfer_from( + ref self: TContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256 + ) -> bool; + + fn approve(ref self: TContractState, spender: ContractAddress, amount: u256) -> bool; +} +``` + +Listing 15-1: A simple ERC20 Interface. + +In the next chapter, we will see how we can call contracts from other smart contracts using _dispatchers_ and _syscalls_ . +# Contract Dispatchers, Library Dispatchers and System Calls + +Each time a contract interface is defined, two dispatchers are automatically created and exported by the compiler. Let's consider an interface that we named IERC20, these would be: + +1. The Contract Dispatcher `IERC20Dispatcher` +2. The Library Dispatcher `IERC20LibraryDispatcher` + +The compiler also generates a trait `IERC20DispatcherTrait`, allowing us to call the functions defined in the interface on the dispatcher struct. + +In this chapter, we are going to discuss what these are, how they work and how to use them. + +To effectively break down the concepts in this chapter, we are going to be using the IERC20 interface from the previous chapter (refer to Listing 15-1). + +## Contract Dispatcher + +As mentioned previously, traits annotated with the `#[starknet::interface]` attribute automatically generate a dispatcher and a trait on compilation. +Our `IERC20` interface is expanded into something like this: + +**Note:** The expanded code for our IERC20 interface is a lot longer, but to keep this chapter concise and straight to the point, we focused on one view function `name`, and one external function `transfer`. + +```rust,noplayground +use starknet::{ContractAddress}; + +trait IERC20DispatcherTrait { + fn name(self: T) -> felt252; + fn transfer(self: T, recipient: ContractAddress, amount: u256); +} + +#[derive(Copy, Drop, starknet::Store, Serde)] +struct IERC20Dispatcher { + contract_address: ContractAddress, +} + +impl IERC20DispatcherImpl of IERC20DispatcherTrait { + fn name( + self: IERC20Dispatcher + ) -> felt252 { // starknet::call_contract_syscall is called in here + } + fn transfer( + self: IERC20Dispatcher, recipient: ContractAddress, amount: u256 + ) { // starknet::call_contract_syscall is called in here + } +} +``` + +Listing 15-2: An expanded form of the IERC20Dispatcher trait. + +As you can see, the "classic" dispatcher is just a struct that wraps a contract address and implements the `DispatcherTrait` generated by the compiler, allowing us to call functions from another contract. This means that we can instantiate a struct with the address of the contract we want to call, and then simply call the functions defined in the interface on the dispatcher struct as if they were methods of that type. + +It's also worthy of note that all these are abstracted behind the scenes thanks to the power of Cairo plugins. + +### Calling Contracts using the Contract Dispatcher + +This is an example of a contract named `TokenWrapper` using a dispatcher to call functions defined on an ERC-20 token. Calling `transfer_token` will modify the state of the contract deployed at `contract_address`. + +```rust,noplayground +# use starknet::ContractAddress; +# +# #[starknet::interface] +# trait IERC20 { +# fn name(self: @TContractState) -> felt252; +# +# fn symbol(self: @TContractState) -> felt252; +# +# fn decimals(self: @TContractState) -> u8; +# +# fn total_supply(self: @TContractState) -> u256; +# +# fn balance_of(self: @TContractState, account: ContractAddress) -> u256; +# +# fn allowance(self: @TContractState, owner: ContractAddress, spender: ContractAddress) -> u256; +# +# fn transfer(ref self: TContractState, recipient: ContractAddress, amount: u256) -> bool; +# +# fn transfer_from( +# ref self: TContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256 +# ) -> bool; +# +# fn approve(ref self: TContractState, spender: ContractAddress, amount: u256) -> bool; +# } +# +# #[starknet::interface] +# trait ITokenWrapper { +# fn token_name(self: @TContractState, contract_address: ContractAddress) -> felt252; +# +# fn transfer_token( +# ref self: TContractState, +# contract_address: ContractAddress, +# recipient: ContractAddress, +# amount: u256 +# ) -> bool; +# } +# +# +//**** Specify interface here ****// +#[starknet::contract] +mod TokenWrapper { + use super::IERC20DispatcherTrait; + use super::IERC20Dispatcher; + use super::ITokenWrapper; + use starknet::ContractAddress; + + #[storage] + struct Storage {} + + impl TokenWrapper of ITokenWrapper { + fn token_name(self: @ContractState, contract_address: ContractAddress) -> felt252 { + IERC20Dispatcher { contract_address }.name() + } + + fn transfer_token( + ref self: ContractState, + contract_address: ContractAddress, + recipient: ContractAddress, + amount: u256 + ) -> bool { + IERC20Dispatcher { contract_address }.transfer(recipient, amount) + } + } +} +# +# +``` + +Listing 15-3: A sample contract which uses the Contract Dispatcher. + +As you can see, we had to first import `IERC20DispatcherTrait` and `IERC20Dispatcher` generated by the compiler, which allows us to make calls to the methods implemented for the `IERC20Dispatcher` struct (`name`, `transfer`, etc), passing in the `contract_address` of the contract we want to call in the `IERC20Dispatcher` struct. + +## Library Dispatcher + +The key difference between the contract dispatcher and the library dispatcher lies in the execution context of the logic defined in the class. While regular dispatchers are used to call functions from **contracts** (with an associated state), library dispatchers are used to call **classes** (stateless). + +Let's consider two contracts A and B. + +When A uses `IBDispatcher` to call functions from the **contract** B, the execution context of the logic defined in B is that of B. This means that the value returned by `get_caller_address()` in B will return the address of A, and updating a storage variable in B will update the storage of B. + +When A uses `IBLibraryDispatcher` to call functions from the **class** of B, the execution context of the logic defined in B's class is that of A. This means that the value returned by `get_caller_address()` variable in B will return the address of the caller of A, and updating a storage variable in B's class will update the storage of A (remember that the **class** of B is stateless; there is no state that can be updated!) + +The expanded form of the struct and trait generated by the compiler look like: + +```rust,noplayground +use starknet::ContractAddress; + +trait IERC20DispatcherTrait { + fn name(self: T) -> felt252; + fn transfer(self: T, recipient: ContractAddress, amount: u256); +} + +#[derive(Copy, Drop, starknet::Store, Serde)] +struct IERC20LibraryDispatcher { + class_hash: starknet::ClassHash, +} + +impl IERC20LibraryDispatcherImpl of IERC20DispatcherTrait { + fn name( + self: IERC20LibraryDispatcher + ) -> felt252 { // starknet::syscalls::library_call_syscall is called in here + } + fn transfer( + self: IERC20LibraryDispatcher, recipient: ContractAddress, amount: u256 + ) { // starknet::syscalls::library_call_syscall is called in here + } +} +``` + +Listing 15-4: An expanded form of the IERC20 trait. + +Notice that the main difference between the regular contract dispatcher and the library dispatcher is that the former uses `call_contract_syscall` while the latter uses `library_call_syscall`. + +### Calling Contracts using the Library Dispatcher + +Below's a sample code for calling contracts using the Library Dispatcher. + +```rust,noplayground +use starknet::ContractAddress; + +#[starknet::interface] +trait IContractA { + fn set_value(ref self: TContractState, value: u128); + + fn get_value(self: @TContractState) -> u128; +} + +#[starknet::contract] +mod ContractA { + use super::{IContractADispatcherTrait, IContractALibraryDispatcher}; + use starknet::{ContractAddress, class_hash::class_hash_const}; + + #[storage] + struct Storage { + value: u128 + } + + #[abi(embed_v0)] + impl ContractA of super::IContractA { + fn set_value(ref self: ContractState, value: u128) { + IContractALibraryDispatcher { class_hash: class_hash_const::<0x1234>() } + .set_value(value) + } + + fn get_value(self: @ContractState) -> u128 { + self.value.read() + } + } +} +``` + +Listing 15-5: A sample contract using the Library Dispatcher. + +As you can see, we had to first import in our contract the `IContractADispatcherTrait` and `IContractALibraryDispatcher` which were generated from our interface by the compiler. Then, we can create an instance of `IContractALibraryDispatcher` passing in the `class_hash` of the class we want to make library calls to. From there, we can call the functions defined in that class, executing its logic in the context of our contract. When we call `set_value` on ContractA, it will make a library call to the `set_value` function in IContractA, updating the value of the storage variable `value` in ContractA. + +## Using low-level syscalls + +Another way to call other contracts and classes is to use the `starknet::call_contract_syscall`and `starknet::library_call_syscall` system calls. The dispatchers we described in the previous sections are high-level syntaxes for these low-level system calls. + +Using these syscalls can be handy for customized error handling or to get more control over the serialization/deserialization of the call data and the returned data. Here's an example demonstrating how to use a `call_contract_sycall` to call the `transfer` function of an ERC20 contract: + +```rust,noplayground +use starknet::ContractAddress; +#[starknet::interface] +trait ITokenWrapper { + fn transfer_token( + ref self: TContractState, + address: ContractAddress, + sender: ContractAddress, + recipient: ContractAddress, + amount: u256 + ) -> bool; +} + +#[starknet::contract] +mod TokenWrapper { + use super::ITokenWrapper; + use core::serde::Serde; + use starknet::{SyscallResultTrait, ContractAddress, syscalls}; + + #[storage] + struct Storage {} + + impl TokenWrapper of ITokenWrapper { + fn transfer_token( + ref self: ContractState, + address: ContractAddress, + sender: ContractAddress, + recipient: ContractAddress, + amount: u256 + ) -> bool { + let mut call_data: Array = ArrayTrait::new(); + Serde::serialize(@sender, ref call_data); + Serde::serialize(@recipient, ref call_data); + Serde::serialize(@amount, ref call_data); + + let mut res = syscalls::call_contract_syscall( + address, selector!("transferFrom"), call_data.span() + ) + .unwrap_syscall(); + + Serde::::deserialize(ref res).unwrap() + } + } +} + +``` + +Listing 15-6: A sample contract using syscalls. + +To use this syscall, we passed in the contract address, the selector of the function we want to call (see next section), and the call arguments. + +The call arguments must be provided as an array of `felt252`. To build this array, we serialize the expected function parameters into an `Array` using the `Serde` trait, and then pass this array as calldata. At the end, we are returned a serialized value which we'll need to deserialize ourselves! + +### Entry Point Selector + +In the context of a smart contract, a selector is a unique identifier for a specific entrypoint of a contract. When a transaction is sent to a contract, it includes the selector in the calldata to specify which function should be executed. + +On Starknet, the selector is computed by applying the `sn_keccak` hash function to the string representation of the function name. If the function name is `transfer`, the selector can be computed with `selector!("transfer")` + +Note that in `starknet::call_contract_syscall`, we didn't specify the function name as a string, but rather used the `selector!` macro, which computes the `sn_keccak` hash of the provided function signature. +# Building Advanced Starknet Smart Contracts +# Optimizing Storage Costs + +Bit-packing is a simple concept: use as few bits as possible to store a piece of data. When done well, it can significantly reduce the size of the data you need to store. This is especially important in smart contracts, where storage is expensive. + +When writing Cairo smart contracts, it is important to optimize storage usage to reduce gas costs. Indeed, most of the cost associated with a transaction is related to storage updates; and each storage slot costs gas to write to. +This means that by packing multiple values into fewer slots, you can decrease the gas cost incurred by the users of your smart contract. + +## Integer Structure and Bitwise Operators + +An integer is coded on a certain number of bits, depending on its size (For example, a `u8` integer is coded on 8 bits). + +
+ a u8 integer in bits +
+
+ Representation of a u8 integer in bits +
+ +Intuitively, several integers can be combined into a single integer if the size of this single integer is greater than or equal to the sum of the sizes of the integers (For example, two `u8` and one `u16` in one `u32`). + +But, to do that, we need some bitwise operators: + +- multiplying or dividing an integer by a power of 2 shifts the integer value to the left or to the right respectively + +
+ shift operators +
+
+ Shifting to the left or to the right an integer value +
+ +- applying a mask (`AND` operator) on an integer value isolates some bits of this integer + +
+ applying a mask +
+
+ Isolate bits with a mask +
+ +- adding (`OR` operator) two integers will combine both values into a single one. + +
+ combining two values +
+
+ Combining two integers +
+ +With these bitwise operators, let's see how to combine two `u8` integers into a single `u16` integer (called `packing`) and reversely (called `unpacking`) in the following example: + +
+ packing and unpacking integer values +
+
+ Packing and unpacking integer values +
+ +## Bit-packing in Cairo + +The storage of a Starknet smart contract is a map with 2251 slots, where each slot is a `felt252` which is initialized to 0. + +As we saw earlier, to reduce gas costs due to storage updates, we have to use as few bits as possible, so we have to organize stored variables by packing them. + +For example, consider the following `Sizes` struct with 3 fields of different types: one `u8`, one `u32` and one `u64`. The total size is 8 + 32 + 64 = 104 bits. This is less than a slot size (i.e 251 bits) so we can pack them together to be stored into a single slot. + +Note that, as it also fits in a `u128`, it's a good practice to use the smallest type to pack all your variables, so here a `u128` should be used. + +```rust,noplayground +struct Sizes { + tiny: u8, + small: u32, + medium: u64, +} +``` + +To pack these 3 variables into a `u128` we have to successively shift them to the left, and finally sum them. + +
+ Sizes packing +
+
+ Sizes packing +
+ +To unpack these 3 variables from a `u128` we have to successively shift them to the right and use a mask to isolate them. + +
+ Sizes unpacking +
+
+ Sizes unpacking +
+ +## The `StorePacking` Trait + +Cairo provides the `StorePacking` trait to enable packing struct fields into fewer storage slots. `StorePacking` is a generic trait taking the type you want to pack (`T`) and the destination type (`PackedT`) as parameters. It provides two functions to implement: `pack` and `unpack`. + +Here is the implementation of the example of the previous chapter: + +```rust,noplayground +use starknet::storage_access::StorePacking; + +#[derive(Drop, Serde)] +struct Sizes { + tiny: u8, + small: u32, + medium: u64, +} + +const TWO_POW_8: u128 = 0x100; +const TWO_POW_40: u128 = 0x10000000000; + +const MASK_8: u128 = 0xff; +const MASK_32: u128 = 0xffffffff; + +impl SizesStorePacking of StorePacking { + fn pack(value: Sizes) -> u128 { + value.tiny.into() + (value.small.into() * TWO_POW_8) + (value.medium.into() * TWO_POW_40) + } + + fn unpack(value: u128) -> Sizes { + let tiny = value & MASK_8; + let small = (value / TWO_POW_8) & MASK_32; + let medium = (value / TWO_POW_40); + + Sizes { + tiny: tiny.try_into().unwrap(), + small: small.try_into().unwrap(), + medium: medium.try_into().unwrap(), + } + } +} + +#[starknet::contract] +mod SizeFactory { + use super::Sizes; + use super::SizesStorePacking; //don't forget to import it! + + #[storage] + struct Storage { + remaining_sizes: Sizes + } + + #[abi(embed_v0)] + fn update_sizes(ref self: ContractState, sizes: Sizes) { + // This will automatically pack the + // struct into a single u128 + self.remaining_sizes.write(sizes); + } + + + #[abi(embed_v0)] + fn get_sizes(ref self: ContractState) -> Sizes { + // this will automatically unpack the + // packed-representation into the Sizes struct + self.remaining_sizes.read() + } +} +``` + +
+ Optimizing storage by implementing the `StorePacking` trait. +
+ +In this code snippet, you see that: + +- `TWO_POW_8` and `TWO_POW_40` are used to shift left in the `pack` function and shift right in the `unpack`function, +- `MASK_8` and `MASK_32` are used to isolate a variable in the `unpack` function, +- all the variables from the storage are converted to `u128` to be able to use bitwise operators. + +This technique can be used for any group of fields that fit within the bit size of the packed storage type. For example, if you have a struct with multiple fields whose bit sizes add up to 256 bits, you can pack them into a single `u256` variable. If the bit sizes add up to 512 bits, you can pack them into a single `u512` variable, and so on. You can define your own structs and logic to pack and unpack them. + +The rest of the work is done magically by the compiler - if a type implements the `StorePacking` trait, then the compiler will know it can use the `StoreUsingPacking` implementation of the `Store` trait in order to pack before writing and unpack after reading from storage. +One important detail, however, is that the type that `StorePacking::pack` spits out also has to implement `Store` for `StoreUsingPacking` to work. Most of the time, we will want to pack into a felt252 or u256 - but if you want to pack into a type of your own, make sure that this one implements the `Store` trait. +# Components: Lego-Like Building Blocks for Smart Contracts + +Developing contracts sharing a common logic and storage can be painful and +bug-prone, as this logic can hardly be reused and needs to be reimplemented in +each contract. But what if there was a way to snap in just the extra +functionality you need inside your contract, separating the core logic of your +contract from the rest? + +Components provide exactly that. They are modular add-ons encapsulating reusable +logic, storage, and events that can be incorporated into multiple contracts. +They can be used to extend a contract's functionality, without having to +reimplement the same logic over and over again. + +Think of components as Lego blocks. They allow you to enrich your contracts by +plugging in a module that you or someone else wrote. This module can be a simple +one, like an ownership component, or more complex like a full-fledged ERC20 +token. + +A component is a separate module that can contain storage, events, and +functions. Unlike a contract, a component cannot be declared or deployed. Its +logic will eventually be part of the contract’s bytecode it has been embedded +in. + +## What's in a Component? + +A component is very similar to a contract. It can contain: + +- Storage variables +- Events +- External and internal functions + +Unlike a contract, a component cannot be deployed on its own. The component's +code becomes part of the contract it's embedded to. + +## Creating Components + +To create a component, first define it in its own module decorated with a +`#[starknet::component]` attribute. Within this module, you can declare a ` +Storage` struct and `Event` enum, as usually done in [contracts][contract anatomy]. + +The next step is to define the component interface, containing the signatures of +the functions that will allow external access to the component's logic. You can +define the interface of the component by declaring a trait with the +`#[starknet::interface]` attribute, just as you would with contracts. This +interface will be used to enable external access to the component's functions +using the [dispatcher][contract dispatcher] pattern. + +The actual implementation of the component's external logic is done in an `impl` +block marked as `#[embeddable_as(name)]`. Usually, this `impl` block will be an +implementation of the trait defining the interface of the component. + +> Note: `name` is the name that we’ll be using in the contract to refer to the +> component. It is different than the name of your impl. + +You can also define internal functions that will not be accessible externally, +by simply omitting the `#[embeddable_as(name)]` attribute above the internal +`impl` block. You will be able to use these internal functions inside the +contract you embed the component in, but not interact with it from outside, as +they're not a part of the abi of the contract. + +Functions within these `impl` block expect arguments like `ref self: +ComponentState` (for state-modifying functions) or `self: +@ComponentState` (for view functions). This makes the impl +generic over `TContractState`, allowing us to use this component in any +contract. + +[contract anatomy]: ./ch13-02-anatomy-of-a-simple-contract.md +[contract dispatcher]: ./ch15-02-contract-dispatchers-library-dispatchers-and-system-calls.md + +### Example: an Ownable Component + +> ⚠️ The example shown below has not been audited and is not intended for +> production use. The authors are not responsible for any damages caused by the +> use of this code. + +The interface of the Ownable component, defining the methods available +externally to manage ownership of a contract, would look like this: + +```rust,noplayground +#[starknet::interface] +trait IOwnable { + fn owner(self: @TContractState) -> ContractAddress; + fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress); + fn renounce_ownership(ref self: TContractState); +} +``` + +The component itself is defined as: + +```rust,noplayground +#[starknet::component] +pub mod ownable_component { + use starknet::ContractAddress; + use starknet::get_caller_address; + use super::Errors; + use core::num::traits::Zero; + + #[storage] + struct Storage { + owner: ContractAddress + } + + #[event] + #[derive(Drop, starknet::Event)] + pub enum Event { + OwnershipTransferred: OwnershipTransferred + } + + #[derive(Drop, starknet::Event)] + struct OwnershipTransferred { + previous_owner: ContractAddress, + new_owner: ContractAddress, + } + + #[embeddable_as(Ownable)] + impl OwnableImpl< + TContractState, +HasComponent + > of super::IOwnable> { + fn owner(self: @ComponentState) -> ContractAddress { + self.owner.read() + } + + fn transfer_ownership( + ref self: ComponentState, new_owner: ContractAddress + ) { + assert(!new_owner.is_zero(), Errors::ZERO_ADDRESS_OWNER); + self.assert_only_owner(); + self._transfer_ownership(new_owner); + } + + fn renounce_ownership(ref self: ComponentState) { + self.assert_only_owner(); + self._transfer_ownership(Zero::zero()); + } + } + + #[generate_trait] + pub impl InternalImpl< + TContractState, +HasComponent + > of InternalTrait { + fn initializer(ref self: ComponentState, owner: ContractAddress) { + self._transfer_ownership(owner); + } + + fn assert_only_owner(self: @ComponentState) { + let owner: ContractAddress = self.owner.read(); + let caller: ContractAddress = get_caller_address(); + assert(!caller.is_zero(), Errors::ZERO_ADDRESS_CALLER); + assert(caller == owner, Errors::NOT_OWNER); + } + + fn _transfer_ownership( + ref self: ComponentState, new_owner: ContractAddress + ) { + let previous_owner: ContractAddress = self.owner.read(); + self.owner.write(new_owner); + self + .emit( + OwnershipTransferred { previous_owner: previous_owner, new_owner: new_owner } + ); + } + } +} +``` + +This syntax is actually quite similar to the syntax used for contracts. The only +differences relate to the `#[embeddable_as]` attribute above the impl and the +genericity of the impl block that we will dissect in details. + +As you can see, our component has two `impl` blocks: one corresponding to the +implementation of the interface trait, and one containing methods that should +not be exposed externally and are only meant for internal use. Exposing the +`assert_only_owner` as part of the interface wouldn't make sense, as it's only +meant to be used internally by a contract embedding the component. + +## A Closer Look at the `impl` Block + +```rust,noplayground + #[embeddable_as(Ownable)] + impl OwnableImpl< + TContractState, +HasComponent + > of super::IOwnable> { +``` + +The `#[embeddable_as]` attribute is used to mark the impl as embeddable inside a +contract. It allows us to specify the name of the impl that will be used in the +contract to refer to this component. In this case, the component will be +referred to as `Ownable` in contracts embedding it. + +The implementation itself is generic over `ComponentState`, with +the added restriction that `TContractState` must implement the `HasComponent` +trait. This allows us to use the component in any contract, as long as the +contract implements the `HasComponent` trait. Understanding this mechanism in +details is not required to use components, but if you're curious about the inner +workings, you can read more in the ["Components Under the Hood"][components inner working] section. + +One of the major differences from a regular smart contract is that access to +storage and events is done via the generic `ComponentState` type +and not `ContractState`. Note that while the type is different, accessing +storage or emitting events is done similarly via `self.storage_var_name.read()` +or `self.emit(...).` + +> Note: To avoid the confusion between the embeddable name and the impl name, we +> recommend keeping the suffix `Impl` in the impl name. + +[components inner working]: ./ch16-02-01-under-the-hood.md + +## Migrating a Contract to a Component + +Since both contracts and components share a lot of similarities, it's actually +very easy to migrate from a contract to a component. The only changes required +are: + +- Adding the `#[starknet::component]` attribute to the module. +- Adding the `#[embeddable_as(name)]` attribute to the `impl` block that will be + embedded in another contract. +- Adding generic parameters to the `impl` block: + - Adding `TContractState` as a generic parameter. + - Adding `+HasComponent` as an impl restriction. +- Changing the type of the `self` argument in the functions inside the `impl` + block to `ComponentState` instead of `ContractState`. + +For traits that do not have an explicit definition and are generated using +`#[generate_trait]`, the logic is the same - but the trait is generic over +`TContractState` instead of `ComponentState`, as demonstrated in +the example with the `InternalTrait`. + +## Using Components Inside a Contract + +The major strength of components is how it allows reusing already built +primitives inside your contracts with a restricted amount of boilerplate. To +integrate a component into your contract, you need to: + +1. Declare it with the `component!()` macro, specifying + + 1. The path to the component `path::to::component`. + 2. The name of the variable in your contract's storage referring to this + component's storage (e.g. `ownable`). + 3. The name of the variant in your contract's event enum referring to this + component's events (e.g. `OwnableEvent`). + +2. Add the path to the component's storage and events to the contract's + `Storage` and `Event`. They must match the names provided in step 1 (e.g. + `ownable: ownable_component::Storage` and `OwnableEvent: +ownable_component::Event`). + + The storage variable **MUST** be annotated with the `#[substorage(v0)]` + attribute. + +3. Embed the component's logic defined inside your contract, by instantiating + the component's generic impl with a concrete `ContractState` using an impl + alias. This alias must be annotated with `#[abi(embed_v0)]` to externally + expose the component's functions. + + As you can see, the InternalImpl is not marked with `#[abi(embed_v0)]`. + Indeed, we don't want to expose externally the functions defined in this + impl. However, we might still want to access them internally. + +For example, to embed the `Ownable` component defined above, we would do the +following: + +```rust,noplayground +#[starknet::contract] +mod OwnableCounter { + use listing_01_ownable::component::ownable_component; + + component!(path: ownable_component, storage: ownable, event: OwnableEvent); + + #[abi(embed_v0)] + impl OwnableImpl = ownable_component::Ownable; + + impl OwnableInternalImpl = ownable_component::InternalImpl; + + #[storage] + struct Storage { + counter: u128, + #[substorage(v0)] + ownable: ownable_component::Storage + } + + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + OwnableEvent: ownable_component::Event + } + + + #[abi(embed_v0)] + fn foo(ref self: ContractState) { + self.ownable.assert_only_owner(); + self.counter.write(self.counter.read() + 1); + } +} +``` + +The component's logic is now seamlessly part of the contract! We can interact +with the components functions externally by calling them using the +`IOwnableDispatcher` instantiated with the contract's address. + +```rust +#[starknet::interface] +trait IOwnable { + fn owner(self: @TContractState) -> ContractAddress; + fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress); + fn renounce_ownership(ref self: TContractState); +} +``` + +## Stacking Components for Maximum Composability + +The composability of components really shines when combining multiple of them +together. Each adds its features onto the contract. You can rely on +[Openzeppelin's][OpenZeppelin Cairo Contracts] implementation +of components to quickly plug-in all the common functionalities you need a contract +to have. + +Developers can focus on their core contract logic while relying on battle-tested +and audited components for everything else. + +Components can even [depend][component dependencies] on other components by restricting the +`TContractstate` they're generic on to implement the trait of another component. +Before we dive into this mechanism, let's first look at [how components work under the hood][components inner working]. + + +[OpenZeppelin Cairo Contracts]: https://github.com/OpenZeppelin/cairo-contracts +[component dependencies]: ./ch16-02-02-component-dependencies.md +[components inner working]: ./ch16-02-01-under-the-hood.md +# Components: Under the Hood + +Components provide powerful modularity to Starknet contracts. But how does this +magic actually happen behind the scenes? + +This chapter will dive deep into the compiler internals to explain the +mechanisms that enable component composability. + +## A Primer on Embeddable Impls + +Before digging into components, we need to understand _embeddable impls_. + +An impl of a Starknet interface trait (marked with `#[starknet::interface]`) can +be made embeddable. Embeddable impls can be injected into any contract, adding +new entry points and modifying the ABI of the contract. + +Let's look at an example to see this in action: + +```rust,noplayground +#[starknet::interface] +trait SimpleTrait { + fn ret_4(self: @TContractState) -> u8; +} + +#[starknet::embeddable] +impl SimpleImpl of SimpleTrait { + fn ret_4(self: @TContractState) -> u8 { + 4 + } +} + +#[starknet::contract] +mod simple_contract { + #[storage] + struct Storage {} + + #[abi(embed_v0)] + impl MySimpleImpl = super::SimpleImpl; +} +``` + +By embedding `SimpleImpl`, we externally expose `ret4` in the contract's ABI. + +Now that we’re more familiar with the embedding mechanism, we can now see how +components build on this. + +## Inside Components: Generic Impls + +Recall the impl block syntax used in components: + +```rust,noplayground + #[embeddable_as(Ownable)] + impl OwnableImpl< + TContractState, +HasComponent + > of super::IOwnable> { +``` + +The key points: + +- `OwnableImpl` requires the implementation of the + `HasComponent` trait by the underlying contract, which is + automatically generated with the `component!()` macro when using a component + inside a contract. + + The compiler will generate an impl that wraps any function in `OwnableImpl`, + replacing the `self: ComponentState` argument with `self: +TContractState`, where access to the component state is made via the + `get_component` function in the `HasComponent` trait. + + For each component, the compiler generates a `HasComponent` trait. This trait + defines the interface to bridge between the actual `TContractState` of a + generic contract, and `ComponentState`. + + ```rust,noplayground + // generated per component + trait HasComponent { + fn get_component(self: @TContractState) -> @ComponentState; + fn get_component_mut(ref self: TContractState) -> ComponentState; + fn get_contract(self: @ComponentState) -> @TContractState; + fn get_contract_mut(ref self: ComponentState) -> TContractState; + fn emit>(ref self: ComponentState, event: S); + } + ``` + + In our context `ComponentState` is a type specific to the + ownable component, i.e. it has members based on the storage variables defined + in `ownable_component::Storage`. Moving from the generic `TContractState` to + `ComponentState` will allow us to embed `Ownable` in any + contract that wants to use it. The opposite direction + (`ComponentState` to `ContractState`) is useful for + dependencies (see the `Upgradeable` component depending on an `IOwnable` + implementation example in the [Components dependencies ](./ch16-02-02-component-dependencies.md) section). + + To put it briefly, one should think of an implementation of the above + `HasComponent` as saying: **“Contract whose state T has the upgradeable + component”.** + +- `Ownable` is annotated with the `embeddable_as()` attribute: + + `embeddable_as` is similar to `embeddable`; it only applies to impls of + `starknet::interface` traits and allows embedding this impl in a contract + module. That said, `embeddable_as()` has another role in the context of + components. Eventually, when embedding `OwnableImpl` in some contract, we + expect to get an impl with the following functions: + + ```rust,noplayground + fn owner(self: @TContractState) -> ContractAddress; + fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress); + fn renounce_ownership(ref self: TContractState); + ``` + + Note that while starting with a function receiving the generic type + `ComponentState`, we want to end up with a function receiving + `ContractState`. This is where `embeddable_as()` comes in. To see the + full picture, we need to see what is the impl generated by the compiler due to + the `embeddable_as(Ownable)` annotation: + +```rust,noplayground +#[starknet::embeddable] +impl Ownable< + TContractState, +HasComponent, impl TContractStateDrop: Drop +> of super::IOwnable { + fn owner(self: @TContractState) -> ContractAddress { + let component = HasComponent::get_component(self); + OwnableImpl::owner(component,) + } + + fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress) { + let mut component = HasComponent::get_component_mut(ref self); + OwnableImpl::transfer_ownership(ref component, new_owner,) + } + + fn renounce_ownership(ref self: TContractState) { + let mut component = HasComponent::get_component_mut(ref self); + OwnableImpl::renounce_ownership(ref component,) + } +} +``` + + Note that thanks to having an impl of `HasComponent`, the + compiler was able to wrap our functions in a new impl that doesn’t directly + know about the `ComponentState` type. `Ownable`, whose name we chose when + writing `embeddable_as(Ownable)`, is the impl that we will embed in a contract + that wants ownership. + +## Contract Integration + +We've seen how generic impls enable component reusability. Next let's see how a +contract integrates a component. + +The contract uses an **impl alias** to instantiate the component's generic impl +with the concrete `ContractState` of the contract. + +```rust,noplayground + #[abi(embed_v0)] + impl OwnableImpl = ownable_component::Ownable; + + impl OwnableInternalImpl = ownable_component::InternalImpl; +``` + +The above lines use the Cairo impl embedding mechanism alongside the impl alias +syntax. We’re instantiating the generic `OwnableImpl` with the +concrete type `ContractState`. Recall that `OwnableImpl` has the +`HasComponent` generic impl parameter. An implementation of this +trait is generated by the `component!` macro. + +Note that only the using contract +could have implemented this trait since only it knows about both the contract +state and the component state. + +This glues everything together to inject the component logic into the contract. + +## Key Takeaways + +- Embeddable impls allow injecting components logic into contracts by adding + entry points and modifying the contract ABI. +- The compiler automatically generates a `HasComponent` trait implementation + when a component is used in a contract. This creates a bridge between the + contract's state and the component's state, enabling interaction between the + two. +- Components encapsulate reusable logic in a generic, contract-agnostic way. + Contracts integrate components through impl aliases and access them via the + generated `HasComponent` trait. +- Components build on embeddable impls by defining generic component logic that + can be integrated into any contract wanting to use that component. Impl + aliases instantiate these generic impls with the contract's concrete storage + types. +# Component Dependencies + +Working with components becomes more complex when we try to use one component inside another. As mentioned earlier, a component can only be embedded within a contract, meaning that it's not possible to embed a component within another component. However, this doesn't mean that we can't use one component inside another. In this section, we will see how to use a component as a dependency of another component. + +Consider a component called `OwnableCounter` whose purpose is to create a counter that can only be incremented by its owner. This component can be embedded in any contract, so that any contract that uses it will have a counter that can only be incremented by its owner. + +The first way to implement this is to create a single component that contains both counter and ownership features from within a single component. However, this approach is not recommended: our goal is to minimize the amount of code duplication and take advantage of component reusability. Instead, we can create a new component that _depends_ on the `Ownable` component for the ownership features, and internally defines the logic for the counter. + +Listing 16-1 shows the complete implementation, which we'll break down right after: + +```rust,noplayground +use starknet::ContractAddress; + +#[starknet::interface] +trait IOwnableCounter { + fn get_counter(self: @TContractState) -> u32; + fn increment(ref self: TContractState); + fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress); +} + +#[starknet::component] +mod OwnableCounterComponent { + use listing_03_component_dep::owner::{ownable_component, ownable_component::InternalImpl}; + use starknet::ContractAddress; + + #[storage] + struct Storage { + value: u32 + } + + #[embeddable_as(OwnableCounterImpl)] + impl OwnableCounter< + TContractState, + +HasComponent, + +Drop, + impl Owner: ownable_component::HasComponent + > of super::IOwnableCounter> { + fn get_counter(self: @ComponentState) -> u32 { + self.value.read() + } + + fn increment(ref self: ComponentState) { + let ownable_comp = get_dep_component!(@self, Owner); + ownable_comp.assert_only_owner(); + self.value.write(self.value.read() + 1); + } + + fn transfer_ownership( + ref self: ComponentState, new_owner: ContractAddress + ) { + let mut ownable_comp = get_dep_component_mut!(ref self, Owner); + ownable_comp._transfer_ownership(new_owner); + } + } +} +``` + +Listing 16-1: An OwnableCounter Component + +## Specificities + +### Specifying Dependencies on Another Component + +```rust,noplayground + impl OwnableCounter< + TContractState, + +HasComponent, + +Drop, + impl Owner: ownable_component::HasComponent + > of super::IOwnableCounter> { +``` + +In [chapter 8][cairo traits], we introduced trait bounds, which are used to specify that a generic type must implement a certain trait. In the same way, we can specify that a component depends on another component by restricting the `impl` block to be available only for contracts that contain the required component. +In our case, this is done by adding a restriction `impl Owner: ownable_component::HasComponent`, which indicates that this `impl` block is only available for contracts that contain an implementation of the `ownable_component::HasComponent` trait. This essentially means that the `TContractState' type has access to the ownable component. See [Components under the hood][component impl] for more information. + +Although most of the trait bounds were defined using [anonymous parameters][anonymous generic impl operator], the dependency on the `Ownable` component is defined using a named parameter (here, `Owner`). We will need to use this explicit name when accessing the `Ownable`component within the`impl` block. + +While this mechanism is verbose and may not be easy to approach at first, it is a powerful leverage of the trait system in Cairo. The inner workings of this mechanism are abstracted away from the user, and all you need to know is that when you embed a component in a contract, all other components in the same contract can access it. + +[cairo traits]: ./ch08-02-traits-in-cairo.md +[component impl]: ch16-02-01-under-the-hood.md#inside-components-generic-impls +[anonymous generic impl operator]: ./ch08-01-generic-data-types md#anonymous-generic-implementation-parameter--operator + +### Using the Dependency + +Now that we have made our `impl` depend on the `Ownable` component, we can access its functions, storage, and events within the implementation block. To bring the `Ownable` component into scope, we have two choices, depending on whether we intend to mutate the state of the `Ownable` component or not. +If we want to access the state of the `Ownable` component without mutating it, we use the `get_dep_component!` macro. If we want to mutate the state of the `Ownable` component (for example, change the current owner), we use the `get_dep_component_mut!` macro. +Both macros take two arguments: the first is `self`, either as a snapshot or by reference depending on mutability, representing the state of the component using the dependency, and the second is the component to access. + +```rust,noplayground + fn increment(ref self: ComponentState) { + let ownable_comp = get_dep_component!(@self, Owner); + ownable_comp.assert_only_owner(); + self.value.write(self.value.read() + 1); + } +``` + +In this function, we want to make sure that only the owner can call the `increment` function. We need to use +the `assert_only_owner` function from the `Ownable` component. We'll use the `get_dep_component!` macro which will return a snapshot of the requested component state, and call `assert_only_owner` on it, as a method of that component. + +For the `transfer_ownership` function, we want to mutate that state to change the current owner. We need to use the `get_dep_component_mut!` macro, which will return the requested component state as a mutable reference, and call `transfer_ownership` on it. + +```rust,noplayground + fn transfer_ownership( + ref self: ComponentState, new_owner: ContractAddress + ) { + let mut ownable_comp = get_dep_component_mut!(ref self, Owner); + ownable_comp._transfer_ownership(new_owner); + } +``` + +It works exactly the same as `get_dep_component!` except that we need to pass the state as a `ref` so we can +mutate it to transfer the ownership. +# Testing Components + +Testing components is a bit different than testing contracts. +Contracts need to be tested against a specific state, which can be achieved by either deploying the contract in a test, or by simply getting the `ContractState` object and modifying it in the context of your tests. + +Components are a generic construct, meant to be integrated in contracts, that can't be deployed on their own and don't have a `ContractState` object that we could use. So how do we test them? + +Let's consider that we want to test a very simple component called "Counter", that will allow each contract to have a counter that can be incremented. The component is defined in Listing 16-2: + +```rust, noplayground +#[starknet::component] +pub mod CounterComponent { + #[storage] + struct Storage { + value: u32 + } + + #[embeddable_as(CounterImpl)] + impl Counter< + TContractState, +HasComponent + > of super::ICounter> { + fn get_counter(self: @ComponentState) -> u32 { + self.value.read() + } + + fn increment(ref self: ComponentState) { + self.value.write(self.value.read() + 1); + } + } +} +``` + +Listing 16-2: A simple Counter component + +## Testing the Component by Deploying a Mock Contract + +The easiest way to test a component is to integrate it within a mock contract. This mock contract is only used for testing purposes, and only integrates the component you want to test. This allows you to test the component in the context of a contract, and to use a Dispatcher to call the component's entry points. + +We can define such a mock contract as follows: + +```rust, noplayground +#[starknet::contract] +mod MockContract { + use super::counter::CounterComponent; + + component!(path: CounterComponent, storage: counter, event: CounterEvent); + + #[storage] + struct Storage { + #[substorage(v0)] + counter: CounterComponent::Storage, + } + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + CounterEvent: CounterComponent::Event + } + + #[abi(embed_v0)] + impl CounterImpl = CounterComponent::CounterImpl; +} +``` + +This contract is entirely dedicated to testing the `Counter` component. It embeds the component with the `component!` macro, exposes the component's entry points by annotating the impl aliases with `#[abi(embed_v0)]`. + +We also need to define an interface that will be required to interact externally with this mock contract. + +```rust, noplayground +#[starknet::interface] +pub trait ICounter { + fn get_counter(self: @TContractState) -> u32; + fn increment(ref self: TContractState); +} +``` + +We can now write tests for the component by deploying this mock contract and calling its entry points, as we would with a typical contract. + +```rust, noplayground +use super::MockContract; +use super::counter::{ICounterDispatcher, ICounterDispatcherTrait}; +use starknet::deploy_syscall; +use starknet::SyscallResultTrait; + +fn setup_counter() -> ICounterDispatcher { + let (address, _) = deploy_syscall( + MockContract::TEST_CLASS_HASH.try_into().unwrap(), 0, array![].span(), false + ) + .unwrap_syscall(); + ICounterDispatcher { contract_address: address } +} + +#[test] +fn test_constructor() { + let counter = setup_counter(); + assert_eq!(counter.get_counter(), 0); +} + +#[test] +fn test_increment() { + let counter = setup_counter(); + counter.increment(); + assert_eq!(counter.get_counter(), 1); +} +``` + +## Testing Components Without Deploying a Contract + +In [Components under the hood][components inner working], we saw that components leveraged genericity to define storage and logic that could be embedded in multiple contracts. If a contract embeds a component, a `HasComponent` trait is created in this contract, and the component methods are made available. + +This informs us that if we can provide a concrete `TContractState` that implements the `HasComponent` trait to the `ComponentState` struct, should be able to directly invoke the methods of the component using this concrete `ComponentState` object, without having to deploy a mock. + +Let's see how we can do that by using type aliases. We still need to define a mock contract - let's use the same as above - but this time, we won't need to deploy it. + +First, we need to define a concrete implementation of the generic `ComponentState` type using a type alias. We will use the `MockContract::ContractState` type to do so. + +```rust, noplayground +# use super::counter::{CounterComponent}; +# use super::MockContract; +# use CounterComponent::{CounterImpl}; +# +type TestingState = CounterComponent::ComponentState; + +// You can derive even `Default` on this type alias +impl TestingStateDefault of Default { + fn default() -> TestingState { + CounterComponent::component_state_for_testing() + } +} +# +# #[test] +# fn test_increment() { +# let mut counter: TestingState = Default::default(); +# +# counter.increment(); +# counter.increment(); +# +# assert_eq!(counter.get_counter(), 2); +# } +# +# +``` + +We defined the `TestingState` type as an alias of the `CounterComponent::ComponentState` type. By passing the `MockContract::ContractState` type as a concrete type for `ComponentState`, we aliased a concrete implementation of the `ComponentState` struct to `TestingState`. + +Because `MockContract` embeds `CounterComponent`, the methods of `CounterComponent` defined in the `CounterImpl` block can now be used on a `TestingState` object. + +Now that we have made these methods available, we need to instantiate an object of type `TestingState`, that we will use to test the component. We can do so by calling the `component_state_for_testing` function, which automatically infers that it should return an object of type `TestingState`. + +We can even implement this as part of the `Default` trait, which allows us to return an empty `TestingState` with the `Default::default()` syntax. + +Let's summarize what we've done so far: + +- We defined a mock contract that embeds the component we want to test. +- We defined a concrete implementation of `ComponentState` using a type alias with `MockContract::ContractState`, that we named `TestingState`. +- We defined a function that uses `component_state_for_testing` to return a `TestingState` object. + +We can now write tests for the component by calling its functions directly, without having to deploy a mock contract. This approach is more lightweight than the previous one, and it allows testing internal functions of the component that are not exposed to the outside world trivially. + +```rust, noplayground +# use super::counter::{CounterComponent}; +# use super::MockContract; +# use CounterComponent::{CounterImpl}; +# +# type TestingState = CounterComponent::ComponentState; +# +# // You can derive even `Default` on this type alias +# impl TestingStateDefault of Default { +# fn default() -> TestingState { +# CounterComponent::component_state_for_testing() +# } +# } +# +#[test] +fn test_increment() { + let mut counter: TestingState = Default::default(); + + counter.increment(); + counter.increment(); + + assert_eq!(counter.get_counter(), 2); +} +# +# +``` + +[components inner working]: ./ch16-02-01-under-the-hood.md +# Upgradeable Contracts + +Starknet separates contracts into classes and instances, making it simple to upgrade a contract's logic without affecting its state. + +A contract class is the definition of the semantics of a contract. It includes the entire logic of a contract: the name of the entry points, the addresses of the storage variables, the events that can be emitted, etc. Each class is uniquely identified by its class hash. A class does not have its own storage: it's only a definition of logic. + +Classes are typically identified by a [class hash][class hash doc]. When declaring a class, the network registers it and assigns a unique hash used to identify the class and deploy contract instances from it. + +A contract instance is a deployed contract corresponding to a class, with its own storage. + +Starknet natively supports upgradeable contracts through the `replace_class_syscall` [system call][syscalls doc], enabling simple contract upgrades without affecting the contract's state. + +[class hash doc]: https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/class-hash +[syscalls doc]: https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/system-calls-cairo1/ + +## Upgrading Contracts + +To upgrade a contract, expose an entry point that executes `replace_class_syscall` with the new class hash as an argument: + +```rust,noplayground +use starknet::{ClassHash, syscalls}; +use starknet::class_hash::class_hash_const; +use core::num::traits::Zero; + +fn _upgrade(new_class_hash: ClassHash) { + assert(!new_class_hash.is_zero(), 'Class hash cannot be zero'); + syscalls::replace_class_syscall(new_class_hash).unwrap(); +} +``` + +Listing 16-3: Exposing `replace_class_syscall` to update the contract's class + +> Note: Thoroughly review changes and potential impacts before upgrading, as it's a delicate procedure with security implications. Don't allow arbitrary addresses to upgrade your contract. + +## Upgradeable Component + +OpenZeppelin Contracts for Cairo provides the `Upgradeable` component that can be embedded into your contract to make it upgradeable. This component is a simple way to add upgradeability to your contract while relying on an audited library. It can be combined with the `Ownable` component to restrict the upgradeability to a single address, so that the contract owner has the exclusive right to upgrade the contract. + +```rust,noplayground +#[starknet::contract] +mod UpgradeableContract { + use openzeppelin::access::ownable::OwnableComponent; + use openzeppelin::upgrades::UpgradeableComponent; + use openzeppelin::upgrades::interface::IUpgradeable; + use starknet::ClassHash; + use starknet::ContractAddress; + + component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); + component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent); + + /// Ownable + #[abi(embed_v0)] + impl OwnableImpl = OwnableComponent::OwnableImpl; + impl OwnableInternalImpl = OwnableComponent::InternalImpl; + + /// Upgradeable + impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl; + + #[storage] + struct Storage { + #[substorage(v0)] + ownable: OwnableComponent::Storage, + #[substorage(v0)] + upgradeable: UpgradeableComponent::Storage + } + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + #[flat] + OwnableEvent: OwnableComponent::Event, + #[flat] + UpgradeableEvent: UpgradeableComponent::Event + } + + #[constructor] + fn constructor(ref self: ContractState, owner: ContractAddress) { + self.ownable.initializer(owner); + } + + #[abi(embed_v0)] + impl UpgradeableImpl of IUpgradeable { + fn upgrade(ref self: ContractState, new_class_hash: ClassHash) { + // This function can only be called by the owner + self.ownable.assert_only_owner(); + + // Replace the class hash upgrading the contract + self.upgradeable._upgrade(new_class_hash); + } + } +} +``` + +Listing 16-4 Integrating OpenZeppelin's Upgradeable component in a contract + +For more information, please refer to the [OpenZeppelin docs API reference][oz upgradeability api]. + +[oz upgradeability api]: https://docs.openzeppelin.com/contracts-cairo/0.9.0/api/upgrades +# L1-L2 Messaging + +A crucial feature of a Layer 2 is its ability to interact with Layer 1. + +Starknet has its own `L1-L2` messaging system, which is different from its consensus mechanism and the submission of state updates on L1. Messaging is a way for smart-contracts on L1 to interact with smart-contracts on L2 (or the other way around), allowing us to do "cross-chain" transactions. For example, we can do some computations on a chain and use the result of this computation on the other chain. + +Bridges on Starknet all use `L1-L2` messaging. Let's say that you want to bridge tokens from Ethereum to Starknet. You will simply have to deposit your tokens in the L1 bridge contract, which will automatically trigger the minting of the same token on L2. Another good use case for `L1-L2` messaging would be [DeFi pooling][defi pooling doc]. + +On Starknet, it's important to note that the messaging system is **asynchronous** and **asymmetric**. + +- **Asynchronous**: this means that in your contract code (being Solidity or Cairo), you can't wait the result of the message being sent on the other chain within your contract code execution. +- **Asymmetric**: sending a message from Ethereum to Starknet (`L1->L2`) is fully automated by the Starknet sequencer, which means that the message is being automatically delivered to the target contract on L2. However, when sending a message from Starknet to Ethereum (`L2->L1`), only the hash of the message is sent on L1 by the Starknet sequencer. You must then consume the message manually via a transaction on L1. + +Let's dive into the details. + +[defi pooling doc]: https://starkware.co/resource/defi-pooling/ + +## The StarknetMessaging Contract + +The crucial component of the `L1-L2` Messaging system is the [`StarknetCore`][starknetcore etherscan] contract. It is a set of Solidity contracts deployed on Ethereum that allows Starknet to function properly. One of the contracts of `StarknetCore` is called `StarknetMessaging` and it is the contract responsible for passing messages between Starknet and Ethereum. `StarknetMessaging` follows an [interface][IStarknetMessaging] with functions allowing to send message to L2, receiving messages on L1 from L2 and canceling messages. + +```js +interface IStarknetMessaging is IStarknetMessagingEvents { + + function sendMessageToL2( + uint256 toAddress, + uint256 selector, + uint256[] calldata payload + ) external returns (bytes32); + + function consumeMessageFromL2(uint256 fromAddress, uint256[] calldata payload) + external + returns (bytes32); + + function startL1ToL2MessageCancellation( + uint256 toAddress, + uint256 selector, + uint256[] calldata payload, + uint256 nonce + ) external; + + function cancelL1ToL2Message( + uint256 toAddress, + uint256 selector, + uint256[] calldata payload, + uint256 nonce + ) external; +} +``` + + Starknet messaging contract interface + +In the case of `L1->L2` messages, the Starknet sequencer is constantly listening to the logs emitted by the `StarknetMessaging` contract on Ethereum. +Once a message is detected in a log, the sequencer prepares and executes a `L1HandlerTransaction` to call the function on the target L2 contract. This takes up to 1-2 minutes to be done (few seconds for ethereum block to be mined, and then the sequencer must build and execute the transaction). + +`L2->L1` messages are prepared by contracts execution on L2 and are part of the block produced. When the sequencer produces a block, it sends the hash of each message prepared by contracts execution +to the `StarknetCore` contract on L1, where they can then be consumed once the block they belong to is proven and verified on Ethereum (which for now is around 3-4 hours). + +[starknetcore etherscan]: https://etherscan.io/address/0xc662c410C0ECf747543f5bA90660f6ABeBD9C8c4 +[IStarknetMessaging]: https://github.com/starkware-libs/cairo-lang/blob/4e233516f52477ad158bc81a86ec2760471c1b65/src/starkware/starknet/eth/IStarknetMessaging.sol#L6 + +## Sending Messages from Ethereum to Starknet + +If you want to send messages from Ethereum to Starknet, your Solidity contracts must call the `sendMessageToL2` function of the `StarknetMessaging` contract. To receive these messages on Starknet, you will need to annotate functions that can be called from L1 with the `#[l1_handler]` attribute. + +Let's take a simple contract taken from [this tutorial][messaging contract] where we want to send a message to Starknet. +The `_snMessaging` is a state variable already initialized with the address of the `StarknetMessaging` contract. You can check all Starknet contract and sequencer addresses [here][starknet addresses]. + +```js +// Sends a message on Starknet with a single felt. +function sendMessageFelt( + uint256 contractAddress, + uint256 selector, + uint256 myFelt +) + external + payable +{ + // We "serialize" here the felt into a payload, which is an array of uint256. + uint256[] memory payload = new uint256[](1); + payload[0] = myFelt; + + // msg.value must always be >= 20_000 wei. + _snMessaging.sendMessageToL2{value: msg.value}( + contractAddress, + selector, + payload + ); +} +``` + +The function sends a message with a single felt value to the `StarknetMessaging` contract. +Please note that if you want to send more complex data you can. Just be aware that your Cairo contract will only understand `felt252` data type. So you must ensure that the serialization of your data into the `uint256` array follow the Cairo serialization scheme. + +It's important to note that we have `{value: msg.value}`. In fact, the minimum value we've to send here is `20k wei`, due to the fact that the `StarknetMessaging` contract will register +the hash of our message in the storage of Ethereum. + +In addition to those `20k wei`, since the `L1HandlerTransaction` executed by the sequencer is not tied to any account (the message originates from L1), you must also ensure +that you pay enough fees on L1 for your message to be deserialized and processed on L2. + +The fees of the `L1HandlerTransaction` are computed in a regular manner as it would be done for an `Invoke` transaction. For this, you can profile +the gas consumption using `starkli` or `snforge` to estimate the cost of your message execution. + +The signature of the `sendMessageToL2` is: + +```js +function sendMessageToL2( + uint256 toAddress, + uint256 selector, + uint256[] calldata payload + ) external override returns (bytes32); +``` + +The parameters are as follows: + +- `toAddress`: The contract address on L2 that will be called. +- `selector`: The selector of the function of this contract at `toAddress`. This selector (function) must have the `#[l1_handler]` attribute to be callable. +- `payload`: The payload is always an array of `felt252` (which are represented by `uint256` in Solidity). For this reason we've inserted the input `myFelt` into the array. + This is why we need to insert the input data into an array. + +On the Starknet side, to receive this message, we have: + +```rust,noplayground + #[l1_handler] + fn msg_handler_felt(ref self: ContractState, from_address: felt252, my_felt: felt252) { + assert(from_address == self.allowed_message_sender.read(), 'Invalid message sender'); + + // You can now use the data, automatically deserialized from the message payload. + assert(my_felt == 123, 'Invalid value'); + } +``` + +We need to add the `#[l1_handler]` attribute to our function. L1 handlers are special functions that can only be executed by a `L1HandlerTransaction`. There is nothing particular to do to receive transactions from L1, as the message is relayed by the sequencer automatically. In your `#[l1_handler]` functions, it is important to verify the sender of the L1 message to ensure that our contract can only receive messages from a trusted L1 contract. + +[messaging contract]: https://github.com/glihm/starknet-messaging-dev/blob/main/solidity/src/ContractMsg.sol +[starknet addresses]: https://docs.starknet.io/documentation/tools/important_addresses/ + +## Sending Messages from Starknet to Ethereum + +When sending messages from Starknet to Ethereum, you will have to use the `send_message_to_l1` syscall in your Cairo contracts. This syscall allows you to send messages to the `StarknetMessaging` contract on L1. Unlike `L1->L2` messages, `L2->L1` messages must be consumed manually, which means that you will need your Solidity contract to call the `consumeMessageFromL2` function of the `StarknetMessaging` contract explicitly in order to consume the message. + +To send a message from L2 to L1, what we would do on Starknet is: + +```rust,noplayground + fn send_message_felt(ref self: ContractState, to_address: EthAddress, my_felt: felt252) { + // Note here, we "serialize" my_felt, as the payload must be + // a `Span`. + syscalls::send_message_to_l1_syscall(to_address.into(), array![my_felt].span()) + .unwrap(); + } +``` + +We simply build the payload and pass it, along with the L1 contract address, to the syscall function. + +On L1, the important part is to build the same payload sent by the L2. Then you call `consumeMessageFromL2` in you Solidity contract by passing the L2 contract address and the payload. Please be aware that the L2 contract address expected by the `consumeMessageFromL2` is the address of the contract that sends the message on the L2 by calling `send_message_to_l1_syscall`. + +```js +function consumeMessageFelt( + uint256 fromAddress, + uint256[] calldata payload +) + external +{ + let messageHash = _snMessaging.consumeMessageFromL2(fromAddress, payload); + + // You can use the message hash if you want here. + + // We expect the payload to contain only a felt252 value (which is a uint256 in Solidity). + require(payload.length == 1, "Invalid payload"); + + uint256 my_felt = payload[0]; + + // From here, you can safely use `my_felt` as the message has been verified by StarknetMessaging. + require(my_felt > 0, "Invalid value"); +} +``` + +As you can see, in this context we don't have to verify which contract from L2 is sending the message (as we do on the L2 to verify which contract from L1 is sending the message). But we are actually using the `consumeMessageFromL2` of the `StarknetCore` contract to validate the inputs (the contract address on L2 and the payload) to ensure we are only consuming valid messages. + +> **Note:** The `consumeMessageFromL2` function of the `StarknetCore` contract is expected to be called from a Solidity contract, and not directly on the `StarknetCore` contract. The reason of that is because the `StarknetCore` contract is using `msg.sender` to actually compute the hash of the message. And this `msg.sender` must correspond to the `to_address` field that is given to the function `send_message_to_l1_syscall` that is called on Starknet. + +It is important to remember that on L1 we are sending a payload of `uint256`, but the basic data type on Starknet is `felt252`; however, `felt252` are approximately 4 bits smaller than `uint256`. So we have to pay attention to the values contained in the payload of the messages we are sending. If, on L1, we build a message with values above the maximum `felt252`, the message will be stuck and never consumed on L2. + +## Cairo Serde + +Before sending messages between L1 and L2, you must remember that Starknet contracts, written in Cairo, can only understand serialized data. And serialized data is always an array of `felt252`. +In Solidity we have `uint256` type, and `felt252` are approximately 4 bits smaller than `uint256`. So we have to pay attention to the values contained in the payload of the messages we are sending. +If, on L1, we build a message with values above the maximum `felt252`, the message will be stuck and never consumed on L2. + +So for instance, an actual `uint256` value in Cairo is represented by a struct like: + +```rust,does_not_compile +struct u256 { + low: u128, + high: u128, +} +``` + +which will be serialized as **TWO** felts, one for the `low`, and one for the `high`. This means that to send only one `u256` to Cairo, you'll need to send a payload from L1 with **TWO** values. + +```js +uint256[] memory payload = new uint256[](2); +// Let's send the value 1 as a u256 in cairo: low = 1, high = 0. +payload[0] = 1; +payload[1] = 0; +``` + +If you want to learn more about the messaging mechanism, you can visit the [Starknet documentation][starknet messaging doc]. + +You can also find a [detailed guide here][glihm messaging guide] to test the messaging system locally. + +[starknet messaging doc]: https://docs.starknet.io/documentation/architecture_and_concepts/Network_Architecture/messaging-mechanism/ +[glihm messaging guide]: https://github.com/glihm/starknet-messaging-dev +# Price Feeds + +Price feeds enabled by an oracle serve as a bridge between real-world data feed and the blockchain. They provide real time pricing data that is aggregated from multiple trusted external sources ( e.g. crypto exchanges, financial data providers, etc. ) to the blockchain network. + +For the example in this book section, we will use Pragma Oracle to read the price feed for `ETH/USD` asset pair and also showcase a mini application that utilizes this feed. + +[Pragma Oracle](https://www.pragma.build/) is a leading zero knowledge oracle that provides access to off-chain data on Starknet blockchain in a verifiable way. + +## Add Pragma as a Project Dependency + +To get started with integrating Pragma on your Cairo smart contract for price feed data, edit your project's `Scarb.toml` file to include the path to use Pragma. + +```toml +[dependencies] +pragma_lib = { git = "https://github.com/astraly-labs/pragma-lib" } +``` + +## Creating a Price Feed Contract + +After adding the required dependencies for your project, you'll need to define a contract interface that includes the required pragma price feed entry point. + +### Contract Interface + +```rust,noplayground +#[starknet::interface] +pub trait IPriceFeedExample { + fn buy_item(ref self: TContractState); + fn get_asset_price(self: @TContractState, asset_id: felt252) -> u128; +} +``` + +Of the two public functions exposed in the `IPriceFeedExample`, the one necessary to interact with the pragma price feed oracle is the `get_asset_price` function, a view function that takes in the `asset_id` argument and returns a `u128` value. + +### Pragma Dependency Import to Contract + +```rust,noplayground + use pragma_lib::abi::{IPragmaABIDispatcher, IPragmaABIDispatcherTrait}; + use pragma_lib::types::{DataType, PragmaPricesResponse}; +``` + +The snippet above shows the necessary imports you need to add to your contract module in order to interact with the Pragma oracle. + +### Required Price Feed Function Impl in Contract + +```rust,noplayground + fn get_asset_price(self: @ContractState, asset_id: felt252) -> u128 { + // Retrieve the oracle dispatcher + let oracle_dispatcher = IPragmaABIDispatcher { + contract_address: self.pragma_contract.read() + }; + + // Call the Oracle contract, for a spot entry + let output: PragmaPricesResponse = oracle_dispatcher + .get_data_median(DataType::SpotEntry(asset_id)); + + return output.price; + } +``` + +The `get_asset_price` function is responsible for retrieving the price of the asset specified by the `asset_id` argument from Pragma Oracle. The `get_data_median` method is called from the `IPragmaDispatcher` instance by passing the `DataType::SpotEntry(asset_id)` as an argument and its output is assigned to a variable named `output` of type `PragmaPricesResponse`. Finally, the function returns the price of the requested asset as a `u128`. + +## Example Application Using Pragma Price Feed + +```rust,noplayground +#[starknet::contract] +mod PriceFeedExample { + use super::{ContractAddress, IPriceFeedExample}; + use pragma_lib::abi::{IPragmaABIDispatcher, IPragmaABIDispatcherTrait}; + use pragma_lib::types::{DataType, PragmaPricesResponse}; + use openzeppelin::token::erc20::interface::{ERC20ABIDispatcher, ERC20ABIDispatcherTrait}; + use starknet::contract_address::contract_address_const; + use starknet::{get_caller_address}; + + const ETH_USD: felt252 = 19514442401534788; + const EIGHT_DECIMAL_FACTOR: u256 = 100000000; + + #[storage] + struct Storage { + pragma_contract: ContractAddress, + product_price_in_usd: u256, + } + + #[constructor] + fn constructor(ref self: ContractState, pragma_contract: ContractAddress) { + self.pragma_contract.write(pragma_contract); + self.product_price_in_usd.write(100); + } + + #[abi(embed_v0)] + impl PriceFeedExampleImpl of IPriceFeedExample { + fn buy_item(ref self: ContractState) { + let caller_address = get_caller_address(); + let eth_price = self.get_asset_price(ETH_USD).into(); + let product_price = self.product_price_in_usd.read(); + + // Calculate the amount of ETH needed + let eth_needed = product_price * EIGHT_DECIMAL_FACTOR / eth_price; + + let eth_dispatcher = ERC20ABIDispatcher { + contract_address: contract_address_const::< + 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 + >() // ETH Contract Address + }; + + // Transfer the ETH to the caller + eth_dispatcher + .transfer_from( + caller_address, + contract_address_const::< + 0x0237726d12d3c7581156e141c1b132f2db9acf788296a0e6e4e9d0ef27d092a2 + >(), + eth_needed + ); + } + + fn get_asset_price(self: @ContractState, asset_id: felt252) -> u128 { + // Retrieve the oracle dispatcher + let oracle_dispatcher = IPragmaABIDispatcher { + contract_address: self.pragma_contract.read() + }; + + // Call the Oracle contract, for a spot entry + let output: PragmaPricesResponse = oracle_dispatcher + .get_data_median(DataType::SpotEntry(asset_id)); + + return output.price; + } + } +} +``` + +> Note: Pragma returns the value of different token pairs using the decimal factor of 6 or 8. You can convert the value to the required decimal factor by dividing the value by \\( {10^{n}} \\), where `n` is the decimal factor. + +The code above is an example implementation of an applications consuming a price feed from the Pragma oracle. The contract imports necessary modules and interfaces, including the `IPragmaABIDispatcher` for interacting with the Pragma oracle contract and the `ERC20ABIDispatcher` for interacting with the ETH ERC20 token contract. + +The contract has a `const` that stores the token pair ID of `ETH/USD`, and a `Storage` struct that holds two fields `pragma_contract` and `product_price_in_usd`. The constructor function initializes the `pragma_contract` address and sets the `product_price_in_usd` to 100. + +The `buy_item` function is the main entry point for a user to purchase an item. It retrieves the caller's address. It calls the `get_asset_price` function to get the current price of ETH in USD using the `ETH_USD` asset ID. It calculates the amount of ETH needed to buy the product based on the product price in USD at the corresponding ETH price. It then checks if the caller has enough ETH by calling the `balance_of` method on the ERC20 ETH contract. If the caller has enough ETH, it calls the `transfer_from` method of the `eth_dispatcher` instance to transfer the required amount of ETH from the caller to another contract address. + +The `get_asset_price` function is the entry point to interact with the Pragma oracle and has been explained in the section above. + +You can get a detailed guide on consuming data using Pragma price feeds [here](https://docs.pragma.build/Resources/Cairo%201/data-feeds/consuming-data). +# Randomness + +Since all blockchains are fundamentally deterministic and most are public ledgers, generating truly unpredictatable randomness on-chain presents a challenge. This randomness is crucial for fair outcomes in gaming, lotteries, and unique generation of NFTs. To address this, verifiable random functions (VRFs) provided by oracles offer a solution. VRFs guarantee that the randomness can't be predicted or tampered with, ensuring trust and transparency in these applications. + +## Overview on VRFs + +Pseudo-random but secure: VRFs use a secret key and a nonce (a unique input) to generate an output that appears random. While technically 'pseudo-random', it's practically impossible for another party to predict the outcome without knowing the secret key. + +Verifiable output: VRFs produce not only the random number but also a proof that anyone can use to independently verify that the result was generated correctly according to the function's parameters. + +## Generating Randomness with Pragma + +[Pragma](https://www.pragma.build/), an oracle on Starknet provides a solution for generating random numbers using VRFs. +Let's dive into how to use Pragma VRF to generate a random number in a simple dice game contract. + +### Add Pragma as a Dependency + +Edit your cairo project's `Scarb.toml` file to include the path to use Pragma. + +```toml +[dependencies] +pragma_lib = { git = "https://github.com/astraly-labs/pragma-lib" } +``` + +### Interface + +```rust,noplayground +use starknet::ContractAddress; + +#[starknet::interface] +pub trait IPragmaVRF { + fn get_last_random_number(self: @TContractState) -> felt252; + fn request_randomness_from_pragma( + ref self: TContractState, + seed: u64, + callback_address: ContractAddress, + callback_fee_limit: u128, + publish_delay: u64, + num_words: u64, + calldata: Array + ); + fn receive_random_words( + ref self: TContractState, + requester_address: ContractAddress, + request_id: u64, + random_words: Span, + calldata: Array + ); + fn withdraw_extra_fee_fund(ref self: TContractState, receiver: ContractAddress); +} + +#[starknet::interface] +pub trait IDiceGame { + fn guess(ref self: TContractState, guess: u8); + fn toggle_play_window(ref self: TContractState); + fn get_game_window(self: @TContractState) -> bool; + fn process_game_winners(ref self: TContractState); +} +``` + +Listing 16-5 shows a contract interfaces for Pragma VRF and a simple dice game. + +### Description of Key IPragmaVRF Entrypoints and Their Inputs + +The function `request_randomness_from_pragma` initiates a request for verifiable randomness from the Pragma oracle. It does this by emitting an event that triggers the following actions off-chain: + +1. Randomness generation: The oracle generates random values and a corresponding proof. +2. On-chain submission: The oracle submits the generated randomness and proof back to the blockchain via the `receive_random_words` callback function. + +#### `request_randomness_from_pragma` Inputs + +1. `seed`: A value used to initialize the randomness generation process. This should be unique to ensure unpredictable results. +2. `callback_address`: The contract address where the `receive_random_words` function will be called to deliver the generated randomness. It is typically the address of your deployed contract implementing Pragma VRF. +3. `callback_fee_limit`: The maximum amount of gas you're willing to spend on executing the `receive_random_words` callback function. +4. `publish_delay`: The minimum delay (in blocks) between requesting randomness and the oracle fulfilling the request. +5. `num_words`: The number of random values (each represented as a `felt252`) you want to receive in a single callback. +6. `calldata`: Additional data you want to pass to the `receive_random_words` callback function. + +#### `receive_randomn_words` Inputs + +1. `requester_address`: The contract address that initiated the randomness request. +2. `request_id`: A unique identifier assigned to the randomness request. +3. `random_words`: An array (span) of the generated random values (represented as `felt252`). +4. `calldata`: Additional data passed along with the initial randomness request. + +### Dice Game Contract + +This dice game contract allows players to guess a number between 1 & 6 during an active game window. The contract owner then has the ability to toggle the game window to disable new guesses from players. To determine the winning number, the contract owner calls the `request_randomness_from_pragma` function to request a random number from the Pragma VRF oracle. Once the random number is received through the `receive_random_words` callback function, it is stored in the `last_random_number` storage variable. Each player has to call `process_game_winners` function to determine if they have won or lost. The `last_random_number` generated is then reduced to a number between 1 & 6, and compared to the guesses of the players stored in the `user_guesses` mapping, which leads to the emission of an event `GameWinner` or `GameLost`. + +```rust,noplayground +#[starknet::contract] +mod DiceGame { + use starknet::{ + ContractAddress, contract_address_const, get_block_number, get_caller_address, + get_contract_address + }; + use pragma_lib::abi::{IRandomnessDispatcher, IRandomnessDispatcherTrait}; + use openzeppelin::token::erc20::interface::{ERC20ABIDispatcher, ERC20ABIDispatcherTrait}; + use openzeppelin::access::ownable::OwnableComponent; + + component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); + + #[abi(embed_v0)] + impl OwnableImpl = OwnableComponent::OwnableImpl; + impl InternalImpl = OwnableComponent::InternalImpl; + + #[storage] + struct Storage { + user_guesses: LegacyMap, + pragma_vrf_contract_address: ContractAddress, + game_window: bool, + min_block_number_storage: u64, + last_random_number: felt252, + #[substorage(v0)] + ownable: OwnableComponent::Storage + } + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + GameWinner: ResultAnnouncement, + GameLost: ResultAnnouncement, + #[flat] + OwnableEvent: OwnableComponent::Event + } + + #[derive(Drop, starknet::Event)] + struct ResultAnnouncement { + caller: ContractAddress, + guess: u8, + random_number: u256 + } + + #[constructor] + fn constructor( + ref self: ContractState, + pragma_vrf_contract_address: ContractAddress, + owner: ContractAddress + ) { + self.ownable.initializer(owner); + self.pragma_vrf_contract_address.write(pragma_vrf_contract_address); + self.game_window.write(true); + } + + #[abi(embed_v0)] + impl DiceGame of super::IDiceGame { + fn guess(ref self: ContractState, guess: u8) { + assert(self.game_window.read(), 'GAME_INACTIVE'); + assert(guess >= 1 && guess <= 6, 'INVALID_GUESS'); + + let caller = get_caller_address(); + self.user_guesses.write(caller, guess); + } + + fn toggle_play_window(ref self: ContractState) { + self.ownable.assert_only_owner(); + + let current: bool = self.game_window.read(); + self.game_window.write(!current); + } + + fn get_game_window(self: @ContractState) -> bool { + self.game_window.read() + } + + fn process_game_winners(ref self: ContractState) { + assert(!self.game_window.read(), 'GAME_ACTIVE'); + assert(self.last_random_number.read() != 0, 'NO_RANDOM_NUMBER_YET'); + + let caller = get_caller_address(); + let user_guess: u8 = self.user_guesses.read(caller); + let reduced_random_number: u256 = self.last_random_number.read().into() % 6 + 1; + + if user_guess == reduced_random_number.try_into().unwrap() { + self + .emit( + Event::GameWinner( + ResultAnnouncement { + caller: caller, + guess: user_guess, + random_number: reduced_random_number + } + ) + ); + } else { + self + .emit( + Event::GameLost( + ResultAnnouncement { + caller: caller, + guess: user_guess, + random_number: reduced_random_number + } + ) + ); + } + } + } + + #[abi(embed_v0)] + impl PragmaVRFOracle of super::IPragmaVRF { + fn get_last_random_number(self: @ContractState) -> felt252 { + let last_random = self.last_random_number.read(); + last_random + } + + fn request_randomness_from_pragma( + ref self: ContractState, + seed: u64, + callback_address: ContractAddress, + callback_fee_limit: u128, + publish_delay: u64, + num_words: u64, + calldata: Array + ) { + self.ownable.assert_only_owner(); + + let randomness_contract_address = self.pragma_vrf_contract_address.read(); + let randomness_dispatcher = IRandomnessDispatcher { + contract_address: randomness_contract_address + }; + + // Approve the randomness contract to transfer the callback fee + // You would need to send some ETH to this contract first to cover the fees + let eth_dispatcher = ERC20ABIDispatcher { + contract_address: contract_address_const::< + 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 + >() // ETH Contract Address + }; + eth_dispatcher + .approve( + randomness_contract_address, + (callback_fee_limit + callback_fee_limit / 5).into() + ); + + // Request the randomness + randomness_dispatcher + .request_random( + seed, callback_address, callback_fee_limit, publish_delay, num_words, calldata + ); + + let current_block_number = get_block_number(); + self.min_block_number_storage.write(current_block_number + publish_delay); + } + + fn receive_random_words( + ref self: ContractState, + requester_address: ContractAddress, + request_id: u64, + random_words: Span, + calldata: Array + ) { + // Have to make sure that the caller is the Pragma Randomness Oracle contract + let caller_address = get_caller_address(); + assert( + caller_address == self.pragma_vrf_contract_address.read(), + 'caller not randomness contract' + ); + // and that the current block is within publish_delay of the request block + let current_block_number = get_block_number(); + let min_block_number = self.min_block_number_storage.read(); + assert(min_block_number <= current_block_number, 'block number issue'); + + let random_word = *random_words.at(0); + self.last_random_number.write(random_word); + } + + fn withdraw_extra_fee_fund(ref self: ContractState, receiver: ContractAddress) { + self.ownable.assert_only_owner(); + let eth_dispatcher = ERC20ABIDispatcher { + contract_address: contract_address_const::< + 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 + >() // ETH Contract Address + }; + let balance = eth_dispatcher.balance_of(get_contract_address()); + eth_dispatcher.transfer(receiver, balance); + } + } +} +``` + +Listing 16-6: Simple Dice Game Contract using Pragma VRF. + +#### NB: Fund Your Contract After Deployment to Utilize Pragma VRF + +After deploying your contract that includes Pragma VRF functionalities, ensure it holds sufficient ETH to cover the expenses related to requesting random values. Pragma VRF requires payment for both generating the random numbers and executing the callback function defined in your contract. + +For more information, please refer to the [Pragma](https://docs.pragma.build/Resources/Cairo%201/randomness/randomness) docs. +# Oracle Interactions + +This section focuses on the concept of bringing off-chain data to the Starknet blockchain using oracles. Oracles are third-party services that serve as intermediaries, securely transmitting external data, such as asset prices, weather information, or other real-world data, to blockchains and smart contracts. It also provides practical examples and code snippets demonstrating how developers can interact with a specific oracle named Pragma on Starknet network, covering topics like querying and handling price data, and verifiable random function (VRF) to generate random numbers. +# Other Examples + +This section contains additional examples of Starknet smart contracts, utilizing various features of the Cairo programming language. Your contributions are welcome and encouraged, as we aim to gather as many diverse examples as possible. +# Deploying and Interacting with a Voting contract + +The **`Vote`** contract in Starknet begins by registering voters through the contract's constructor. Three voters are initialized at this stage, and their addresses are passed to an internal function **`_register_voters`**. This function adds the voters to the contract's state, marking them as registered and eligible to vote. + +Within the contract, the constants **`YES`** and **`NO`** are defined to represent the voting options (1 and 0, respectively). These constants facilitate the voting process by standardizing the input values. + +Once registered, a voter is able to cast a vote using the **`vote`** function, selecting either the 1 (YES) or 0 (NO) as their vote. When voting, the state of the contract is updated, recording the vote and marking the voter as having voted. This ensures that the voter is not able to cast a vote again within the same proposal. The casting of a vote triggers the **`VoteCast`** event, logging the action. + +The contract also monitors unauthorized voting attempts. If an unauthorized action is detected, such as a non-registered user attempting to vote or a user trying to vote again, the **`UnauthorizedAttempt`** event is emitted. + +Together, these functions, states, constants, and events create a structured voting system, managing the lifecycle of a vote from registration to casting, event logging, and result retrieval within the Starknet environment. Constants like **`YES`** and **`NO`** help streamline the voting process, while events play a vital role in ensuring transparency and traceability. + +Listing 16-7 shows the `Vote` contract in detail: + +```rust,noplayground +/// @dev Core Library Imports for the Traits outside the Starknet Contract +use starknet::ContractAddress; + +/// @dev Trait defining the functions that can be implemented or called by the Starknet Contract +#[starknet::interface] +trait VoteTrait { + /// @dev Function that returns the current vote status + fn get_vote_status(self: @T) -> (u8, u8, u8, u8); + /// @dev Function that checks if the user at the specified address is allowed to vote + fn voter_can_vote(self: @T, user_address: ContractAddress) -> bool; + /// @dev Function that checks if the specified address is registered as a voter + fn is_voter_registered(self: @T, address: ContractAddress) -> bool; + /// @dev Function that allows a user to vote + fn vote(ref self: T, vote: u8); +} + +/// @dev Starknet Contract allowing three registered voters to vote on a proposal +#[starknet::contract] +mod Vote { + use starknet::ContractAddress; + use starknet::get_caller_address; + + const YES: u8 = 1_u8; + const NO: u8 = 0_u8; + + /// @dev Structure that stores vote counts and voter states + #[storage] + struct Storage { + yes_votes: u8, + no_votes: u8, + can_vote: LegacyMap::, + registered_voter: LegacyMap::, + } + + /// @dev Contract constructor initializing the contract with a list of registered voters and 0 vote count + #[constructor] + fn constructor( + ref self: ContractState, + voter_1: ContractAddress, + voter_2: ContractAddress, + voter_3: ContractAddress + ) { + // Register all voters by calling the _register_voters function + self._register_voters(voter_1, voter_2, voter_3); + + // Initialize the vote count to 0 + self.yes_votes.write(0_u8); + self.no_votes.write(0_u8); + } + + /// @dev Event that gets emitted when a vote is cast + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + VoteCast: VoteCast, + UnauthorizedAttempt: UnauthorizedAttempt, + } + + /// @dev Represents a vote that was cast + #[derive(Drop, starknet::Event)] + struct VoteCast { + voter: ContractAddress, + vote: u8, + } + + /// @dev Represents an unauthorized attempt to vote + #[derive(Drop, starknet::Event)] + struct UnauthorizedAttempt { + unauthorized_address: ContractAddress, + } + + /// @dev Implementation of VoteTrait for ContractState + #[abi(embed_v0)] + impl VoteImpl of super::VoteTrait { + /// @dev Returns the voting results + fn get_vote_status(self: @ContractState) -> (u8, u8, u8, u8) { + let (n_yes, n_no) = self._get_voting_result(); + let (yes_percentage, no_percentage) = self._get_voting_result_in_percentage(); + (n_yes, n_no, yes_percentage, no_percentage) + } + + /// @dev Check whether a voter is allowed to vote + fn voter_can_vote(self: @ContractState, user_address: ContractAddress) -> bool { + self.can_vote.read(user_address) + } + + /// @dev Check whether an address is registered as a voter + fn is_voter_registered(self: @ContractState, address: ContractAddress) -> bool { + self.registered_voter.read(address) + } + + /// @dev Submit a vote + fn vote(ref self: ContractState, vote: u8) { + assert!(vote == NO || vote == YES, "VOTE_0_OR_1"); + let caller: ContractAddress = get_caller_address(); + self._assert_allowed(caller); + self.can_vote.write(caller, false); + + if (vote == NO) { + self.no_votes.write(self.no_votes.read() + 1_u8); + } + if (vote == YES) { + self.yes_votes.write(self.yes_votes.read() + 1_u8); + } + + self.emit(VoteCast { voter: caller, vote: vote, }); + } + } + + /// @dev Internal Functions implementation for the Vote contract + #[generate_trait] + impl InternalFunctions of InternalFunctionsTrait { + /// @dev Registers the voters and initializes their voting status to true (can vote) + fn _register_voters( + ref self: ContractState, + voter_1: ContractAddress, + voter_2: ContractAddress, + voter_3: ContractAddress + ) { + self.registered_voter.write(voter_1, true); + self.can_vote.write(voter_1, true); + + self.registered_voter.write(voter_2, true); + self.can_vote.write(voter_2, true); + + self.registered_voter.write(voter_3, true); + self.can_vote.write(voter_3, true); + } + } + + /// @dev Asserts implementation for the Vote contract + #[generate_trait] + impl AssertsImpl of AssertsTrait { + // @dev Internal function that checks if an address is allowed to vote + fn _assert_allowed(ref self: ContractState, address: ContractAddress) { + let is_voter: bool = self.registered_voter.read((address)); + let can_vote: bool = self.can_vote.read((address)); + + if (!can_vote) { + self.emit(UnauthorizedAttempt { unauthorized_address: address, }); + } + + assert!(is_voter, "USER_NOT_REGISTERED"); + assert!(can_vote, "USER_ALREADY_VOTED"); + } + } + + /// @dev Implement the VotingResultTrait for the Vote contract + #[generate_trait] + impl VoteResultFunctionsImpl of VoteResultFunctionsTrait { + // @dev Internal function to get the voting results (yes and no vote counts) + fn _get_voting_result(self: @ContractState) -> (u8, u8) { + let n_yes: u8 = self.yes_votes.read(); + let n_no: u8 = self.no_votes.read(); + + (n_yes, n_no) + } + + // @dev Internal function to calculate the voting results in percentage + fn _get_voting_result_in_percentage(self: @ContractState) -> (u8, u8) { + let n_yes: u8 = self.yes_votes.read(); + let n_no: u8 = self.no_votes.read(); + + let total_votes: u8 = n_yes + n_no; + + if (total_votes == 0_u8) { + return (0, 0); + } + let yes_percentage: u8 = (n_yes * 100_u8) / (total_votes); + let no_percentage: u8 = (n_no * 100_u8) / (total_votes); + + (yes_percentage, no_percentage) + } + } +} +``` +Listing 16-7: A voting smart contract + +## Deploying, Calling and Invoking the Voting Contract + +Part of the Starknet experience is deploying and interacting with smart contracts. + +Once the contract is deployed, we can interact with it by calling and invoking its functions: + +- Calling contracts: Interacting with external functions that only read from the state. These functions do not alter the state of the network, so they don't require fees or signing. +- Invoking contracts: Interacting with external functions that can write to the state. These functions do alter the state of the network and require fees and signing. + +We will setup a local development node using `katana` to deploy the voting contract. Then, we'll interact with the contract by calling and invoking its functions. You can also use the Goerli Testnet instead of `katana`. However, we recommend using `katana` for local development and testing. You can find the complete tutorial for `katana` in the ["Katana: A Local Node"][katana chapter] chapter of the Starknet Book. + +[katana chapter]: https://book.starknet.io/ch02-04-katana.html + +### The `katana` Local Starknet Node + +`katana` is designed to support local development by the [Dojo team][dojo katana]. It will allow you to do everything you need to do with Starknet, but locally. It is a great tool for development and testing. + +To install `katana` from the source code, please refer to the ["Basic Installation"][katana installation] chapter of the Starknet Book. + +> Note: Please verify that the version of `katana` match the specified version provided below. +> +> ```bash +> $ katana --version +> katana 0.6.0 +> ``` +> +> To upgrade `katana` version, refer to the ["Basic Installation"][katana installation] chapter of the Starknet Book. + +Once you have `katana` installed, you can start the local Starknet node with: + +```bash +katana --accounts 3 --seed 0 --gas-price 250 +``` + +This command will start a local Starknet node with 3 deployed accounts. We will use these accounts to deploy and interact with the voting contract: + +```bash +... +PREFUNDED ACCOUNTS +================== + +| Account address | 0x03ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0 +| Private key | 0x0300001800000000300000180000000000030000000000003006001800006600 +| Public key | 0x01b7b37a580d91bc3ad4f9933ed61f3a395e0e51c9dd5553323b8ca3942bb44e + +| Account address | 0x033c627a3e5213790e246a917770ce23d7e562baa5b4d2917c23b1be6d91961c +| Private key | 0x0333803103001800039980190300d206608b0070db0012135bd1fb5f6282170b +| Public key | 0x04486e2308ef3513531042acb8ead377b887af16bd4cdd8149812dfef1ba924d + +| Account address | 0x01d98d835e43b032254ffbef0f150c5606fa9c5c9310b1fae370ab956a7919f5 +| Private key | 0x07ca856005bee0329def368d34a6711b2d95b09ef9740ebf2c7c7e3b16c1ca9c +| Public key | 0x07006c42b1cfc8bd45710646a0bb3534b182e83c313c7bc88ecf33b53ba4bcbc +... +``` + +Before we can interact with the voting contract, we need to prepare the voter and admin accounts on Starknet. Each voter account must be registered and sufficiently funded for voting. For a more detailed understanding of how accounts operate with Account Abstraction, refer to the ["Account Abstraction"][aa chapter] chapter of the Starknet Book. + +[dojo katana]: https://github.com/dojoengine/dojo/blob/main/crates/katana +[katana installation]: https://book.starknet.io/ch02-01-basic-installation.html#katana-node-installation +[aa chapter]: https://book.starknet.io/ch04-00-account-abstraction.html + +### Smart Wallets for Voting + +Aside from Scarb you will need to have Starkli installed. Starkli is a command line tool that allows you to interact with Starknet. You can find the installation instructions in the ["Basic Installation"][starkli installation] chapter of the Starknet Book. + +> Note: Please verify that the version of `starkli` match the specified version provided below. +> +> ```bash +> $ starkli --version +> 0.2.9 (0535f44) +> ``` +> +> To upgrade `starkli` to `0.2.9`, use the `starkliup -v 0.2.9` command, or simply `starkliup` which installed the latest stable version. + +For each smart wallet we'll use, we must create a Signer within the encrypted keystore and an Account Descriptor. This process is also detailed in the ["Testnet Deployment"][signer creation] chapter of the Starknet Book. + +We can create Signers and Account Descriptors for the accounts we want to use for voting. Let's create a smart wallet for voting in our smart contract. + +Firstly, we create a signer from a private key: + +```bash +starkli signer keystore from-key ~/.starkli-wallets/deployer/account0_keystore.json +``` + +Then, we create the Account Descriptor by fetching the katana account we want to use: + +```bash +starkli account fetch --rpc http://0.0.0.0:5050 --output ~/.starkli-wallets/deployer/account0_account.json +``` + +This command will create a new `account0_account.json` file containing the following details: + +```bash +{ + "version": 1, + "variant": { + "type": "open_zeppelin", + "version": 1, + "public_key": "" + }, + "deployment": { + "status": "deployed", + "class_hash": "", + "address": "" + } +} +``` + +You can retrieve the smart wallet class hash (it will be the same for all your smart wallets) with the following command. Notice the use of the `--rpc` flag and the RPC endpoint provided by `katana`: + +``` +starkli class-hash-at --rpc http://0.0.0.0:5050 +``` + +For the public key, you can use the `starkli signer keystore inspect` command with the directory of the keystore json file: + +```bash +starkli signer keystore inspect ~/.starkli-wallets/deployer/account0_keystore.json +``` + +This process is identical for `account_1` and `account_2` in case you want to have a second and a third voter. + +[starkli installation]: https://book.starknet.io/ch02-01-basic-installation.html#starkli-installation) +[signer creation]: https://book.starknet.io/ch02-05-testnet-deployment.html?highlight=signer#creating-a-signer + +### Contract Deployment + +Before deploying, we need to declare the contract. We can do this with the `starkli declare` command: + +```bash +starkli declare target/dev/starknetbook_chapter_2_Vote.sierra.json --rpc http://0.0.0.0:5050 --account ~/.starkli-wallets/deployer/account0_account.json --keystore ~/.starkli-wallets/deployer/account0_keystore.json +``` + +If the compiler version you're using is older than the one used by Starkli and you encounter a `compiler-version` error while using the command above, you can specify a compiler version to use in the command by adding the `--compiler-version x.y.z` flag. + +If you're still encountering issues with the compiler version, try upgrading Starkli using the command: `starkliup` to make sure you're using the latest version of starkli. + +The class hash of the contract is: `0x06974677a079b7edfadcd70aa4d12aac0263a4cda379009fca125e0ab1a9ba52`. You can declare this contract on Sepolia testnet and see that the class hash will correspond. + +The `--rpc` flag specifies the RPC endpoint to use (the one provided by `katana`). The `--account` flag specifies the account to use for signing the transaction. The account we use here is the one we created in the previous step. The `--keystore` flag specifies the keystore file to use for signing the transaction. + +Since we are using a local node, the transaction will achieve finality immediately. If you are using the Goerli Testnet, you will need to wait for the transaction to be final, which usually takes a few seconds. + +The following command deploys the voting contract and registers voter_0, voter_1, and voter_2 as eligible voters. These are the constructor arguments, so add a voter account that you can later vote with. + +```bash +starkli deploy --rpc http://0.0.0.0:5050 --account ~/.starkli-wallets/deployer/account0_account.json --keystore ~/.starkli-wallets/deployer/account0_keystore.json +``` + +An example command: + +```bash +starkli deploy 0x06974677a079b7edfadcd70aa4d12aac0263a4cda379009fca125e0ab1a9ba52 0x03ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0 0x033c627a3e5213790e246a917770ce23d7e562baa5b4d2917c23b1be6d91961c 0x01d98d835e43b032254ffbef0f150c5606fa9c5c9310b1fae370ab956a7919f5 --rpc http://0.0.0.0:5050 --account ~/.starkli-wallets/deployer/account0_account.json --keystore ~/.starkli-wallets/deployer/account0_keystore.json +``` + +In this case, the contract has been deployed at an specific address: `0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349`. This address will be different for you. We will use this address to interact with the contract. + +### Voter Eligibility Verification + +In our voting contract, we have two functions to validate voter eligibility, `voter_can_vote` and `is_voter_registered`. These are external read functions, which mean they don't alter the state of the contract but only read the current state. + +The `is_voter_registered` function checks whether a particular address is registered as an eligible voter in the contract. The `voter_can_vote` function, on the other hand, checks whether the voter at a specific address is currently eligible to vote, i.e., they are registered and haven't voted already. + +You can call these functions using the `starkli call` command. Note that the `call` command is used for read functions, while the `invoke` command is used for functions that can also write to storage. The `call` command does not require signing, while the `invoke` command does. + +```bash+ +starkli call 0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349 voter_can_vote 0x03ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0 --rpc http://0.0.0.0:5050 +``` + +First we added the address of the contract, then the function we want to call, and finally the input for the function. In this case, we are checking whether the voter at the address `0x03ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0` can vote. + +Since we provided a registered voter address as an input, the result is 1 (boolean true), indicating the voter is eligible to vote. + +Next, let's call the `is_voter_registered` function using an unregistered account address to observe the output: + +```bash +starkli call 0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349 is_voter_registered 0x44444444444444444 --rpc http://0.0.0.0:5050 +``` + +With an unregistered account address, the terminal output is 0 (i.e., false), confirming that the account is not eligible to vote. + +### Casting a Vote + +Now that we have established how to verify voter eligibility, we can vote! To vote, we interact with the `vote` function, which is flagged as external, necessitating the use of the `starknet invoke` command. + +The `invoke` command syntax resembles the `call` command, but for voting, we submit either `1` (for Yes) or `0` (for No) as our input. When we invoke the `vote` function, we are charged a fee, and the transaction must be signed by the voter; we are writing to the contract's storage. + +```bash +//Voting Yes +starkli invoke 0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349 vote 1 --rpc http://0.0.0.0:5050 --account ~/.starkli-wallets/deployer/account0_account.json --keystore ~/.starkli-wallets/deployer/account0_keystore.json + +//Voting No +starkli invoke 0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349 vote 0 --rpc http://0.0.0.0:5050 --account ~/.starkli-wallets/deployer/account0_account.json --keystore ~/.starkli-wallets/deployer/account0_keystore.json +``` + +You will be prompted to enter the password for the signer. Once you enter the password, the transaction will be signed and submitted to the Starknet network. You will receive the transaction hash as output. With the starkli transaction command, you can get more details about the transaction: + +```bash +starkli transaction --rpc http://0.0.0.0:5050 +``` + +This returns: + +```bash +{ + "transaction_hash": "0x5604a97922b6811060e70ed0b40959ea9e20c726220b526ec690de8923907fd", + "max_fee": "0x430e81", + "version": "0x1", + "signature": [ + "0x75e5e4880d7a8301b35ff4a1ed1e3d72fffefa64bb6c306c314496e6e402d57", + "0xbb6c459b395a535dcd00d8ab13d7ed71273da4a8e9c1f4afe9b9f4254a6f51" + ], + "nonce": "0x3", + "type": "INVOKE", + "sender_address": "0x3ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0", + "calldata": [ + "0x1", + "0x5ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349", + "0x132bdf85fc8aa10ac3c22f02317f8f53d4b4f52235ed1eabb3a4cbbe08b5c41", + "0x0", + "0x1", + "0x1", + "0x1" + ] +} +``` + +If you try to vote twice with the same signer you will get an error: + +```bash +Error: code=ContractError, message="Contract error" +``` + +The error is not very informative, but you can get more details when looking at the output in the terminal where you started `katana` (our local Starknet node): + +```bash +... +Transaction execution error: "Error in the called contract (0x03ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0): + Error at pc=0:81: + Got an exception while executing a hint: Custom Hint Error: Execution failed. Failure reason: \"USER_ALREADY_VOTED\". + ... +``` + +The key for the error is `USER_ALREADY_VOTED`. + +```bash +assert!(can_vote, "USER_ALREADY_VOTED"); +``` + +We can repeat the process to create Signers and Account Descriptors for the accounts we want to use for voting. Remember that each Signer must be created from a private key, and each Account Descriptor must be created from a public key, a smart wallet address, and the smart wallet class hash (which is the same for each voter). + +```bash +starkli invoke 0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349 vote 0 --rpc http://0.0.0.0:5050 --account ~/.starkli-wallets/deployer/account1_account.json --keystore ~/.starkli-wallets/deployer/account1_keystore.json + +starkli invoke 0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349 vote 1 --rpc http://0.0.0.0:5050 --account ~/.starkli-wallets/deployer/account2_account.json --keystore ~/.starkli-wallets/deployer/account2_keystore.json +``` + +### Visualizing Vote Outcomes + +To examine the voting results, we invoke the `get_vote_status` function, another view function, through the `starknet call` command. + +```bash +starkli call 0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349 get_vote_status --rpc http://0.0.0.0:5050 +``` + +The output reveals the tally of "Yes" and "No" votes along with their relative percentages. +# Starknet Smart Contracts Security +# General Recommendations + +When developing software, ensuring it functions as intended is usually straightforward. However, preventing unintended usage and vulnerabilities can be more challenging. + +In smart contract development, security is very important. A single error can result in the loss of valuable assets or the improper functioning of certain features. + +Smart contracts are executed in a public environment where anyone can examine the code and interact with it. Any errors or vulnerabilities in the code can be exploited by malicious actors. + +This chapter presents general recommendations for writing secure smart contracts. By incorporating these concepts during development, you can create robust and reliable smart contracts. This reduces the chance of unexpected behavior or vulnerabilities. + +## Disclaimer + +This chapter does not provide an exhaustive list of all possible security issues, and it does not guarantee that your contracts will be completely secure. + +If you are developing smart contracts for production use, it is highly recommended to conduct external audits performed by security experts. + +## Mindset + +Cairo is a highly safe language inspired by Rust. It is designed in a way that forces you to cover all possible cases. Security issues on Starknet mostly arise from the way smart contract flows are designed, not much from the language itself. + +Adopting a security mindset is the initial step in writing secure smart contracts. Try to always consider all possible scenarios when writing code. + +### Viewing Smart Contracts as Finite State Machines + +Transactions in smart contracts are atomic, meaning they either succeed or fail without making any changes. + +Think of smart contracts as state machines: they have a set of initial states defined by the constructor constraints, and external functions represent a set of possible state transitions. A transaction is nothing more than a state transition. + +The `assert!` or `panic!` macros can be used to validate conditions before performing specific actions. You can learn more about these on the [Unrecoverable Errors with panic](./ch09-01-unrecoverable-errors-with-panic.md) page. + +These validations can include: + +- Inputs provided by the caller +- Execution requirements +- Invariants (conditions that must always be true) +- Return values from other function calls + +For example, you could use the `assert!` macro to validate that a user has enough funds to perform a withdraw transaction. If the condition is not met, the transaction will fail and the state of the contract will not change. + +```rust,noplayground + impl Contract of IContract { + fn withdraw(ref self: ContractState, amount: u256) { + let current_balance = self.balance.read(); + + assert!(self.balance.read() >= amount, "Insufficient funds"); + + self.balance.write(current_balance - amount); + } +``` + +Using these functions to check conditions adds constraints that help clearly define the boundaries of possible state transitions for each function in your smart contract. These checks ensure that the behavior of the contract stays within the expected limits. + +## Recommendations + +### Checks Effects Interactions Pattern + +The Checks Effects Interactions pattern is a common design pattern used to prevent reentrancy attacks on Ethereum. While reentrancy is harder to achieve in Starknet, it is still recommended to use this pattern in your smart contracts. + + + +The pattern consists of following a specific order of operations in your functions: + +1. **Checks**: Validate all conditions and inputs before performing any state changes. +2. **Effects**: Perform all state changes. +3. **Interactions**: All external calls to other contracts should be made at the end of the function. + +### Access Control + +Access control is the process of restricting access to certain features or resources. It is a common security mechanism used to prevent unauthorized access to sensitive information or actions. In smart contracts, some functions may often be restricted to specific users or roles. + +You can implement the access control pattern to easily manage permissions. This pattern consists of defining a set of roles and assigning them to specific users. Each function can then be restricted to specific roles. + +```rust,noplayground +#[starknet::contract] +mod access_control_contract { + use starknet::ContractAddress; + use starknet::get_caller_address; + + trait IContract { + fn is_owner(self: @TContractState) -> bool; + fn is_role_a(self: @TContractState) -> bool; + fn only_owner(self: @TContractState); + fn only_role_a(self: @TContractState); + fn only_allowed(self: @TContractState); + fn set_role_a(ref self: TContractState, _target: ContractAddress, _active: bool); + fn role_a_action(ref self: ContractState); + fn allowed_action(ref self: ContractState); + } + + #[storage] + struct Storage { + // Role 'owner': only one address + owner: ContractAddress, + // Role 'role_a': a set of addresses + role_a: LegacyMap:: + } + + #[constructor] + fn constructor(ref self: ContractState) { + self.owner.write(get_caller_address()); + } + + // Guard functions to check roles + + impl Contract of IContract { + #[inline(always)] + fn is_owner(self: @ContractState) -> bool { + self.owner.read() == get_caller_address() + } + + #[inline(always)] + fn is_role_a(self: @ContractState) -> bool { + self.role_a.read(get_caller_address()) + } + + #[inline(always)] + fn only_owner(self: @ContractState) { + assert!(Contract::is_owner(self), "Not owner"); + } + + #[inline(always)] + fn only_role_a(self: @ContractState) { + assert!(Contract::is_role_a(self), "Not role A"); + } + + // You can easily combine guards to perform complex checks + fn only_allowed(self: @ContractState) { + assert!(Contract::is_owner(self) || Contract::is_role_a(self), "Not allowed"); + } + + // Functions to manage roles + + fn set_role_a(ref self: ContractState, _target: ContractAddress, _active: bool) { + Contract::only_owner(@self); + self.role_a.write(_target, _active); + } + + // You can now focus on the business logic of your contract + // and reduce the complexity of your code by using guard functions + + fn role_a_action(ref self: ContractState) { + Contract::only_role_a(@self); + // ... + } + + fn allowed_action(ref self: ContractState) { + Contract::only_allowed(@self); + // ... + } + } +} + +``` +# Testing Smart Contracts + +Testing smart contracts is a critical part of the development process. It is important to ensure that smart contracts behave as expected and that they are secure. + +In a previous section of the Cairo Book, we learned how to write and structure our tests for Cairo programs. We demonstrated how these tests could be run using the `scarb` command-line tool. +While this approach is useful for testing standalone Cairo programs and functions, it lacks functionality for testing smart contracts that require control over the contract state and execution context. Therefore, in this section, we will introduce how to use Starknet Foundry, a smart contract development toolchain for Starknet, to test your Cairo contracts. + +Throughout this chapter, we will be using as an example the `PizzaFactory` contract in Listing 17-1 to demonstrate how to write tests with Starknet Foundry. + +```rust,noplayground +use starknet::ContractAddress; + +#[starknet::interface] +pub trait IPizzaFactory { + fn increase_pepperoni(ref self: TContractState, amount: u32); + fn increase_pineapple(ref self: TContractState, amount: u32); + fn get_owner(self: @TContractState) -> ContractAddress; + fn change_owner(ref self: TContractState, new_owner: ContractAddress); + fn make_pizza(ref self: TContractState); + fn count_pizza(self: @TContractState) -> u32; +} + +#[starknet::contract] +pub mod PizzaFactory { + use super::IPizzaFactory; + use starknet::ContractAddress; + use starknet::get_caller_address; + + #[storage] + pub struct Storage { + pepperoni: u32, + pineapple: u32, + owner: ContractAddress, + pizzas: u32 + } + + #[constructor] + fn constructor(ref self: ContractState, owner: ContractAddress) { + self.pepperoni.write(10); + self.pineapple.write(10); + self.owner.write(owner); + } + + + #[event] + #[derive(Drop, starknet::Event)] + pub enum Event { + PizzaEmission: PizzaEmission + } + + #[derive(Drop, starknet::Event)] + pub struct PizzaEmission { + pub counter: u32 + } + + #[abi(embed_v0)] + impl PizzaFactoryimpl of super::IPizzaFactory { + fn increase_pepperoni(ref self: ContractState, amount: u32) { + assert!(amount != 0, "Amount cannot be 0"); + self.pepperoni.write(self.pepperoni.read() + amount); + } + + fn increase_pineapple(ref self: ContractState, amount: u32) { + assert!(amount != 0, "Amount cannot be 0"); + self.pineapple.write(self.pineapple.read() + amount); + } + + fn make_pizza(ref self: ContractState) { + assert!(self.pepperoni.read() > 0, "Not enough pepperoni"); + assert!(self.pineapple.read() > 0, "Not enough pineapple"); + + let caller: ContractAddress = get_caller_address(); + let owner: ContractAddress = self.get_owner(); + + assert!(caller == owner, "Only the owner can make pizza"); + + self.pepperoni.write(self.pepperoni.read() - 1); + self.pineapple.write(self.pineapple.read() - 1); + self.pizzas.write(self.pizzas.read() + 1); + + self.emit(PizzaEmission { counter: self.pizzas.read() }); + } + + fn get_owner(self: @ContractState) -> ContractAddress { + self.owner.read() + } + + fn change_owner(ref self: ContractState, new_owner: ContractAddress) { + self.set_owner(new_owner); + } + + fn count_pizza(self: @ContractState) -> u32 { + self.pizzas.read() + } + } + + #[generate_trait] + pub impl InternalImpl of InternalTrait { + fn set_owner(ref self: ContractState, new_owner: ContractAddress) { + let caller: ContractAddress = get_caller_address(); + assert!(caller == self.get_owner(), "Only the owner can set ownership"); + + self.owner.write(new_owner); + } + } +} +``` + +Listing 17-1: A pizza factory that needs to be tested + +## Configuring your Scarb project with Starknet Foundry + +The settings of your Scarb project can be configured in the `Scarb.toml` file. To use Starknet Foundry as your testing tool, you will need to add it as a dev dependency in your `Scarb.toml` file. At the time of writing, the latest version of Starknet Foundry is `v0.22.0` - but you should use the latest version. + +```toml,noplayground +[dev-dependencies] +snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.22.0" } + +[scripts] +test = "snforge test" +``` + +The `scarb test` command is configured to execute `scarb cairo-test` by default. In our settings, we have configured it to execute `snforge test` instead. This will allow us to run our tests using Starknet Foundry when we run the `scarb test` command. + +Once your project is configured, you will need to install Starknet Foundry by following the installation guide from the [Starknet Foundry Documentation](https://foundry-rs.github.io/starknet-foundry/getting-started/installation.html). As usual, we recommend to use `asdf` to manage versions of your development tools. + +## Testing Smart Contracts with Starknet Foundry + +The usual command to run your tests using Starknet Foundry is `snforge test`. However, when we configured our projects, we defined that the `scarb test` command will run the `snforge test` command. Therefore, during the rest of this chapter, consider that the `scarb test` command will be using `snforge test` under the hood. + +The usual testing flow of a contract is as follows: + +1. Declare the class of the contract to test, identified by its name +2. Serialize the constructor calldata into an array +3. Deploy the contract and retrieve its address +4. Interact with the contract's entrypoint to test various scenarios + +### Deploying the Contract to Test + +In Listing 17-2, we wrote a function that deploys the `PizzaFactory` contract and sets up the dispatcher for interactions. + +```rust,noplayground +# use source::pizza::{ +# IPizzaFactoryDispatcher, IPizzaFactorySafeDispatcher, IPizzaFactoryDispatcherTrait, +# PizzaFactory, PizzaFactory::{Event as PizzaEvents, PizzaEmission} +# }; +# use source::pizza::PizzaFactory::{ownerContractMemberStateTrait, InternalTrait}; +# +# use starknet::{ContractAddress, contract_address_const}; +# +# use snforge_std::{ +# declare, ContractClassTrait, ContractClass, start_cheat_caller_address, +# stop_cheat_caller_address, SpyOn, EventSpy, EventAssertions, spy_events, EventFetcher, load, +# cheatcodes::storage::load_felt252 +# }; +# +# fn owner() -> ContractAddress { +# contract_address_const::<'owner'>() +# } +# +fn deploy_pizza_factory() -> (IPizzaFactoryDispatcher, ContractAddress) { + let contract = declare("PizzaFactory").unwrap(); + let owner: ContractAddress = contract_address_const::<'owner'>(); + + let mut constructor_calldata = array![owner.into()]; + + let (contract_address, _) = contract.deploy(@constructor_calldata).unwrap(); + + let dispatcher = IPizzaFactoryDispatcher { contract_address }; + + (dispatcher, contract_address) +} +# +# #[test] +# fn test_constructor() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# +# let pepperoni_count = load(pizza_factory_address, selector!("pepperoni"), 1); +# let pineapple_count = load(pizza_factory_address, selector!("pineapple"), 1); +# assert_eq!(pepperoni_count, array![10]); +# assert_eq!(pineapple_count, array![10]); +# assert_eq!(pizza_factory.get_owner(), owner()); +# } +# +# #[test] +# fn test_change_owner_should_change_owner() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# +# let new_owner: ContractAddress = contract_address_const::<'new_owner'>(); +# assert_eq!(pizza_factory.get_owner(), owner()); +# +# start_cheat_caller_address(pizza_factory_address, owner()); +# +# pizza_factory.change_owner(new_owner); +# +# assert_eq!(pizza_factory.get_owner(), new_owner); +# } +# +# #[test] +# #[should_panic(expected: ("Only the owner can set ownership",))] +# fn test_change_owner_should_panic_when_not_owner() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# let not_owner = contract_address_const::<'not_owner'>(); +# start_cheat_caller_address(pizza_factory_address, not_owner); +# pizza_factory.change_owner(not_owner); +# stop_cheat_caller_address(pizza_factory_address); +# } +# +# #[test] +# #[should_panic(expected: ("Only the owner can make pizza",))] +# fn test_make_pizza_should_panic_when_not_owner() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# let not_owner = contract_address_const::<'not_owner'>(); +# start_cheat_caller_address(pizza_factory_address, not_owner); +# +# pizza_factory.make_pizza(); +# } +# +# #[test] +# fn test_make_pizza_should_increment_pizza_counter() { +# // Setup +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# start_cheat_caller_address(pizza_factory_address, owner()); +# let mut spy = spy_events(SpyOn::One(pizza_factory_address)); +# +# // When +# pizza_factory.make_pizza(); +# +# // Then +# let expected_event = PizzaEvents::PizzaEmission(PizzaEmission { counter: 1 }); +# assert_eq!(pizza_factory.count_pizza(), 1); +# spy.assert_emitted(@array![(pizza_factory_address, expected_event)]); +# } +# +# #[test] +# fn test_set_as_new_owner_direct() { +# let mut state = PizzaFactory::contract_state_for_testing(); +# let owner: ContractAddress = contract_address_const::<'owner'>(); +# state.set_owner(owner); +# assert_eq!(state.owner.read(), owner); +# } +# +# +``` + +Listing 17-2 Deploying the contract to test + +### Testing our Contract + +Determining the behavior that your contract should respect is the first step in writing tests. In the `PizzaFactory` contract, we determined that the contract should have the following behavior: + +- Upon deployment, the contract owner should be set to the address provided in the constructor, and the factory should have 10 units of pepperoni and pineapple, and no pizzas created. +- If someone tries to make a pizza and they are not the owner, the operation should fail. Otherwise, the pizza count should be incremented, and an event should be emitted. +- If someone tries to take ownership of the contract and they are not the owner, the operation should fail. Otherwise, the owner should be updated. + +#### Accessing Storage Variables with `load` + +```rust,noplayground +# use source::pizza::{ +# IPizzaFactoryDispatcher, IPizzaFactorySafeDispatcher, IPizzaFactoryDispatcherTrait, +# PizzaFactory, PizzaFactory::{Event as PizzaEvents, PizzaEmission} +# }; +# use source::pizza::PizzaFactory::{ownerContractMemberStateTrait, InternalTrait}; +# +# use starknet::{ContractAddress, contract_address_const}; +# +# use snforge_std::{ +# declare, ContractClassTrait, ContractClass, start_cheat_caller_address, +# stop_cheat_caller_address, SpyOn, EventSpy, EventAssertions, spy_events, EventFetcher, load, +# cheatcodes::storage::load_felt252 +# }; +# +# fn owner() -> ContractAddress { +# contract_address_const::<'owner'>() +# } +# +# fn deploy_pizza_factory() -> (IPizzaFactoryDispatcher, ContractAddress) { +# let contract = declare("PizzaFactory").unwrap(); +# let owner: ContractAddress = contract_address_const::<'owner'>(); +# +# let mut constructor_calldata = array![owner.into()]; +# +# let (contract_address, _) = contract.deploy(@constructor_calldata).unwrap(); +# +# let dispatcher = IPizzaFactoryDispatcher { contract_address }; +# +# (dispatcher, contract_address) +# } +# +#[test] +fn test_constructor() { + let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); + + let pepperoni_count = load(pizza_factory_address, selector!("pepperoni"), 1); + let pineapple_count = load(pizza_factory_address, selector!("pineapple"), 1); + assert_eq!(pepperoni_count, array![10]); + assert_eq!(pineapple_count, array![10]); + assert_eq!(pizza_factory.get_owner(), owner()); +} +# +# #[test] +# fn test_change_owner_should_change_owner() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# +# let new_owner: ContractAddress = contract_address_const::<'new_owner'>(); +# assert_eq!(pizza_factory.get_owner(), owner()); +# +# start_cheat_caller_address(pizza_factory_address, owner()); +# +# pizza_factory.change_owner(new_owner); +# +# assert_eq!(pizza_factory.get_owner(), new_owner); +# } +# +# #[test] +# #[should_panic(expected: ("Only the owner can set ownership",))] +# fn test_change_owner_should_panic_when_not_owner() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# let not_owner = contract_address_const::<'not_owner'>(); +# start_cheat_caller_address(pizza_factory_address, not_owner); +# pizza_factory.change_owner(not_owner); +# stop_cheat_caller_address(pizza_factory_address); +# } +# +# #[test] +# #[should_panic(expected: ("Only the owner can make pizza",))] +# fn test_make_pizza_should_panic_when_not_owner() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# let not_owner = contract_address_const::<'not_owner'>(); +# start_cheat_caller_address(pizza_factory_address, not_owner); +# +# pizza_factory.make_pizza(); +# } +# +# #[test] +# fn test_make_pizza_should_increment_pizza_counter() { +# // Setup +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# start_cheat_caller_address(pizza_factory_address, owner()); +# let mut spy = spy_events(SpyOn::One(pizza_factory_address)); +# +# // When +# pizza_factory.make_pizza(); +# +# // Then +# let expected_event = PizzaEvents::PizzaEmission(PizzaEmission { counter: 1 }); +# assert_eq!(pizza_factory.count_pizza(), 1); +# spy.assert_emitted(@array![(pizza_factory_address, expected_event)]); +# } +# +# #[test] +# fn test_set_as_new_owner_direct() { +# let mut state = PizzaFactory::contract_state_for_testing(); +# let owner: ContractAddress = contract_address_const::<'owner'>(); +# state.set_owner(owner); +# assert_eq!(state.owner.read(), owner); +# } +# +# +``` + +Listing 17-3: Testing the initial state by loading storage variables + +Once our contract is deployed, we want to assert that the initial values are set as expected. If our contract has an entrypoint that returns the value of a storage variable, we can call this entrypoint. Otherwise, we can use the `load` function from `snforge` to load the value of a storage variable inside our contract, even if not exposed by an entrypoint. + +#### Mocking the Caller Address with `start_cheat_caller_address` + +The security of our factory relies on the owner being the only one able to make pizzas and transfer ownership. To test this, we can use the `start_cheat_caller_address` function to mock the caller address and assert that the contract behaves as expected. + +```rust,noplayground +# use source::pizza::{ +# IPizzaFactoryDispatcher, IPizzaFactorySafeDispatcher, IPizzaFactoryDispatcherTrait, +# PizzaFactory, PizzaFactory::{Event as PizzaEvents, PizzaEmission} +# }; +# use source::pizza::PizzaFactory::{ownerContractMemberStateTrait, InternalTrait}; +# +# use starknet::{ContractAddress, contract_address_const}; +# +# use snforge_std::{ +# declare, ContractClassTrait, ContractClass, start_cheat_caller_address, +# stop_cheat_caller_address, SpyOn, EventSpy, EventAssertions, spy_events, EventFetcher, load, +# cheatcodes::storage::load_felt252 +# }; +# +# fn owner() -> ContractAddress { +# contract_address_const::<'owner'>() +# } +# +# fn deploy_pizza_factory() -> (IPizzaFactoryDispatcher, ContractAddress) { +# let contract = declare("PizzaFactory").unwrap(); +# let owner: ContractAddress = contract_address_const::<'owner'>(); +# +# let mut constructor_calldata = array![owner.into()]; +# +# let (contract_address, _) = contract.deploy(@constructor_calldata).unwrap(); +# +# let dispatcher = IPizzaFactoryDispatcher { contract_address }; +# +# (dispatcher, contract_address) +# } +# +# #[test] +# fn test_constructor() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# +# let pepperoni_count = load(pizza_factory_address, selector!("pepperoni"), 1); +# let pineapple_count = load(pizza_factory_address, selector!("pineapple"), 1); +# assert_eq!(pepperoni_count, array![10]); +# assert_eq!(pineapple_count, array![10]); +# assert_eq!(pizza_factory.get_owner(), owner()); +# } +# +#[test] +fn test_change_owner_should_change_owner() { + let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); + + let new_owner: ContractAddress = contract_address_const::<'new_owner'>(); + assert_eq!(pizza_factory.get_owner(), owner()); + + start_cheat_caller_address(pizza_factory_address, owner()); + + pizza_factory.change_owner(new_owner); + + assert_eq!(pizza_factory.get_owner(), new_owner); +} + +#[test] +#[should_panic(expected: ("Only the owner can set ownership",))] +fn test_change_owner_should_panic_when_not_owner() { + let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); + let not_owner = contract_address_const::<'not_owner'>(); + start_cheat_caller_address(pizza_factory_address, not_owner); + pizza_factory.change_owner(not_owner); + stop_cheat_caller_address(pizza_factory_address); +} +# +# #[test] +# #[should_panic(expected: ("Only the owner can make pizza",))] +# fn test_make_pizza_should_panic_when_not_owner() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# let not_owner = contract_address_const::<'not_owner'>(); +# start_cheat_caller_address(pizza_factory_address, not_owner); +# +# pizza_factory.make_pizza(); +# } +# +# #[test] +# fn test_make_pizza_should_increment_pizza_counter() { +# // Setup +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# start_cheat_caller_address(pizza_factory_address, owner()); +# let mut spy = spy_events(SpyOn::One(pizza_factory_address)); +# +# // When +# pizza_factory.make_pizza(); +# +# // Then +# let expected_event = PizzaEvents::PizzaEmission(PizzaEmission { counter: 1 }); +# assert_eq!(pizza_factory.count_pizza(), 1); +# spy.assert_emitted(@array![(pizza_factory_address, expected_event)]); +# } +# +# #[test] +# fn test_set_as_new_owner_direct() { +# let mut state = PizzaFactory::contract_state_for_testing(); +# let owner: ContractAddress = contract_address_const::<'owner'>(); +# state.set_owner(owner); +# assert_eq!(state.owner.read(), owner); +# } +# +# +``` + +Listing 17-4: Testing ownership of the contract by mocking the caller address + +Using `start_cheat_caller_address`, we call the `change_owner` function first as the owner, and then as a different address. We assert that the operation fails when the caller is not the owner, and that the owner is updated when the caller is the owner. + +#### Capturing Events with `spy_events` + +When a pizza is created, the contract emits an event. To test this, we can use the `spy_events` function to capture the emitted events and assert that the event was emitted with the expected parameters. Naturally, we can also assert that the pizza count was incremented, and that only the owner can make a pizza. + +```rust,noplayground +# use source::pizza::{ +# IPizzaFactoryDispatcher, IPizzaFactorySafeDispatcher, IPizzaFactoryDispatcherTrait, +# PizzaFactory, PizzaFactory::{Event as PizzaEvents, PizzaEmission} +# }; +# use source::pizza::PizzaFactory::{ownerContractMemberStateTrait, InternalTrait}; +# +# use starknet::{ContractAddress, contract_address_const}; +# +# use snforge_std::{ +# declare, ContractClassTrait, ContractClass, start_cheat_caller_address, +# stop_cheat_caller_address, SpyOn, EventSpy, EventAssertions, spy_events, EventFetcher, load, +# cheatcodes::storage::load_felt252 +# }; +# +# fn owner() -> ContractAddress { +# contract_address_const::<'owner'>() +# } +# +# fn deploy_pizza_factory() -> (IPizzaFactoryDispatcher, ContractAddress) { +# let contract = declare("PizzaFactory").unwrap(); +# let owner: ContractAddress = contract_address_const::<'owner'>(); +# +# let mut constructor_calldata = array![owner.into()]; +# +# let (contract_address, _) = contract.deploy(@constructor_calldata).unwrap(); +# +# let dispatcher = IPizzaFactoryDispatcher { contract_address }; +# +# (dispatcher, contract_address) +# } +# +# #[test] +# fn test_constructor() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# +# let pepperoni_count = load(pizza_factory_address, selector!("pepperoni"), 1); +# let pineapple_count = load(pizza_factory_address, selector!("pineapple"), 1); +# assert_eq!(pepperoni_count, array![10]); +# assert_eq!(pineapple_count, array![10]); +# assert_eq!(pizza_factory.get_owner(), owner()); +# } +# +# #[test] +# fn test_change_owner_should_change_owner() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# +# let new_owner: ContractAddress = contract_address_const::<'new_owner'>(); +# assert_eq!(pizza_factory.get_owner(), owner()); +# +# start_cheat_caller_address(pizza_factory_address, owner()); +# +# pizza_factory.change_owner(new_owner); +# +# assert_eq!(pizza_factory.get_owner(), new_owner); +# } +# +# #[test] +# #[should_panic(expected: ("Only the owner can set ownership",))] +# fn test_change_owner_should_panic_when_not_owner() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# let not_owner = contract_address_const::<'not_owner'>(); +# start_cheat_caller_address(pizza_factory_address, not_owner); +# pizza_factory.change_owner(not_owner); +# stop_cheat_caller_address(pizza_factory_address); +# } +# +#[test] +#[should_panic(expected: ("Only the owner can make pizza",))] +fn test_make_pizza_should_panic_when_not_owner() { + let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); + let not_owner = contract_address_const::<'not_owner'>(); + start_cheat_caller_address(pizza_factory_address, not_owner); + + pizza_factory.make_pizza(); +} + +#[test] +fn test_make_pizza_should_increment_pizza_counter() { + // Setup + let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); + start_cheat_caller_address(pizza_factory_address, owner()); + let mut spy = spy_events(SpyOn::One(pizza_factory_address)); + + // When + pizza_factory.make_pizza(); + + // Then + let expected_event = PizzaEvents::PizzaEmission(PizzaEmission { counter: 1 }); + assert_eq!(pizza_factory.count_pizza(), 1); + spy.assert_emitted(@array![(pizza_factory_address, expected_event)]); +} +# +# #[test] +# fn test_set_as_new_owner_direct() { +# let mut state = PizzaFactory::contract_state_for_testing(); +# let owner: ContractAddress = contract_address_const::<'owner'>(); +# state.set_owner(owner); +# assert_eq!(state.owner.read(), owner); +# } +# +# +``` + +Listing 17-5: Testing the events emitted when a pizza is created + +#### Accessing Internal Functions with `contract_state_for_testing` + +All the tests we have seen so far have been using a workflow that involves deploying the contract and interacting with the contract's entrypoints. However, sometimes we may want to test the internals of the contract directly, without deploying the contract. How could this be done, if we were reasoning in purely Cairo terms? + +Recall the struct `ContractState`, which is used as a parameter to all the entrypoints of a contract. To make it short, this struct contains zero-sized fields, corresponding to the storage variables of the contract. The only purpose of these fields is to allow the Cairo compiler to generate the correct code for accessing the storage variables. If we could create an instance of this struct, we could access these storage variables directly, without deploying the contract... + +...and this is exactly what the `contract_state_for_testing` function does! It creates an instance of the `ContractState` struct, allowing us to call any function that takes as parameter a `ContractState` struct, without deploying the contract. To interact with the storage variables properly, we need to manually import the traits that define access to the storage variables. + +```rust,noplayground +# use source::pizza::{ +# IPizzaFactoryDispatcher, IPizzaFactorySafeDispatcher, IPizzaFactoryDispatcherTrait, +# PizzaFactory, PizzaFactory::{Event as PizzaEvents, PizzaEmission} +# }; +use source::pizza::PizzaFactory::{ownerContractMemberStateTrait, InternalTrait}; +# +# use starknet::{ContractAddress, contract_address_const}; +# +# use snforge_std::{ +# declare, ContractClassTrait, ContractClass, start_cheat_caller_address, +# stop_cheat_caller_address, SpyOn, EventSpy, EventAssertions, spy_events, EventFetcher, load, +# cheatcodes::storage::load_felt252 +# }; +# +# fn owner() -> ContractAddress { +# contract_address_const::<'owner'>() +# } +# +# fn deploy_pizza_factory() -> (IPizzaFactoryDispatcher, ContractAddress) { +# let contract = declare("PizzaFactory").unwrap(); +# let owner: ContractAddress = contract_address_const::<'owner'>(); +# +# let mut constructor_calldata = array![owner.into()]; +# +# let (contract_address, _) = contract.deploy(@constructor_calldata).unwrap(); +# +# let dispatcher = IPizzaFactoryDispatcher { contract_address }; +# +# (dispatcher, contract_address) +# } +# +# #[test] +# fn test_constructor() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# +# let pepperoni_count = load(pizza_factory_address, selector!("pepperoni"), 1); +# let pineapple_count = load(pizza_factory_address, selector!("pineapple"), 1); +# assert_eq!(pepperoni_count, array![10]); +# assert_eq!(pineapple_count, array![10]); +# assert_eq!(pizza_factory.get_owner(), owner()); +# } +# +# #[test] +# fn test_change_owner_should_change_owner() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# +# let new_owner: ContractAddress = contract_address_const::<'new_owner'>(); +# assert_eq!(pizza_factory.get_owner(), owner()); +# +# start_cheat_caller_address(pizza_factory_address, owner()); +# +# pizza_factory.change_owner(new_owner); +# +# assert_eq!(pizza_factory.get_owner(), new_owner); +# } +# +# #[test] +# #[should_panic(expected: ("Only the owner can set ownership",))] +# fn test_change_owner_should_panic_when_not_owner() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# let not_owner = contract_address_const::<'not_owner'>(); +# start_cheat_caller_address(pizza_factory_address, not_owner); +# pizza_factory.change_owner(not_owner); +# stop_cheat_caller_address(pizza_factory_address); +# } +# +# #[test] +# #[should_panic(expected: ("Only the owner can make pizza",))] +# fn test_make_pizza_should_panic_when_not_owner() { +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# let not_owner = contract_address_const::<'not_owner'>(); +# start_cheat_caller_address(pizza_factory_address, not_owner); +# +# pizza_factory.make_pizza(); +# } +# +# #[test] +# fn test_make_pizza_should_increment_pizza_counter() { +# // Setup +# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); +# start_cheat_caller_address(pizza_factory_address, owner()); +# let mut spy = spy_events(SpyOn::One(pizza_factory_address)); +# +# // When +# pizza_factory.make_pizza(); +# +# // Then +# let expected_event = PizzaEvents::PizzaEmission(PizzaEmission { counter: 1 }); +# assert_eq!(pizza_factory.count_pizza(), 1); +# spy.assert_emitted(@array![(pizza_factory_address, expected_event)]); +# } +# +# #[test] +# fn test_set_as_new_owner_direct() { +# let mut state = PizzaFactory::contract_state_for_testing(); +# let owner: ContractAddress = contract_address_const::<'owner'>(); +# state.set_owner(owner); +# assert_eq!(state.owner.read(), owner); +# } +# +# +``` + +Listing 17-6: Unit testing our contract without deployment + +These imports give us access to our internal functions (notably, `set_owner`), as well as the +read/write access to the `owner` storage variable. Once we have these, we can interact with the +contract directly, changing the address of the owner by calling the `set_owner` method, accessible +through `InternalTrait`, and reading the `owner` storage variable. + +> Note: Both approaches cannot be used at the same time. If you decide to deploy the contract, you interact with it using the dispatcher. If you decide to test the internal functions, you interact with the `ContractState` object directly. + +```bash,noplayground +$ scarb test + Running test source (snforge test) + Compiling source v0.1.0 (listings/ch17-starknet-smart-contracts-security/listing_02_pizza_factory_snfoundry/Scarb.toml) + Finished release target(s) in 1 second + + +Collected 6 test(s) from source package +Running 6 test(s) from src/ +[PASS] source::tests::foundry_test::test_set_as_new_owner_direct (gas: ~130) +[PASS] source::tests::foundry_test::test_constructor (gas: ~296) +[PASS] source::tests::foundry_test::test_change_owner_should_panic_when_not_owner (gas: ~297) +[PASS] source::tests::foundry_test::test_make_pizza_should_panic_when_not_owner (gas: ~297) +[PASS] source::tests::foundry_test::test_make_pizza_should_increment_pizza_counter (gas: ~368) +[PASS] source::tests::foundry_test::test_change_owner_should_change_owner (gas: ~301) +Tests: 6 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out + +``` + +The output of the tests shows that all the tests passed successfully, along with an estimation of the gas consumed by each test. + +## Summary + +In this chapter, we learned how to test smart contracts using Starknet Foundry. We demonstrated how to deploy a contract and interact with it using the dispatcher. We also showed how to test the contract's behavior by mocking the caller address and capturing events. Finally, we demonstrated how to test the internal functions of the contract directly, without deploying the contract. + +To learn more about Starknet Foundry, refer to the [Starknet Foundry documentation](https://foundry-rs.github.io/starknet-foundry/index.html). +# Static Analysis Tools + +Static analysis refers to the process of examining code without its execution, focusing on its structure, syntax, and properties. It involves analyzing the source code to identify potential issues, vulnerabilities, or violations of specified rules. + +By defining rules, such as coding conventions or security guidelines, developers can utilize static analysis tools to automatically check the code against these standards. + +Reference: + +- [Semgrep Cairo 1.0 support](https://semgrep.dev/blog/2023/semgrep-now-supports-cairo-1-0) +- [Caracal, a Starknet static analyzer](https://github.com/crytic/caracal) +# Introduction +# The Cairo Book + +By the Cairo Community and its [contributors](https://github.com/cairo-book/cairo-book.github.io). Special thanks to [StarkWare](https://starkware.co/) through [OnlyDust](https://www.onlydust.xyz/), and [Voyager](https://voyager.online/) for supporting the creation of this book. + +This version of the text assumes you’re using the [Cairo Compiler](https://github.com/starkware-libs/cairo) [version 2.6.3](https://github.com/starkware-libs/cairo/releases). See the [Installation](ch01-01-installation.md) section of Chapter 1 to install or update Cairo. + +If you want to play around with Cairo code and see how it compiles into Sierra (Intermediate Representation) and CASM (Cairo Assembly), you can use [cairovm.codes](https://cairovm.codes/) playground. diff --git a/contracts/manifests/dev/base/abis/contracts/pixelaw-actions-16928a49.json b/contracts/manifests/dev/base/abis/contracts/pixelaw-actions-16928a49.json deleted file mode 100644 index e71ba18..0000000 --- a/contracts/manifests/dev/base/abis/contracts/pixelaw-actions-16928a49.json +++ /dev/null @@ -1,775 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsImpl", - "interface_name": "pixelaw::core::actions::IActions" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permission", - "members": [ - { - "name": "app", - "type": "core::bool" - }, - { - "name": "color", - "type": "core::bool" - }, - { - "name": "owner", - "type": "core::bool" - }, - { - "name": "text", - "type": "core::bool" - }, - { - "name": "timestamp", - "type": "core::bool" - }, - { - "name": "action", - "type": "core::bool" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::pixel::Pixel", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "created_at", - "type": "core::integer::u64" - }, - { - "name": "updated_at", - "type": "core::integer::u64" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "text", - "type": "core::felt252" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "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": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "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": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "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": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::actions::IActions", - "items": [ - { - "type": "function", - "name": "init", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_permission", - "inputs": [ - { - "name": "app_key", - "type": "core::felt252" - }, - { - "name": "permission", - "type": "pixelaw::core::models::permissions::Permission" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "has_write_access", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "pixel", - "type": "pixelaw::core::models::pixel::Pixel" - }, - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [ - { - "type": "core::bool" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "process_queue", - "inputs": [ - { - "name": "id", - "type": "core::felt252" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "schedule_queue", - "inputs": [ - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_pixel", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "new_app", - "inputs": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "icon", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "pixelaw::core::models::registry::App" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_system_address", - "inputs": [ - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "get_player_address", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "alert_player", - "inputs": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "message", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_instruction", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "instruction", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "pixelaw::core::actions::actions::IDojoInit" - }, - { - "type": "interface", - "name": "pixelaw::core::actions::actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::QueueScheduled", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "calldata", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::QueueProcessed", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::AppNameUpdated", - "kind": "struct", - "members": [ - { - "name": "app", - "type": "pixelaw::core::models::registry::App", - "kind": "data" - }, - { - "name": "caller", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::Alert", - "kind": "struct", - "members": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position", - "kind": "data" - }, - { - "name": "caller", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "message", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "QueueScheduled", - "type": "pixelaw::core::actions::actions::QueueScheduled", - "kind": "nested" - }, - { - "name": "QueueProcessed", - "type": "pixelaw::core::actions::actions::QueueProcessed", - "kind": "nested" - }, - { - "name": "AppNameUpdated", - "type": "pixelaw::core::actions::actions::AppNameUpdated", - "kind": "nested" - }, - { - "name": "Alert", - "type": "pixelaw::core::actions::actions::Alert", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json b/contracts/manifests/dev/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json index 1e29a57..6b58deb 100644 --- a/contracts/manifests/dev/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json +++ b/contracts/manifests/dev/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json @@ -175,6 +175,22 @@ "outputs": [], "state_mutability": "external" }, + { + "type": "function", + "name": "join_guild", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "guild_id", + "type": "core::integer::u32" + } + ], + "outputs": [], + "state_mutability": "external" + }, { "type": "function", "name": "remove_member", diff --git a/contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json b/contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json index b9e6307..5119cbe 100644 --- a/contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json +++ b/contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json @@ -357,6 +357,70 @@ "name": "ActionsImpl", "interface_name": "p_war::systems::actions::IActions" }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "p_war::models::game::Game", + "members": [ + { + "name": "id", + "type": "core::integer::u32" + }, + { + "name": "start", + "type": "core::integer::u64" + }, + { + "name": "end", + "type": "core::integer::u64" + }, + { + "name": "proposal_idx", + "type": "core::integer::u32" + }, + { + "name": "base_cost", + "type": "core::integer::u32" + }, + { + "name": "const_val", + "type": "core::integer::u32" + }, + { + "name": "coeff_own_pixels", + "type": "core::integer::u32" + }, + { + "name": "coeff_commits", + "type": "core::integer::u32" + }, + { + "name": "winner_config", + "type": "core::integer::u32" + }, + { + "name": "winner", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "guild_ids", + "type": "core::array::Span::" + }, + { + "name": "guild_count", + "type": "core::integer::u32" + } + ] + }, { "type": "interface", "name": "p_war::systems::actions::IActions", @@ -396,6 +460,18 @@ ], "state_mutability": "external" }, + { + "type": "function", + "name": "create_game_guilds", + "inputs": [ + { + "name": "game", + "type": "p_war::models::game::Game" + } + ], + "outputs": [], + "state_mutability": "external" + }, { "type": "function", "name": "get_game_id", diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-AllowedApp-4aa27058.json b/contracts/manifests/dev/base/abis/models/pixelaw-AllowedApp-4aa27058.json deleted file mode 100644 index 316e91a..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-AllowedApp-4aa27058.json +++ /dev/null @@ -1,425 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "allowed_appImpl", - "interface_name": "p_war::models::allowed_app::Iallowed_app" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_app::AllowedApp", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "contract", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "is_allowed", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_app::Iallowed_app", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_app::AllowedApp" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_app::allowed_app::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-AllowedColor-22c1a796.json b/contracts/manifests/dev/base/abis/models/pixelaw-AllowedColor-22c1a796.json deleted file mode 100644 index 48cc27f..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-AllowedColor-22c1a796.json +++ /dev/null @@ -1,425 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "allowed_colorImpl", - "interface_name": "p_war::models::allowed_color::Iallowed_color" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::AllowedColor", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "is_allowed", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Iallowed_color", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::AllowedColor" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::allowed_color::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-App-36504565.json b/contracts/manifests/dev/base/abis/models/pixelaw-App-36504565.json deleted file mode 100644 index c2e9c0e..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-App-36504565.json +++ /dev/null @@ -1,415 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "appImpl", - "interface_name": "pixelaw::core::models::registry::Iapp" - }, - { - "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": "interface", - "name": "pixelaw::core::models::registry::Iapp", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::App" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-AppName-3b816829.json b/contracts/manifests/dev/base/abis/models/pixelaw-AppName-3b816829.json deleted file mode 100644 index 87a5e61..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-AppName-3b816829.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "app_nameImpl", - "interface_name": "pixelaw::core::models::registry::Iapp_name" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::AppName", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iapp_name", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::AppName" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app_name::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-AppUser-4eda3c52.json b/contracts/manifests/dev/base/abis/models/pixelaw-AppUser-4eda3c52.json deleted file mode 100644 index a578a2c..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-AppUser-4eda3c52.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "app_userImpl", - "interface_name": "pixelaw::core::models::registry::Iapp_user" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::AppUser", - "members": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iapp_user", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::AppUser" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app_user::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Board-124dc3e7.json b/contracts/manifests/dev/base/abis/models/pixelaw-Board-124dc3e7.json deleted file mode 100644 index 6f4d779..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Board-124dc3e7.json +++ /dev/null @@ -1,429 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "boardImpl", - "interface_name": "p_war::models::board::Iboard" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::board::Board", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "origin", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "width", - "type": "core::integer::u32" - }, - { - "name": "height", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Iboard", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::Board" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::board::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json b/contracts/manifests/dev/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json deleted file mode 100644 index 512af25..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "core_actions_addressImpl", - "interface_name": "pixelaw::core::models::registry::Icore_actions_address" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::CoreActionsAddress", - "members": [ - { - "name": "key", - "type": "core::felt252" - }, - { - "name": "value", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Icore_actions_address", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::CoreActionsAddress" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::core_actions_address::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Game-5c1fa23f.json b/contracts/manifests/dev/base/abis/models/pixelaw-Game-5c1fa23f.json deleted file mode 100644 index 4b89c1a..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Game-5c1fa23f.json +++ /dev/null @@ -1,457 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "gameImpl", - "interface_name": "p_war::models::game::Igame" - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::game::Game", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "start", - "type": "core::integer::u64" - }, - { - "name": "end", - "type": "core::integer::u64" - }, - { - "name": "proposal_idx", - "type": "core::integer::u32" - }, - { - "name": "base_cost", - "type": "core::integer::u32" - }, - { - "name": "const_val", - "type": "core::integer::u32" - }, - { - "name": "coeff_own_pixels", - "type": "core::integer::u32" - }, - { - "name": "coeff_commits", - "type": "core::integer::u32" - }, - { - "name": "winner_config", - "type": "core::integer::u32" - }, - { - "name": "winner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "guild_ids", - "type": "core::array::Span::" - }, - { - "name": "guild_count", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::game::Igame", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::game::Game" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::game::game::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-GameId-1ee8756e.json b/contracts/manifests/dev/base/abis/models/pixelaw-GameId-1ee8756e.json deleted file mode 100644 index 869e2a6..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-GameId-1ee8756e.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "game_idImpl", - "interface_name": "p_war::models::board::Igame_id" - }, - { - "type": "struct", - "name": "p_war::models::board::GameId", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "value", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Igame_id", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::GameId" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::game_id::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-GamePalette-49013f2b.json b/contracts/manifests/dev/base/abis/models/pixelaw-GamePalette-49013f2b.json deleted file mode 100644 index 2ee77e7..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-GamePalette-49013f2b.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "game_paletteImpl", - "interface_name": "p_war::models::allowed_color::Igame_palette" - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::GamePalette", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "length", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Igame_palette", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::GamePalette" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::game_palette::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Guild-40e97c00.json b/contracts/manifests/dev/base/abis/models/pixelaw-Guild-40e97c00.json deleted file mode 100644 index f963145..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Guild-40e97c00.json +++ /dev/null @@ -1,433 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "guildImpl", - "interface_name": "p_war::models::guilds::Iguild" - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::guilds::Guild", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "guild_name", - "type": "core::felt252" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "members", - "type": "core::array::Span::" - }, - { - "name": "member_count", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::guilds::Iguild", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::guilds::Guild" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::guilds::guild::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-InPalette-7a46e3ad.json b/contracts/manifests/dev/base/abis/models/pixelaw-InPalette-7a46e3ad.json deleted file mode 100644 index 4c58dd9..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-InPalette-7a46e3ad.json +++ /dev/null @@ -1,425 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "in_paletteImpl", - "interface_name": "p_war::models::allowed_color::Iin_palette" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::InPalette", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "value", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Iin_palette", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::InPalette" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::in_palette::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Instruction-4c7c4844.json b/contracts/manifests/dev/base/abis/models/pixelaw-Instruction-4c7c4844.json deleted file mode 100644 index a79b066..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Instruction-4c7c4844.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "instructionImpl", - "interface_name": "pixelaw::core::models::registry::Iinstruction" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::Instruction", - "members": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "instruction", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iinstruction", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::Instruction" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::instruction::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-PWarPixel-15195913.json b/contracts/manifests/dev/base/abis/models/pixelaw-PWarPixel-15195913.json deleted file mode 100644 index 4fb9f2a..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-PWarPixel-15195913.json +++ /dev/null @@ -1,421 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "p_war_pixelImpl", - "interface_name": "p_war::models::board::Ip_war_pixel" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::board::PWarPixel", - "members": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Ip_war_pixel", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::PWarPixel" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::p_war_pixel::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-PaletteColors-39a92a0a.json b/contracts/manifests/dev/base/abis/models/pixelaw-PaletteColors-39a92a0a.json deleted file mode 100644 index ac5324c..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-PaletteColors-39a92a0a.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "palette_colorsImpl", - "interface_name": "p_war::models::allowed_color::Ipalette_colors" - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::PaletteColors", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "idx", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Ipalette_colors", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::PaletteColors" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::palette_colors::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Permissions-72b77307.json b/contracts/manifests/dev/base/abis/models/pixelaw-Permissions-72b77307.json deleted file mode 100644 index 2e1a096..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Permissions-72b77307.json +++ /dev/null @@ -1,455 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "permissionsImpl", - "interface_name": "pixelaw::core::models::permissions::Ipermissions" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permission", - "members": [ - { - "name": "app", - "type": "core::bool" - }, - { - "name": "color", - "type": "core::bool" - }, - { - "name": "owner", - "type": "core::bool" - }, - { - "name": "text", - "type": "core::bool" - }, - { - "name": "timestamp", - "type": "core::bool" - }, - { - "name": "action", - "type": "core::bool" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permissions", - "members": [ - { - "name": "allowing_app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "allowed_app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "permission", - "type": "pixelaw::core::models::permissions::Permission" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::permissions::Ipermissions", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::permissions::Permissions" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::permissions::permissions::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Pixel-7e607b2f.json b/contracts/manifests/dev/base/abis/models/pixelaw-Pixel-7e607b2f.json deleted file mode 100644 index 8f6c36a..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Pixel-7e607b2f.json +++ /dev/null @@ -1,439 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "pixelImpl", - "interface_name": "pixelaw::core::models::pixel::Ipixel" - }, - { - "type": "struct", - "name": "pixelaw::core::models::pixel::Pixel", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "created_at", - "type": "core::integer::u64" - }, - { - "name": "updated_at", - "type": "core::integer::u64" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "text", - "type": "core::felt252" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::pixel::Ipixel", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::pixel::Pixel" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::pixel::pixel::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json b/contracts/manifests/dev/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json deleted file mode 100644 index 6458f14..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "pixel_recovery_rateImpl", - "interface_name": "p_war::models::proposal::Ipixel_recovery_rate" - }, - { - "type": "struct", - "name": "p_war::models::proposal::PixelRecoveryRate", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "rate", - "type": "core::integer::u64" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Ipixel_recovery_rate", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::PixelRecoveryRate" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::pixel_recovery_rate::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Player-30a1b371.json b/contracts/manifests/dev/base/abis/models/pixelaw-Player-30a1b371.json deleted file mode 100644 index 7e279da..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Player-30a1b371.json +++ /dev/null @@ -1,441 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "playerImpl", - "interface_name": "p_war::models::player::Iplayer" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::player::Player", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "max_px", - "type": "core::integer::u32" - }, - { - "name": "num_owns", - "type": "core::integer::u32" - }, - { - "name": "num_commit", - "type": "core::integer::u32" - }, - { - "name": "current_px", - "type": "core::integer::u32" - }, - { - "name": "last_date", - "type": "core::integer::u64" - }, - { - "name": "is_banned", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::player::Iplayer", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::player::Player" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::player::player::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-PlayerVote-326c17c6.json b/contracts/manifests/dev/base/abis/models/pixelaw-PlayerVote-326c17c6.json deleted file mode 100644 index aed1379..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-PlayerVote-326c17c6.json +++ /dev/null @@ -1,433 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "player_voteImpl", - "interface_name": "p_war::models::proposal::Iplayer_vote" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::proposal::PlayerVote", - "members": [ - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "is_in_favor", - "type": "core::bool" - }, - { - "name": "px", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Iplayer_vote", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::PlayerVote" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::player_vote::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Proposal-49e1daf5.json b/contracts/manifests/dev/base/abis/models/pixelaw-Proposal-49e1daf5.json deleted file mode 100644 index 2ce1647..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Proposal-49e1daf5.json +++ /dev/null @@ -1,457 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "proposalImpl", - "interface_name": "p_war::models::proposal::Iproposal" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::proposal::Proposal", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "author", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "proposal_type", - "type": "core::integer::u8" - }, - { - "name": "target_args_1", - "type": "core::integer::u32" - }, - { - "name": "target_args_2", - "type": "core::integer::u32" - }, - { - "name": "start", - "type": "core::integer::u64" - }, - { - "name": "end", - "type": "core::integer::u64" - }, - { - "name": "yes_px", - "type": "core::integer::u32" - }, - { - "name": "no_px", - "type": "core::integer::u32" - }, - { - "name": "is_activated", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Iproposal", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::Proposal" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::proposal::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-QueueItem-549a17f2.json b/contracts/manifests/dev/base/abis/models/pixelaw-QueueItem-549a17f2.json deleted file mode 100644 index 8496a6c..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-QueueItem-549a17f2.json +++ /dev/null @@ -1,421 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "queue_itemImpl", - "interface_name": "pixelaw::core::models::queue::Iqueue_item" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::queue::QueueItem", - "members": [ - { - "name": "id", - "type": "core::felt252" - }, - { - "name": "valid", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::queue::Iqueue_item", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::queue::QueueItem" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::queue::queue_item::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/contracts/pixelaw-actions-16928a49.toml b/contracts/manifests/dev/base/contracts/pixelaw-actions-16928a49.toml deleted file mode 100644 index 5ab4bd2..0000000 --- a/contracts/manifests/dev/base/contracts/pixelaw-actions-16928a49.toml +++ /dev/null @@ -1,19 +0,0 @@ -kind = "DojoContract" -class_hash = "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f" -original_class_hash = "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f" -base_class_hash = "0x0" -abi = "manifests/dev/base/abis/contracts/pixelaw-actions-16928a49.json" -reads = [] -writes = [] -init_calldata = [] -tag = "pixelaw-actions" -systems = [ - "init", - "update_permission", - "schedule_queue", - "process_queue", - "update_pixel", - "alert_player", - "set_instruction", -] -manifest_name = "pixelaw-actions-16928a49" diff --git a/contracts/manifests/dev/base/contracts/pixelaw-guild_actions-4c9f5931.toml b/contracts/manifests/dev/base/contracts/pixelaw-guild_actions-4c9f5931.toml index b28f8b0..23e8f2c 100644 --- a/contracts/manifests/dev/base/contracts/pixelaw-guild_actions-4c9f5931.toml +++ b/contracts/manifests/dev/base/contracts/pixelaw-guild_actions-4c9f5931.toml @@ -1,6 +1,6 @@ kind = "DojoContract" -class_hash = "0x11472c33465ac19ee8fd27f6d901c6c4c68ec3b7aca25da683f9ada76edf5ff" -original_class_hash = "0x11472c33465ac19ee8fd27f6d901c6c4c68ec3b7aca25da683f9ada76edf5ff" +class_hash = "0x6f6ccb38ccf4fa5456f18b40b2c3f133730e62a0680746dc5afe6f3a03ce03b" +original_class_hash = "0x6f6ccb38ccf4fa5456f18b40b2c3f133730e62a0680746dc5afe6f3a03ce03b" base_class_hash = "0x0" abi = "manifests/dev/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json" reads = [] @@ -9,6 +9,7 @@ init_calldata = [] tag = "pixelaw-guild_actions" systems = [ "add_member", + "join_guild", "remove_member", ] manifest_name = "pixelaw-guild_actions-4c9f5931" diff --git a/contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml b/contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml index 749ef73..20e0d7a 100644 --- a/contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml +++ b/contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml @@ -1,6 +1,6 @@ kind = "DojoContract" -class_hash = "0x317693d5c8f562ba5920e57218000c8839bf0624e9310f947068947e4e0c3fb" -original_class_hash = "0x317693d5c8f562ba5920e57218000c8839bf0624e9310f947068947e4e0c3fb" +class_hash = "0x1a367552a5c071c3632eb91e7bdb42d6abe1b92ad1ae1710a036b487f695288" +original_class_hash = "0x1a367552a5c071c3632eb91e7bdb42d6abe1b92ad1ae1710a036b487f695288" base_class_hash = "0x0" abi = "manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json" reads = [] @@ -13,6 +13,7 @@ systems = [ "set_pixel", "init", "interact", + "create_game_guilds", "place_pixel", "update_pixel", "end_game", diff --git a/contracts/manifests/dev/base/models/pixelaw-AllowedApp-4aa27058.toml b/contracts/manifests/dev/base/models/pixelaw-AllowedApp-4aa27058.toml deleted file mode 100644 index 3c18d84..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-AllowedApp-4aa27058.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f" -original_class_hash = "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f" -abi = "manifests/dev/base/abis/models/pixelaw-AllowedApp-4aa27058.json" -tag = "pixelaw-AllowedApp" -qualified_path = "p_war::models::allowed_app::allowed_app" -manifest_name = "pixelaw-AllowedApp-4aa27058" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "contract" -type = "ContractAddress" -key = true - -[[members]] -name = "is_allowed" -type = "bool" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-AllowedColor-22c1a796.toml b/contracts/manifests/dev/base/models/pixelaw-AllowedColor-22c1a796.toml deleted file mode 100644 index fe91aad..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-AllowedColor-22c1a796.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54" -original_class_hash = "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54" -abi = "manifests/dev/base/abis/models/pixelaw-AllowedColor-22c1a796.json" -tag = "pixelaw-AllowedColor" -qualified_path = "p_war::models::allowed_color::allowed_color" -manifest_name = "pixelaw-AllowedColor-22c1a796" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "color" -type = "u32" -key = true - -[[members]] -name = "is_allowed" -type = "bool" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-App-36504565.toml b/contracts/manifests/dev/base/models/pixelaw-App-36504565.toml deleted file mode 100644 index ce308c9..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-App-36504565.toml +++ /dev/null @@ -1,27 +0,0 @@ -kind = "DojoModel" -class_hash = "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c" -original_class_hash = "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c" -abi = "manifests/dev/base/abis/models/pixelaw-App-36504565.json" -tag = "pixelaw-App" -qualified_path = "pixelaw::core::models::registry::app" -manifest_name = "pixelaw-App-36504565" - -[[members]] -name = "system" -type = "ContractAddress" -key = true - -[[members]] -name = "name" -type = "felt252" -key = false - -[[members]] -name = "icon" -type = "felt252" -key = false - -[[members]] -name = "action" -type = "felt252" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-AppName-3b816829.toml b/contracts/manifests/dev/base/models/pixelaw-AppName-3b816829.toml deleted file mode 100644 index d48078e..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-AppName-3b816829.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8" -original_class_hash = "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8" -abi = "manifests/dev/base/abis/models/pixelaw-AppName-3b816829.json" -tag = "pixelaw-AppName" -qualified_path = "pixelaw::core::models::registry::app_name" -manifest_name = "pixelaw-AppName-3b816829" - -[[members]] -name = "name" -type = "felt252" -key = true - -[[members]] -name = "system" -type = "ContractAddress" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-AppUser-4eda3c52.toml b/contracts/manifests/dev/base/models/pixelaw-AppUser-4eda3c52.toml deleted file mode 100644 index 426707a..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-AppUser-4eda3c52.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1" -original_class_hash = "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1" -abi = "manifests/dev/base/abis/models/pixelaw-AppUser-4eda3c52.json" -tag = "pixelaw-AppUser" -qualified_path = "pixelaw::core::models::registry::app_user" -manifest_name = "pixelaw-AppUser-4eda3c52" - -[[members]] -name = "system" -type = "ContractAddress" -key = true - -[[members]] -name = "player" -type = "ContractAddress" -key = true - -[[members]] -name = "action" -type = "felt252" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Board-124dc3e7.toml b/contracts/manifests/dev/base/models/pixelaw-Board-124dc3e7.toml deleted file mode 100644 index 9cc4cfe..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Board-124dc3e7.toml +++ /dev/null @@ -1,27 +0,0 @@ -kind = "DojoModel" -class_hash = "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c" -original_class_hash = "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c" -abi = "manifests/dev/base/abis/models/pixelaw-Board-124dc3e7.json" -tag = "pixelaw-Board" -qualified_path = "p_war::models::board::board" -manifest_name = "pixelaw-Board-124dc3e7" - -[[members]] -name = "id" -type = "usize" -key = true - -[[members]] -name = "origin" -type = "Position" -key = false - -[[members]] -name = "width" -type = "u32" -key = false - -[[members]] -name = "height" -type = "u32" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml b/contracts/manifests/dev/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml deleted file mode 100644 index b6eec60..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2" -original_class_hash = "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2" -abi = "manifests/dev/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json" -tag = "pixelaw-CoreActionsAddress" -qualified_path = "pixelaw::core::models::registry::core_actions_address" -manifest_name = "pixelaw-CoreActionsAddress-5379e1ce" - -[[members]] -name = "key" -type = "felt252" -key = true - -[[members]] -name = "value" -type = "ContractAddress" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Game-5c1fa23f.toml b/contracts/manifests/dev/base/models/pixelaw-Game-5c1fa23f.toml deleted file mode 100644 index bddf5c1..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Game-5c1fa23f.toml +++ /dev/null @@ -1,67 +0,0 @@ -kind = "DojoModel" -class_hash = "0x794c64750ec570c0678f6afd54210e88f6da106ba0172f2ec03405c3c0ad70e" -original_class_hash = "0x794c64750ec570c0678f6afd54210e88f6da106ba0172f2ec03405c3c0ad70e" -abi = "manifests/dev/base/abis/models/pixelaw-Game-5c1fa23f.json" -tag = "pixelaw-Game" -qualified_path = "p_war::models::game::game" -manifest_name = "pixelaw-Game-5c1fa23f" - -[[members]] -name = "id" -type = "usize" -key = true - -[[members]] -name = "start" -type = "u64" -key = false - -[[members]] -name = "end" -type = "u64" -key = false - -[[members]] -name = "proposal_idx" -type = "usize" -key = false - -[[members]] -name = "base_cost" -type = "u32" -key = false - -[[members]] -name = "const_val" -type = "u32" -key = false - -[[members]] -name = "coeff_own_pixels" -type = "u32" -key = false - -[[members]] -name = "coeff_commits" -type = "u32" -key = false - -[[members]] -name = "winner_config" -type = "u32" -key = false - -[[members]] -name = "winner" -type = "ContractAddress" -key = false - -[[members]] -name = "guild_ids" -type = "Span" -key = false - -[[members]] -name = "guild_count" -type = "usize" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-GameId-1ee8756e.toml b/contracts/manifests/dev/base/models/pixelaw-GameId-1ee8756e.toml deleted file mode 100644 index c38abc0..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-GameId-1ee8756e.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4" -original_class_hash = "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4" -abi = "manifests/dev/base/abis/models/pixelaw-GameId-1ee8756e.json" -tag = "pixelaw-GameId" -qualified_path = "p_war::models::board::game_id" -manifest_name = "pixelaw-GameId-1ee8756e" - -[[members]] -name = "x" -type = "u32" -key = true - -[[members]] -name = "y" -type = "u32" -key = true - -[[members]] -name = "value" -type = "usize" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-GamePalette-49013f2b.toml b/contracts/manifests/dev/base/models/pixelaw-GamePalette-49013f2b.toml deleted file mode 100644 index 1eaf78e..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-GamePalette-49013f2b.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398" -original_class_hash = "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398" -abi = "manifests/dev/base/abis/models/pixelaw-GamePalette-49013f2b.json" -tag = "pixelaw-GamePalette" -qualified_path = "p_war::models::allowed_color::game_palette" -manifest_name = "pixelaw-GamePalette-49013f2b" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "length" -type = "usize" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Guild-40e97c00.toml b/contracts/manifests/dev/base/models/pixelaw-Guild-40e97c00.toml deleted file mode 100644 index 42941e2..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Guild-40e97c00.toml +++ /dev/null @@ -1,37 +0,0 @@ -kind = "DojoModel" -class_hash = "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95" -original_class_hash = "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95" -abi = "manifests/dev/base/abis/models/pixelaw-Guild-40e97c00.json" -tag = "pixelaw-Guild" -qualified_path = "p_war::models::guilds::guild" -manifest_name = "pixelaw-Guild-40e97c00" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "guild_id" -type = "usize" -key = true - -[[members]] -name = "guild_name" -type = "felt252" -key = false - -[[members]] -name = "creator" -type = "ContractAddress" -key = false - -[[members]] -name = "members" -type = "Span" -key = false - -[[members]] -name = "member_count" -type = "usize" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-InPalette-7a46e3ad.toml b/contracts/manifests/dev/base/models/pixelaw-InPalette-7a46e3ad.toml deleted file mode 100644 index d3d005c..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-InPalette-7a46e3ad.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372" -original_class_hash = "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372" -abi = "manifests/dev/base/abis/models/pixelaw-InPalette-7a46e3ad.json" -tag = "pixelaw-InPalette" -qualified_path = "p_war::models::allowed_color::in_palette" -manifest_name = "pixelaw-InPalette-7a46e3ad" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "color" -type = "u32" -key = true - -[[members]] -name = "value" -type = "bool" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Instruction-4c7c4844.toml b/contracts/manifests/dev/base/models/pixelaw-Instruction-4c7c4844.toml deleted file mode 100644 index c6a8378..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Instruction-4c7c4844.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af" -original_class_hash = "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af" -abi = "manifests/dev/base/abis/models/pixelaw-Instruction-4c7c4844.json" -tag = "pixelaw-Instruction" -qualified_path = "pixelaw::core::models::registry::instruction" -manifest_name = "pixelaw-Instruction-4c7c4844" - -[[members]] -name = "system" -type = "ContractAddress" -key = true - -[[members]] -name = "selector" -type = "felt252" -key = true - -[[members]] -name = "instruction" -type = "felt252" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-PWarPixel-15195913.toml b/contracts/manifests/dev/base/models/pixelaw-PWarPixel-15195913.toml deleted file mode 100644 index 30703ad..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-PWarPixel-15195913.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261" -original_class_hash = "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261" -abi = "manifests/dev/base/abis/models/pixelaw-PWarPixel-15195913.json" -tag = "pixelaw-PWarPixel" -qualified_path = "p_war::models::board::p_war_pixel" -manifest_name = "pixelaw-PWarPixel-15195913" - -[[members]] -name = "position" -type = "Position" -key = true - -[[members]] -name = "owner" -type = "ContractAddress" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-PaletteColors-39a92a0a.toml b/contracts/manifests/dev/base/models/pixelaw-PaletteColors-39a92a0a.toml deleted file mode 100644 index 9e95d01..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-PaletteColors-39a92a0a.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444" -original_class_hash = "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444" -abi = "manifests/dev/base/abis/models/pixelaw-PaletteColors-39a92a0a.json" -tag = "pixelaw-PaletteColors" -qualified_path = "p_war::models::allowed_color::palette_colors" -manifest_name = "pixelaw-PaletteColors-39a92a0a" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "idx" -type = "u32" -key = true - -[[members]] -name = "color" -type = "u32" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Permissions-72b77307.toml b/contracts/manifests/dev/base/models/pixelaw-Permissions-72b77307.toml deleted file mode 100644 index e2dd2e5..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Permissions-72b77307.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302" -original_class_hash = "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302" -abi = "manifests/dev/base/abis/models/pixelaw-Permissions-72b77307.json" -tag = "pixelaw-Permissions" -qualified_path = "pixelaw::core::models::permissions::permissions" -manifest_name = "pixelaw-Permissions-72b77307" - -[[members]] -name = "allowing_app" -type = "ContractAddress" -key = true - -[[members]] -name = "allowed_app" -type = "ContractAddress" -key = true - -[[members]] -name = "permission" -type = "Permission" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Pixel-7e607b2f.toml b/contracts/manifests/dev/base/models/pixelaw-Pixel-7e607b2f.toml deleted file mode 100644 index 31ddb3b..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Pixel-7e607b2f.toml +++ /dev/null @@ -1,57 +0,0 @@ -kind = "DojoModel" -class_hash = "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d" -original_class_hash = "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d" -abi = "manifests/dev/base/abis/models/pixelaw-Pixel-7e607b2f.json" -tag = "pixelaw-Pixel" -qualified_path = "pixelaw::core::models::pixel::pixel" -manifest_name = "pixelaw-Pixel-7e607b2f" - -[[members]] -name = "x" -type = "u32" -key = true - -[[members]] -name = "y" -type = "u32" -key = true - -[[members]] -name = "app" -type = "ContractAddress" -key = false - -[[members]] -name = "color" -type = "u32" -key = false - -[[members]] -name = "created_at" -type = "u64" -key = false - -[[members]] -name = "updated_at" -type = "u64" -key = false - -[[members]] -name = "timestamp" -type = "u64" -key = false - -[[members]] -name = "owner" -type = "ContractAddress" -key = false - -[[members]] -name = "text" -type = "felt252" -key = false - -[[members]] -name = "action" -type = "felt252" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml b/contracts/manifests/dev/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml deleted file mode 100644 index 9167f2e..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067" -original_class_hash = "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067" -abi = "manifests/dev/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json" -tag = "pixelaw-PixelRecoveryRate" -qualified_path = "p_war::models::proposal::pixel_recovery_rate" -manifest_name = "pixelaw-PixelRecoveryRate-3aa284c0" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "rate" -type = "u64" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Player-30a1b371.toml b/contracts/manifests/dev/base/models/pixelaw-Player-30a1b371.toml deleted file mode 100644 index c8c1ce5..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Player-30a1b371.toml +++ /dev/null @@ -1,42 +0,0 @@ -kind = "DojoModel" -class_hash = "0x73f4c14a1b7cfadff6bdad338ebacc61fa1c429a6610fd00480312ec6f37180" -original_class_hash = "0x73f4c14a1b7cfadff6bdad338ebacc61fa1c429a6610fd00480312ec6f37180" -abi = "manifests/dev/base/abis/models/pixelaw-Player-30a1b371.json" -tag = "pixelaw-Player" -qualified_path = "p_war::models::player::player" -manifest_name = "pixelaw-Player-30a1b371" - -[[members]] -name = "address" -type = "ContractAddress" -key = true - -[[members]] -name = "max_px" -type = "u32" -key = false - -[[members]] -name = "num_owns" -type = "u32" -key = false - -[[members]] -name = "num_commit" -type = "u32" -key = false - -[[members]] -name = "current_px" -type = "u32" -key = false - -[[members]] -name = "last_date" -type = "u64" -key = false - -[[members]] -name = "is_banned" -type = "bool" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-PlayerVote-326c17c6.toml b/contracts/manifests/dev/base/models/pixelaw-PlayerVote-326c17c6.toml deleted file mode 100644 index 4061d5a..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-PlayerVote-326c17c6.toml +++ /dev/null @@ -1,32 +0,0 @@ -kind = "DojoModel" -class_hash = "0x249aaae81a4275050c7d9f959c5b09c1babbd39b47697bb895adc72cf7965c5" -original_class_hash = "0x249aaae81a4275050c7d9f959c5b09c1babbd39b47697bb895adc72cf7965c5" -abi = "manifests/dev/base/abis/models/pixelaw-PlayerVote-326c17c6.json" -tag = "pixelaw-PlayerVote" -qualified_path = "p_war::models::proposal::player_vote" -manifest_name = "pixelaw-PlayerVote-326c17c6" - -[[members]] -name = "player" -type = "ContractAddress" -key = true - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "index" -type = "usize" -key = true - -[[members]] -name = "is_in_favor" -type = "bool" -key = false - -[[members]] -name = "px" -type = "u32" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Proposal-49e1daf5.toml b/contracts/manifests/dev/base/models/pixelaw-Proposal-49e1daf5.toml deleted file mode 100644 index 60b4aab..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Proposal-49e1daf5.toml +++ /dev/null @@ -1,62 +0,0 @@ -kind = "DojoModel" -class_hash = "0x404d31fa774f450e44ff386730f3f43c2932d7cfcc55251e2a0ef2c77f5dc96" -original_class_hash = "0x404d31fa774f450e44ff386730f3f43c2932d7cfcc55251e2a0ef2c77f5dc96" -abi = "manifests/dev/base/abis/models/pixelaw-Proposal-49e1daf5.json" -tag = "pixelaw-Proposal" -qualified_path = "p_war::models::proposal::proposal" -manifest_name = "pixelaw-Proposal-49e1daf5" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "index" -type = "usize" -key = true - -[[members]] -name = "author" -type = "ContractAddress" -key = false - -[[members]] -name = "proposal_type" -type = "u8" -key = false - -[[members]] -name = "target_args_1" -type = "u32" -key = false - -[[members]] -name = "target_args_2" -type = "u32" -key = false - -[[members]] -name = "start" -type = "u64" -key = false - -[[members]] -name = "end" -type = "u64" -key = false - -[[members]] -name = "yes_px" -type = "u32" -key = false - -[[members]] -name = "no_px" -type = "u32" -key = false - -[[members]] -name = "is_activated" -type = "bool" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-QueueItem-549a17f2.toml b/contracts/manifests/dev/base/models/pixelaw-QueueItem-549a17f2.toml deleted file mode 100644 index 8e33ac5..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-QueueItem-549a17f2.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70" -original_class_hash = "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70" -abi = "manifests/dev/base/abis/models/pixelaw-QueueItem-549a17f2.json" -tag = "pixelaw-QueueItem" -qualified_path = "pixelaw::core::models::queue::queue_item" -manifest_name = "pixelaw-QueueItem-549a17f2" - -[[members]] -name = "id" -type = "felt252" -key = true - -[[members]] -name = "valid" -type = "bool" -key = false diff --git a/contracts/src/lib.cairo b/contracts/src/lib.cairo index 4a879f5..8ec8e7e 100644 --- a/contracts/src/lib.cairo +++ b/contracts/src/lib.cairo @@ -20,10 +20,10 @@ mod models { #[cfg(test)] mod tests { - mod test_add_color; - mod test_create_world; - mod test_extend_game_end; + // mod test_add_color; + // mod test_create_world; + // mod test_extend_game_end; mod test_guild; - mod test_reset_to_white; + // mod test_reset_to_white; mod utils; } diff --git a/contracts/src/systems/actions.cairo b/contracts/src/systems/actions.cairo index e5c10d3..4361329 100644 --- a/contracts/src/systems/actions.cairo +++ b/contracts/src/systems/actions.cairo @@ -5,7 +5,9 @@ use p_war::constants::{ INITIAL_COLOR, BASE_COST, DEFAULT_PX }; use p_war::models::board::Position; +use p_war::systems::guilds::{IGuildDispatcher, IGuildDispatcherTrait}; use pixelaw::core::models::pixel::PixelUpdate; +use p_war::models::game::Game; use pixelaw::core::utils::DefaultParameters; use starknet::ContractAddress; @@ -15,6 +17,7 @@ trait IActions { fn init(ref world: IWorldDispatcher); fn interact(ref world: IWorldDispatcher, default_params: DefaultParameters); fn create_game(ref world: IWorldDispatcher, origin: Position) -> usize; + fn create_game_guilds(ref world: IWorldDispatcher, game: Game); fn get_game_id(world: @IWorldDispatcher, position: Position) -> usize; fn place_pixel( ref world: IWorldDispatcher, app: ContractAddress, default_params: DefaultParameters @@ -33,6 +36,7 @@ mod p_war_actions { allowed_color::{AllowedColor, PaletteColors, InPalette, GamePalette}, allowed_app::AllowedApp }; + use p_war::systems::guilds::{IGuildDispatcher, IGuildDispatcherTrait}; use p_war::systems::apps::{IAllowedApp, IAllowedAppDispatcher, IAllowedAppDispatcherTrait}; use p_war::systems::utils::{recover_px, update_max_px, check_game_status}; use pixelaw::core::actions::{ @@ -275,10 +279,21 @@ mod p_war_actions { // recover px recover_px(world, id, player); + self.create_game_guilds(game); + id // emit event that game has started } + // initialize guilds for the game + fn create_game_guilds(ref world: IWorldDispatcher, game: Game) { + let guild_dispatcher = IGuildDispatcher { contract_address: world.contract_address }; + guild_dispatcher.create_guild(game.id, 'Fire'); + guild_dispatcher.create_guild(game.id, 'Water'); + guild_dispatcher.create_guild(game.id, 'Earth'); + guild_dispatcher.create_guild(game.id, 'Air'); + } + // To paint, basically use this function. fn place_pixel( ref world: IWorldDispatcher, app: ContractAddress, default_params: DefaultParameters diff --git a/contracts/src/systems/guilds.cairo b/contracts/src/systems/guilds.cairo index 0a7277c..b8098b8 100644 --- a/contracts/src/systems/guilds.cairo +++ b/contracts/src/systems/guilds.cairo @@ -11,6 +11,7 @@ trait IGuild { fn add_member( ref world: IWorldDispatcher, game_id: usize, guild_id: usize, new_member: ContractAddress ); + fn join_guild(ref world: IWorldDispatcher, game_id: usize, guild_id: usize); fn remove_member( ref world: IWorldDispatcher, game_id: usize, guild_id: usize, member: ContractAddress ); @@ -26,6 +27,7 @@ mod guild_actions { use starknet::{ ContractAddress, get_block_timestamp, get_caller_address, get_contract_address, get_tx_info }; + use p_war::systems::utils::{is_member}; use super::{IGuild}; @@ -94,18 +96,7 @@ mod guild_actions { assert(guild.creator == caller, 'Only creator can add members'); // Check if the member is not already in the guild - let mut is_member = false; - let mut i = 0; - loop { - if i == guild.members.len() { - break; - } - if guild.members.at(i) == @new_member { - is_member = true; - } - i += 1; - }; - println!("is_member: {}", is_member); + let is_member = is_member(world, game_id, guild_id, new_member); assert(is_member == false, 'New Member already in guild'); // Create a new Array and populate it with existing guild_ids @@ -132,6 +123,13 @@ mod guild_actions { set!(world, (guild)); } + fn join_guild(ref world: IWorldDispatcher, game_id: usize, guild_id: usize) { + let caller = get_caller_address(); + + // Add the member to the guild + self.add_member(game_id, guild_id, caller); + } + fn remove_member( ref world: IWorldDispatcher, game_id: usize, guild_id: usize, member: ContractAddress ) { @@ -143,23 +141,9 @@ mod guild_actions { // Check if the caller is the creator assert(guild.creator == caller, 'Only creator can remove members'); - // Check if the member is in the guild - let mut is_member = false; - let mut i = 0; - loop { - if i == guild.members.len() { - break; - } - if guild.members.at(i) == @member { - is_member = true; - } - i += 1; - }; - println!("is_member: {}", is_member); - assert(is_member == true, 'Member not in guild'); - - // Remove the member + // Remove the member and check if it existed let mut updated_members = ArrayTrait::new(); + let mut member_found = false; let mut i = 0; loop { if i == guild.member_count { @@ -167,9 +151,14 @@ mod guild_actions { } if *guild.members.at(i) != member { updated_members.append(*guild.members.at(i)); + } else { + member_found = true; } i += 1; }; + + assert(member_found, 'Member not in guild'); + guild.members = updated_members.span(); guild.member_count -= 1; @@ -177,8 +166,6 @@ mod guild_actions { set!(world, (guild)); } - // //this function is very inefficient. better implementation is updating guild points when - // member points are updated. fn get_guild_points(world: @IWorldDispatcher, game_id: usize, guild_id: usize) -> usize { // Get the guild let mut guild = get!(world, (game_id, guild_id), (Guild)); diff --git a/contracts/src/systems/utils.cairo b/contracts/src/systems/utils.cairo index 6e428a9..4d6e679 100644 --- a/contracts/src/systems/utils.cairo +++ b/contracts/src/systems/utils.cairo @@ -3,7 +3,8 @@ use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; use p_war::constants::DEFAULT_PX; use p_war::models::{ game::{Game, Status}, board::{Board, GameId, Position}, player::{Player}, - proposal::{PixelRecoveryRate}, allowed_color::AllowedColor, allowed_app::AllowedApp + proposal::{PixelRecoveryRate}, allowed_color::AllowedColor, allowed_app::AllowedApp, + guilds::{Guild} }; use starknet::{ ContractAddress, get_block_timestamp, get_caller_address, get_contract_address, get_tx_info @@ -70,3 +71,20 @@ fn recover_px(world: IWorldDispatcher, game_id: usize, player_address: ContractA fn check_game_status(status: Status) -> bool { status == Status::Pending || status == Status::Ongoing } + +fn is_member(world: IWorldDispatcher, game_id: usize, guild_id: usize, member: ContractAddress) -> bool { + let guild = get!(world, (game_id, guild_id), (Guild)); + let mut is_member = false; + let mut i = 0; + loop { + if i == guild.members.len() { + break; + } + if guild.members.at(i) == @member { + is_member = true; + break; + } + i += 1; + }; + is_member +} \ No newline at end of file From 3f3ca88af5b4bbed9c482875118b1d1529a29e6e Mon Sep 17 00:00:00 2001 From: OwnerOfJK Date: Thu, 10 Oct 2024 11:34:21 +0700 Subject: [PATCH 02/18] added the create guild to create game --- contracts/.gitignore | 3 +- .../contracts/pixelaw-actions-16928a49.json | 775 ++++++++++++++++++ .../pixelaw-guild_actions-4c9f5931.json | 410 +++++++++ .../pixelaw-p_war_actions-60819afd.json | 84 +- .../pixelaw-propose_actions-4ee7028a.json | 363 ++++++++ .../pixelaw-voting_actions-6aab73ea.json | 292 +++++++ .../models/pixelaw-AllowedApp-4aa27058.json | 425 ++++++++++ .../models/pixelaw-AllowedColor-22c1a796.json | 425 ++++++++++ .../abis/models/pixelaw-App-36504565.json | 415 ++++++++++ .../abis/models/pixelaw-AppName-3b816829.json | 407 +++++++++ .../abis/models/pixelaw-AppUser-4eda3c52.json | 411 ++++++++++ .../abis/models/pixelaw-Board-124dc3e7.json | 429 ++++++++++ .../pixelaw-CoreActionsAddress-5379e1ce.json | 407 +++++++++ .../abis/models/pixelaw-Game-5c1fa23f.json | 457 +++++++++++ .../abis/models/pixelaw-GameId-1ee8756e.json | 411 ++++++++++ .../models/pixelaw-GamePalette-49013f2b.json | 407 +++++++++ .../abis/models/pixelaw-Guild-40e97c00.json | 433 ++++++++++ ...pixelaw-GuildContractAddress-6a64b8e1.json | 407 +++++++++ .../models/pixelaw-InPalette-7a46e3ad.json | 425 ++++++++++ .../models/pixelaw-Instruction-4c7c4844.json | 411 ++++++++++ .../models/pixelaw-PWarPixel-15195913.json | 421 ++++++++++ .../pixelaw-PaletteColors-39a92a0a.json | 411 ++++++++++ .../models/pixelaw-Permissions-72b77307.json | 455 ++++++++++ .../abis/models/pixelaw-Pixel-7e607b2f.json | 439 ++++++++++ .../pixelaw-PixelRecoveryRate-3aa284c0.json | 407 +++++++++ .../abis/models/pixelaw-Player-30a1b371.json | 441 ++++++++++ .../models/pixelaw-PlayerVote-326c17c6.json | 433 ++++++++++ .../models/pixelaw-Proposal-49e1daf5.json | 457 +++++++++++ .../models/pixelaw-QueueItem-549a17f2.json | 421 ++++++++++ .../contracts/pixelaw-actions-16928a49.toml | 19 + .../pixelaw-guild_actions-4c9f5931.toml | 15 + .../pixelaw-p_war_actions-60819afd.toml | 5 +- .../pixelaw-propose_actions-4ee7028a.toml | 11 + .../pixelaw-voting_actions-6aab73ea.toml | 11 + .../models/pixelaw-AllowedApp-4aa27058.toml | 22 + .../models/pixelaw-AllowedColor-22c1a796.toml | 22 + .../dev/base/models/pixelaw-App-36504565.toml | 27 + .../base/models/pixelaw-AppName-3b816829.toml | 17 + .../base/models/pixelaw-AppUser-4eda3c52.toml | 22 + .../base/models/pixelaw-Board-124dc3e7.toml | 27 + .../pixelaw-CoreActionsAddress-5379e1ce.toml | 17 + .../base/models/pixelaw-Game-5c1fa23f.toml | 67 ++ .../base/models/pixelaw-GameId-1ee8756e.toml | 22 + .../models/pixelaw-GamePalette-49013f2b.toml | 17 + .../base/models/pixelaw-Guild-40e97c00.toml | 37 + ...pixelaw-GuildContractAddress-6a64b8e1.toml | 17 + .../models/pixelaw-InPalette-7a46e3ad.toml | 22 + .../models/pixelaw-Instruction-4c7c4844.toml | 22 + .../models/pixelaw-PWarPixel-15195913.toml | 17 + .../pixelaw-PaletteColors-39a92a0a.toml | 22 + .../models/pixelaw-Permissions-72b77307.toml | 22 + .../base/models/pixelaw-Pixel-7e607b2f.toml | 57 ++ .../pixelaw-PixelRecoveryRate-3aa284c0.toml | 17 + .../base/models/pixelaw-Player-30a1b371.toml | 42 + .../models/pixelaw-PlayerVote-326c17c6.toml | 32 + .../models/pixelaw-Proposal-49e1daf5.toml | 62 ++ .../models/pixelaw-QueueItem-549a17f2.toml | 17 + contracts/src/systems/actions.cairo | 38 +- contracts/src/systems/guilds.cairo | 7 + 59 files changed, 12357 insertions(+), 77 deletions(-) create mode 100644 contracts/manifests/dev/base/abis/contracts/pixelaw-actions-16928a49.json create mode 100644 contracts/manifests/dev/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json create mode 100644 contracts/manifests/dev/base/abis/contracts/pixelaw-propose_actions-4ee7028a.json create mode 100644 contracts/manifests/dev/base/abis/contracts/pixelaw-voting_actions-6aab73ea.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-AllowedApp-4aa27058.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-AllowedColor-22c1a796.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-App-36504565.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-AppName-3b816829.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-AppUser-4eda3c52.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Board-124dc3e7.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Game-5c1fa23f.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-GameId-1ee8756e.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-GamePalette-49013f2b.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Guild-40e97c00.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-GuildContractAddress-6a64b8e1.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-InPalette-7a46e3ad.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Instruction-4c7c4844.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-PWarPixel-15195913.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-PaletteColors-39a92a0a.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Permissions-72b77307.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Pixel-7e607b2f.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Player-30a1b371.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-PlayerVote-326c17c6.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Proposal-49e1daf5.json create mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-QueueItem-549a17f2.json create mode 100644 contracts/manifests/dev/base/contracts/pixelaw-actions-16928a49.toml create mode 100644 contracts/manifests/dev/base/contracts/pixelaw-guild_actions-4c9f5931.toml create mode 100644 contracts/manifests/dev/base/contracts/pixelaw-propose_actions-4ee7028a.toml create mode 100644 contracts/manifests/dev/base/contracts/pixelaw-voting_actions-6aab73ea.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-AllowedApp-4aa27058.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-AllowedColor-22c1a796.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-App-36504565.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-AppName-3b816829.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-AppUser-4eda3c52.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-Board-124dc3e7.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-Game-5c1fa23f.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-GameId-1ee8756e.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-GamePalette-49013f2b.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-Guild-40e97c00.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-GuildContractAddress-6a64b8e1.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-InPalette-7a46e3ad.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-Instruction-4c7c4844.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-PWarPixel-15195913.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-PaletteColors-39a92a0a.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-Permissions-72b77307.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-Pixel-7e607b2f.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-Player-30a1b371.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-PlayerVote-326c17c6.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-Proposal-49e1daf5.toml create mode 100644 contracts/manifests/dev/base/models/pixelaw-QueueItem-549a17f2.toml diff --git a/contracts/.gitignore b/contracts/.gitignore index f145cc6..fa002b3 100644 --- a/contracts/.gitignore +++ b/contracts/.gitignore @@ -1,4 +1,5 @@ db target generated -.idea \ No newline at end of file +.idea +manifests \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/contracts/pixelaw-actions-16928a49.json b/contracts/manifests/dev/base/abis/contracts/pixelaw-actions-16928a49.json new file mode 100644 index 0000000..e71ba18 --- /dev/null +++ b/contracts/manifests/dev/base/abis/contracts/pixelaw-actions-16928a49.json @@ -0,0 +1,775 @@ +[ + { + "type": "impl", + "name": "ContractImpl", + "interface_name": "dojo::contract::contract::IContract" + }, + { + "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::contract::contract::IContract", + "items": [ + { + "type": "function", + "name": "contract_name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "WorldProviderImpl", + "interface_name": "dojo::world::world_contract::IWorldProvider" + }, + { + "type": "struct", + "name": "dojo::world::world_contract::IWorldDispatcher", + "members": [ + { + "name": "contract_address", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "type": "interface", + "name": "dojo::world::world_contract::IWorldProvider", + "items": [ + { + "type": "function", + "name": "world", + "inputs": [], + "outputs": [ + { + "type": "dojo::world::world_contract::IWorldDispatcher" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "ActionsImpl", + "interface_name": "pixelaw::core::actions::IActions" + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "pixelaw::core::models::permissions::Permission", + "members": [ + { + "name": "app", + "type": "core::bool" + }, + { + "name": "color", + "type": "core::bool" + }, + { + "name": "owner", + "type": "core::bool" + }, + { + "name": "text", + "type": "core::bool" + }, + { + "name": "timestamp", + "type": "core::bool" + }, + { + "name": "action", + "type": "core::bool" + } + ] + }, + { + "type": "struct", + "name": "pixelaw::core::models::pixel::Pixel", + "members": [ + { + "name": "x", + "type": "core::integer::u32" + }, + { + "name": "y", + "type": "core::integer::u32" + }, + { + "name": "app", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "color", + "type": "core::integer::u32" + }, + { + "name": "created_at", + "type": "core::integer::u64" + }, + { + "name": "updated_at", + "type": "core::integer::u64" + }, + { + "name": "timestamp", + "type": "core::integer::u64" + }, + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "text", + "type": "core::felt252" + }, + { + "name": "action", + "type": "core::felt252" + } + ] + }, + { + "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": "x", + "type": "core::integer::u32" + }, + { + "name": "y", + "type": "core::integer::u32" + }, + { + "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": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "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": "struct", + "name": "pixelaw::core::utils::Position", + "members": [ + { + "name": "x", + "type": "core::integer::u32" + }, + { + "name": "y", + "type": "core::integer::u32" + } + ] + }, + { + "type": "interface", + "name": "pixelaw::core::actions::IActions", + "items": [ + { + "type": "function", + "name": "init", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "update_permission", + "inputs": [ + { + "name": "app_key", + "type": "core::felt252" + }, + { + "name": "permission", + "type": "pixelaw::core::models::permissions::Permission" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "has_write_access", + "inputs": [ + { + "name": "for_player", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "for_system", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "pixel", + "type": "pixelaw::core::models::pixel::Pixel" + }, + { + "name": "pixel_update", + "type": "pixelaw::core::models::pixel::PixelUpdate" + } + ], + "outputs": [ + { + "type": "core::bool" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "process_queue", + "inputs": [ + { + "name": "id", + "type": "core::felt252" + }, + { + "name": "timestamp", + "type": "core::integer::u64" + }, + { + "name": "called_system", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "calldata", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "schedule_queue", + "inputs": [ + { + "name": "timestamp", + "type": "core::integer::u64" + }, + { + "name": "called_system", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "calldata", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "update_pixel", + "inputs": [ + { + "name": "for_player", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "for_system", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "pixel_update", + "type": "pixelaw::core::models::pixel::PixelUpdate" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "new_app", + "inputs": [ + { + "name": "system", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "icon", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "pixelaw::core::models::registry::App" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "get_system_address", + "inputs": [ + { + "name": "for_system", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "get_player_address", + "inputs": [ + { + "name": "for_player", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "alert_player", + "inputs": [ + { + "name": "position", + "type": "pixelaw::core::utils::Position" + }, + { + "name": "player", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "message", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "set_instruction", + "inputs": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "instruction", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "impl", + "name": "IDojoInitImpl", + "interface_name": "pixelaw::core::actions::actions::IDojoInit" + }, + { + "type": "interface", + "name": "pixelaw::core::actions::actions::IDojoInit", + "items": [ + { + "type": "function", + "name": "dojo_init", + "inputs": [], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "UpgradableImpl", + "interface_name": "dojo::contract::upgradeable::IUpgradeable" + }, + { + "type": "interface", + "name": "dojo::contract::upgradeable::IUpgradeable", + "items": [ + { + "type": "function", + "name": "upgrade", + "inputs": [ + { + "name": "new_class_hash", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "event", + "name": "dojo::contract::upgradeable::upgradeable::Upgraded", + "kind": "struct", + "members": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::contract::upgradeable::upgradeable::Event", + "kind": "enum", + "variants": [ + { + "name": "Upgraded", + "type": "dojo::contract::upgradeable::upgradeable::Upgraded", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "pixelaw::core::actions::actions::QueueScheduled", + "kind": "struct", + "members": [ + { + "name": "id", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "timestamp", + "type": "core::integer::u64", + "kind": "data" + }, + { + "name": "called_system", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "selector", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "calldata", + "type": "core::array::Span::", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "pixelaw::core::actions::actions::QueueProcessed", + "kind": "struct", + "members": [ + { + "name": "id", + "type": "core::felt252", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "pixelaw::core::actions::actions::AppNameUpdated", + "kind": "struct", + "members": [ + { + "name": "app", + "type": "pixelaw::core::models::registry::App", + "kind": "data" + }, + { + "name": "caller", + "type": "core::felt252", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "pixelaw::core::actions::actions::Alert", + "kind": "struct", + "members": [ + { + "name": "position", + "type": "pixelaw::core::utils::Position", + "kind": "data" + }, + { + "name": "caller", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "player", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "message", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "timestamp", + "type": "core::integer::u64", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "pixelaw::core::actions::actions::Event", + "kind": "enum", + "variants": [ + { + "name": "UpgradeableEvent", + "type": "dojo::contract::upgradeable::upgradeable::Event", + "kind": "nested" + }, + { + "name": "QueueScheduled", + "type": "pixelaw::core::actions::actions::QueueScheduled", + "kind": "nested" + }, + { + "name": "QueueProcessed", + "type": "pixelaw::core::actions::actions::QueueProcessed", + "kind": "nested" + }, + { + "name": "AppNameUpdated", + "type": "pixelaw::core::actions::actions::AppNameUpdated", + "kind": "nested" + }, + { + "name": "Alert", + "type": "pixelaw::core::actions::actions::Alert", + "kind": "nested" + } + ] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json b/contracts/manifests/dev/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json new file mode 100644 index 0000000..1c07f99 --- /dev/null +++ b/contracts/manifests/dev/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json @@ -0,0 +1,410 @@ +[ + { + "type": "impl", + "name": "ContractImpl", + "interface_name": "dojo::contract::contract::IContract" + }, + { + "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::contract::contract::IContract", + "items": [ + { + "type": "function", + "name": "contract_name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "WorldProviderImpl", + "interface_name": "dojo::world::world_contract::IWorldProvider" + }, + { + "type": "struct", + "name": "dojo::world::world_contract::IWorldDispatcher", + "members": [ + { + "name": "contract_address", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "type": "interface", + "name": "dojo::world::world_contract::IWorldProvider", + "items": [ + { + "type": "function", + "name": "world", + "inputs": [], + "outputs": [ + { + "type": "dojo::world::world_contract::IWorldDispatcher" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "GuildImpl", + "interface_name": "p_war::systems::guilds::IGuild" + }, + { + "type": "interface", + "name": "p_war::systems::guilds::IGuild", + "items": [ + { + "type": "function", + "name": "create_guild", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "guild_name", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::integer::u32" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "add_member", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "guild_id", + "type": "core::integer::u32" + }, + { + "name": "new_member", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "join_guild", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "guild_id", + "type": "core::integer::u32" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "remove_member", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "guild_id", + "type": "core::integer::u32" + }, + { + "name": "member", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "get_guild_contract_address", + "inputs": [], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "get_guild_points", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "guild_id", + "type": "core::integer::u32" + } + ], + "outputs": [ + { + "type": "core::integer::u32" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "IDojoInitImpl", + "interface_name": "p_war::systems::guilds::guild_actions::IDojoInit" + }, + { + "type": "interface", + "name": "p_war::systems::guilds::guild_actions::IDojoInit", + "items": [ + { + "type": "function", + "name": "dojo_init", + "inputs": [], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "UpgradableImpl", + "interface_name": "dojo::contract::upgradeable::IUpgradeable" + }, + { + "type": "interface", + "name": "dojo::contract::upgradeable::IUpgradeable", + "items": [ + { + "type": "function", + "name": "upgrade", + "inputs": [ + { + "name": "new_class_hash", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "event", + "name": "dojo::contract::upgradeable::upgradeable::Upgraded", + "kind": "struct", + "members": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::contract::upgradeable::upgradeable::Event", + "kind": "enum", + "variants": [ + { + "name": "Upgraded", + "type": "dojo::contract::upgradeable::upgradeable::Upgraded", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "p_war::systems::guilds::guild_actions::GuildCreated", + "kind": "struct", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32", + "kind": "data" + }, + { + "name": "guild_id", + "type": "core::integer::u32", + "kind": "data" + }, + { + "name": "guild_name", + "type": "core::felt252", + "kind": "data" + }, + { + "name": "creator", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "p_war::systems::guilds::guild_actions::MemberAdded", + "kind": "struct", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32", + "kind": "data" + }, + { + "name": "guild_id", + "type": "core::integer::u32", + "kind": "data" + }, + { + "name": "member", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "p_war::systems::guilds::guild_actions::MemberRemoved", + "kind": "struct", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32", + "kind": "data" + }, + { + "name": "guild_id", + "type": "core::integer::u32", + "kind": "data" + }, + { + "name": "member", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "p_war::systems::guilds::guild_actions::Event", + "kind": "enum", + "variants": [ + { + "name": "UpgradeableEvent", + "type": "dojo::contract::upgradeable::upgradeable::Event", + "kind": "nested" + }, + { + "name": "GuildCreated", + "type": "p_war::systems::guilds::guild_actions::GuildCreated", + "kind": "nested" + }, + { + "name": "MemberAdded", + "type": "p_war::systems::guilds::guild_actions::MemberAdded", + "kind": "nested" + }, + { + "name": "MemberRemoved", + "type": "p_war::systems::guilds::guild_actions::MemberRemoved", + "kind": "nested" + } + ] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json b/contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json index 5119cbe..fb24eea 100644 --- a/contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json +++ b/contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json @@ -357,70 +357,6 @@ "name": "ActionsImpl", "interface_name": "p_war::systems::actions::IActions" }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::game::Game", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "start", - "type": "core::integer::u64" - }, - { - "name": "end", - "type": "core::integer::u64" - }, - { - "name": "proposal_idx", - "type": "core::integer::u32" - }, - { - "name": "base_cost", - "type": "core::integer::u32" - }, - { - "name": "const_val", - "type": "core::integer::u32" - }, - { - "name": "coeff_own_pixels", - "type": "core::integer::u32" - }, - { - "name": "coeff_commits", - "type": "core::integer::u32" - }, - { - "name": "winner_config", - "type": "core::integer::u32" - }, - { - "name": "winner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "guild_ids", - "type": "core::array::Span::" - }, - { - "name": "guild_count", - "type": "core::integer::u32" - } - ] - }, { "type": "interface", "name": "p_war::systems::actions::IActions", @@ -460,13 +396,29 @@ ], "state_mutability": "external" }, + { + "type": "function", + "name": "set_guild_contract_address", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, { "type": "function", "name": "create_game_guilds", "inputs": [ { - "name": "game", - "type": "p_war::models::game::Game" + "name": "game_id", + "type": "core::integer::u32" } ], "outputs": [], diff --git a/contracts/manifests/dev/base/abis/contracts/pixelaw-propose_actions-4ee7028a.json b/contracts/manifests/dev/base/abis/contracts/pixelaw-propose_actions-4ee7028a.json new file mode 100644 index 0000000..8aa1e40 --- /dev/null +++ b/contracts/manifests/dev/base/abis/contracts/pixelaw-propose_actions-4ee7028a.json @@ -0,0 +1,363 @@ +[ + { + "type": "impl", + "name": "ContractImpl", + "interface_name": "dojo::contract::contract::IContract" + }, + { + "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::contract::contract::IContract", + "items": [ + { + "type": "function", + "name": "contract_name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "WorldProviderImpl", + "interface_name": "dojo::world::world_contract::IWorldProvider" + }, + { + "type": "struct", + "name": "dojo::world::world_contract::IWorldDispatcher", + "members": [ + { + "name": "contract_address", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "type": "interface", + "name": "dojo::world::world_contract::IWorldProvider", + "items": [ + { + "type": "function", + "name": "world", + "inputs": [], + "outputs": [ + { + "type": "dojo::world::world_contract::IWorldDispatcher" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "ProposeImpl", + "interface_name": "p_war::systems::propose::IPropose" + }, + { + "type": "struct", + "name": "pixelaw::core::utils::Position", + "members": [ + { + "name": "x", + "type": "core::integer::u32" + }, + { + "name": "y", + "type": "core::integer::u32" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "interface", + "name": "p_war::systems::propose::IPropose", + "items": [ + { + "type": "function", + "name": "create_proposal", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "proposal_type", + "type": "core::integer::u8" + }, + { + "name": "target_args_1", + "type": "core::integer::u32" + }, + { + "name": "target_args_2", + "type": "core::integer::u32" + } + ], + "outputs": [ + { + "type": "core::integer::u32" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "activate_proposal", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "index", + "type": "core::integer::u32" + }, + { + "name": "clear_data", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "impl", + "name": "IDojoInitImpl", + "interface_name": "p_war::systems::propose::propose_actions::IDojoInit" + }, + { + "type": "interface", + "name": "p_war::systems::propose::propose_actions::IDojoInit", + "items": [ + { + "type": "function", + "name": "dojo_init", + "inputs": [], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "UpgradableImpl", + "interface_name": "dojo::contract::upgradeable::IUpgradeable" + }, + { + "type": "interface", + "name": "dojo::contract::upgradeable::IUpgradeable", + "items": [ + { + "type": "function", + "name": "upgrade", + "inputs": [ + { + "name": "new_class_hash", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "event", + "name": "dojo::contract::upgradeable::upgradeable::Upgraded", + "kind": "struct", + "members": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::contract::upgradeable::upgradeable::Event", + "kind": "enum", + "variants": [ + { + "name": "Upgraded", + "type": "dojo::contract::upgradeable::upgradeable::Upgraded", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "p_war::systems::propose::propose_actions::ProposalCreated", + "kind": "struct", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32", + "kind": "data" + }, + { + "name": "index", + "type": "core::integer::u32", + "kind": "data" + }, + { + "name": "proposal_type", + "type": "core::integer::u8", + "kind": "data" + }, + { + "name": "target_args_1", + "type": "core::integer::u32", + "kind": "data" + }, + { + "name": "target_args_2", + "type": "core::integer::u32", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "p_war::systems::propose::propose_actions::ProposalActivated", + "kind": "struct", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32", + "kind": "data" + }, + { + "name": "index", + "type": "core::integer::u32", + "kind": "data" + }, + { + "name": "proposal_type", + "type": "core::integer::u8", + "kind": "data" + }, + { + "name": "target_args_1", + "type": "core::integer::u32", + "kind": "data" + }, + { + "name": "target_args_2", + "type": "core::integer::u32", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "p_war::systems::propose::propose_actions::Event", + "kind": "enum", + "variants": [ + { + "name": "UpgradeableEvent", + "type": "dojo::contract::upgradeable::upgradeable::Event", + "kind": "nested" + }, + { + "name": "ProposalCreated", + "type": "p_war::systems::propose::propose_actions::ProposalCreated", + "kind": "nested" + }, + { + "name": "ProposalActivated", + "type": "p_war::systems::propose::propose_actions::ProposalActivated", + "kind": "nested" + } + ] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/contracts/pixelaw-voting_actions-6aab73ea.json b/contracts/manifests/dev/base/abis/contracts/pixelaw-voting_actions-6aab73ea.json new file mode 100644 index 0000000..cea01cd --- /dev/null +++ b/contracts/manifests/dev/base/abis/contracts/pixelaw-voting_actions-6aab73ea.json @@ -0,0 +1,292 @@ +[ + { + "type": "impl", + "name": "ContractImpl", + "interface_name": "dojo::contract::contract::IContract" + }, + { + "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::contract::contract::IContract", + "items": [ + { + "type": "function", + "name": "contract_name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "WorldProviderImpl", + "interface_name": "dojo::world::world_contract::IWorldProvider" + }, + { + "type": "struct", + "name": "dojo::world::world_contract::IWorldDispatcher", + "members": [ + { + "name": "contract_address", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "type": "interface", + "name": "dojo::world::world_contract::IWorldProvider", + "items": [ + { + "type": "function", + "name": "world", + "inputs": [], + "outputs": [ + { + "type": "dojo::world::world_contract::IWorldDispatcher" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "VotingImpl", + "interface_name": "p_war::systems::voting::IVoting" + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "p_war::systems::voting::IVoting", + "items": [ + { + "type": "function", + "name": "vote", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "index", + "type": "core::integer::u32" + }, + { + "name": "use_px", + "type": "core::integer::u32" + }, + { + "name": "is_in_favor", + "type": "core::bool" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "impl", + "name": "IDojoInitImpl", + "interface_name": "p_war::systems::voting::voting_actions::IDojoInit" + }, + { + "type": "interface", + "name": "p_war::systems::voting::voting_actions::IDojoInit", + "items": [ + { + "type": "function", + "name": "dojo_init", + "inputs": [], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "UpgradableImpl", + "interface_name": "dojo::contract::upgradeable::IUpgradeable" + }, + { + "type": "interface", + "name": "dojo::contract::upgradeable::IUpgradeable", + "items": [ + { + "type": "function", + "name": "upgrade", + "inputs": [ + { + "name": "new_class_hash", + "type": "core::starknet::class_hash::ClassHash" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "event", + "name": "dojo::contract::upgradeable::upgradeable::Upgraded", + "kind": "struct", + "members": [ + { + "name": "class_hash", + "type": "core::starknet::class_hash::ClassHash", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "dojo::contract::upgradeable::upgradeable::Event", + "kind": "enum", + "variants": [ + { + "name": "Upgraded", + "type": "dojo::contract::upgradeable::upgradeable::Upgraded", + "kind": "nested" + } + ] + }, + { + "type": "event", + "name": "p_war::systems::voting::voting_actions::Voted", + "kind": "struct", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32", + "kind": "data" + }, + { + "name": "index", + "type": "core::integer::u32", + "kind": "data" + }, + { + "name": "timestamp", + "type": "core::integer::u64", + "kind": "data" + }, + { + "name": "voter", + "type": "core::starknet::contract_address::ContractAddress", + "kind": "data" + }, + { + "name": "is_in_favor", + "type": "core::bool", + "kind": "data" + } + ] + }, + { + "type": "event", + "name": "p_war::systems::voting::voting_actions::Event", + "kind": "enum", + "variants": [ + { + "name": "UpgradeableEvent", + "type": "dojo::contract::upgradeable::upgradeable::Event", + "kind": "nested" + }, + { + "name": "Voted", + "type": "p_war::systems::voting::voting_actions::Voted", + "kind": "nested" + } + ] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-AllowedApp-4aa27058.json b/contracts/manifests/dev/base/abis/models/pixelaw-AllowedApp-4aa27058.json new file mode 100644 index 0000000..316e91a --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-AllowedApp-4aa27058.json @@ -0,0 +1,425 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "allowed_appImpl", + "interface_name": "p_war::models::allowed_app::Iallowed_app" + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "p_war::models::allowed_app::AllowedApp", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "contract", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "is_allowed", + "type": "core::bool" + } + ] + }, + { + "type": "interface", + "name": "p_war::models::allowed_app::Iallowed_app", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "p_war::models::allowed_app::AllowedApp" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "p_war::models::allowed_app::allowed_app::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-AllowedColor-22c1a796.json b/contracts/manifests/dev/base/abis/models/pixelaw-AllowedColor-22c1a796.json new file mode 100644 index 0000000..48cc27f --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-AllowedColor-22c1a796.json @@ -0,0 +1,425 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "allowed_colorImpl", + "interface_name": "p_war::models::allowed_color::Iallowed_color" + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "p_war::models::allowed_color::AllowedColor", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "color", + "type": "core::integer::u32" + }, + { + "name": "is_allowed", + "type": "core::bool" + } + ] + }, + { + "type": "interface", + "name": "p_war::models::allowed_color::Iallowed_color", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "p_war::models::allowed_color::AllowedColor" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "p_war::models::allowed_color::allowed_color::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-App-36504565.json b/contracts/manifests/dev/base/abis/models/pixelaw-App-36504565.json new file mode 100644 index 0000000..c2e9c0e --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-App-36504565.json @@ -0,0 +1,415 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "appImpl", + "interface_name": "pixelaw::core::models::registry::Iapp" + }, + { + "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": "interface", + "name": "pixelaw::core::models::registry::Iapp", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "pixelaw::core::models::registry::App" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "pixelaw::core::models::registry::app::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-AppName-3b816829.json b/contracts/manifests/dev/base/abis/models/pixelaw-AppName-3b816829.json new file mode 100644 index 0000000..87a5e61 --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-AppName-3b816829.json @@ -0,0 +1,407 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "app_nameImpl", + "interface_name": "pixelaw::core::models::registry::Iapp_name" + }, + { + "type": "struct", + "name": "pixelaw::core::models::registry::AppName", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "system", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "type": "interface", + "name": "pixelaw::core::models::registry::Iapp_name", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "pixelaw::core::models::registry::AppName" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "pixelaw::core::models::registry::app_name::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-AppUser-4eda3c52.json b/contracts/manifests/dev/base/abis/models/pixelaw-AppUser-4eda3c52.json new file mode 100644 index 0000000..a578a2c --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-AppUser-4eda3c52.json @@ -0,0 +1,411 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "app_userImpl", + "interface_name": "pixelaw::core::models::registry::Iapp_user" + }, + { + "type": "struct", + "name": "pixelaw::core::models::registry::AppUser", + "members": [ + { + "name": "system", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "player", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "action", + "type": "core::felt252" + } + ] + }, + { + "type": "interface", + "name": "pixelaw::core::models::registry::Iapp_user", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "pixelaw::core::models::registry::AppUser" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "pixelaw::core::models::registry::app_user::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Board-124dc3e7.json b/contracts/manifests/dev/base/abis/models/pixelaw-Board-124dc3e7.json new file mode 100644 index 0000000..6f4d779 --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-Board-124dc3e7.json @@ -0,0 +1,429 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "boardImpl", + "interface_name": "p_war::models::board::Iboard" + }, + { + "type": "struct", + "name": "pixelaw::core::utils::Position", + "members": [ + { + "name": "x", + "type": "core::integer::u32" + }, + { + "name": "y", + "type": "core::integer::u32" + } + ] + }, + { + "type": "struct", + "name": "p_war::models::board::Board", + "members": [ + { + "name": "id", + "type": "core::integer::u32" + }, + { + "name": "origin", + "type": "pixelaw::core::utils::Position" + }, + { + "name": "width", + "type": "core::integer::u32" + }, + { + "name": "height", + "type": "core::integer::u32" + } + ] + }, + { + "type": "interface", + "name": "p_war::models::board::Iboard", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "p_war::models::board::Board" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "p_war::models::board::board::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json b/contracts/manifests/dev/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json new file mode 100644 index 0000000..512af25 --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json @@ -0,0 +1,407 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "core_actions_addressImpl", + "interface_name": "pixelaw::core::models::registry::Icore_actions_address" + }, + { + "type": "struct", + "name": "pixelaw::core::models::registry::CoreActionsAddress", + "members": [ + { + "name": "key", + "type": "core::felt252" + }, + { + "name": "value", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "type": "interface", + "name": "pixelaw::core::models::registry::Icore_actions_address", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "pixelaw::core::models::registry::CoreActionsAddress" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "pixelaw::core::models::registry::core_actions_address::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Game-5c1fa23f.json b/contracts/manifests/dev/base/abis/models/pixelaw-Game-5c1fa23f.json new file mode 100644 index 0000000..4b89c1a --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-Game-5c1fa23f.json @@ -0,0 +1,457 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "gameImpl", + "interface_name": "p_war::models::game::Igame" + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "p_war::models::game::Game", + "members": [ + { + "name": "id", + "type": "core::integer::u32" + }, + { + "name": "start", + "type": "core::integer::u64" + }, + { + "name": "end", + "type": "core::integer::u64" + }, + { + "name": "proposal_idx", + "type": "core::integer::u32" + }, + { + "name": "base_cost", + "type": "core::integer::u32" + }, + { + "name": "const_val", + "type": "core::integer::u32" + }, + { + "name": "coeff_own_pixels", + "type": "core::integer::u32" + }, + { + "name": "coeff_commits", + "type": "core::integer::u32" + }, + { + "name": "winner_config", + "type": "core::integer::u32" + }, + { + "name": "winner", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "guild_ids", + "type": "core::array::Span::" + }, + { + "name": "guild_count", + "type": "core::integer::u32" + } + ] + }, + { + "type": "interface", + "name": "p_war::models::game::Igame", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "p_war::models::game::Game" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "p_war::models::game::game::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-GameId-1ee8756e.json b/contracts/manifests/dev/base/abis/models/pixelaw-GameId-1ee8756e.json new file mode 100644 index 0000000..869e2a6 --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-GameId-1ee8756e.json @@ -0,0 +1,411 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "game_idImpl", + "interface_name": "p_war::models::board::Igame_id" + }, + { + "type": "struct", + "name": "p_war::models::board::GameId", + "members": [ + { + "name": "x", + "type": "core::integer::u32" + }, + { + "name": "y", + "type": "core::integer::u32" + }, + { + "name": "value", + "type": "core::integer::u32" + } + ] + }, + { + "type": "interface", + "name": "p_war::models::board::Igame_id", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "p_war::models::board::GameId" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "p_war::models::board::game_id::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-GamePalette-49013f2b.json b/contracts/manifests/dev/base/abis/models/pixelaw-GamePalette-49013f2b.json new file mode 100644 index 0000000..2ee77e7 --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-GamePalette-49013f2b.json @@ -0,0 +1,407 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "game_paletteImpl", + "interface_name": "p_war::models::allowed_color::Igame_palette" + }, + { + "type": "struct", + "name": "p_war::models::allowed_color::GamePalette", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "length", + "type": "core::integer::u32" + } + ] + }, + { + "type": "interface", + "name": "p_war::models::allowed_color::Igame_palette", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "p_war::models::allowed_color::GamePalette" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "p_war::models::allowed_color::game_palette::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Guild-40e97c00.json b/contracts/manifests/dev/base/abis/models/pixelaw-Guild-40e97c00.json new file mode 100644 index 0000000..f963145 --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-Guild-40e97c00.json @@ -0,0 +1,433 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "guildImpl", + "interface_name": "p_war::models::guilds::Iguild" + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "p_war::models::guilds::Guild", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "guild_id", + "type": "core::integer::u32" + }, + { + "name": "guild_name", + "type": "core::felt252" + }, + { + "name": "creator", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "members", + "type": "core::array::Span::" + }, + { + "name": "member_count", + "type": "core::integer::u32" + } + ] + }, + { + "type": "interface", + "name": "p_war::models::guilds::Iguild", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "p_war::models::guilds::Guild" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "p_war::models::guilds::guild::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-GuildContractAddress-6a64b8e1.json b/contracts/manifests/dev/base/abis/models/pixelaw-GuildContractAddress-6a64b8e1.json new file mode 100644 index 0000000..b4ee5cd --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-GuildContractAddress-6a64b8e1.json @@ -0,0 +1,407 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "guild_contract_addressImpl", + "interface_name": "p_war::systems::actions::p_war_actions::Iguild_contract_address" + }, + { + "type": "struct", + "name": "p_war::systems::actions::p_war_actions::GuildContractAddress", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "type": "interface", + "name": "p_war::systems::actions::p_war_actions::Iguild_contract_address", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "p_war::systems::actions::p_war_actions::GuildContractAddress" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "p_war::systems::actions::p_war_actions::guild_contract_address::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-InPalette-7a46e3ad.json b/contracts/manifests/dev/base/abis/models/pixelaw-InPalette-7a46e3ad.json new file mode 100644 index 0000000..4c58dd9 --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-InPalette-7a46e3ad.json @@ -0,0 +1,425 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "in_paletteImpl", + "interface_name": "p_war::models::allowed_color::Iin_palette" + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "p_war::models::allowed_color::InPalette", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "color", + "type": "core::integer::u32" + }, + { + "name": "value", + "type": "core::bool" + } + ] + }, + { + "type": "interface", + "name": "p_war::models::allowed_color::Iin_palette", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "p_war::models::allowed_color::InPalette" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "p_war::models::allowed_color::in_palette::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Instruction-4c7c4844.json b/contracts/manifests/dev/base/abis/models/pixelaw-Instruction-4c7c4844.json new file mode 100644 index 0000000..a79b066 --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-Instruction-4c7c4844.json @@ -0,0 +1,411 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "instructionImpl", + "interface_name": "pixelaw::core::models::registry::Iinstruction" + }, + { + "type": "struct", + "name": "pixelaw::core::models::registry::Instruction", + "members": [ + { + "name": "system", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "instruction", + "type": "core::felt252" + } + ] + }, + { + "type": "interface", + "name": "pixelaw::core::models::registry::Iinstruction", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "pixelaw::core::models::registry::Instruction" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "pixelaw::core::models::registry::instruction::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-PWarPixel-15195913.json b/contracts/manifests/dev/base/abis/models/pixelaw-PWarPixel-15195913.json new file mode 100644 index 0000000..4fb9f2a --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-PWarPixel-15195913.json @@ -0,0 +1,421 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "p_war_pixelImpl", + "interface_name": "p_war::models::board::Ip_war_pixel" + }, + { + "type": "struct", + "name": "pixelaw::core::utils::Position", + "members": [ + { + "name": "x", + "type": "core::integer::u32" + }, + { + "name": "y", + "type": "core::integer::u32" + } + ] + }, + { + "type": "struct", + "name": "p_war::models::board::PWarPixel", + "members": [ + { + "name": "position", + "type": "pixelaw::core::utils::Position" + }, + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "type": "interface", + "name": "p_war::models::board::Ip_war_pixel", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "p_war::models::board::PWarPixel" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "p_war::models::board::p_war_pixel::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-PaletteColors-39a92a0a.json b/contracts/manifests/dev/base/abis/models/pixelaw-PaletteColors-39a92a0a.json new file mode 100644 index 0000000..ac5324c --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-PaletteColors-39a92a0a.json @@ -0,0 +1,411 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "palette_colorsImpl", + "interface_name": "p_war::models::allowed_color::Ipalette_colors" + }, + { + "type": "struct", + "name": "p_war::models::allowed_color::PaletteColors", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "idx", + "type": "core::integer::u32" + }, + { + "name": "color", + "type": "core::integer::u32" + } + ] + }, + { + "type": "interface", + "name": "p_war::models::allowed_color::Ipalette_colors", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "p_war::models::allowed_color::PaletteColors" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "p_war::models::allowed_color::palette_colors::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Permissions-72b77307.json b/contracts/manifests/dev/base/abis/models/pixelaw-Permissions-72b77307.json new file mode 100644 index 0000000..2e1a096 --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-Permissions-72b77307.json @@ -0,0 +1,455 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "permissionsImpl", + "interface_name": "pixelaw::core::models::permissions::Ipermissions" + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "pixelaw::core::models::permissions::Permission", + "members": [ + { + "name": "app", + "type": "core::bool" + }, + { + "name": "color", + "type": "core::bool" + }, + { + "name": "owner", + "type": "core::bool" + }, + { + "name": "text", + "type": "core::bool" + }, + { + "name": "timestamp", + "type": "core::bool" + }, + { + "name": "action", + "type": "core::bool" + } + ] + }, + { + "type": "struct", + "name": "pixelaw::core::models::permissions::Permissions", + "members": [ + { + "name": "allowing_app", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "allowed_app", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "permission", + "type": "pixelaw::core::models::permissions::Permission" + } + ] + }, + { + "type": "interface", + "name": "pixelaw::core::models::permissions::Ipermissions", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "pixelaw::core::models::permissions::Permissions" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "pixelaw::core::models::permissions::permissions::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Pixel-7e607b2f.json b/contracts/manifests/dev/base/abis/models/pixelaw-Pixel-7e607b2f.json new file mode 100644 index 0000000..8f6c36a --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-Pixel-7e607b2f.json @@ -0,0 +1,439 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "pixelImpl", + "interface_name": "pixelaw::core::models::pixel::Ipixel" + }, + { + "type": "struct", + "name": "pixelaw::core::models::pixel::Pixel", + "members": [ + { + "name": "x", + "type": "core::integer::u32" + }, + { + "name": "y", + "type": "core::integer::u32" + }, + { + "name": "app", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "color", + "type": "core::integer::u32" + }, + { + "name": "created_at", + "type": "core::integer::u64" + }, + { + "name": "updated_at", + "type": "core::integer::u64" + }, + { + "name": "timestamp", + "type": "core::integer::u64" + }, + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "text", + "type": "core::felt252" + }, + { + "name": "action", + "type": "core::felt252" + } + ] + }, + { + "type": "interface", + "name": "pixelaw::core::models::pixel::Ipixel", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "pixelaw::core::models::pixel::Pixel" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "pixelaw::core::models::pixel::pixel::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json b/contracts/manifests/dev/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json new file mode 100644 index 0000000..6458f14 --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json @@ -0,0 +1,407 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "pixel_recovery_rateImpl", + "interface_name": "p_war::models::proposal::Ipixel_recovery_rate" + }, + { + "type": "struct", + "name": "p_war::models::proposal::PixelRecoveryRate", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "rate", + "type": "core::integer::u64" + } + ] + }, + { + "type": "interface", + "name": "p_war::models::proposal::Ipixel_recovery_rate", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "p_war::models::proposal::PixelRecoveryRate" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "p_war::models::proposal::pixel_recovery_rate::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Player-30a1b371.json b/contracts/manifests/dev/base/abis/models/pixelaw-Player-30a1b371.json new file mode 100644 index 0000000..7e279da --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-Player-30a1b371.json @@ -0,0 +1,441 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "playerImpl", + "interface_name": "p_war::models::player::Iplayer" + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "p_war::models::player::Player", + "members": [ + { + "name": "address", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "max_px", + "type": "core::integer::u32" + }, + { + "name": "num_owns", + "type": "core::integer::u32" + }, + { + "name": "num_commit", + "type": "core::integer::u32" + }, + { + "name": "current_px", + "type": "core::integer::u32" + }, + { + "name": "last_date", + "type": "core::integer::u64" + }, + { + "name": "is_banned", + "type": "core::bool" + } + ] + }, + { + "type": "interface", + "name": "p_war::models::player::Iplayer", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "p_war::models::player::Player" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "p_war::models::player::player::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-PlayerVote-326c17c6.json b/contracts/manifests/dev/base/abis/models/pixelaw-PlayerVote-326c17c6.json new file mode 100644 index 0000000..aed1379 --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-PlayerVote-326c17c6.json @@ -0,0 +1,433 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "player_voteImpl", + "interface_name": "p_war::models::proposal::Iplayer_vote" + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "p_war::models::proposal::PlayerVote", + "members": [ + { + "name": "player", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "index", + "type": "core::integer::u32" + }, + { + "name": "is_in_favor", + "type": "core::bool" + }, + { + "name": "px", + "type": "core::integer::u32" + } + ] + }, + { + "type": "interface", + "name": "p_war::models::proposal::Iplayer_vote", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "p_war::models::proposal::PlayerVote" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "p_war::models::proposal::player_vote::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Proposal-49e1daf5.json b/contracts/manifests/dev/base/abis/models/pixelaw-Proposal-49e1daf5.json new file mode 100644 index 0000000..2ce1647 --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-Proposal-49e1daf5.json @@ -0,0 +1,457 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "proposalImpl", + "interface_name": "p_war::models::proposal::Iproposal" + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "p_war::models::proposal::Proposal", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "index", + "type": "core::integer::u32" + }, + { + "name": "author", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "proposal_type", + "type": "core::integer::u8" + }, + { + "name": "target_args_1", + "type": "core::integer::u32" + }, + { + "name": "target_args_2", + "type": "core::integer::u32" + }, + { + "name": "start", + "type": "core::integer::u64" + }, + { + "name": "end", + "type": "core::integer::u64" + }, + { + "name": "yes_px", + "type": "core::integer::u32" + }, + { + "name": "no_px", + "type": "core::integer::u32" + }, + { + "name": "is_activated", + "type": "core::bool" + } + ] + }, + { + "type": "interface", + "name": "p_war::models::proposal::Iproposal", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "p_war::models::proposal::Proposal" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "p_war::models::proposal::proposal::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-QueueItem-549a17f2.json b/contracts/manifests/dev/base/abis/models/pixelaw-QueueItem-549a17f2.json new file mode 100644 index 0000000..8496a6c --- /dev/null +++ b/contracts/manifests/dev/base/abis/models/pixelaw-QueueItem-549a17f2.json @@ -0,0 +1,421 @@ +[ + { + "type": "impl", + "name": "DojoModelImpl", + "interface_name": "dojo::model::model::IModel" + }, + { + "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": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "core::integer::u32" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::layout::FieldLayout", + "members": [ + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "layout", + "type": "dojo::model::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::model::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": "struct", + "name": "dojo::model::introspect::Member", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "ty", + "type": "dojo::model::introspect::Ty" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Struct", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "dojo::model::introspect::Enum", + "members": [ + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "attrs", + "type": "core::array::Span::" + }, + { + "name": "children", + "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "enum", + "name": "dojo::model::introspect::Ty", + "variants": [ + { + "name": "Primitive", + "type": "core::felt252" + }, + { + "name": "Struct", + "type": "dojo::model::introspect::Struct" + }, + { + "name": "Enum", + "type": "dojo::model::introspect::Enum" + }, + { + "name": "Tuple", + "type": "core::array::Span::" + }, + { + "name": "Array", + "type": "core::array::Span::" + }, + { + "name": "ByteArray", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "dojo::model::model::IModel", + "items": [ + { + "type": "function", + "name": "name", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "tag", + "inputs": [], + "outputs": [ + { + "type": "core::byte_array::ByteArray" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "version", + "inputs": [], + "outputs": [ + { + "type": "core::integer::u8" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "selector", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "name_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "namespace_hash", + "inputs": [], + "outputs": [ + { + "type": "core::felt252" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "unpacked_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "packed_size", + "inputs": [], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "layout", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::layout::Layout" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "schema", + "inputs": [], + "outputs": [ + { + "type": "dojo::model::introspect::Ty" + } + ], + "state_mutability": "view" + } + ] + }, + { + "type": "impl", + "name": "queue_itemImpl", + "interface_name": "pixelaw::core::models::queue::Iqueue_item" + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "pixelaw::core::models::queue::QueueItem", + "members": [ + { + "name": "id", + "type": "core::felt252" + }, + { + "name": "valid", + "type": "core::bool" + } + ] + }, + { + "type": "interface", + "name": "pixelaw::core::models::queue::Iqueue_item", + "items": [ + { + "type": "function", + "name": "ensure_abi", + "inputs": [ + { + "name": "model", + "type": "pixelaw::core::models::queue::QueueItem" + } + ], + "outputs": [], + "state_mutability": "view" + } + ] + }, + { + "type": "event", + "name": "pixelaw::core::models::queue::queue_item::Event", + "kind": "enum", + "variants": [] + } +] \ No newline at end of file diff --git a/contracts/manifests/dev/base/contracts/pixelaw-actions-16928a49.toml b/contracts/manifests/dev/base/contracts/pixelaw-actions-16928a49.toml new file mode 100644 index 0000000..5ab4bd2 --- /dev/null +++ b/contracts/manifests/dev/base/contracts/pixelaw-actions-16928a49.toml @@ -0,0 +1,19 @@ +kind = "DojoContract" +class_hash = "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f" +original_class_hash = "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f" +base_class_hash = "0x0" +abi = "manifests/dev/base/abis/contracts/pixelaw-actions-16928a49.json" +reads = [] +writes = [] +init_calldata = [] +tag = "pixelaw-actions" +systems = [ + "init", + "update_permission", + "schedule_queue", + "process_queue", + "update_pixel", + "alert_player", + "set_instruction", +] +manifest_name = "pixelaw-actions-16928a49" diff --git a/contracts/manifests/dev/base/contracts/pixelaw-guild_actions-4c9f5931.toml b/contracts/manifests/dev/base/contracts/pixelaw-guild_actions-4c9f5931.toml new file mode 100644 index 0000000..63fc0a4 --- /dev/null +++ b/contracts/manifests/dev/base/contracts/pixelaw-guild_actions-4c9f5931.toml @@ -0,0 +1,15 @@ +kind = "DojoContract" +class_hash = "0x16dce3a4c8116fa7d866bd8896050201427a10214befa642a93135b327bd250" +original_class_hash = "0x16dce3a4c8116fa7d866bd8896050201427a10214befa642a93135b327bd250" +base_class_hash = "0x0" +abi = "manifests/dev/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json" +reads = [] +writes = [] +init_calldata = [] +tag = "pixelaw-guild_actions" +systems = [ + "add_member", + "join_guild", + "remove_member", +] +manifest_name = "pixelaw-guild_actions-4c9f5931" diff --git a/contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml b/contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml index 9738e98..a936dae 100644 --- a/contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml +++ b/contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml @@ -1,6 +1,6 @@ kind = "DojoContract" -class_hash = "0x65b2b00b404aa52d2d1b6a7680b3f30902d84e7e297bb075dbd0a8c3443716d" -original_class_hash = "0x65b2b00b404aa52d2d1b6a7680b3f30902d84e7e297bb075dbd0a8c3443716d" +class_hash = "0x10825ca403e033ca686cee54d2df5cd164cffadecb7172d4f6fcf542a551453" +original_class_hash = "0x10825ca403e033ca686cee54d2df5cd164cffadecb7172d4f6fcf542a551453" base_class_hash = "0x0" abi = "manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json" reads = [] @@ -13,6 +13,7 @@ systems = [ "set_pixel", "init", "interact", + "set_guild_contract_address", "create_game_guilds", "place_pixel", "update_pixel", diff --git a/contracts/manifests/dev/base/contracts/pixelaw-propose_actions-4ee7028a.toml b/contracts/manifests/dev/base/contracts/pixelaw-propose_actions-4ee7028a.toml new file mode 100644 index 0000000..9b72f70 --- /dev/null +++ b/contracts/manifests/dev/base/contracts/pixelaw-propose_actions-4ee7028a.toml @@ -0,0 +1,11 @@ +kind = "DojoContract" +class_hash = "0x263ab9727c708c507c2d88afe371d50e7dbdd50723938494525f54de583fa20" +original_class_hash = "0x263ab9727c708c507c2d88afe371d50e7dbdd50723938494525f54de583fa20" +base_class_hash = "0x0" +abi = "manifests/dev/base/abis/contracts/pixelaw-propose_actions-4ee7028a.json" +reads = [] +writes = [] +init_calldata = [] +tag = "pixelaw-propose_actions" +systems = ["activate_proposal"] +manifest_name = "pixelaw-propose_actions-4ee7028a" diff --git a/contracts/manifests/dev/base/contracts/pixelaw-voting_actions-6aab73ea.toml b/contracts/manifests/dev/base/contracts/pixelaw-voting_actions-6aab73ea.toml new file mode 100644 index 0000000..9812616 --- /dev/null +++ b/contracts/manifests/dev/base/contracts/pixelaw-voting_actions-6aab73ea.toml @@ -0,0 +1,11 @@ +kind = "DojoContract" +class_hash = "0x9f68df7e2c3f6d463c1f6dcca9f2ca3f2d444d5f98557d4c270baf3426fe3c" +original_class_hash = "0x9f68df7e2c3f6d463c1f6dcca9f2ca3f2d444d5f98557d4c270baf3426fe3c" +base_class_hash = "0x0" +abi = "manifests/dev/base/abis/contracts/pixelaw-voting_actions-6aab73ea.json" +reads = [] +writes = [] +init_calldata = [] +tag = "pixelaw-voting_actions" +systems = ["vote"] +manifest_name = "pixelaw-voting_actions-6aab73ea" diff --git a/contracts/manifests/dev/base/models/pixelaw-AllowedApp-4aa27058.toml b/contracts/manifests/dev/base/models/pixelaw-AllowedApp-4aa27058.toml new file mode 100644 index 0000000..3c18d84 --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-AllowedApp-4aa27058.toml @@ -0,0 +1,22 @@ +kind = "DojoModel" +class_hash = "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f" +original_class_hash = "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f" +abi = "manifests/dev/base/abis/models/pixelaw-AllowedApp-4aa27058.json" +tag = "pixelaw-AllowedApp" +qualified_path = "p_war::models::allowed_app::allowed_app" +manifest_name = "pixelaw-AllowedApp-4aa27058" + +[[members]] +name = "game_id" +type = "usize" +key = true + +[[members]] +name = "contract" +type = "ContractAddress" +key = true + +[[members]] +name = "is_allowed" +type = "bool" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-AllowedColor-22c1a796.toml b/contracts/manifests/dev/base/models/pixelaw-AllowedColor-22c1a796.toml new file mode 100644 index 0000000..fe91aad --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-AllowedColor-22c1a796.toml @@ -0,0 +1,22 @@ +kind = "DojoModel" +class_hash = "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54" +original_class_hash = "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54" +abi = "manifests/dev/base/abis/models/pixelaw-AllowedColor-22c1a796.json" +tag = "pixelaw-AllowedColor" +qualified_path = "p_war::models::allowed_color::allowed_color" +manifest_name = "pixelaw-AllowedColor-22c1a796" + +[[members]] +name = "game_id" +type = "usize" +key = true + +[[members]] +name = "color" +type = "u32" +key = true + +[[members]] +name = "is_allowed" +type = "bool" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-App-36504565.toml b/contracts/manifests/dev/base/models/pixelaw-App-36504565.toml new file mode 100644 index 0000000..ce308c9 --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-App-36504565.toml @@ -0,0 +1,27 @@ +kind = "DojoModel" +class_hash = "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c" +original_class_hash = "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c" +abi = "manifests/dev/base/abis/models/pixelaw-App-36504565.json" +tag = "pixelaw-App" +qualified_path = "pixelaw::core::models::registry::app" +manifest_name = "pixelaw-App-36504565" + +[[members]] +name = "system" +type = "ContractAddress" +key = true + +[[members]] +name = "name" +type = "felt252" +key = false + +[[members]] +name = "icon" +type = "felt252" +key = false + +[[members]] +name = "action" +type = "felt252" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-AppName-3b816829.toml b/contracts/manifests/dev/base/models/pixelaw-AppName-3b816829.toml new file mode 100644 index 0000000..d48078e --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-AppName-3b816829.toml @@ -0,0 +1,17 @@ +kind = "DojoModel" +class_hash = "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8" +original_class_hash = "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8" +abi = "manifests/dev/base/abis/models/pixelaw-AppName-3b816829.json" +tag = "pixelaw-AppName" +qualified_path = "pixelaw::core::models::registry::app_name" +manifest_name = "pixelaw-AppName-3b816829" + +[[members]] +name = "name" +type = "felt252" +key = true + +[[members]] +name = "system" +type = "ContractAddress" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-AppUser-4eda3c52.toml b/contracts/manifests/dev/base/models/pixelaw-AppUser-4eda3c52.toml new file mode 100644 index 0000000..426707a --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-AppUser-4eda3c52.toml @@ -0,0 +1,22 @@ +kind = "DojoModel" +class_hash = "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1" +original_class_hash = "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1" +abi = "manifests/dev/base/abis/models/pixelaw-AppUser-4eda3c52.json" +tag = "pixelaw-AppUser" +qualified_path = "pixelaw::core::models::registry::app_user" +manifest_name = "pixelaw-AppUser-4eda3c52" + +[[members]] +name = "system" +type = "ContractAddress" +key = true + +[[members]] +name = "player" +type = "ContractAddress" +key = true + +[[members]] +name = "action" +type = "felt252" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Board-124dc3e7.toml b/contracts/manifests/dev/base/models/pixelaw-Board-124dc3e7.toml new file mode 100644 index 0000000..9cc4cfe --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-Board-124dc3e7.toml @@ -0,0 +1,27 @@ +kind = "DojoModel" +class_hash = "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c" +original_class_hash = "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c" +abi = "manifests/dev/base/abis/models/pixelaw-Board-124dc3e7.json" +tag = "pixelaw-Board" +qualified_path = "p_war::models::board::board" +manifest_name = "pixelaw-Board-124dc3e7" + +[[members]] +name = "id" +type = "usize" +key = true + +[[members]] +name = "origin" +type = "Position" +key = false + +[[members]] +name = "width" +type = "u32" +key = false + +[[members]] +name = "height" +type = "u32" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml b/contracts/manifests/dev/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml new file mode 100644 index 0000000..b6eec60 --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml @@ -0,0 +1,17 @@ +kind = "DojoModel" +class_hash = "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2" +original_class_hash = "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2" +abi = "manifests/dev/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json" +tag = "pixelaw-CoreActionsAddress" +qualified_path = "pixelaw::core::models::registry::core_actions_address" +manifest_name = "pixelaw-CoreActionsAddress-5379e1ce" + +[[members]] +name = "key" +type = "felt252" +key = true + +[[members]] +name = "value" +type = "ContractAddress" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Game-5c1fa23f.toml b/contracts/manifests/dev/base/models/pixelaw-Game-5c1fa23f.toml new file mode 100644 index 0000000..bddf5c1 --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-Game-5c1fa23f.toml @@ -0,0 +1,67 @@ +kind = "DojoModel" +class_hash = "0x794c64750ec570c0678f6afd54210e88f6da106ba0172f2ec03405c3c0ad70e" +original_class_hash = "0x794c64750ec570c0678f6afd54210e88f6da106ba0172f2ec03405c3c0ad70e" +abi = "manifests/dev/base/abis/models/pixelaw-Game-5c1fa23f.json" +tag = "pixelaw-Game" +qualified_path = "p_war::models::game::game" +manifest_name = "pixelaw-Game-5c1fa23f" + +[[members]] +name = "id" +type = "usize" +key = true + +[[members]] +name = "start" +type = "u64" +key = false + +[[members]] +name = "end" +type = "u64" +key = false + +[[members]] +name = "proposal_idx" +type = "usize" +key = false + +[[members]] +name = "base_cost" +type = "u32" +key = false + +[[members]] +name = "const_val" +type = "u32" +key = false + +[[members]] +name = "coeff_own_pixels" +type = "u32" +key = false + +[[members]] +name = "coeff_commits" +type = "u32" +key = false + +[[members]] +name = "winner_config" +type = "u32" +key = false + +[[members]] +name = "winner" +type = "ContractAddress" +key = false + +[[members]] +name = "guild_ids" +type = "Span" +key = false + +[[members]] +name = "guild_count" +type = "usize" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-GameId-1ee8756e.toml b/contracts/manifests/dev/base/models/pixelaw-GameId-1ee8756e.toml new file mode 100644 index 0000000..c38abc0 --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-GameId-1ee8756e.toml @@ -0,0 +1,22 @@ +kind = "DojoModel" +class_hash = "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4" +original_class_hash = "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4" +abi = "manifests/dev/base/abis/models/pixelaw-GameId-1ee8756e.json" +tag = "pixelaw-GameId" +qualified_path = "p_war::models::board::game_id" +manifest_name = "pixelaw-GameId-1ee8756e" + +[[members]] +name = "x" +type = "u32" +key = true + +[[members]] +name = "y" +type = "u32" +key = true + +[[members]] +name = "value" +type = "usize" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-GamePalette-49013f2b.toml b/contracts/manifests/dev/base/models/pixelaw-GamePalette-49013f2b.toml new file mode 100644 index 0000000..1eaf78e --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-GamePalette-49013f2b.toml @@ -0,0 +1,17 @@ +kind = "DojoModel" +class_hash = "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398" +original_class_hash = "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398" +abi = "manifests/dev/base/abis/models/pixelaw-GamePalette-49013f2b.json" +tag = "pixelaw-GamePalette" +qualified_path = "p_war::models::allowed_color::game_palette" +manifest_name = "pixelaw-GamePalette-49013f2b" + +[[members]] +name = "game_id" +type = "usize" +key = true + +[[members]] +name = "length" +type = "usize" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Guild-40e97c00.toml b/contracts/manifests/dev/base/models/pixelaw-Guild-40e97c00.toml new file mode 100644 index 0000000..42941e2 --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-Guild-40e97c00.toml @@ -0,0 +1,37 @@ +kind = "DojoModel" +class_hash = "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95" +original_class_hash = "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95" +abi = "manifests/dev/base/abis/models/pixelaw-Guild-40e97c00.json" +tag = "pixelaw-Guild" +qualified_path = "p_war::models::guilds::guild" +manifest_name = "pixelaw-Guild-40e97c00" + +[[members]] +name = "game_id" +type = "usize" +key = true + +[[members]] +name = "guild_id" +type = "usize" +key = true + +[[members]] +name = "guild_name" +type = "felt252" +key = false + +[[members]] +name = "creator" +type = "ContractAddress" +key = false + +[[members]] +name = "members" +type = "Span" +key = false + +[[members]] +name = "member_count" +type = "usize" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-GuildContractAddress-6a64b8e1.toml b/contracts/manifests/dev/base/models/pixelaw-GuildContractAddress-6a64b8e1.toml new file mode 100644 index 0000000..c42bb1d --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-GuildContractAddress-6a64b8e1.toml @@ -0,0 +1,17 @@ +kind = "DojoModel" +class_hash = "0x7061fde93c6cf87511892ac88bc9d5443971aaf07983022821d3f0e5407b95" +original_class_hash = "0x7061fde93c6cf87511892ac88bc9d5443971aaf07983022821d3f0e5407b95" +abi = "manifests/dev/base/abis/models/pixelaw-GuildContractAddress-6a64b8e1.json" +tag = "pixelaw-GuildContractAddress" +qualified_path = "p_war::systems::actions::p_war_actions::guild_contract_address" +manifest_name = "pixelaw-GuildContractAddress-6a64b8e1" + +[[members]] +name = "game_id" +type = "usize" +key = true + +[[members]] +name = "address" +type = "ContractAddress" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-InPalette-7a46e3ad.toml b/contracts/manifests/dev/base/models/pixelaw-InPalette-7a46e3ad.toml new file mode 100644 index 0000000..d3d005c --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-InPalette-7a46e3ad.toml @@ -0,0 +1,22 @@ +kind = "DojoModel" +class_hash = "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372" +original_class_hash = "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372" +abi = "manifests/dev/base/abis/models/pixelaw-InPalette-7a46e3ad.json" +tag = "pixelaw-InPalette" +qualified_path = "p_war::models::allowed_color::in_palette" +manifest_name = "pixelaw-InPalette-7a46e3ad" + +[[members]] +name = "game_id" +type = "usize" +key = true + +[[members]] +name = "color" +type = "u32" +key = true + +[[members]] +name = "value" +type = "bool" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Instruction-4c7c4844.toml b/contracts/manifests/dev/base/models/pixelaw-Instruction-4c7c4844.toml new file mode 100644 index 0000000..c6a8378 --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-Instruction-4c7c4844.toml @@ -0,0 +1,22 @@ +kind = "DojoModel" +class_hash = "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af" +original_class_hash = "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af" +abi = "manifests/dev/base/abis/models/pixelaw-Instruction-4c7c4844.json" +tag = "pixelaw-Instruction" +qualified_path = "pixelaw::core::models::registry::instruction" +manifest_name = "pixelaw-Instruction-4c7c4844" + +[[members]] +name = "system" +type = "ContractAddress" +key = true + +[[members]] +name = "selector" +type = "felt252" +key = true + +[[members]] +name = "instruction" +type = "felt252" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-PWarPixel-15195913.toml b/contracts/manifests/dev/base/models/pixelaw-PWarPixel-15195913.toml new file mode 100644 index 0000000..30703ad --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-PWarPixel-15195913.toml @@ -0,0 +1,17 @@ +kind = "DojoModel" +class_hash = "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261" +original_class_hash = "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261" +abi = "manifests/dev/base/abis/models/pixelaw-PWarPixel-15195913.json" +tag = "pixelaw-PWarPixel" +qualified_path = "p_war::models::board::p_war_pixel" +manifest_name = "pixelaw-PWarPixel-15195913" + +[[members]] +name = "position" +type = "Position" +key = true + +[[members]] +name = "owner" +type = "ContractAddress" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-PaletteColors-39a92a0a.toml b/contracts/manifests/dev/base/models/pixelaw-PaletteColors-39a92a0a.toml new file mode 100644 index 0000000..9e95d01 --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-PaletteColors-39a92a0a.toml @@ -0,0 +1,22 @@ +kind = "DojoModel" +class_hash = "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444" +original_class_hash = "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444" +abi = "manifests/dev/base/abis/models/pixelaw-PaletteColors-39a92a0a.json" +tag = "pixelaw-PaletteColors" +qualified_path = "p_war::models::allowed_color::palette_colors" +manifest_name = "pixelaw-PaletteColors-39a92a0a" + +[[members]] +name = "game_id" +type = "usize" +key = true + +[[members]] +name = "idx" +type = "u32" +key = true + +[[members]] +name = "color" +type = "u32" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Permissions-72b77307.toml b/contracts/manifests/dev/base/models/pixelaw-Permissions-72b77307.toml new file mode 100644 index 0000000..e2dd2e5 --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-Permissions-72b77307.toml @@ -0,0 +1,22 @@ +kind = "DojoModel" +class_hash = "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302" +original_class_hash = "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302" +abi = "manifests/dev/base/abis/models/pixelaw-Permissions-72b77307.json" +tag = "pixelaw-Permissions" +qualified_path = "pixelaw::core::models::permissions::permissions" +manifest_name = "pixelaw-Permissions-72b77307" + +[[members]] +name = "allowing_app" +type = "ContractAddress" +key = true + +[[members]] +name = "allowed_app" +type = "ContractAddress" +key = true + +[[members]] +name = "permission" +type = "Permission" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Pixel-7e607b2f.toml b/contracts/manifests/dev/base/models/pixelaw-Pixel-7e607b2f.toml new file mode 100644 index 0000000..31ddb3b --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-Pixel-7e607b2f.toml @@ -0,0 +1,57 @@ +kind = "DojoModel" +class_hash = "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d" +original_class_hash = "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d" +abi = "manifests/dev/base/abis/models/pixelaw-Pixel-7e607b2f.json" +tag = "pixelaw-Pixel" +qualified_path = "pixelaw::core::models::pixel::pixel" +manifest_name = "pixelaw-Pixel-7e607b2f" + +[[members]] +name = "x" +type = "u32" +key = true + +[[members]] +name = "y" +type = "u32" +key = true + +[[members]] +name = "app" +type = "ContractAddress" +key = false + +[[members]] +name = "color" +type = "u32" +key = false + +[[members]] +name = "created_at" +type = "u64" +key = false + +[[members]] +name = "updated_at" +type = "u64" +key = false + +[[members]] +name = "timestamp" +type = "u64" +key = false + +[[members]] +name = "owner" +type = "ContractAddress" +key = false + +[[members]] +name = "text" +type = "felt252" +key = false + +[[members]] +name = "action" +type = "felt252" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml b/contracts/manifests/dev/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml new file mode 100644 index 0000000..9167f2e --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml @@ -0,0 +1,17 @@ +kind = "DojoModel" +class_hash = "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067" +original_class_hash = "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067" +abi = "manifests/dev/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json" +tag = "pixelaw-PixelRecoveryRate" +qualified_path = "p_war::models::proposal::pixel_recovery_rate" +manifest_name = "pixelaw-PixelRecoveryRate-3aa284c0" + +[[members]] +name = "game_id" +type = "usize" +key = true + +[[members]] +name = "rate" +type = "u64" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Player-30a1b371.toml b/contracts/manifests/dev/base/models/pixelaw-Player-30a1b371.toml new file mode 100644 index 0000000..c8c1ce5 --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-Player-30a1b371.toml @@ -0,0 +1,42 @@ +kind = "DojoModel" +class_hash = "0x73f4c14a1b7cfadff6bdad338ebacc61fa1c429a6610fd00480312ec6f37180" +original_class_hash = "0x73f4c14a1b7cfadff6bdad338ebacc61fa1c429a6610fd00480312ec6f37180" +abi = "manifests/dev/base/abis/models/pixelaw-Player-30a1b371.json" +tag = "pixelaw-Player" +qualified_path = "p_war::models::player::player" +manifest_name = "pixelaw-Player-30a1b371" + +[[members]] +name = "address" +type = "ContractAddress" +key = true + +[[members]] +name = "max_px" +type = "u32" +key = false + +[[members]] +name = "num_owns" +type = "u32" +key = false + +[[members]] +name = "num_commit" +type = "u32" +key = false + +[[members]] +name = "current_px" +type = "u32" +key = false + +[[members]] +name = "last_date" +type = "u64" +key = false + +[[members]] +name = "is_banned" +type = "bool" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-PlayerVote-326c17c6.toml b/contracts/manifests/dev/base/models/pixelaw-PlayerVote-326c17c6.toml new file mode 100644 index 0000000..4061d5a --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-PlayerVote-326c17c6.toml @@ -0,0 +1,32 @@ +kind = "DojoModel" +class_hash = "0x249aaae81a4275050c7d9f959c5b09c1babbd39b47697bb895adc72cf7965c5" +original_class_hash = "0x249aaae81a4275050c7d9f959c5b09c1babbd39b47697bb895adc72cf7965c5" +abi = "manifests/dev/base/abis/models/pixelaw-PlayerVote-326c17c6.json" +tag = "pixelaw-PlayerVote" +qualified_path = "p_war::models::proposal::player_vote" +manifest_name = "pixelaw-PlayerVote-326c17c6" + +[[members]] +name = "player" +type = "ContractAddress" +key = true + +[[members]] +name = "game_id" +type = "usize" +key = true + +[[members]] +name = "index" +type = "usize" +key = true + +[[members]] +name = "is_in_favor" +type = "bool" +key = false + +[[members]] +name = "px" +type = "u32" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Proposal-49e1daf5.toml b/contracts/manifests/dev/base/models/pixelaw-Proposal-49e1daf5.toml new file mode 100644 index 0000000..60b4aab --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-Proposal-49e1daf5.toml @@ -0,0 +1,62 @@ +kind = "DojoModel" +class_hash = "0x404d31fa774f450e44ff386730f3f43c2932d7cfcc55251e2a0ef2c77f5dc96" +original_class_hash = "0x404d31fa774f450e44ff386730f3f43c2932d7cfcc55251e2a0ef2c77f5dc96" +abi = "manifests/dev/base/abis/models/pixelaw-Proposal-49e1daf5.json" +tag = "pixelaw-Proposal" +qualified_path = "p_war::models::proposal::proposal" +manifest_name = "pixelaw-Proposal-49e1daf5" + +[[members]] +name = "game_id" +type = "usize" +key = true + +[[members]] +name = "index" +type = "usize" +key = true + +[[members]] +name = "author" +type = "ContractAddress" +key = false + +[[members]] +name = "proposal_type" +type = "u8" +key = false + +[[members]] +name = "target_args_1" +type = "u32" +key = false + +[[members]] +name = "target_args_2" +type = "u32" +key = false + +[[members]] +name = "start" +type = "u64" +key = false + +[[members]] +name = "end" +type = "u64" +key = false + +[[members]] +name = "yes_px" +type = "u32" +key = false + +[[members]] +name = "no_px" +type = "u32" +key = false + +[[members]] +name = "is_activated" +type = "bool" +key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-QueueItem-549a17f2.toml b/contracts/manifests/dev/base/models/pixelaw-QueueItem-549a17f2.toml new file mode 100644 index 0000000..8e33ac5 --- /dev/null +++ b/contracts/manifests/dev/base/models/pixelaw-QueueItem-549a17f2.toml @@ -0,0 +1,17 @@ +kind = "DojoModel" +class_hash = "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70" +original_class_hash = "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70" +abi = "manifests/dev/base/abis/models/pixelaw-QueueItem-549a17f2.json" +tag = "pixelaw-QueueItem" +qualified_path = "pixelaw::core::models::queue::queue_item" +manifest_name = "pixelaw-QueueItem-549a17f2" + +[[members]] +name = "id" +type = "felt252" +key = true + +[[members]] +name = "valid" +type = "bool" +key = false diff --git a/contracts/src/systems/actions.cairo b/contracts/src/systems/actions.cairo index 530f0d4..fdc2322 100644 --- a/contracts/src/systems/actions.cairo +++ b/contracts/src/systems/actions.cairo @@ -12,7 +12,8 @@ trait IActions { fn init(ref world: IWorldDispatcher); fn interact(ref world: IWorldDispatcher, default_params: DefaultParameters); fn create_game(ref world: IWorldDispatcher, origin: Position) -> usize; - fn create_game_guilds(ref world: IWorldDispatcher, game: Game); + fn set_guild_contract_address(ref world: IWorldDispatcher, game_id: usize, address: ContractAddress); + fn create_game_guilds(ref world: IWorldDispatcher, game_id: usize); fn get_game_id(world: @IWorldDispatcher, position: Position) -> usize; fn place_pixel( ref world: IWorldDispatcher, app: ContractAddress, default_params: DefaultParameters @@ -57,6 +58,15 @@ mod p_war_actions { EndedGame: EndedGame } + #[derive(Copy, Drop, Serde)] + #[dojo::event] + #[dojo::model] + struct GuildContractAddress { + #[key] + game_id: usize, + address: ContractAddress, + } + #[derive(Drop, Serde, starknet::Event)] struct StartedGame { id: usize, @@ -151,6 +161,12 @@ mod p_war_actions { return 1; } + fn set_guild_contract_address(ref world: IWorldDispatcher, game_id: usize, address: ContractAddress) { + // Only allow the contract owner or an authorized address to set this + //assert(get_caller_address() == world.get_owner(), 'Unauthorized'); + set!(world, (GuildContractAddress { game_id, address })); + } + fn create_game(ref world: IWorldDispatcher, origin: Position) -> usize { println!("create_game BEGIN"); @@ -273,19 +289,25 @@ mod p_war_actions { // recover px recover_px(world, id, player); - self.create_game_guilds(game); + self.create_game_guilds(id); id // emit event that game has started } // initialize guilds for the game - fn create_game_guilds(ref world: IWorldDispatcher, game: Game) { - let guild_dispatcher = IGuildDispatcher { contract_address: world.contract_address }; - guild_dispatcher.create_guild(game.id, 'Fire'); - guild_dispatcher.create_guild(game.id, 'Water'); - guild_dispatcher.create_guild(game.id, 'Earth'); - guild_dispatcher.create_guild(game.id, 'Air'); + fn create_game_guilds(ref world: IWorldDispatcher, game_id: usize) { + let guild_address = get!(world, game_id, GuildContractAddress).address; + let guild_dispatcher = IGuildDispatcher { contract_address: guild_address }; + + guild_dispatcher.create_guild(game_id, 'Fire'); + guild_dispatcher.create_guild(game_id, 'Water'); + guild_dispatcher.create_guild(game_id, 'Earth'); + guild_dispatcher.create_guild(game_id, 'Air'); + // when initilaising pwar it needs a guild contract + // setter for guild contract + // secure pwar to not call the wrong for guild contract + // modify initialising steps } // To paint, basically use this function. diff --git a/contracts/src/systems/guilds.cairo b/contracts/src/systems/guilds.cairo index 92835d5..7f60481 100644 --- a/contracts/src/systems/guilds.cairo +++ b/contracts/src/systems/guilds.cairo @@ -15,6 +15,7 @@ trait IGuild { fn remove_member( ref world: IWorldDispatcher, game_id: usize, guild_id: usize, member: ContractAddress ); + fn get_guild_contract_address(world: @IWorldDispatcher) -> ContractAddress; fn get_guild_points(world: @IWorldDispatcher, game_id: usize, guild_id: usize) -> usize; } @@ -210,6 +211,12 @@ mod guild_actions { emit!(world, (Event::MemberRemoved(MemberRemoved { game_id, guild_id, member }))); } + fn get_guild_contract_address(world: @IWorldDispatcher) -> ContractAddress { + let guild_contract_address = get_contract_address(); + + guild_contract_address + } + fn get_guild_points(world: @IWorldDispatcher, game_id: usize, guild_id: usize) -> usize { // Get the guild let mut guild = get!(world, (game_id, guild_id), (Guild)); From 9b26eee88496e055a674e85a596574546fe304eb Mon Sep 17 00:00:00 2001 From: OwnerOfJK Date: Mon, 25 Nov 2024 18:18:39 +0800 Subject: [PATCH 03/18] in process of updating to dojo1.0.1 --- contracts/.tool-versions | 4 +- contracts/Scarb.lock | 12 +- contracts/Scarb.toml | 27 +- .../pixelaw-p_war_actions-60819afd.json | 16 +- ...pixelaw-GuildContractAddress-6a64b8e1.json | 407 ------------------ .../pixelaw-p_war_actions-60819afd.toml | 6 +- ...pixelaw-GuildContractAddress-6a64b8e1.toml | 17 - contracts/src/lib.cairo | 4 +- contracts/src/models/payments.cairo | 29 ++ contracts/src/systems/actions.cairo | 243 ++++------- contracts/src/systems/apps.cairo | 2 +- contracts/src/systems/guilds.cairo | 66 ++- contracts/src/systems/payments.cairo | 117 +++++ contracts/src/systems/propose.cairo | 365 ++++++++-------- contracts/src/systems/voting.cairo | 2 +- contracts/src/tests/test_guild.cairo | 135 +++++- contracts/src/tests/utils.cairo | 5 +- 17 files changed, 580 insertions(+), 877 deletions(-) delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-GuildContractAddress-6a64b8e1.json delete mode 100644 contracts/manifests/dev/base/models/pixelaw-GuildContractAddress-6a64b8e1.toml create mode 100644 contracts/src/models/payments.cairo create mode 100644 contracts/src/systems/payments.cairo diff --git a/contracts/.tool-versions b/contracts/.tool-versions index e7a7460..a62484c 100644 --- a/contracts/.tool-versions +++ b/contracts/.tool-versions @@ -1,2 +1,2 @@ -scarb 2.7.0 -dojo 1.0.0-alpha.11 \ No newline at end of file +dojo 1.0.1 +scarb 2.7.0 \ No newline at end of file diff --git a/contracts/Scarb.lock b/contracts/Scarb.lock index bc22c64..485b9f3 100644 --- a/contracts/Scarb.lock +++ b/contracts/Scarb.lock @@ -3,16 +3,16 @@ version = 1 [[package]] name = "dojo" -version = "1.0.0-alpha.4" -source = "git+https://github.com/dojoengine/dojo?tag=v1.0.0-alpha.11#fbff45b249e2b931f5007edf2d526beef7dc553f" +version = "1.0.1" +source = "git+https://github.com/dojoengine/dojo?tag=v1.0.1#d7335e6f5c76a1dda887ec00c594c2c019b4a05f" dependencies = [ "dojo_plugin", ] [[package]] name = "dojo_plugin" -version = "1.0.0-alpha.4" -source = "git+https://github.com/dojoengine/dojo?rev=f15def33#f15def330c0d099e79351d11c197f63e8cc1ff36" +version = "2.8.4" +source = "git+https://github.com/dojoengine/dojo?tag=v1.0.1#d7335e6f5c76a1dda887ec00c594c2c019b4a05f" [[package]] name = "p_war" @@ -24,8 +24,8 @@ dependencies = [ [[package]] name = "pixelaw" -version = "0.3.50" -source = "git+https://github.com/pixelaw/core?branch=main#8d3103416e52f4782cc14aaba78f5845d9e0fd77" +version = "0.5.7" +source = "git+https://github.com/pixelaw/core?tag=v0.5.7#96260a5d1142e24eb30d63eb69ed47c036081376" dependencies = [ "dojo", ] diff --git a/contracts/Scarb.toml b/contracts/Scarb.toml index 0be7681..4564898 100644 --- a/contracts/Scarb.toml +++ b/contracts/Scarb.toml @@ -1,5 +1,5 @@ [package] -cairo-version = "=2.7.0" +cairo-version = "=2.8.4" name = "p_war" version = "0.3.54" @@ -7,23 +7,22 @@ version = "0.3.54" sierra-replace-ids = true [dependencies] -pixelaw = { git = "https://github.com/pixelaw/core", branch = "main" } -# Added explicitly for https://github.com/dojoengine/dojo/issues/2430 -dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.0.0-alpha.11" } +pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.5.7" } +dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.0.1" } -[[target.dojo]] +[[target.starknet-contract]] build-external-contracts = [ - "pixelaw::core::models::pixel::pixel", + "dojo::world::world_contract::world", + "pixelaw::core::models::pixel::Pixel", "pixelaw::core::models::pixel::PixelUpdate", - "pixelaw::core::models::queue::queue_item", - "pixelaw::core::models::registry::app", - "pixelaw::core::models::registry::app_name", - "pixelaw::core::models::registry::app_user", - "pixelaw::core::models::registry::app_instruction", - "pixelaw::core::models::registry::instruction", - "pixelaw::core::models::registry::core_actions_address", - "pixelaw::core::models::permissions::permissions", + "pixelaw::core::models::queue::QueueItem", + "pixelaw::core::models::registry::App", + "pixelaw::core::models::registry::AppName", + "pixelaw::core::utils::get_core_actions", + "pixelaw::core::models::registry::CoreActionsAddress", "pixelaw::core::actions::actions", + "pixelaw::core::actions::IActionsDispatcher", + "pixelaw::core::actions::IActionsDispatcherTrait" ] [tool.fmt] diff --git a/contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json b/contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json index fb24eea..1cce46a 100644 --- a/contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json +++ b/contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json @@ -398,30 +398,22 @@ }, { "type": "function", - "name": "set_guild_contract_address", + "name": "create_game_guilds", "inputs": [ { "name": "game_id", "type": "core::integer::u32" }, { - "name": "address", + "name": "guild_address", "type": "core::starknet::contract_address::ContractAddress" } ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "create_game_guilds", - "inputs": [ + "outputs": [ { - "name": "game_id", - "type": "core::integer::u32" + "type": "core::array::Array::" } ], - "outputs": [], "state_mutability": "external" }, { diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-GuildContractAddress-6a64b8e1.json b/contracts/manifests/dev/base/abis/models/pixelaw-GuildContractAddress-6a64b8e1.json deleted file mode 100644 index b4ee5cd..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-GuildContractAddress-6a64b8e1.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "guild_contract_addressImpl", - "interface_name": "p_war::systems::actions::p_war_actions::Iguild_contract_address" - }, - { - "type": "struct", - "name": "p_war::systems::actions::p_war_actions::GuildContractAddress", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::actions::p_war_actions::Iguild_contract_address", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::systems::actions::p_war_actions::GuildContractAddress" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::guild_contract_address::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml b/contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml index a936dae..7ddb808 100644 --- a/contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml +++ b/contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml @@ -1,6 +1,6 @@ kind = "DojoContract" -class_hash = "0x10825ca403e033ca686cee54d2df5cd164cffadecb7172d4f6fcf542a551453" -original_class_hash = "0x10825ca403e033ca686cee54d2df5cd164cffadecb7172d4f6fcf542a551453" +class_hash = "0x69dd41f9af4392ca2812831a77b4295acff9473da298b871a6833907e4084fd" +original_class_hash = "0x69dd41f9af4392ca2812831a77b4295acff9473da298b871a6833907e4084fd" base_class_hash = "0x0" abi = "manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json" reads = [] @@ -13,8 +13,6 @@ systems = [ "set_pixel", "init", "interact", - "set_guild_contract_address", - "create_game_guilds", "place_pixel", "update_pixel", "end_game", diff --git a/contracts/manifests/dev/base/models/pixelaw-GuildContractAddress-6a64b8e1.toml b/contracts/manifests/dev/base/models/pixelaw-GuildContractAddress-6a64b8e1.toml deleted file mode 100644 index c42bb1d..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-GuildContractAddress-6a64b8e1.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x7061fde93c6cf87511892ac88bc9d5443971aaf07983022821d3f0e5407b95" -original_class_hash = "0x7061fde93c6cf87511892ac88bc9d5443971aaf07983022821d3f0e5407b95" -abi = "manifests/dev/base/abis/models/pixelaw-GuildContractAddress-6a64b8e1.json" -tag = "pixelaw-GuildContractAddress" -qualified_path = "p_war::systems::actions::p_war_actions::guild_contract_address" -manifest_name = "pixelaw-GuildContractAddress-6a64b8e1" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "address" -type = "ContractAddress" -key = false diff --git a/contracts/src/lib.cairo b/contracts/src/lib.cairo index 14ca972..52f7e42 100644 --- a/contracts/src/lib.cairo +++ b/contracts/src/lib.cairo @@ -23,7 +23,7 @@ mod tests { // mod test_add_color; // // mod test_create_world; // mod test_extend_game_end; - // mod test_guild; - // // mod test_reset_to_white; + mod test_guild; + // mod test_reset_to_white; mod utils; } diff --git a/contracts/src/models/payments.cairo b/contracts/src/models/payments.cairo new file mode 100644 index 0000000..1fbf727 --- /dev/null +++ b/contracts/src/models/payments.cairo @@ -0,0 +1,29 @@ +use starknet::ContractAddress; + +#[derive(Copy, Drop, Serde)] +#[dojo::model(namespace: "pixelaw", nomapping: true)] +struct GamePayments { + #[key] + game_id: u32, + participation_fee: u256, + prize_pool: u256, + treasury_balance: u256 +} + +#[derive(Copy, Drop, Serde)] +#[dojo::model(namespace: "pixelaw", nomapping: true)] +struct PlayerPayment { + #[key] + game_id: u32, + #[key] + player: ContractAddress, + amount_paid: u256 +} + +#[derive(Copy, Drop, Serde)] +#[dojo::model(namespace: "pixelaw", nomapping: true)] +struct TreasuryInfo { + #[key] + dummy_key: u32, + treasury_address: ContractAddress +} \ No newline at end of file diff --git a/contracts/src/systems/actions.cairo b/contracts/src/systems/actions.cairo index fdc2322..7257384 100644 --- a/contracts/src/systems/actions.cairo +++ b/contracts/src/systems/actions.cairo @@ -7,19 +7,18 @@ use pixelaw::core::utils::DefaultParameters; use starknet::ContractAddress; // define the interface -#[dojo::interface] -trait IActions { - fn init(ref world: IWorldDispatcher); - fn interact(ref world: IWorldDispatcher, default_params: DefaultParameters); - fn create_game(ref world: IWorldDispatcher, origin: Position) -> usize; - fn set_guild_contract_address(ref world: IWorldDispatcher, game_id: usize, address: ContractAddress); - fn create_game_guilds(ref world: IWorldDispatcher, game_id: usize); - fn get_game_id(world: @IWorldDispatcher, position: Position) -> usize; +#[starknet::interface] +pub trait IActions { + fn init(ref self: T); + fn interact(ref self: T, default_params: DefaultParameters); + fn create_game(ref self: T, origin: Position) -> usize; + fn create_game_guilds(ref self: T, game_id: usize, guild_address: ContractAddress) -> Array; + fn get_game_id(self: @T, position: Position) -> usize; fn place_pixel( - ref world: IWorldDispatcher, app: ContractAddress, default_params: DefaultParameters + ref self: T, app: ContractAddress, default_params: DefaultParameters ); - fn update_pixel(ref world: IWorldDispatcher, pixel_update: PixelUpdate); - fn end_game(ref world: IWorldDispatcher, game_id: usize); + fn update_pixel(ref self: T, pixel_update: PixelUpdate); + fn end_game(ref self: T, game_id: usize); } // dojo decorator @@ -58,15 +57,6 @@ mod p_war_actions { EndedGame: EndedGame } - #[derive(Copy, Drop, Serde)] - #[dojo::event] - #[dojo::model] - struct GuildContractAddress { - #[key] - game_id: usize, - address: ContractAddress, - } - #[derive(Drop, Serde, starknet::Event)] struct StartedGame { id: usize, @@ -81,32 +71,9 @@ mod p_war_actions { // should we emit here the states of the pixel as well? } - #[abi(embed_v0)] - impl ActionsInteroperability of IInteroperability { - fn on_pre_update( - ref world: IWorldDispatcher, - pixel_update: PixelUpdate, - app_caller: App, - player_caller: ContractAddress - ) { - // do nothing - let _world = world; - } - - fn on_post_update( - ref world: IWorldDispatcher, - pixel_update: PixelUpdate, - app_caller: App, - player_caller: ContractAddress - ) { - // do nothing - let _world = world; - } - } - #[abi(embed_v0)] impl AllowedAppImpl of IAllowedApp { - fn set_pixel(default_params: DefaultParameters) { + fn set_pixel(ref self: ContractState, default_params: DefaultParameters) { let actions = IActionsDispatcher { contract_address: get_contract_address() }; actions .update_pixel( @@ -126,12 +93,13 @@ mod p_war_actions { #[abi(embed_v0)] impl ActionsImpl of IActions { - fn init(ref world: IWorldDispatcher) { - let core_actions = get_core_actions(world); + fn init(ref self: ContractState) { + let mut world = self.world(@"pixelaw"); + let core_actions = self.get_core_actions(); core_actions.new_app(contract_address_const::<0>(), APP_KEY, APP_ICON); } - fn interact(ref world: IWorldDispatcher, default_params: DefaultParameters) { + fn interact(ref self: ContractState, default_params: DefaultParameters) { let position = Position { x: default_params.position.x, y: default_params.position.y }; let game_id = self.get_game_id(position); if game_id == 0 { @@ -144,14 +112,16 @@ mod p_war_actions { }; } - fn get_game_id(world: @IWorldDispatcher, position: Position) -> usize { + fn get_game_id(self: @ContractState, position: Position) -> usize { + let mut world = self.world(@"pixelaw"); let mut id = world.uuid(); if id == 0 { return 0; }; // set id as GAME_ID=1 - let board = get!(world, (GAME_ID), (Board)); + // let board = get!(world, (GAME_ID), (Board)); this is the pre-dojo 1.0.0 implementation + let board = world.read_model(GAME_ID); if position.x < board.origin.x || position.x >= board.origin.x + board.width || position.y < board.origin.y || position.y >= board.origin.y @@ -161,13 +131,8 @@ mod p_war_actions { return 1; } - fn set_guild_contract_address(ref world: IWorldDispatcher, game_id: usize, address: ContractAddress) { - // Only allow the contract owner or an authorized address to set this - //assert(get_caller_address() == world.get_owner(), 'Unauthorized'); - set!(world, (GuildContractAddress { game_id, address })); - } - - fn create_game(ref world: IWorldDispatcher, origin: Position) -> usize { + fn create_game(ref self: ContractState, origin: Position) -> usize { + let mut world = self.world(@"pixelaw"); println!("create_game BEGIN"); // check if a game exists @@ -203,49 +168,7 @@ mod p_war_actions { let board = Board { id, origin, width: DEFAULT_AREA, height: DEFAULT_AREA, }; - // To make a bigger area, we deleted this part. - // // make sure that game board has been set with game id - // let mut y = origin.y; - // loop { - // if y >= origin.y + DEFAULT_AREA { - // break; - // }; - // let mut x = origin.x; - // loop { - // if x >= origin.x + DEFAULT_AREA { - // break; - // }; - // core_actions - // .update_pixel( - // player, - // system, - // PixelUpdate { - // x, - // y, - // color: Option::Some(INITIAL_COLOR), - // timestamp: Option::None, - // text: Option::None, - // app: Option::Some(system), - // owner: Option::None, - // action: Option::None - // } - // ); - // set!( - // world, - // ( - // GameId { - // x, - // y, - // value: id - // } - // ) - // ); - // x += 1; - // }; - // y += 1; - // }; - - set!(world, (game, board)); + world.write_model(@game); println!("create_game 1"); // add default colors (changed these to RGBA) let mut color_idx = 0; @@ -264,69 +187,74 @@ mod p_war_actions { if color_idx > 8 { break; }; - set!( - world, - ( - AllowedColor { game_id: id, color: *a.at(color_idx), is_allowed: true, }, - PaletteColors { game_id: id, idx: color_idx, color: *a.at(color_idx), }, - InPalette { game_id: id, color: *a.at(color_idx), value: true } - ) - ); + let allowed_color = AllowedColor { game_id: id, color: *a.at(color_idx), is_allowed: true }; + let palette_colors = PaletteColors { game_id: id, idx: color_idx, color: *a.at(color_idx) }; + let in_palette = InPalette { game_id: id, color: *a.at(color_idx), value: true }; + world.write_model(@allowed_color); + world.write_model(@palette_colors); + world.write_model(@in_palette); + + //is the above the correct implementation of the below? + // set!( + // world, + // ( + // AllowedColor { game_id: id, color: *a.at(color_idx), is_allowed: true, }, + // PaletteColors { game_id: id, idx: color_idx, color: *a.at(color_idx), }, + // InPalette { game_id: id, color: *a.at(color_idx), value: true } + // ) + // ); color_idx += 1; }; println!("create_game 2"); // set default recovery_rate - set!( - world, - ( - PixelRecoveryRate { game_id: id, rate: DEFAULT_RECOVERY_RATE, }, - GamePalette { game_id: id, length: 9 } - ) - ); + let pixel_recovery_rate = PixelRecoveryRate { game_id: id, rate: DEFAULT_RECOVERY_RATE }; + let game_palette = GamePalette { game_id: id, length: 9 }; + world.write_model(@pixel_recovery_rate); + world.write_model(@game_palette); + // set!( + // world, + // ( + // PixelRecoveryRate { game_id: id, rate: DEFAULT_RECOVERY_RATE, }, + // GamePalette { game_id: id, length: 9 } + // ) + // ); println!("create_game 2.1"); // recover px - recover_px(world, id, player); - - self.create_game_guilds(id); + recover_px(world, id, player); id // emit event that game has started } // initialize guilds for the game - fn create_game_guilds(ref world: IWorldDispatcher, game_id: usize) { - let guild_address = get!(world, game_id, GuildContractAddress).address; + fn create_game_guilds(ref self: ContractState, game_id: usize, guild_address: ContractAddress) -> Array { + //let guild_address = get!(world, game_id, GuildContractAddress).address; let guild_dispatcher = IGuildDispatcher { contract_address: guild_address }; - - guild_dispatcher.create_guild(game_id, 'Fire'); - guild_dispatcher.create_guild(game_id, 'Water'); - guild_dispatcher.create_guild(game_id, 'Earth'); - guild_dispatcher.create_guild(game_id, 'Air'); - // when initilaising pwar it needs a guild contract - // setter for guild contract - // secure pwar to not call the wrong for guild contract - // modify initialising steps + let mut guild_ids = ArrayTrait::new(); + guild_ids.append(guild_dispatcher.create_guild(game_id, 'Fire')); + guild_ids.append(guild_dispatcher.create_guild(game_id, 'Water')); + guild_ids.append(guild_dispatcher.create_guild(game_id, 'Earth')); + guild_ids.append(guild_dispatcher.create_guild(game_id, 'Air')); + guild_ids } // To paint, basically use this function. fn place_pixel( - ref world: IWorldDispatcher, app: ContractAddress, default_params: DefaultParameters + ref self: ContractState, app: ContractAddress, default_params: DefaultParameters ) { + let mut world = self.world(@"pixelaw"); let position = Position { x: default_params.position.x, y: default_params.position.y }; - - // let game_id = get!(world, (default_params.position.x, default_params.position.y), - // GameId); let game_id = self.get_game_id(position); assert(game_id != 0, 'this game does not exist'); - let allowed_color = get!(world, (game_id, default_params.color), (AllowedColor)); + let allowed_color: AllowedColor = world.read_model((game_id, default_params.color)); assert( allowed_color.is_allowed, 'color is not allowed' ); // cannot test correctly without cheatcodes. - let allowed_app = get!(world, (game_id, app), (AllowedApp)); + let allowed_app: AllowedApp = world.read_model((game_id, app)); assert(app.is_zero() || allowed_app.is_allowed, 'app is not allowed'); let contract_address = if app.is_zero() { @@ -343,10 +271,10 @@ mod p_war_actions { recover_px(world, game_id, player_address); // if this is first time for the caller, let's set initial px. - let mut player = get!(world, (player_address), (Player)); + let mut player: Player = world.read_model(player_address); // get the game info - let game = get!(world, (game_id), (Game)); + let game: Game = world.read_model(game_id); // check the current px is eq or larger than cost_paint assert(player.current_px >= game.base_cost, 'not enough PX'); @@ -359,53 +287,48 @@ mod p_war_actions { app.set_pixel(default_params); - set!( - world, - (Player { - address: player.address, - max_px: player.max_px, - num_owns: player.num_owns + 1, - num_commit: player.num_commit + game.base_cost, - current_px: player.current_px - game.base_cost, - last_date: get_block_timestamp(), - is_banned: false, - }), - ); + player.num_owns += 1; + player.num_commit += game.base_cost; + player.current_px -= game.base_cost; + player.last_date = get_block_timestamp(); + world.write_model(@player); // get the previous owner of PWarPixel let position = Position { x: default_params.position.x, y: default_params.position.y }; - let previous_pwarpixel = get!(world, (position), (PWarPixel)); + let mut previous_pwarpixel: PWarPixel = world.read_model(position); if (previous_pwarpixel.owner != contract_address_const::<0x0>() && previous_pwarpixel.owner != player.address) { // get the previous player's info - let mut previous_player = get!(world, (previous_pwarpixel.owner), (Player)); - + let mut previous_player: Player = world.read_model(previous_pwarpixel.owner); // decrease the previous player's num_owns previous_player.num_owns -= 1; - set!(world, (previous_player)); + world.write_model(@previous_player); } // set the new owner of PWarPixel - set!(world, (PWarPixel { position: position, owner: player.address }),); + previous_pwarpixel.owner = player.address; + world.write_model(@previous_pwarpixel); + //set!(world, (PWarPixel { position: position, owner: player.address }),); - update_max_px(world, game_id, player.address); + self.update_max_px(game_id, player.address); } // only use for expand areas. - fn update_pixel(ref world: IWorldDispatcher, pixel_update: PixelUpdate) { + fn update_pixel(ref self: ContractState, pixel_update: PixelUpdate) { + let mut world = self.world(@"pixelaw"); assert(get_caller_address() == get_contract_address(), 'invalid caller'); - let player_address = get_tx_info().unbox().account_contract_address; let system = get_contract_address(); - let core_actions = get_core_actions(world); + let core_actions = self.get_core_actions(); core_actions.update_pixel(player_address, system, pixel_update); } - fn end_game(ref world: IWorldDispatcher, game_id: usize) { + fn end_game(ref self: ContractState, game_id: usize) { // check if the time is expired. - let mut game = get!(world, (game_id), (Game)); + let mut world = self.world(@"pixelaw"); + let mut game: Game = world.read_model(game_id); assert(get_block_timestamp() >= game.end, 'game is not ended'); // TODO: emit the status?? @@ -434,7 +357,7 @@ mod p_war_actions { game.winner = winner; - set!(world, (game)); + world.write_model(@game); // TODO: emit the winner! } } diff --git a/contracts/src/systems/apps.cairo b/contracts/src/systems/apps.cairo index 70882cc..5d4fed0 100644 --- a/contracts/src/systems/apps.cairo +++ b/contracts/src/systems/apps.cairo @@ -1,6 +1,6 @@ use pixelaw::core::utils::DefaultParameters; -#[dojo::interface] +#[starknet::interface] trait IAllowedApp { fn set_pixel(default_params: DefaultParameters); } diff --git a/contracts/src/systems/guilds.cairo b/contracts/src/systems/guilds.cairo index 7f60481..427f177 100644 --- a/contracts/src/systems/guilds.cairo +++ b/contracts/src/systems/guilds.cairo @@ -3,20 +3,20 @@ use p_war::models::guilds::Guild; use p_war::models::player::Player; use starknet::{ContractAddress, get_caller_address}; -#[dojo::interface] -trait IGuild { +#[starknet::interface] +pub trait IGuild { fn create_guild( - ref world: IWorldDispatcher, game_id: usize, guild_name: felt252 + ref self: T, game_id: usize, guild_name: felt252 ) -> usize; //returns guild ID fn add_member( - ref world: IWorldDispatcher, game_id: usize, guild_id: usize, new_member: ContractAddress + ref self: T, game_id: usize, guild_id: usize, new_member: ContractAddress ); - fn join_guild(ref world: IWorldDispatcher, game_id: usize, guild_id: usize); + fn join_guild(ref self: T, game_id: usize, guild_id: usize); fn remove_member( - ref world: IWorldDispatcher, game_id: usize, guild_id: usize, member: ContractAddress + ref self: T, game_id: usize, guild_id: usize, member: ContractAddress ); - fn get_guild_contract_address(world: @IWorldDispatcher) -> ContractAddress; - fn get_guild_points(world: @IWorldDispatcher, game_id: usize, guild_id: usize) -> usize; + fn get_guild_contract_address(ref self: T) -> ContractAddress; + fn get_guild_points(ref self: T, game_id: usize, guild_id: usize) -> usize; } #[dojo::contract(namespace: "pixelaw", nomapping: true)] @@ -65,11 +65,12 @@ mod guild_actions { #[abi(embed_v0)] impl GuildImpl of IGuild { - fn create_guild(ref world: IWorldDispatcher, game_id: usize, guild_name: felt252) -> usize { + fn create_guild(ref self: ContractState, game_id: usize, guild_name: felt252) -> usize { + let mut world = self.world(@"pixelaw"); let caller = get_caller_address(); // Check if the game exists and get the game data - let mut game = get!(world, game_id, (Game)); + let mut game: Game = world.read_model(game_id); assert(game.id == game_id, 'Game does not exist'); // Use the current guild_count as the new guild_id @@ -108,34 +109,29 @@ mod guild_actions { println!("new_guild.guild_id: {}", new_guild.guild_id); // Save the guild and update the game - set!(world, (new_guild, game)); + world.write_model(@guild); println!("set guild"); - emit!( - world, - (Event::GuildCreated( - GuildCreated { game_id, guild_id, guild_name, creator: caller, } - )) - ); - + world.emit_event(GuildCreated {game_id, guild_id, guild_name, caller}); guild_id } fn add_member( - ref world: IWorldDispatcher, + ref self: ContractState, game_id: usize, guild_id: usize, new_member: ContractAddress ) { + let mut world = self.world(@"pixelaw"); let caller = get_caller_address(); // Get the guild - let mut guild = get!(world, (game_id, guild_id), (Guild)); + let mut guild: Guild = world.read_model(game_id, guild_id); // Check if the caller is the creator assert(guild.creator == caller, 'Only creator can add members'); // Check if the member is not already in the guild - let is_member = is_member(world, game_id, guild_id, new_member); + let is_member = self.is_member(game_id, guild_id, new_member); assert(is_member == false, 'New Member already in guild'); // Create a new Array and populate it with existing guild_ids @@ -159,14 +155,11 @@ mod guild_actions { guild.member_count += 1; // Save the updated guild - set!(world, (guild)); - - emit!( - world, (Event::MemberAdded(MemberAdded { game_id, guild_id, member: new_member })) - ); + world.write_model(@guild); + world.emit_event(@MemberAdded { game_id, guild_id, new_member }); } - fn join_guild(ref world: IWorldDispatcher, game_id: usize, guild_id: usize) { + fn join_guild(ref self: ContractState, game_id: usize, guild_id: usize) { let caller = get_caller_address(); // Add the member to the guild @@ -174,12 +167,13 @@ mod guild_actions { } fn remove_member( - ref world: IWorldDispatcher, game_id: usize, guild_id: usize, member: ContractAddress + ref self: ContractState, game_id: usize, guild_id: usize, member: ContractAddress ) { + let mut world = self.world(@"pixelaw"); let caller = get_caller_address(); // Get the guild - let mut guild = get!(world, (game_id, guild_id), (Guild)); + let mut guild: Guild = world.read_model(game_id, guild_id); // Check if the caller is the creator assert(guild.creator == caller, 'Only creator can remove members'); @@ -206,20 +200,20 @@ mod guild_actions { guild.member_count -= 1; // Save the updated guild - set!(world, (guild)); - - emit!(world, (Event::MemberRemoved(MemberRemoved { game_id, guild_id, member }))); + world.write_model(@guild); + world.emit_event(@MemberRemoved {game_id, guild_id, member}) } - fn get_guild_contract_address(world: @IWorldDispatcher) -> ContractAddress { + fn get_guild_contract_address(ref self: ContractState) -> ContractAddress { let guild_contract_address = get_contract_address(); guild_contract_address } - fn get_guild_points(world: @IWorldDispatcher, game_id: usize, guild_id: usize) -> usize { + fn get_guild_points(ref self: ContractState , game_id: usize, guild_id: usize) -> usize { // Get the guild - let mut guild = get!(world, (game_id, guild_id), (Guild)); + let mut world = self.world(@"pixelaw"); + let mut guild: Guild = world.read_model(game_id, guild_id); let mut guild_total_points = 0; let mut i = 0; @@ -228,7 +222,7 @@ mod guild_actions { if i >= guild.member_count { break; } - let mut player = get!(world, (*guild.members.at(i), game_id), (Player)); + let mut player: Player = world.read_model(*guild.members.at(i), game_id); println!("player.num_commit: {}", player.num_commit); guild_total_points += player.num_commit; i += 1; diff --git a/contracts/src/systems/payments.cairo b/contracts/src/systems/payments.cairo new file mode 100644 index 0000000..ba0cd59 --- /dev/null +++ b/contracts/src/systems/payments.cairo @@ -0,0 +1,117 @@ +use starknet::{ContractAddress, get_caller_address}; +use p_war::models::payments::{GamePayments, PlayerPayment, TreasuryInfo}; +use p_war::models::game::Game; +use p_war::models::guilds::Guild; + +#[starknet::interface] +pub trait IPayments { + fn initialize_game_payments(ref self: T, game_id: u32, participation_fee: u256); + fn pay_participation_fee(ref self: T, game_id: u32); + fn payout_winning_guild(ref self: T, game_id: u32, winning_guild_id: u32); + fn set_treasury_address(ref self: T, treasury_address: ContractAddress); +} + +#[dojo::contract(namespace: "pixelaw", nomapping: true)] +mod payments { + // use super::*; + + const PRIZE_POOL_PERCENTAGE: u256 = 90; + const TREASURY_PERCENTAGE: u256 = 10; + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + ParticipationFeePaid: ParticipationFeePaid, + WinningGuildPaidOut: WinningGuildPaidOut + } + + #[derive(Drop, starknet::Event)] + struct ParticipationFeePaid { + game_id: u32, + player: ContractAddress, + amount: u256 + } + + #[derive(Drop, starknet::Event)] + struct WinningGuildPaidOut { + game_id: u32, + guild_id: u32, + total_amount: u256 + } + + #[abi(embed_v0)] + impl PaymentsImpl of IPayments { + fn initialize_game_payments(ref self: ContractState, game_id: u32, participation_fee: u256) { + let game_payments = GamePayments { + game_id: game_id, + participation_fee: participation_fee, + prize_pool: 0, + treasury_balance: 0 + }; + set!(world, (game_payments)); + } + + fn pay_participation_fee(ref self: ContractState, game_id: u32) { + let caller = get_caller_address(); + let mut game_payments = get!(world, game_id, (GamePayments)); + let fee = game_payments.participation_fee; + + // TODO: Implement actual token transfer here + // For now, we'll just update the balances + + let prize_pool_amount = (fee * PRIZE_POOL_PERCENTAGE) / 100; + let treasury_amount = (fee * TREASURY_PERCENTAGE) / 100; + + game_payments.prize_pool += prize_pool_amount; + game_payments.treasury_balance += treasury_amount; + + let player_payment = PlayerPayment { + game_id: game_id, + player: caller, + amount_paid: fee + }; + + set!(world, (game_payments, player_payment)); + + emit!(world, ParticipationFeePaid { game_id: game_id, player: caller, amount: fee }); + } + + fn payout_winning_guild(ref self: ContractState, game_id: u32, winning_guild_id: u32) { + let mut game_payments = get!(world, game_id, (GamePayments)); + let guild = get!(world, (game_id, winning_guild_id), (Guild)); + + let total_payout = game_payments.prize_pool; + let members_count = guild.member_count; + let payout_per_member = total_payout / members_count.into(); + + //assert the game state + + // Iterate through guild members and pay each one + let mut i = 0; + loop { + if i == guild.members.len() { + break; + } + let member = *guild.members.at(i); + // TODO: Implement actual token transfer to each member + // For now, we'll just print the payout + println!("Paying {} to member {}", payout_per_member, member); + i += 1; + }; + + // Reset the prize pool + game_payments.prize_pool = 0; + set!(world, (game_payments)); + + emit!(world, WinningGuildPaidOut { game_id: game_id, guild_id: winning_guild_id, total_amount: total_payout }); + } + + fn set_treasury_address(ref self: ContractState, treasury_address: ContractAddress) { + let treasury_info = TreasuryInfo { + dummy_key: 0, + treasury_address: treasury_address + }; + set!(world, (treasury_info)); + } + } +} \ No newline at end of file diff --git a/contracts/src/systems/propose.cairo b/contracts/src/systems/propose.cairo index f444690..552cb19 100644 --- a/contracts/src/systems/propose.cairo +++ b/contracts/src/systems/propose.cairo @@ -1,17 +1,17 @@ use p_war::models::{board::Position}; // define the interface -#[dojo::interface] -trait IPropose { +#[starknet::interface] +pub trait IPropose { fn create_proposal( - ref world: IWorldDispatcher, + ref self: T, game_id: usize, proposal_type: u8, target_args_1: u32, target_args_2: u32 ) -> usize; fn activate_proposal( - ref world: IWorldDispatcher, game_id: usize, index: usize, clear_data: Span + ref self: T, game_id: usize, index: usize, clear_data: Span ); } @@ -64,23 +64,24 @@ mod propose_actions { #[abi(embed_v0)] impl ProposeImpl of IPropose { fn create_proposal( - ref world: IWorldDispatcher, + ref self: ContractState, game_id: usize, proposal_type: u8, target_args_1: u32, target_args_2: u32 ) -> usize { - // get the game - let mut game = get!(world, game_id, (Game)); + //get world + let mut world = self.world(@"pixelaw"); + // get models + let mut game: Game = world.read_model(game_id); assert(check_game_status(game.status()), 'game is not ongoing'); - let player_address = get_tx_info().unbox().account_contract_address; // recover px recover_px(world, game_id, player_address); // if this is first time for the caller, let's set initial px. - let mut player = get!(world, (player_address), (Player)); + let mut player: Player = world.read_model(player_address); // check the current px is eq or larger than cost_paint assert(player.current_px >= game.base_cost * PROPOSAL_FACTOR, 'not enough PX'); @@ -88,7 +89,7 @@ mod propose_actions { // check the player is banned or not assert(player.is_banned == false, 'you are banned'); - let proposal = Proposal { + let new_proposal = Proposal { game_id: game_id, index: game.proposal_idx, author: get_caller_address(), @@ -104,197 +105,59 @@ mod propose_actions { game.proposal_idx += 1; - set!(world, (proposal, game)); + world.write_model(@new_proposal); + world.write_model(@game); - // consume px - set!( - world, - (Player { - address: player.address, - max_px: player.max_px, - num_owns: player.num_owns, - num_commit: player.num_commit + (game.base_cost * PROPOSAL_FACTOR), - current_px: player.current_px - (game.base_cost * PROPOSAL_FACTOR), - last_date: get_block_timestamp(), - is_banned: false, - }), - ); - - emit!( - world, - (Event::ProposalCreated( - ProposalCreated { - game_id, - index: game.proposal_idx, - proposal_type: proposal.proposal_type, - target_args_1, - target_args_2 - } - )) - ); + player.player.num_commit + (game.base_cost * PROPOSAL_FACTOR); + player.current_px - (game.base_cost * PROPOSAL_FACTOR); + world.write_model(@player); + // consume px + // set!( + // world, + // (Player { + // address: player.address, + // max_px: player.max_px, + // num_owns: player.num_owns, + // num_commit: player.num_commit + (game.base_cost * PROPOSAL_FACTOR), + // current_px: player.current_px - (game.base_cost * PROPOSAL_FACTOR), + // last_date: get_block_timestamp(), + // is_banned: false, + // }), + // ); + + world.emit_event(ProposalCreated { game_id, game.proposal_idx, proposal_type, target_args_1, target_args_2 }); proposal.index } - fn activate_proposal( - ref world: IWorldDispatcher, game_id: usize, index: usize, clear_data: Span + ref self: ContractState, game_id: usize, index: usize, clear_data: Span ) { // get the proposal - let mut proposal = get!(world, (game_id, index), (Proposal)); - let game = get!(world, (game_id), (Game)); + let mut world = self.world(@"pixelaw"); + let mut proposal: Proposal = world.read_model(game_id, index); + let mut game: Game = world.read_model(game_id); let current_timestamp = get_block_timestamp(); assert(current_timestamp >= proposal.end, 'proposal period has not ended'); assert(proposal.yes_px >= NEEDED_YES_PX, 'did not reach minimum yes_px'); assert(proposal.yes_px > proposal.no_px, 'yes_px is not more than no_px'); assert(proposal.is_activated == false, 'this is already activated'); assert(check_game_status(game.status()), 'game is not ongoing'); - + // activate the proposal. if proposal.proposal_type == 1 { - // AddNewColor - // new feature: if the color is added, the oldest color become unusable. - - let new_color: u32 = proposal.target_args_1; - let mut new_color_allowed = get!(world, (game_id, new_color), (AllowedColor)); - - // only change it if it's not allowed - if !new_color_allowed.is_allowed { - new_color_allowed.is_allowed = !new_color_allowed.is_allowed; - - set!(world, (new_color_allowed)); - - // check if color already is in the palette - let is_in_palette = get!(world, (game_id, new_color), (InPalette)); - - // if aready in the palette early return - if is_in_palette.value { - return; - } - - let mut game_palette = get!(world, (game_id), (GamePalette)); - - // check if there's less colors in place - if game_palette.length < 9 { - set!( - world, - ( - PaletteColors { - game_id, idx: game_palette.length, color: new_color - }, - InPalette { game_id, color: new_color, value: true }, - GamePalette { game_id, length: game_palette.length + 1 } - ) - ); - } else { - // get 0 idx - let oldest_color = get!(world, (game_id, 0), (PaletteColors)); - - let mut idx = 1; - - loop { - let palette_color = get!(world, (game_id, idx), (PaletteColors)); - - set!( - world, - (PaletteColors { - game_id, idx: idx - 1, color: palette_color.color - }) - ); - - idx = idx + 1; - - if idx == 9 { - break; - }; - }; - - set!( - world, - ( - InPalette { game_id, color: oldest_color.color, value: false }, - InPalette { game_id, color: new_color, value: true }, - PaletteColors { game_id, idx: 8, color: new_color }, - // make it unusable - AllowedColor { - game_id, color: oldest_color.color, is_allowed: false - }, - ) - ); - }; - }; + add_new_color(world, game_id, index, game, proposal); } else if proposal.proposal_type == 2 { - // Reset to white by color - let core_actions = get_core_actions( - world - ); // TODO: should we use p_war_actions insted of core_actions??? - let system = get_caller_address(); - - let target_args_1: u32 = proposal.target_args_1; - - let mut idx: usize = 0; - - loop { - let pixel_to_clear = clear_data.get(idx); - - if let Option::None = pixel_to_clear { - break; - } - - let pixel_to_clear = *clear_data.at(idx); - - let pixel_info = get!(world, (pixel_to_clear.x, pixel_to_clear.y), (Pixel)); - - if pixel_info.color == target_args_1 { - // make it white - core_actions - .update_pixel( - get_caller_address(), // is it okay? - system, - PixelUpdate { - x: pixel_to_clear.x, - y: pixel_to_clear.y, - color: Option::Some(0xffffffff), - timestamp: Option::None, - text: Option::None, - app: Option::Some(system), - owner: Option::None, - action: Option::None - } - ); - - // decrease the previous owner's num_owns - let position = Position { x: pixel_to_clear.x, y: pixel_to_clear.y }; - let previous_pwarpixel = get!(world, (position), (PWarPixel)); - - if (previous_pwarpixel.owner != starknet::contract_address_const::<0x0>()) { - // get the previous player's info - let mut previous_player = get!( - world, (previous_pwarpixel.owner), (Player) - ); - - previous_player.num_owns -= 1; - set!(world, (previous_player)); - }; - }; - idx += 1; - }; + reset_to_white(world, game_id, index, game, proposal, clear_data) } else if proposal.proposal_type == 3 { // ProposalType::ExtendGameEndTime - let mut game = get!(world, (game_id), (Game)); - // let mut board = get!( - // world, - // (game_id), - // (Board) - // ); - + let mut game: Game = world.read_model(game_id); game.end += proposal.target_args_1.into(); - - set!(world, (game,)); + world.write_model(@game); } else if proposal.proposal_type == 4 { // ProposalType::ExpandArea - let mut board = get!(world, (game_id), (Board)); + let mut board: Board = world.read_model(game_id); board.width += proposal.target_args_1.try_into().unwrap(); board.height += proposal.target_args_2.try_into().unwrap(); - set!(world, (board,)); + world.write_model(@board); } else { return; }; @@ -302,20 +165,8 @@ mod propose_actions { // make it activated. proposal.is_activated = true; - set!(world, (proposal)); - - emit!( - world, - (Event::ProposalActivated( - ProposalActivated { - game_id, - index, - proposal_type: proposal.proposal_type, - target_args_1: proposal.target_args_1, - target_args_2: proposal.target_args_2 - } - )) - ); + world.write_model(@proposal); + world.emit_event(@ProposalActivated {game_id, index, proposal.proposal_type, proposal.target_args_1, proposal.target_args_2}) // // Qustion: should we panish the author if the proposal is denied? // // add author's commitment points // let mut author = get!( @@ -330,5 +181,133 @@ mod propose_actions { // (author) // ); } + + // add new color to the palette, if the color is added, the oldest color become unusable. + fn add_new_color( + ref self: ContractState, game_id: usize, index: usize, game: Game, proposal: Proposal + ) { + assert(proposal.proposal_type == 1, 'this is not add new color proposal'); + let mut world = self.world(@"pixelaw"); + let new_color: u32 = proposal.target_args_1; + let mut new_color_allowed: AllowedColor = world.read_model(game_id, new_color); + // only change it if it's not allowed + if !new_color_allowed.is_allowed { + new_color_allowed.is_allowed = !new_color_allowed.is_allowed; + world.write_model(@new_color_allowed); + + // check if color already is in the palette + let mut is_in_palette: InPalette = world.read_model(game_id, new_color); + // if aready in the palette early return + if is_in_palette.value { + return; + } + + let mut game_palette: GamePalette = world.read_model(game_id); + + // check if there's less colors in place + if game_palette.length < 9 { + is_in_palette.value = true; + world.write_model(@is_in_palette); + + let mut palette_color: PaletteColors = world.read_model(game_id, game_palette.length); + palette_color.color = new_color; + world.write_model(@palette_color); + + game_palette.length += 1; + world.write_model(@game_palette); + } else { + // get 0 idx + let oldest_color: PaletteColors = world.read_model(game_id, 0); + let mut idx = 1; + + loop { + let palette_color: PaletteColors = world.read_model(game_id, idx); + palette_color.idx = idx - 1; + palette_color.color = palette_color.color; + world.write_model(@palette_color); + + idx = idx + 1; + if idx == 9 { + break; + }; + }; + + let mut old_in_pallet: InPalette = world.read_model(game_id, oldest_color.color); + old_in_pallet.value = false; + world.write_model(@old_in_pallet); + + is_in_palette.value = true; + world.write_model(@is_in_palette); + + let mut old_color_allowed: AllowedColor = world.read_model(game_id, oldest_color.color); + old_color_allowed.is_allowed = false; + world.write_model(@old_color_allowed); + + + //feel like the below is not needed + //PaletteColors { game_id, idx: 8, color: new_color } + }; + }; + } + + fn reset_to_white( + ref self: ContractState, game_id: usize, index: usize, game: Game, proposal: Proposal, clear_data: Span + ) { + assert(proposal.proposal_type == 2, 'this is not reset to white proposal'); + let mut world = self.world(@"pixelaw"); + // Reset to white by color + let core_actions = get_core_actions( + world + ); // TODO: should we use p_war_actions insted of core_actions??? + let system = get_caller_address(); + + let target_args_1: u32 = proposal.target_args_1; + + let mut idx: usize = 0; + + loop { + let pixel_to_clear = clear_data.get(idx); + + if let Option::None = pixel_to_clear { + break; + } + + let pixel_to_clear = *clear_data.at(idx); + + let pixel_info: Pixel = world.read_model(pixel_to_clear.x, pixel_to_clear.y); + + if pixel_info.color == target_args_1 { + // make it white + core_actions + .update_pixel( + get_caller_address(), // is it okay? + system, + PixelUpdate { + x: pixel_to_clear.x, + y: pixel_to_clear.y, + color: Option::Some(0xffffffff), + timestamp: Option::None, + text: Option::None, + app: Option::Some(system), + owner: Option::None, + action: Option::None + } + ); + + // decrease the previous owner's num_owns + let position = Position { x: pixel_to_clear.x, y: pixel_to_clear.y }; + let previous_pwarpixel: PWarPixel = world.read_model(position); + + if (previous_pwarpixel.owner != starknet::contract_address_const::<0x0>()) { + // get the previous player's info + let mut previous_player: Player = world.read_model(previous_pwarpixel.owner); + + previous_player.num_owns -= 1; + world.write_model(@previous_player); + }; + }; + idx += 1; + }; + } } } diff --git a/contracts/src/systems/voting.cairo b/contracts/src/systems/voting.cairo index 502fd57..9883429 100644 --- a/contracts/src/systems/voting.cairo +++ b/contracts/src/systems/voting.cairo @@ -1,5 +1,5 @@ // define the interface -#[dojo::interface] +#[starknet::interface] trait IVoting { fn vote( ref world: IWorldDispatcher, game_id: usize, index: usize, use_px: u32, is_in_favor: bool diff --git a/contracts/src/tests/test_guild.cairo b/contracts/src/tests/test_guild.cairo index 681cfe1..969daf7 100644 --- a/contracts/src/tests/test_guild.cairo +++ b/contracts/src/tests/test_guild.cairo @@ -20,9 +20,10 @@ use starknet::{ }; const WHITE_COLOR: u32 = 0xFFFFFFFF; +const RED_COLOR: u32 = 0xFF000000; const GAME_ORIGIN_POSITION: Position = Position { x: 0, y: 0 }; const GAME_PAINT_POSITION: Position = Position { x: 1, y: 1 }; - +const GAME_PAINT_POSITION_2: Position = Position { x: 2, y: 2 }; #[test] #[available_gas(999_999_999)] fn test_guild_operations() { @@ -31,7 +32,7 @@ fn test_guild_operations() { let ZERO_ADDRESS: ContractAddress = contract_address_const::<0>(); // Initialize the world and the actions - let (world, _core_actions, p_war_actions, _propose, _voting, guild_actions) = + let (world, _core_actions, p_war_actions, _propose, _voting, guild_actions, _guild_contract_address) = p_war::tests::utils::setup(); println!("setup"); @@ -93,22 +94,116 @@ fn test_guild_operations() { assert(final_guild.member_count == 1, 'remove, should be 1'); println!("guild operations passed"); - // Test guild points -// paint a color inside of the grid -// set_account_contract_address(PLAYER_1); -// set_contract_address(PLAYER_1); -// p_war_actions -// .interact( -// DefaultParameters { -// for_player: ZERO_ADDRESS, // Leave this 0 if not processing the Queue -// for_system: ZERO_ADDRESS, // Leave this 0 if not processing the Queue -// position: GAME_PAINT_POSITION, -// color: WHITE_COLOR -// } -// ); -// let action_game_id = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); -// assert(action_game_id == game_id, 'game id mismatch'); -// let guild_points = guild_actions.get_guild_points(game_id, guild_id); -// println!("test: guild_points: {}", guild_points); -// assert(guild_points == 1, 'Guild points mismatch'); +} + +#[test] +#[available_gas(999_999_999)] +#[should_panic(expected: 'Guild points mismatch')] +fn test_guild_points() { + + // Initialize the world and the actions + let (_world, _core_actions, p_war_actions, _propose, _voting, guild_actions, _guild_contract_address) = + p_war::tests::utils::setup(); + println!("setup"); + + let ZERO_ADDRESS: ContractAddress = contract_address_const::<0>(); + let PLAYER_1 = contract_address_const::<0x1337>(); + set_account_contract_address(PLAYER_1); + set_contract_address(PLAYER_1); + p_war_actions + .interact( + DefaultParameters { + for_player: ZERO_ADDRESS, // Leave this 0 if not processing the Queue + for_system: ZERO_ADDRESS, // Leave this 0 if not processing the Queue + position: GAME_ORIGIN_POSITION, + color: WHITE_COLOR + } + ); + let game_id = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); + println!("game created: game_id = {}", game_id); + + //was not able to import set_call from core::helpers + set_account_contract_address(PLAYER_1); + set_contract_address(PLAYER_1); + let guild_id = guild_actions.create_guild(game_id, 'Test Guild'); + println!("guild created: guild_id = {}", guild_id); + //place a pixel + p_war_actions + .interact( + DefaultParameters { + for_player: ZERO_ADDRESS, // Leave this 0 if not processing the Queue + for_system: ZERO_ADDRESS, // Leave this 0 if not processing the Queue + position: GAME_PAINT_POSITION, + color: WHITE_COLOR + } + ); + p_war_actions + .interact( + DefaultParameters { + for_player: ZERO_ADDRESS, // Leave this 0 if not processing the Queue + for_system: ZERO_ADDRESS, // Leave this 0 if not processing the Queue + position: GAME_PAINT_POSITION_2, + color: WHITE_COLOR + } + ); + let guild_points = guild_actions.get_guild_points(game_id, guild_id); + println!("test: guild_points: {}", guild_points); + assert(guild_points == 1, 'Guild points mismatch'); +} + +#[test] +#[available_gas(999_999_999)] +fn test_guild_creation() { + // Initialize the world and the actions + let (world, _core_actions, p_war_actions, _propose, _voting, _guild_actions, guild_contract_address) = + p_war::tests::utils::setup(); + + // Setup players + let PLAYER_1 = contract_address_const::<0x1337>(); + let ZERO_ADDRESS: ContractAddress = contract_address_const::<0>(); + + // Impersonate player1 + set_account_contract_address(PLAYER_1); + + // Create a game + p_war_actions + .interact( + DefaultParameters { + for_player: ZERO_ADDRESS, + for_system: ZERO_ADDRESS, + position: GAME_ORIGIN_POSITION, + color: WHITE_COLOR + } + ); + + let game_id: u32 = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); + + //p_war_actions.set_guild_contract_address(game_id, guild_contract_address); + + set_account_contract_address(PLAYER_1); + set_contract_address(PLAYER_1); + // Create guilds for the game + let guild_ids: Array = p_war_actions.create_game_guilds(game_id, guild_contract_address); + + // Create a guild + let guild_id: u32 = *guild_ids.at(0); + println!("guild_id: {}", guild_id); + let guild = get!(world, (game_id, guild_id), (Guild)); + assert(guild.guild_name == 'Fire', 'Guild name mismatch'); + + let guild_id_2 = *guild_ids.at(1); + println!("guild_id_2: {}", guild_id_2); + let guild = get!(world, (game_id, guild_id_2), (Guild)); + assert(guild.guild_name == 'Water', 'Guild name mismatch'); + + let guild_id_3 = *guild_ids.at(2); + println!("guild_id_3: {}", guild_id_3); + let guild = get!(world, (game_id, guild_id_3), (Guild)); + assert(guild.guild_name == 'Earth', 'Guild name mismatch'); + + let guild_id_4 = *guild_ids.at(3); + println!("guild_id_4: {}", guild_id_4); + let guild = get!(world, (game_id, guild_id_4), (Guild)); + assert(guild.guild_name == 'Air', 'Guild name mismatch'); + println!("Guild creation tests passed successfully"); } diff --git a/contracts/src/tests/utils.cairo b/contracts/src/tests/utils.cairo index 87f952d..694a5d9 100644 --- a/contracts/src/tests/utils.cairo +++ b/contracts/src/tests/utils.cairo @@ -38,7 +38,8 @@ pub fn setup() -> ( IActionsDispatcher, IProposeDispatcher, IVotingDispatcher, - IGuildDispatcher + IGuildDispatcher, + ContractAddress ) { let mut models = array![ allowed_app::TEST_CLASS_HASH, @@ -128,5 +129,5 @@ pub fn setup() -> ( println!("grants done"); - (world, core_actions, p_war_actions, propose, voting, guild) + (world, core_actions, p_war_actions, propose, voting, guild, guild_address) } From d8518d15e75b76fa2e4ab9369ac0c79c61251bf6 Mon Sep 17 00:00:00 2001 From: OwnerOfJK Date: Mon, 25 Nov 2024 18:25:55 +0800 Subject: [PATCH 04/18] updated utils and voting contract --- contracts/src/systems/utils.cairo | 21 ++++++++++++--------- contracts/src/systems/voting.cairo | 29 ++++++++++------------------- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/contracts/src/systems/utils.cairo b/contracts/src/systems/utils.cairo index 4d6e679..8a2fb93 100644 --- a/contracts/src/systems/utils.cairo +++ b/contracts/src/systems/utils.cairo @@ -10,10 +10,11 @@ use starknet::{ ContractAddress, get_block_timestamp, get_caller_address, get_contract_address, get_tx_info }; -fn update_max_px(world: IWorldDispatcher, game_id: usize, player_address: ContractAddress) { - let mut player = get!(world, (player_address), (Player)); +fn update_max_px(ref self: ContractState, game_id: usize, player_address: ContractAddress) { + let mut world = self.world(@"pixelaw"); + let mut player: Player = world.read_model(player_address); - let game = get!(world, (game_id), (Game)); + let game: Game = world.read_model(game_id); let mut max_px = game.const_val + game.coeff_own_pixels * player.num_owns @@ -34,13 +35,14 @@ fn update_max_px(world: IWorldDispatcher, game_id: usize, player_address: Contra player.max_px = max_px; - set!(world, (player)); + world.write_model(@player); } -fn recover_px(world: IWorldDispatcher, game_id: usize, player_address: ContractAddress) { +fn recover_px(ref self: ContractState, game_id: usize, player_address: ContractAddress) { + let mut world = self.world(@"pixelaw"); update_max_px(world, game_id, player_address); - let mut player = get!(world, (player_address), (Player)); + let mut player: Player = world.read_model(player_address); println!("create_game 3"); let recovery_rate = get!(world, (game_id), (PixelRecoveryRate)); @@ -65,15 +67,16 @@ fn recover_px(world: IWorldDispatcher, game_id: usize, player_address: ContractA print!("## RECOVER_PXS: {} ##\n", recover_pxs); print!("## CURRENT PX: {} ##\n", player.current_px); - set!(world, (player)); + world.write_model(@player); } fn check_game_status(status: Status) -> bool { status == Status::Pending || status == Status::Ongoing } -fn is_member(world: IWorldDispatcher, game_id: usize, guild_id: usize, member: ContractAddress) -> bool { - let guild = get!(world, (game_id, guild_id), (Guild)); +fn is_member(ref self: ContractState, game_id: usize, guild_id: usize, member: ContractAddress) -> bool { + let mut world = self.world(@"pixelaw"); + let guild: Guild = world.read_model(game_id, guild_id); let mut is_member = false; let mut i = 0; loop { diff --git a/contracts/src/systems/voting.cairo b/contracts/src/systems/voting.cairo index 9883429..2592e22 100644 --- a/contracts/src/systems/voting.cairo +++ b/contracts/src/systems/voting.cairo @@ -32,20 +32,21 @@ mod voting_actions { #[abi(embed_v0)] impl VotingImpl of IVoting { fn vote( - ref world: IWorldDispatcher, + ref self: ContractState, game_id: usize, index: usize, use_px: u32, is_in_favor: bool ) { + let mut world = self.world(@"pixelaw"); let player_address = get_caller_address(); - let mut proposal = get!(world, (game_id, index), (Proposal)); - let mut player_vote = get!(world, (player_address, game_id, index), (PlayerVote)); + let mut proposal: Proposal = world.read_model(game_id, index); + let mut player_vote: PlayerVote = world.read_model(player_address, game_id, index); assert(player_vote.px == 0, 'player already voted'); recover_px(world, game_id, player_address); - let mut player = get!(world, (player_address), (Player)); + let mut player: Player = world.read_model(player_address); print!("\n@@ASSERT: CUR: {}, USE: {}\n", player.current_px, use_px); assert(player.current_px >= use_px, 'player do not have enough px'); @@ -61,27 +62,17 @@ mod voting_actions { player.current_px -= use_px; player.num_commit += use_px; - set!(world, (player)); + world.write_model(@player); player_vote.is_in_favor = is_in_favor; player_vote.px = use_px; - set!(world, (proposal, player_vote)); + world.write_model(@proposal); + world.write_model(@player_vote); - update_max_px(world, game_id, player_address); + self.update_max_px(game_id, player_address); - emit!( - world, - (Event::Voted( - Voted { - game_id, - index, - timestamp: get_block_timestamp(), - voter: player_address, - is_in_favor - } - )) - ); + world.emit_event(Voted {game_id, index, get_block_timestamp(), player_address, is_in_favor}); } } } From e9d3470517b3522fc3ecfd3d5e96d5b7d4f23812 Mon Sep 17 00:00:00 2001 From: OwnerOfJK Date: Tue, 26 Nov 2024 16:44:13 +0800 Subject: [PATCH 05/18] fixed a bunch of bugs --- contracts/src/lib.cairo | 1 - contracts/src/models/board.cairo | 4 +-- contracts/src/systems/actions.cairo | 27 +++++++------- contracts/src/systems/apps.cairo | 6 ---- contracts/src/systems/guilds.cairo | 40 +++++++++++++++------ contracts/src/systems/payments.cairo | 3 ++ contracts/src/systems/propose.cairo | 54 +++++++++++++++------------- contracts/src/systems/utils.cairo | 24 +++---------- contracts/src/systems/voting.cairo | 14 ++++---- 9 files changed, 91 insertions(+), 82 deletions(-) delete mode 100644 contracts/src/systems/apps.cairo diff --git a/contracts/src/lib.cairo b/contracts/src/lib.cairo index 52f7e42..b265c70 100644 --- a/contracts/src/lib.cairo +++ b/contracts/src/lib.cairo @@ -1,7 +1,6 @@ mod constants; mod systems { mod actions; - mod apps; mod guilds; mod propose; mod utils; diff --git a/contracts/src/models/board.cairo b/contracts/src/models/board.cairo index 73cd8f0..063a729 100644 --- a/contracts/src/models/board.cairo +++ b/contracts/src/models/board.cairo @@ -37,7 +37,7 @@ trait BoardTrait { impl BoardImpl of BoardTrait { fn is_in_board(self: Board, position: Position) -> bool { position.x >= self.origin.x && position.x <= self.origin.x - + self.width && position.y >= self.origin.y && position.y <= self.origin.y - + self.height + + self.width.into() && position.y >= self.origin.y && position.y <= self.origin.y + + self.height.into() } } diff --git a/contracts/src/systems/actions.cairo b/contracts/src/systems/actions.cairo index 7257384..6bc2aca 100644 --- a/contracts/src/systems/actions.cairo +++ b/contracts/src/systems/actions.cairo @@ -35,20 +35,23 @@ mod p_war_actions { allowed_app::AllowedApp }; use p_war::systems::guilds::{IGuildDispatcher, IGuildDispatcherTrait}; - use p_war::systems::apps::{IAllowedApp, IAllowedAppDispatcher, IAllowedAppDispatcherTrait}; use p_war::systems::utils::{recover_px, update_max_px, check_game_status}; use pixelaw::core::actions::{ IActionsDispatcher as ICoreActionsDispatcher, IActionsDispatcherTrait as ICoreActionsDispatcherTrait }; use pixelaw::core::models::{pixel::PixelUpdate, registry::App}; - use pixelaw::core::traits::IInteroperability; - use pixelaw::core::utils::{get_core_actions, DefaultParameters, Position}; use starknet::{ ContractAddress, get_block_timestamp, get_caller_address, get_contract_address, get_tx_info, contract_address_const, }; use super::{IActions, IActionsDispatcher, IActionsDispatcherTrait}; + use dojo::model::{ModelStorage, ModelValueStorage}; + use dojo::world::WorldStorageTrait; + use dojo::event::EventStorage; + use pixelaw::core::utils::{ + get_callers, get_core_actions, Direction, Position, DefaultParameters + }; #[event] #[derive(Drop, starknet::Event)] @@ -95,7 +98,7 @@ mod p_war_actions { impl ActionsImpl of IActions { fn init(ref self: ContractState) { let mut world = self.world(@"pixelaw"); - let core_actions = self.get_core_actions(); + let core_actions = get_core_actions(ref world); core_actions.new_app(contract_address_const::<0>(), APP_KEY, APP_ICON); } @@ -121,11 +124,11 @@ mod p_war_actions { // set id as GAME_ID=1 // let board = get!(world, (GAME_ID), (Board)); this is the pre-dojo 1.0.0 implementation - let board = world.read_model(GAME_ID); + let board: Board = world.read_model(GAME_ID); if position.x < board.origin.x || position.x >= board.origin.x - + board.width || position.y < board.origin.y || position.y >= board.origin.y - + board.height { + + board.width.into() || position.y < board.origin.y || position.y >= board.origin.y + + board.height.into() { return OUT_OF_BOUNDS_GAME_ID; // OUT_OF_BOUNDS_GAME_ID for out of bounds }; return 1; @@ -147,9 +150,7 @@ mod p_war_actions { let mut id = GAME_ID; // set as a constant for now. let start = get_block_timestamp(); - // let core_actions = get_core_actions(world); let player = get_caller_address(); - // let system = get_contract_address(); let game = Game { id, @@ -222,7 +223,7 @@ mod p_war_actions { println!("create_game 2.1"); // recover px - recover_px(world, id, player); + recover_px(ref world, id, player); id // emit event that game has started @@ -268,7 +269,7 @@ mod p_war_actions { let player_address = get_tx_info().unbox().account_contract_address; // recover px - recover_px(world, game_id, player_address); + recover_px(ref world, game_id, player_address); // if this is first time for the caller, let's set initial px. let mut player: Player = world.read_model(player_address); @@ -320,9 +321,9 @@ mod p_war_actions { assert(get_caller_address() == get_contract_address(), 'invalid caller'); let player_address = get_tx_info().unbox().account_contract_address; let system = get_contract_address(); - let core_actions = self.get_core_actions(); + let core_actions = get_core_actions(ref world); - core_actions.update_pixel(player_address, system, pixel_update); + core_actions.update_pixel(player_address, system, pixel_update, Option::None, false); } fn end_game(ref self: ContractState, game_id: usize) { diff --git a/contracts/src/systems/apps.cairo b/contracts/src/systems/apps.cairo deleted file mode 100644 index 5d4fed0..0000000 --- a/contracts/src/systems/apps.cairo +++ /dev/null @@ -1,6 +0,0 @@ -use pixelaw::core::utils::DefaultParameters; - -#[starknet::interface] -trait IAllowedApp { - fn set_pixel(default_params: DefaultParameters); -} diff --git a/contracts/src/systems/guilds.cairo b/contracts/src/systems/guilds.cairo index 427f177..6b2fc1a 100644 --- a/contracts/src/systems/guilds.cairo +++ b/contracts/src/systems/guilds.cairo @@ -15,6 +15,7 @@ pub trait IGuild { fn remove_member( ref self: T, game_id: usize, guild_id: usize, member: ContractAddress ); + fn is_member(ref self: T, game_id: usize, guild_id: usize, member: ContractAddress) -> bool; fn get_guild_contract_address(ref self: T) -> ContractAddress; fn get_guild_points(ref self: T, game_id: usize, guild_id: usize) -> usize; } @@ -28,8 +29,8 @@ mod guild_actions { use starknet::{ ContractAddress, get_block_timestamp, get_caller_address, get_contract_address, get_tx_info }; - use p_war::systems::utils::{is_member}; - + use dojo::model::{ModelStorage, ModelValueStorage}; + use dojo::event::EventStorage; use super::{IGuild}; #[derive(Drop, Serde, starknet::Event)] @@ -109,9 +110,10 @@ mod guild_actions { println!("new_guild.guild_id: {}", new_guild.guild_id); // Save the guild and update the game - world.write_model(@guild); + world.write_model(@new_guild); println!("set guild"); - world.emit_event(GuildCreated {game_id, guild_id, guild_name, caller}); + let caller = get_caller_address(); + world.emit_event(@GuildCreated {game_id, guild_id, guild_name, creator: caller}); guild_id } @@ -125,13 +127,13 @@ mod guild_actions { let caller = get_caller_address(); // Get the guild - let mut guild: Guild = world.read_model(game_id, guild_id); + let mut guild: Guild = world.read_model((game_id, guild_id)); // Check if the caller is the creator assert(guild.creator == caller, 'Only creator can add members'); // Check if the member is not already in the guild - let is_member = self.is_member(game_id, guild_id, new_member); + let is_member = self.is_member((game_id, guild_id, new_member)); assert(is_member == false, 'New Member already in guild'); // Create a new Array and populate it with existing guild_ids @@ -156,7 +158,7 @@ mod guild_actions { // Save the updated guild world.write_model(@guild); - world.emit_event(@MemberAdded { game_id, guild_id, new_member }); + world.emit_event(@MemberAdded { game_id, guild_id, member: new_member }); } fn join_guild(ref self: ContractState, game_id: usize, guild_id: usize) { @@ -173,7 +175,7 @@ mod guild_actions { let caller = get_caller_address(); // Get the guild - let mut guild: Guild = world.read_model(game_id, guild_id); + let mut guild: Guild = world.read_model((game_id, guild_id)); // Check if the caller is the creator assert(guild.creator == caller, 'Only creator can remove members'); @@ -204,6 +206,24 @@ mod guild_actions { world.emit_event(@MemberRemoved {game_id, guild_id, member}) } + fn is_member(ref self: ContractState, game_id: usize, guild_id: usize, member: ContractAddress) -> bool { + let mut world = self.world(@"pixelaw"); + let guild: Guild = world.read_model((game_id, guild_id)); + let mut is_member = false; + let mut i = 0; + loop { + if i == guild.members.len() { + break; + } + if guild.members.at(i) == @member { + is_member = true; + break; + } + i += 1; + }; + is_member + } + fn get_guild_contract_address(ref self: ContractState) -> ContractAddress { let guild_contract_address = get_contract_address(); @@ -213,7 +233,7 @@ mod guild_actions { fn get_guild_points(ref self: ContractState , game_id: usize, guild_id: usize) -> usize { // Get the guild let mut world = self.world(@"pixelaw"); - let mut guild: Guild = world.read_model(game_id, guild_id); + let mut guild: Guild = world.read_model((game_id, guild_id)); let mut guild_total_points = 0; let mut i = 0; @@ -222,7 +242,7 @@ mod guild_actions { if i >= guild.member_count { break; } - let mut player: Player = world.read_model(*guild.members.at(i), game_id); + let mut player: Player = world.read_model((*guild.members.at(i), game_id)); println!("player.num_commit: {}", player.num_commit); guild_total_points += player.num_commit; i += 1; diff --git a/contracts/src/systems/payments.cairo b/contracts/src/systems/payments.cairo index ba0cd59..cf42265 100644 --- a/contracts/src/systems/payments.cairo +++ b/contracts/src/systems/payments.cairo @@ -15,6 +15,9 @@ pub trait IPayments { mod payments { // use super::*; + use dojo::model::{ModelStorage, ModelValueStorage}; + use dojo::event::EventStorage; + const PRIZE_POOL_PERCENTAGE: u256 = 90; const TREASURY_PERCENTAGE: u256 = 10; diff --git a/contracts/src/systems/propose.cairo b/contracts/src/systems/propose.cairo index 552cb19..d1d3790 100644 --- a/contracts/src/systems/propose.cairo +++ b/contracts/src/systems/propose.cairo @@ -1,4 +1,8 @@ -use p_war::models::{board::Position}; +use p_war::models::{ + game::{Game, Status, GameTrait}, proposal::{Proposal, PixelRecoveryRate}, + board::{GameId, Board, Position, PWarPixel}, player::{Player}, allowed_app::AllowedApp, + allowed_color::{AllowedColor, PaletteColors, InPalette, GamePalette} +}; // define the interface #[starknet::interface] @@ -13,17 +17,14 @@ pub trait IPropose { fn activate_proposal( ref self: T, game_id: usize, index: usize, clear_data: Span ); + fn add_new_color(ref self: T, game_id: usize, index: usize, game: Game, proposal: Proposal); + fn reset_to_white(ref self: T, game_id: usize, index: usize, game: Game, proposal: Proposal, clear_data: Span); } // dojo decorator #[dojo::contract(namespace: "pixelaw", nomapping: true)] mod propose_actions { use p_war::constants::{PROPOSAL_DURATION, NEEDED_YES_PX, DISASTER_SIZE, PROPOSAL_FACTOR}; - use p_war::models::{ - game::{Game, Status, GameTrait}, proposal::{Proposal, PixelRecoveryRate}, - board::{GameId, Board, Position, PWarPixel}, player::{Player}, allowed_app::AllowedApp, - allowed_color::{AllowedColor, PaletteColors, InPalette, GamePalette} - }; use p_war::systems::utils::{recover_px, check_game_status}; use pixelaw::core::actions::{ IActionsDispatcher as ICoreActionsDispatcher, @@ -35,6 +36,13 @@ mod propose_actions { ContractAddress, get_block_timestamp, get_caller_address, get_contract_address, get_tx_info }; use super::{IPropose}; + use dojo::model::{ModelStorage, ModelValueStorage}; + use dojo::event::EventStorage; + use p_war::models::{ + game::{Game, Status, GameTrait}, proposal::{Proposal, PixelRecoveryRate}, + board::{GameId, Board, Position, PWarPixel}, player::{Player}, allowed_app::AllowedApp, + allowed_color::{AllowedColor, PaletteColors, InPalette, GamePalette} + }; #[derive(Drop, Serde, starknet::Event)] pub struct ProposalCreated { @@ -78,7 +86,7 @@ mod propose_actions { let player_address = get_tx_info().unbox().account_contract_address; // recover px - recover_px(world, game_id, player_address); + recover_px(ref world, game_id, player_address); // if this is first time for the caller, let's set initial px. let mut player: Player = world.read_model(player_address); @@ -108,7 +116,7 @@ mod propose_actions { world.write_model(@new_proposal); world.write_model(@game); - player.player.num_commit + (game.base_cost * PROPOSAL_FACTOR); + player.num_commit + (game.base_cost * PROPOSAL_FACTOR); player.current_px - (game.base_cost * PROPOSAL_FACTOR); world.write_model(@player); @@ -126,8 +134,8 @@ mod propose_actions { // }), // ); - world.emit_event(ProposalCreated { game_id, game.proposal_idx, proposal_type, target_args_1, target_args_2 }); - proposal.index + world.emit_event(@ProposalCreated { game_id, index: game.proposal_idx, proposal_type, target_args_1, target_args_2 }); + new_proposal.index } fn activate_proposal( @@ -135,7 +143,7 @@ mod propose_actions { ) { // get the proposal let mut world = self.world(@"pixelaw"); - let mut proposal: Proposal = world.read_model(game_id, index); + let mut proposal: Proposal = world.read_model((game_id, index)); let mut game: Game = world.read_model(game_id); let current_timestamp = get_block_timestamp(); assert(current_timestamp >= proposal.end, 'proposal period has not ended'); @@ -166,7 +174,7 @@ mod propose_actions { proposal.is_activated = true; world.write_model(@proposal); - world.emit_event(@ProposalActivated {game_id, index, proposal.proposal_type, proposal.target_args_1, proposal.target_args_2}) + world.emit_event(@ProposalActivated {game_id, index, proposal_type: proposal.proposal_type, target_args_1: proposal.target_args_1, target_args_2: proposal.target_args_2}) // // Qustion: should we panish the author if the proposal is denied? // // add author's commitment points // let mut author = get!( @@ -189,14 +197,14 @@ mod propose_actions { assert(proposal.proposal_type == 1, 'this is not add new color proposal'); let mut world = self.world(@"pixelaw"); let new_color: u32 = proposal.target_args_1; - let mut new_color_allowed: AllowedColor = world.read_model(game_id, new_color); + let mut new_color_allowed: AllowedColor = world.read_model((game_id, new_color)); // only change it if it's not allowed if !new_color_allowed.is_allowed { new_color_allowed.is_allowed = !new_color_allowed.is_allowed; world.write_model(@new_color_allowed); // check if color already is in the palette - let mut is_in_palette: InPalette = world.read_model(game_id, new_color); + let mut is_in_palette: InPalette = world.read_model((game_id, new_color)); // if aready in the palette early return if is_in_palette.value { return; @@ -209,7 +217,7 @@ mod propose_actions { is_in_palette.value = true; world.write_model(@is_in_palette); - let mut palette_color: PaletteColors = world.read_model(game_id, game_palette.length); + let mut palette_color: PaletteColors = world.read_model((game_id, game_palette.length)); palette_color.color = new_color; world.write_model(@palette_color); @@ -217,13 +225,13 @@ mod propose_actions { world.write_model(@game_palette); } else { // get 0 idx - let oldest_color: PaletteColors = world.read_model(game_id, 0); + let oldest_color: PaletteColors = world.read_model((game_id, 0)); let mut idx = 1; loop { - let palette_color: PaletteColors = world.read_model(game_id, idx); + let current_palette_color: PaletteColors = world.read_model((game_id, idx)); palette_color.idx = idx - 1; - palette_color.color = palette_color.color; + palette_color.color = current_palette_color.color; world.write_model(@palette_color); idx = idx + 1; @@ -232,14 +240,14 @@ mod propose_actions { }; }; - let mut old_in_pallet: InPalette = world.read_model(game_id, oldest_color.color); + let mut old_in_pallet: InPalette = world.read_model((game_id, oldest_color.color)); old_in_pallet.value = false; world.write_model(@old_in_pallet); is_in_palette.value = true; world.write_model(@is_in_palette); - let mut old_color_allowed: AllowedColor = world.read_model(game_id, oldest_color.color); + let mut old_color_allowed: AllowedColor = world.read_model((game_id, oldest_color.color)); old_color_allowed.is_allowed = false; world.write_model(@old_color_allowed); @@ -256,9 +264,7 @@ mod propose_actions { assert(proposal.proposal_type == 2, 'this is not reset to white proposal'); let mut world = self.world(@"pixelaw"); // Reset to white by color - let core_actions = get_core_actions( - world - ); // TODO: should we use p_war_actions insted of core_actions??? + let core_actions = get_core_actions(ref world); // TODO: should we use p_war_actions insted of core_actions??? let system = get_caller_address(); let target_args_1: u32 = proposal.target_args_1; @@ -274,7 +280,7 @@ mod propose_actions { let pixel_to_clear = *clear_data.at(idx); - let pixel_info: Pixel = world.read_model(pixel_to_clear.x, pixel_to_clear.y); + let pixel_info: Pixel = world.read_model((pixel_to_clear.x, pixel_to_clear.y)); if pixel_info.color == target_args_1 { // make it white diff --git a/contracts/src/systems/utils.cairo b/contracts/src/systems/utils.cairo index 8a2fb93..c348c02 100644 --- a/contracts/src/systems/utils.cairo +++ b/contracts/src/systems/utils.cairo @@ -9,6 +9,8 @@ use p_war::models::{ use starknet::{ ContractAddress, get_block_timestamp, get_caller_address, get_contract_address, get_tx_info }; +use dojo::model::{ModelStorage, ModelValueStorage}; +use dojo::event::EventStorage; fn update_max_px(ref self: ContractState, game_id: usize, player_address: ContractAddress) { let mut world = self.world(@"pixelaw"); @@ -40,12 +42,12 @@ fn update_max_px(ref self: ContractState, game_id: usize, player_address: Contra fn recover_px(ref self: ContractState, game_id: usize, player_address: ContractAddress) { let mut world = self.world(@"pixelaw"); - update_max_px(world, game_id, player_address); + update_max_px(ref world, game_id, player_address); let mut player: Player = world.read_model(player_address); println!("create_game 3"); - let recovery_rate = get!(world, (game_id), (PixelRecoveryRate)); + let recovery_rate: PixelRecoveryRate = world.read_model(game_id); println!("create_game 4"); let current_time = get_block_timestamp(); @@ -72,22 +74,4 @@ fn recover_px(ref self: ContractState, game_id: usize, player_address: ContractA fn check_game_status(status: Status) -> bool { status == Status::Pending || status == Status::Ongoing -} - -fn is_member(ref self: ContractState, game_id: usize, guild_id: usize, member: ContractAddress) -> bool { - let mut world = self.world(@"pixelaw"); - let guild: Guild = world.read_model(game_id, guild_id); - let mut is_member = false; - let mut i = 0; - loop { - if i == guild.members.len() { - break; - } - if guild.members.at(i) == @member { - is_member = true; - break; - } - i += 1; - }; - is_member } \ No newline at end of file diff --git a/contracts/src/systems/voting.cairo b/contracts/src/systems/voting.cairo index 2592e22..03d28f2 100644 --- a/contracts/src/systems/voting.cairo +++ b/contracts/src/systems/voting.cairo @@ -1,8 +1,8 @@ // define the interface #[starknet::interface] -trait IVoting { +pub trait IVoting { fn vote( - ref world: IWorldDispatcher, game_id: usize, index: usize, use_px: u32, is_in_favor: bool + ref self: T, game_id: usize, index: usize, use_px: u32, is_in_favor: bool ); } @@ -13,6 +13,8 @@ mod voting_actions { use p_war::systems::utils::{recover_px, update_max_px}; use starknet::{ContractAddress, get_caller_address, get_block_timestamp}; use super::IVoting; + use dojo::model::{ModelStorage, ModelValueStorage}; + use dojo::event::EventStorage; #[derive(Drop, Serde, starknet::Event)] pub struct Voted { @@ -40,11 +42,11 @@ mod voting_actions { ) { let mut world = self.world(@"pixelaw"); let player_address = get_caller_address(); - let mut proposal: Proposal = world.read_model(game_id, index); - let mut player_vote: PlayerVote = world.read_model(player_address, game_id, index); + let mut proposal: Proposal = world.read_model((game_id, index)); + let mut player_vote: PlayerVote = world.read_model((player_address, game_id, index)); assert(player_vote.px == 0, 'player already voted'); - recover_px(world, game_id, player_address); + recover_px(ref world, game_id, player_address); let mut player: Player = world.read_model(player_address); @@ -72,7 +74,7 @@ mod voting_actions { self.update_max_px(game_id, player_address); - world.emit_event(Voted {game_id, index, get_block_timestamp(), player_address, is_in_favor}); + world.emit_event(@Voted {game_id, index, timestamp: get_block_timestamp(), voter: player_address, is_in_favor}); } } } From 3bb4cbe0c374e70ceca47ee985702004f778e8da Mon Sep 17 00:00:00 2001 From: OwnerOfJK Date: Wed, 27 Nov 2024 17:20:53 +0800 Subject: [PATCH 06/18] fixed all compilation issues of all contracts --- contracts/Scarb.lock | 4 +- contracts/Scarb.toml | 2 +- contracts/src/lib.cairo | 1 + contracts/src/models/board.cairo | 20 ++++----- contracts/src/systems/actions.cairo | 32 +++------------ contracts/src/systems/app.cairo | 21 ++++++++++ contracts/src/systems/guilds.cairo | 42 +++++++++---------- contracts/src/systems/propose.cairo | 64 ++++++++++++++--------------- contracts/src/systems/utils.cairo | 9 ++-- contracts/src/systems/voting.cairo | 17 ++++---- 10 files changed, 103 insertions(+), 109 deletions(-) create mode 100644 contracts/src/systems/app.cairo diff --git a/contracts/Scarb.lock b/contracts/Scarb.lock index 485b9f3..6ea6e2d 100644 --- a/contracts/Scarb.lock +++ b/contracts/Scarb.lock @@ -24,8 +24,8 @@ dependencies = [ [[package]] name = "pixelaw" -version = "0.5.7" -source = "git+https://github.com/pixelaw/core?tag=v0.5.7#96260a5d1142e24eb30d63eb69ed47c036081376" +version = "0.5.10" +source = "git+https://github.com/pixelaw/core?tag=v0.5.10#fd8a6981da68fffe4889b48406b69cbbd493cc83" dependencies = [ "dojo", ] diff --git a/contracts/Scarb.toml b/contracts/Scarb.toml index 4564898..117b7c7 100644 --- a/contracts/Scarb.toml +++ b/contracts/Scarb.toml @@ -7,7 +7,7 @@ version = "0.3.54" sierra-replace-ids = true [dependencies] -pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.5.7" } +pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.5.10" } dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.0.1" } [[target.starknet-contract]] diff --git a/contracts/src/lib.cairo b/contracts/src/lib.cairo index b265c70..b3c11a1 100644 --- a/contracts/src/lib.cairo +++ b/contracts/src/lib.cairo @@ -1,6 +1,7 @@ mod constants; mod systems { mod actions; + mod app; mod guilds; mod propose; mod utils; diff --git a/contracts/src/models/board.cairo b/contracts/src/models/board.cairo index 063a729..c064e77 100644 --- a/contracts/src/models/board.cairo +++ b/contracts/src/models/board.cairo @@ -30,14 +30,14 @@ struct GameId { value: usize } -trait BoardTrait { - fn is_in_board(self: Board, position: Position) -> bool; -} +// trait BoardTrait { +// fn is_in_board(self: Board, position: Position) -> bool; +// } -impl BoardImpl of BoardTrait { - fn is_in_board(self: Board, position: Position) -> bool { - position.x >= self.origin.x && position.x <= self.origin.x - + self.width.into() && position.y >= self.origin.y && position.y <= self.origin.y - + self.height.into() - } -} +// impl BoardImpl of BoardTrait { +// fn is_in_board(self: Board, position: Position) -> bool { +// position.x >= self.origin.x && position.x <= self.origin.x +// + self.width && position.y >= self.origin.y && position.y <= self.origin.y +// + self.height +// } +// } diff --git a/contracts/src/systems/actions.cairo b/contracts/src/systems/actions.cairo index 6bc2aca..c15524a 100644 --- a/contracts/src/systems/actions.cairo +++ b/contracts/src/systems/actions.cairo @@ -52,6 +52,7 @@ mod p_war_actions { use pixelaw::core::utils::{ get_callers, get_core_actions, Direction, Position, DefaultParameters }; + use p_war::systems::app::{IAllowedApp, IAllowedAppDispatcher, IAllowedAppDispatcherTrait}; #[event] #[derive(Drop, starknet::Event)] @@ -74,26 +75,6 @@ mod p_war_actions { // should we emit here the states of the pixel as well? } - #[abi(embed_v0)] - impl AllowedAppImpl of IAllowedApp { - fn set_pixel(ref self: ContractState, default_params: DefaultParameters) { - let actions = IActionsDispatcher { contract_address: get_contract_address() }; - actions - .update_pixel( - PixelUpdate { - x: default_params.position.x, - y: default_params.position.y, - color: Option::Some(default_params.color), - timestamp: Option::None, - text: Option::None, - app: Option::None, - owner: Option::None, - action: Option::None - } - ); - } - } - #[abi(embed_v0)] impl ActionsImpl of IActions { fn init(ref self: ContractState) { @@ -117,18 +98,14 @@ mod p_war_actions { fn get_game_id(self: @ContractState, position: Position) -> usize { let mut world = self.world(@"pixelaw"); - let mut id = world.uuid(); - if id == 0 { - return 0; - }; // set id as GAME_ID=1 // let board = get!(world, (GAME_ID), (Board)); this is the pre-dojo 1.0.0 implementation let board: Board = world.read_model(GAME_ID); if position.x < board.origin.x || position.x >= board.origin.x - + board.width.into() || position.y < board.origin.y || position.y >= board.origin.y - + board.height.into() { + + (board.width.try_into().unwrap()) || position.y < board.origin.y || position.y >= board.origin.y + + (board.height.try_into().unwrap()) { return OUT_OF_BOUNDS_GAME_ID; // OUT_OF_BOUNDS_GAME_ID for out of bounds }; return 1; @@ -169,6 +146,7 @@ mod p_war_actions { let board = Board { id, origin, width: DEFAULT_AREA, height: DEFAULT_AREA, }; + world.write_model(@board); //not sure world.write_model(@game); println!("create_game 1"); // add default colors (changed these to RGBA) @@ -312,7 +290,7 @@ mod p_war_actions { world.write_model(@previous_pwarpixel); //set!(world, (PWarPixel { position: position, owner: player.address }),); - self.update_max_px(game_id, player.address); + update_max_px(ref world, game_id, player.address); } // only use for expand areas. diff --git a/contracts/src/systems/app.cairo b/contracts/src/systems/app.cairo new file mode 100644 index 0000000..a329218 --- /dev/null +++ b/contracts/src/systems/app.cairo @@ -0,0 +1,21 @@ +use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; +use pixelaw::core::utils::DefaultParameters; +use starknet::ContractAddress; + +#[starknet::interface] +trait IAllowedApp { + fn set_pixel(ref self: TContractState, default_params: DefaultParameters); +} + +#[dojo::contract(namespace: "pixelaw", nomapping: true)] +mod allowed_app_actions { + use super::IAllowedApp; + use pixelaw::core::utils::DefaultParameters; + + #[abi(embed_v0)] + impl AllowedAppImpl of IAllowedApp { + fn set_pixel(ref self: ContractState, default_params: DefaultParameters) { + // Implementation here + } + } +} \ No newline at end of file diff --git a/contracts/src/systems/guilds.cairo b/contracts/src/systems/guilds.cairo index 6b2fc1a..e0316a4 100644 --- a/contracts/src/systems/guilds.cairo +++ b/contracts/src/systems/guilds.cairo @@ -30,40 +30,38 @@ mod guild_actions { ContractAddress, get_block_timestamp, get_caller_address, get_contract_address, get_tx_info }; use dojo::model::{ModelStorage, ModelValueStorage}; + use dojo::world::WorldStorageTrait; use dojo::event::EventStorage; use super::{IGuild}; - - #[derive(Drop, Serde, starknet::Event)] - pub struct GuildCreated { + + #[derive(Copy, Drop, Serde)] + #[dojo::event] + struct GuildCreated { + #[key] game_id: usize, guild_id: usize, guild_name: felt252, - creator: ContractAddress, + creator: ContractAddress } - - #[derive(Drop, Serde, starknet::Event)] - pub struct MemberAdded { + + #[derive(Copy, Drop, Serde)] + #[dojo::event] + struct MemberAdded { + #[key] game_id: usize, guild_id: usize, - member: ContractAddress, + member: ContractAddress } - - #[derive(Drop, Serde, starknet::Event)] - pub struct MemberRemoved { + + #[derive(Copy, Drop, Serde)] + #[dojo::event] + struct MemberRemoved { + #[key] game_id: usize, guild_id: usize, - member: ContractAddress, + member: ContractAddress } - #[event] - #[derive(Drop, starknet::Event)] - pub enum Event { - GuildCreated: GuildCreated, - MemberAdded: MemberAdded, - MemberRemoved: MemberRemoved, - } - - #[abi(embed_v0)] impl GuildImpl of IGuild { fn create_guild(ref self: ContractState, game_id: usize, guild_name: felt252) -> usize { @@ -133,7 +131,7 @@ mod guild_actions { assert(guild.creator == caller, 'Only creator can add members'); // Check if the member is not already in the guild - let is_member = self.is_member((game_id, guild_id, new_member)); + let is_member = self.is_member(game_id, guild_id, new_member); assert(is_member == false, 'New Member already in guild'); // Create a new Array and populate it with existing guild_ids diff --git a/contracts/src/systems/propose.cairo b/contracts/src/systems/propose.cairo index d1d3790..0edeac4 100644 --- a/contracts/src/systems/propose.cairo +++ b/contracts/src/systems/propose.cairo @@ -37,24 +37,29 @@ mod propose_actions { }; use super::{IPropose}; use dojo::model::{ModelStorage, ModelValueStorage}; + use dojo::world::WorldStorageTrait; use dojo::event::EventStorage; use p_war::models::{ game::{Game, Status, GameTrait}, proposal::{Proposal, PixelRecoveryRate}, board::{GameId, Board, Position, PWarPixel}, player::{Player}, allowed_app::AllowedApp, allowed_color::{AllowedColor, PaletteColors, InPalette, GamePalette} }; - - #[derive(Drop, Serde, starknet::Event)] - pub struct ProposalCreated { + + #[derive(Copy, Drop, Serde)] + #[dojo::event] + struct ProposalCreated { + #[key] game_id: usize, index: usize, proposal_type: u8, target_args_1: u32, target_args_2: u32 } - - #[derive(Drop, Serde, starknet::Event)] - pub struct ProposalActivated { + + #[derive(Copy, Drop, Serde)] + #[dojo::event] + struct ProposalActivated { + #[key] game_id: usize, index: usize, proposal_type: u8, @@ -62,13 +67,6 @@ mod propose_actions { target_args_2: u32 } - #[event] - #[derive(Drop, starknet::Event)] - pub enum Event { - ProposalCreated: ProposalCreated, - ProposalActivated: ProposalActivated - } - #[abi(embed_v0)] impl ProposeImpl of IPropose { fn create_proposal( @@ -154,9 +152,9 @@ mod propose_actions { // activate the proposal. if proposal.proposal_type == 1 { - add_new_color(world, game_id, index, game, proposal); + self.add_new_color(game_id, index, game, proposal); } else if proposal.proposal_type == 2 { - reset_to_white(world, game_id, index, game, proposal, clear_data) + self.reset_to_white(game_id, index, game, proposal, clear_data) } else if proposal.proposal_type == 3 { // ProposalType::ExtendGameEndTime let mut game: Game = world.read_model(game_id); game.end += proposal.target_args_1.into(); @@ -176,25 +174,25 @@ mod propose_actions { world.write_model(@proposal); world.emit_event(@ProposalActivated {game_id, index, proposal_type: proposal.proposal_type, target_args_1: proposal.target_args_1, target_args_2: proposal.target_args_2}) // // Qustion: should we panish the author if the proposal is denied? - // // add author's commitment points - // let mut author = get!( - // world, - // (proposal.author), - // (Player) - // ); - - // author.num_commit += 10; // get 10 commitments if the proposal is accepted - // set!( - // world, - // (author) - // ); + // // add author's commitment points + // let mut author = get!( + // world, + // (proposal.author), + // (Player) + // ); + + // author.num_commit += 10; // get 10 commitments if the proposal is accepted + // set!( + // world, + // (author) + // ); } // add new color to the palette, if the color is added, the oldest color become unusable. fn add_new_color( ref self: ContractState, game_id: usize, index: usize, game: Game, proposal: Proposal ) { - assert(proposal.proposal_type == 1, 'this is not add new color proposal'); + assert(proposal.proposal_type == 1, 'not add new color proposal'); let mut world = self.world(@"pixelaw"); let new_color: u32 = proposal.target_args_1; let mut new_color_allowed: AllowedColor = world.read_model((game_id, new_color)); @@ -229,9 +227,9 @@ mod propose_actions { let mut idx = 1; loop { - let current_palette_color: PaletteColors = world.read_model((game_id, idx)); + let mut palette_color: PaletteColors = world.read_model((game_id, idx)); palette_color.idx = idx - 1; - palette_color.color = current_palette_color.color; + palette_color.color = palette_color.color; world.write_model(@palette_color); idx = idx + 1; @@ -261,7 +259,7 @@ mod propose_actions { fn reset_to_white( ref self: ContractState, game_id: usize, index: usize, game: Game, proposal: Proposal, clear_data: Span ) { - assert(proposal.proposal_type == 2, 'this is not reset to white proposal'); + assert(proposal.proposal_type == 2, 'not reset to white proposal'); let mut world = self.world(@"pixelaw"); // Reset to white by color let core_actions = get_core_actions(ref world); // TODO: should we use p_war_actions insted of core_actions??? @@ -297,7 +295,9 @@ mod propose_actions { app: Option::Some(system), owner: Option::None, action: Option::None - } + }, + Option::None, + false ); // decrease the previous owner's num_owns diff --git a/contracts/src/systems/utils.cairo b/contracts/src/systems/utils.cairo index c348c02..dafd3c3 100644 --- a/contracts/src/systems/utils.cairo +++ b/contracts/src/systems/utils.cairo @@ -11,9 +11,9 @@ use starknet::{ }; use dojo::model::{ModelStorage, ModelValueStorage}; use dojo::event::EventStorage; +use dojo::world::storage::WorldStorage; -fn update_max_px(ref self: ContractState, game_id: usize, player_address: ContractAddress) { - let mut world = self.world(@"pixelaw"); +pub fn update_max_px(ref world: WorldStorage, game_id: usize, player_address: ContractAddress) { let mut player: Player = world.read_model(player_address); let game: Game = world.read_model(game_id); @@ -40,8 +40,7 @@ fn update_max_px(ref self: ContractState, game_id: usize, player_address: Contra world.write_model(@player); } -fn recover_px(ref self: ContractState, game_id: usize, player_address: ContractAddress) { - let mut world = self.world(@"pixelaw"); +pub fn recover_px(ref world: WorldStorage, game_id: usize, player_address: ContractAddress) { update_max_px(ref world, game_id, player_address); let mut player: Player = world.read_model(player_address); @@ -72,6 +71,6 @@ fn recover_px(ref self: ContractState, game_id: usize, player_address: ContractA world.write_model(@player); } -fn check_game_status(status: Status) -> bool { +pub fn check_game_status(status: Status) -> bool { status == Status::Pending || status == Status::Ongoing } \ No newline at end of file diff --git a/contracts/src/systems/voting.cairo b/contracts/src/systems/voting.cairo index 03d28f2..3712742 100644 --- a/contracts/src/systems/voting.cairo +++ b/contracts/src/systems/voting.cairo @@ -14,10 +14,13 @@ mod voting_actions { use starknet::{ContractAddress, get_caller_address, get_block_timestamp}; use super::IVoting; use dojo::model::{ModelStorage, ModelValueStorage}; + use dojo::world::WorldStorageTrait; use dojo::event::EventStorage; - - #[derive(Drop, Serde, starknet::Event)] - pub struct Voted { + + #[derive(Copy, Drop, Serde)] + #[dojo::event] + struct Voted { + #[key] game_id: usize, index: usize, timestamp: u64, @@ -25,12 +28,6 @@ mod voting_actions { is_in_favor: bool } - #[event] - #[derive(Drop, starknet::Event)] - pub enum Event { - Voted: Voted - } - #[abi(embed_v0)] impl VotingImpl of IVoting { fn vote( @@ -72,7 +69,7 @@ mod voting_actions { world.write_model(@proposal); world.write_model(@player_vote); - self.update_max_px(game_id, player_address); + update_max_px(ref world, game_id, player_address); world.emit_event(@Voted {game_id, index, timestamp: get_block_timestamp(), voter: player_address, is_in_favor}); } From 4a96f46800443587d82c4c6f0e0ef5d643b6acd2 Mon Sep 17 00:00:00 2001 From: OwnerOfJK Date: Thu, 28 Nov 2024 18:21:56 +0800 Subject: [PATCH 07/18] update --- contracts/Scarb.lock | 19 ++++++++++++++++ contracts/Scarb.toml | 16 ++++++-------- contracts/src/systems/app.cairo | 22 +++++++++++++++++-- contracts/src/tests/test_add_color.cairo | 8 +++---- contracts/src/tests/test_create_world.cairo | 4 ++-- contracts/src/tests/test_expand_area.cairo | 4 ++-- .../src/tests/test_extend_game_end.cairo | 4 ++-- contracts/src/tests/test_guild.cairo | 14 ++++++------ contracts/src/tests/test_reset_to_white.cairo | 2 +- contracts/src/tests/utils.cairo | 13 ++++++++--- 10 files changed, 74 insertions(+), 32 deletions(-) diff --git a/contracts/Scarb.lock b/contracts/Scarb.lock index 6ea6e2d..431883e 100644 --- a/contracts/Scarb.lock +++ b/contracts/Scarb.lock @@ -9,6 +9,14 @@ dependencies = [ "dojo_plugin", ] +[[package]] +name = "dojo_cairo_test" +version = "1.0.0-rc.0" +source = "git+https://github.com/dojoengine/dojo?tag=v1.0.1#d7335e6f5c76a1dda887ec00c594c2c019b4a05f" +dependencies = [ + "dojo", +] + [[package]] name = "dojo_plugin" version = "2.8.4" @@ -19,7 +27,9 @@ name = "p_war" version = "0.3.54" dependencies = [ "dojo", + "dojo_cairo_test", "pixelaw", + "pixelaw_test_helpers", ] [[package]] @@ -29,3 +39,12 @@ source = "git+https://github.com/pixelaw/core?tag=v0.5.10#fd8a6981da68fffe4889b4 dependencies = [ "dojo", ] + +[[package]] +name = "pixelaw_test_helpers" +version = "0.5.10" +source = "git+https://github.com/pixelaw/core?tag=v0.5.10#fd8a6981da68fffe4889b48406b69cbbd493cc83" +dependencies = [ + "dojo", + "dojo_cairo_test", +] diff --git a/contracts/Scarb.toml b/contracts/Scarb.toml index 117b7c7..ec025de 100644 --- a/contracts/Scarb.toml +++ b/contracts/Scarb.toml @@ -8,21 +8,19 @@ sierra-replace-ids = true [dependencies] pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.5.10" } +#pixelaw = { path = "../core/contracts" } dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.0.1" } +[dev-dependencies] +dojo_cairo_test = { git = "https://github.com/dojoengine/dojo", tag = "v1.0.1" } +pixelaw_test_helpers = { git = "https://github.com/pixelaw/core", tag = "v0.5.10" } +#pixelaw_test_helpers = { path = "../core/test_helpers" } + [[target.starknet-contract]] +allowed-libfuncs-list.name = "experimental" build-external-contracts = [ "dojo::world::world_contract::world", - "pixelaw::core::models::pixel::Pixel", - "pixelaw::core::models::pixel::PixelUpdate", - "pixelaw::core::models::queue::QueueItem", - "pixelaw::core::models::registry::App", - "pixelaw::core::models::registry::AppName", - "pixelaw::core::utils::get_core_actions", - "pixelaw::core::models::registry::CoreActionsAddress", "pixelaw::core::actions::actions", - "pixelaw::core::actions::IActionsDispatcher", - "pixelaw::core::actions::IActionsDispatcherTrait" ] [tool.fmt] diff --git a/contracts/src/systems/app.cairo b/contracts/src/systems/app.cairo index a329218..bec70ca 100644 --- a/contracts/src/systems/app.cairo +++ b/contracts/src/systems/app.cairo @@ -1,6 +1,8 @@ use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; use pixelaw::core::utils::DefaultParameters; -use starknet::ContractAddress; +use pixelaw::core::models::pixel::PixelUpdate; +use starknet::{ContractAddress, get_contract_address}; +use super::actions::{IActionsDispatcher, IActionsDispatcherTrait}; // Add this import #[starknet::interface] trait IAllowedApp { @@ -11,11 +13,27 @@ trait IAllowedApp { mod allowed_app_actions { use super::IAllowedApp; use pixelaw::core::utils::DefaultParameters; + use pixelaw::core::models::pixel::PixelUpdate; + use starknet::{ContractAddress, get_contract_address}; + use super::super::actions::{IActionsDispatcher, IActionsDispatcherTrait}; // Add this import #[abi(embed_v0)] impl AllowedAppImpl of IAllowedApp { fn set_pixel(ref self: ContractState, default_params: DefaultParameters) { - // Implementation here + let actions = IActionsDispatcher { contract_address: get_contract_address() }; + actions + .update_pixel( + PixelUpdate { + x: default_params.position.x, + y: default_params.position.y, + color: Option::Some(default_params.color), + timestamp: Option::None, + text: Option::None, + app: Option::None, + owner: Option::None, + action: Option::None + } + ); } } } \ No newline at end of file diff --git a/contracts/src/tests/test_add_color.cairo b/contracts/src/tests/test_add_color.cairo index c0c3c26..6559385 100644 --- a/contracts/src/tests/test_add_color.cairo +++ b/contracts/src/tests/test_add_color.cairo @@ -68,13 +68,13 @@ fn test_add_color() { // (Game) // ); - let oldest_color_palette = get!(world, (id, 0), (PaletteColors)); + let oldest_color_pallette: PaletteColors = world.read_model(id, 0); // let index = propose_system.toggle_allowed_color(id, NEW_COLOR); let vote_px = 3; voting_system.vote(id, index, vote_px, true); - let proposal = get!(world, (id, index), (Proposal)); + let proposal: Proposal = world.read_model(id, index); println!("\n## PROPOSAL INFO ##"); println!("Proposal end: {}", proposal.end); @@ -96,11 +96,11 @@ fn test_add_color() { p_war_actions.interact(new_params); // check if the oldest color is unusable - let oldest_color_allowed = get!(world, (id, oldest_color_palette.color), (AllowedColor)); + let oldest_color_allowed: AllowedColor = world.read_model(id, oldest_color_pallette.color); println!( "@@@@@ OLDEST_ALLOWED: {}, {} @@@@", - oldest_color_palette.color, + oldest_color_pallette.color, oldest_color_allowed.is_allowed ); diff --git a/contracts/src/tests/test_create_world.cairo b/contracts/src/tests/test_create_world.cairo index 8822bb8..33b1889 100644 --- a/contracts/src/tests/test_create_world.cairo +++ b/contracts/src/tests/test_create_world.cairo @@ -36,7 +36,7 @@ fn test_create_game() { // call place_pixel let NEW_COLOR: u32 = 0xFFFFFFFF; - let allowed_color = get!(world, (id, NEW_COLOR), (AllowedColor)); + let allowed_color: AllowedColor = world.read_model(id, NEW_COLOR); println!("allowed_color: {}", allowed_color.is_allowed); @@ -48,7 +48,7 @@ fn test_create_game() { }; p_war_actions.interact(new_params); - let player = get!(world, (get_tx_info().unbox().account_contract_address), (Player)); + let player: Player = world.read_model(get_tx_info().unbox().account_contract_address); assert(player.current_px == 9, 'current px should be 9'); } diff --git a/contracts/src/tests/test_expand_area.cairo b/contracts/src/tests/test_expand_area.cairo index 509d843..2011625 100644 --- a/contracts/src/tests/test_expand_area.cairo +++ b/contracts/src/tests/test_expand_area.cairo @@ -46,7 +46,7 @@ fn test_expand_area() { let vote_px = 3; voting_system.vote(id, index, vote_px, true); - let proposal = get!(world, (id, index), (Proposal)); + let proposal: Proposal = world.read_model(id, index); print!("\n## PROPOSAL INFO ##\n"); print!("Proposal end: {}\n", proposal.end); @@ -54,7 +54,7 @@ fn test_expand_area() { // should add cheat code to spend time propose_system.activate_proposal(id, index); - let board = get!(world, (id), (Board)); + let board: Board = world.read_model(id); assert(board.width == DEFAULT_AREA + 20, 'game area extended'); assert(board.height == DEFAULT_AREA + 30, 'game area extended'); diff --git a/contracts/src/tests/test_extend_game_end.cairo b/contracts/src/tests/test_extend_game_end.cairo index 6f1bc5c..58f4f0e 100644 --- a/contracts/src/tests/test_extend_game_end.cairo +++ b/contracts/src/tests/test_extend_game_end.cairo @@ -51,7 +51,7 @@ fn test_extend_game_end() { let vote_px = 3; voting_system.vote(id, index, vote_px, true); - let proposal = get!(world, (id, index), (Proposal)); + let proposal: Proposal = world.read_model(id, index); println!("## PROPOSAL INFO ##"); println!("Proposal end: {}", proposal.end); @@ -73,7 +73,7 @@ fn test_extend_game_end() { // p_war_actions.interact(new_params); - let game = get!(world, (id), (Game)); + let game: Game = world.read_model(id); assert(game.end > GAME_DURATION + 60 * 60 - 1, 'game end extended'); } diff --git a/contracts/src/tests/test_guild.cairo b/contracts/src/tests/test_guild.cairo index 969daf7..84d1272 100644 --- a/contracts/src/tests/test_guild.cairo +++ b/contracts/src/tests/test_guild.cairo @@ -70,7 +70,7 @@ fn test_guild_operations() { println!("guild created: guild_id = {}", guild_id); // Check if the guild was created - let guild = get!(world, (game_id, guild_id), (Guild)); + let guild: Guild = world.read_model(game_id, guild_id); assert(guild.guild_name == 'Test Guild', 'Guild name mismatch'); assert(guild.creator == PLAYER_1, 'Guild creator mismatch'); assert(guild.member_count == 1, 'create, should be 1'); @@ -83,14 +83,14 @@ fn test_guild_operations() { guild_actions.add_member(game_id, guild_id, PLAYER_2); // Check if the member was added - let updated_guild = get!(world, (game_id, guild_id), (Guild)); + let updated_guild: Guild = world.read_model(game_id, guild_id); assert(updated_guild.member_count == 2, 'Member count should be 2'); // Remove a member guild_actions.remove_member(game_id, guild_id, PLAYER_2); // Check if the member was removed - let final_guild = get!(world, (game_id, guild_id), (Guild)); + let final_guild: Guild = world.read_model(game_id, guild_id); assert(final_guild.member_count == 1, 'remove, should be 1'); println!("guild operations passed"); @@ -188,22 +188,22 @@ fn test_guild_creation() { // Create a guild let guild_id: u32 = *guild_ids.at(0); println!("guild_id: {}", guild_id); - let guild = get!(world, (game_id, guild_id), (Guild)); + let guild: Guild = world.read_model(game_id, guild_id); assert(guild.guild_name == 'Fire', 'Guild name mismatch'); let guild_id_2 = *guild_ids.at(1); println!("guild_id_2: {}", guild_id_2); - let guild = get!(world, (game_id, guild_id_2), (Guild)); + let guild: Guild = world.read_model(game_id, guild_id_2); assert(guild.guild_name == 'Water', 'Guild name mismatch'); let guild_id_3 = *guild_ids.at(2); println!("guild_id_3: {}", guild_id_3); - let guild = get!(world, (game_id, guild_id_3), (Guild)); + let guild: Guild = world.read_model(game_id, guild_id_3); assert(guild.guild_name == 'Earth', 'Guild name mismatch'); let guild_id_4 = *guild_ids.at(3); println!("guild_id_4: {}", guild_id_4); - let guild = get!(world, (game_id, guild_id_4), (Guild)); + let guild: Guild = world.read_model(game_id, guild_id_4); assert(guild.guild_name == 'Air', 'Guild name mismatch'); println!("Guild creation tests passed successfully"); } diff --git a/contracts/src/tests/test_reset_to_white.cairo b/contracts/src/tests/test_reset_to_white.cairo index 285e318..a951cc9 100644 --- a/contracts/src/tests/test_reset_to_white.cairo +++ b/contracts/src/tests/test_reset_to_white.cairo @@ -95,7 +95,7 @@ fn test_reset_to_white() { voting.vote(game_id, proposal_id, VOTE_PIXEL_COUNT, true); - let proposal = get!(world, (game_id, proposal_id), (Proposal)); + let proposal: Proposal = world.read_model(game_id, proposal_id); print!("proposal.end: {}\n", proposal.end); diff --git a/contracts/src/tests/utils.cairo b/contracts/src/tests/utils.cairo index 694a5d9..cbf44c2 100644 --- a/contracts/src/tests/utils.cairo +++ b/contracts/src/tests/utils.cairo @@ -1,5 +1,5 @@ // import test utils -use dojo::utils::test::{spawn_test_world, deploy_contract}; +use dojo::test_utils::{spawn_test_world, deploy_contract}; // import world dispatcher use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; // import test utils @@ -30,7 +30,8 @@ use pixelaw::core::{ utils::{DefaultParameters, Position} }; use starknet::{class_hash::Felt252TryIntoClassHash, ContractAddress}; - +use dojo::model::Model; +use dojo::database::schema::{SchemaIntrospection, TypeTag}; pub fn setup() -> ( IWorldDispatcher, @@ -67,7 +68,8 @@ pub fn setup() -> ( ]; // deploy world with models - let world = spawn_test_world(["pixelaw"].span(), models.into()); + //let world = spawn_test_world(["pixelaw"].span(), models.into()); + let world = spawn_test_world(models); println!("world deployed"); @@ -93,6 +95,10 @@ pub fn setup() -> ( .deploy_contract('salty3', guild_actions::TEST_CLASS_HASH.try_into().unwrap()); let guild = IGuildDispatcher { contract_address: guild_address }; + let allowed_app_address = world + .deploy_contract('salty4', allowed_app_actions::TEST_CLASS_HASH.try_into().unwrap()); + let allowed_app = IAllowedAppDispatcher { contract_address: allowed_app_address }; + println!("contracts deployed"); world.grant_writer(selector_from_tag!("pixelaw-App"), core_actions_address); @@ -125,6 +131,7 @@ pub fn setup() -> ( world.grant_writer(selector_from_tag!("pixelaw-Guild"), guild_address); world.grant_writer(selector_from_tag!("pixelaw-Game"), guild_address); world.grant_writer(selector_from_tag!("pixelaw-Player"), guild_address); + world.grant_writer(selector_from_tag!("pixelaw-AllowedApp"), allowed_app_address); core_actions.init(); println!("grants done"); From 07a96415dd5555c0a5e360484be73abb8b2f92bc Mon Sep 17 00:00:00 2001 From: OwnerOfJK Date: Thu, 28 Nov 2024 19:29:28 +0800 Subject: [PATCH 08/18] updated tests --- .devcontainer/devcontainer.json | 56 + cairo_prompt | 14614 ---------------- client/bun.lockb | Bin 297028 -> 314740 bytes client/package.json | 2 +- contracts/.cursorrules | 73 + contracts/Scarb.toml | 9 +- contracts/dojo_dev.toml | 6 +- contracts/dojo_sepolia.toml | 15 + contracts/scripts/account_from_key.sh | 13 + contracts/scripts/build_sepolia.sh | 5 + contracts/scripts/deploy_sepolia.sh | 5 + contracts/src/lib.cairo | 5 +- contracts/src/tests/test_add_color.cairo | 40 +- contracts/src/tests/test_setup.cairo | 9 + contracts/src/tests/utils.cairo | 337 +- contracts/src/tests_old/test_add_color.cairo | 108 + .../test_create_world.cairo | 0 .../test_expand_area.cairo | 0 .../test_extend_game_end.cairo | 0 .../src/{tests => tests_old}/test_guild.cairo | 0 .../test_reset_to_white.cairo | 0 21 files changed, 535 insertions(+), 14762 deletions(-) create mode 100644 .devcontainer/devcontainer.json delete mode 100644 cairo_prompt create mode 100644 contracts/.cursorrules create mode 100644 contracts/dojo_sepolia.toml create mode 100755 contracts/scripts/account_from_key.sh create mode 100755 contracts/scripts/build_sepolia.sh create mode 100755 contracts/scripts/deploy_sepolia.sh create mode 100644 contracts/src/tests/test_setup.cairo create mode 100644 contracts/src/tests_old/test_add_color.cairo rename contracts/src/{tests => tests_old}/test_create_world.cairo (100%) rename contracts/src/{tests => tests_old}/test_expand_area.cairo (100%) rename contracts/src/{tests => tests_old}/test_extend_game_end.cairo (100%) rename contracts/src/{tests => tests_old}/test_guild.cairo (100%) rename contracts/src/{tests => tests_old}/test_reset_to_white.cairo (100%) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..6e5d786 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,56 @@ +{ + "name": "My Project", + "image": "ghcr.io/pixelaw/core:0.5.10", + "workspaceFolder": "/workspaces/pwar", + "workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/pwar,type=bind", + "forwardPorts": [ + 5050, + 8080, + 9090, + 3000 + ], + "containerEnv": { + "RPC_URL": "http://localhost:5050", + "TORII_URL": "http://localhost:8080", + "RELAY_URL": "http://localhost:8080", + "PUBLIC_SERVER_URL": "http://localhost:3000", + "PUBLIC_RPC_URL": "http://localhost:5050", + "PUBLIC_TORII_URL": "http://localhost:8080", + "PUBLIC_RELAY_URL": "http://localhost:8080", + "MASTER_ADDRESS": "0xb3ff441a68610b30fd5e2abbf3a1548eb6ba6f3559f2862bf2dc757e5828ca", + "MASTER_PRIVATE_KEY": "0x2bbf4f9fd0bbb2e60b0316c1fe0b76cf7a4d0198bd493ced9b8df2a3a24d68a", + "WORLD_ADDRESS": "0x6f130c8e150882e39cbe878c650c8f35c86579180dbc77d0c1cbe169449b5f6", + "ACCOUNT_CLASS_HASH": "0x05400e90f7e0ae78bd02c77cd75527280470e2fe19c54970dd79dc37a9d3645c", + "FEETOKEN_ADDRESS": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", + "SERVER_PORT": "3000" + }, + "postStartCommand": [ + "/pixelaw/scripts/startup.sh" + ], + // 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.0.1/bin/dojo-language-server", + "cairo1.enableScarb": true, + "cairo1.scarbPath": "${userHome}/.asdf/installs/scarb/2.7.0/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" + ] + } + } +} \ No newline at end of file diff --git a/cairo_prompt b/cairo_prompt deleted file mode 100644 index 8e055e3..0000000 --- a/cairo_prompt +++ /dev/null @@ -1,14614 +0,0 @@ -# Appendix - -The following sections contain reference material you may find useful in your -Cairo journey. -# Appendix - -The following sections contain reference material you may find useful in your -Starknet journey. -# Appendix A - Keywords - -The following list contains keywords that are reserved for current or future use by the Cairo language. - -There are three keyword categories: - -- strict -- loose -- reserved - -There is a fourth category, which are functions from the core library. While their names are not reserved, -they are not recommended to be used as names of any items to follow good practices. - ---- - -## Strict keywords - -These keywords can only be used in their correct contexts. -They cannot be used as names of any items. - -- `as` - Rename import -- `break` - Exit a loop immediately -- `const` - Define constant items -- `continue` - Continue to the next loop iteration -- `else` - Fallback for `if` and `if let` control flow constructs -- `enum` - Define an enumeration -- `extern` - Function defined at the compiler level that can be compiled to CASM -- `false` - Boolean false literal -- `fn` - Define a function -- `if` - Branch based on the result of a conditional expression -- `impl` - Implement inherent or trait functionality -- `implicits` - Special kind of function parameters that are required to perform certain actions -- `let` - Bind a variable -- `loop` - Loop unconditionally -- `match` - Match a value to patterns -- `mod` - Define a module -- `mut` - Denote variable mutability -- `nopanic` - Functions marked with this notation mean that the function will never panic. -- `of` - Implement a trait -- `pub` - Denote public visibility in items, such as struct and struct fields, enums, consts, traits and impl blocks, or modules -- `ref` - Parameter passed implicitly returned at the end of a function -- `return` - Return from function -- `struct` - Define a structure -- `trait` - Define a trait -- `true` - Boolean true literal -- `type` - Define a type alias -- `use` - Bring symbols into scope -- `while` - loop conditionally based on the result of an expression - ---- - -## Loose Keywords - -These keywords are associated with a specific behaviour, but can also be used to define items. - -- `self` - Method subject -- `super` - Parent module of the current module - ---- - -## Reserved Keywords - -These keywords aren't used yet, but they are reserved for future use. -For now, it is possible to use them to define items, although it is highly recommended not to do so. -The reasoning behind this recommendation is to make current programs forward compatible with future versions of -Cairo by forbidding them to use these keywords. - -- `Self` -- `do` -- `dyn` -- `for` -- `hint` -- `in` -- `macro` -- `move` -- `static_assert` -- `static` -- `try` -- `typeof` -- `unsafe` -- `where` -- `with` -- `yield` - ---- - -## Built-in Functions - -The Cairo programming language provides several specific functions that serve a special purpose. We will not cover all of them in this book, but using the names of these functions as names of other items is not recommended. - -- `assert` - This function checks a boolean expression, and if it evaluates to false, it triggers the panic function. -- `panic` - This function acknowledges the occurrence of an error and terminates the program. -# Appendix B - Operators and Symbols - -This appendix contains a glossary of Cairo's syntax, including operators and other symbols that appear by themselves or in the context of paths, generics, macros, attributes, comments, tuples, and brackets. - -## Operators - -Table B-1 contains the operators in Cairo, an example of how the operator would appear in context, a short explanation, and whether that operator is overloadable. If an operator is overloadable, the relevant trait to use to overload that operator is listed. - -| Operator | Example | Explanation | Overloadable? | -| ------------------------- | ------------------------------------------------------- | ---------------------------------------- | ------------- | -| `!` | `!expr` | Logical complement | `Not` | -| `~` | `~expr` | Bitwise NOT | `BitNot` | -| `!=` | `expr != expr` | Non-equality comparison | `PartialEq` | -| `%` | `expr % expr` | Arithmetic remainder | `Rem` | -| `%=` | `var %= expr` | Arithmetic remainder and assignment | `RemEq` | -| `&` | `expr & expr` | Bitwise AND | `BitAnd` | -| `&&` | `expr && expr` | Short-circuiting logical AND | | -| `*` | `expr * expr` | Arithmetic multiplication | `Mul` | -| `*=` | `var *= expr` | Arithmetic multiplication and assignment | `MulEq` | -| `@` | `@var` | Snapshot | | -| `*` | `*var` | Desnap | | -| `+` | `expr + expr` | Arithmetic addition | `Add` | -| `+=` | `var += expr` | Arithmetic addition and assignment | `AddEq` | -| `,` | `expr, expr` | Argument and element separator | | -| `-` | `-expr` | Arithmetic negation | `Neg` | -| `-` | `expr - expr` | Arithmetic subtraction | `Sub` | -| `-=` | `var -= expr` | Arithmetic subtraction and assignment | `SubEq` | -| `->` | `fn(...) -> type`, |...| -> type | Function and closure return type | | -| `.` | `expr.ident` | Member access | | -| `/` | `expr / expr` | Arithmetic division | `Div` | -| `/=` | `var /= expr` | Arithmetic division and assignment | `DivEq` | -| `:` | `pat: type`, `ident: type` | Constraints | | -| `:` | `ident: expr` | Struct field initializer | | -| `;` | `expr;` | Statement and item terminator | | -| `<` | `expr < expr` | Less than comparison | `PartialOrd` | -| `<=` | `expr <= expr` | Less than or equal to comparison | `PartialOrd` | -| `=` | `var = expr` | Assignment | | -| `==` | `expr == expr` | Equality comparison | `PartialEq` | -| `=>` | `pat => expr` | Part of match arm syntax | | -| `>` | `expr > expr` | Greater than comparison | `PartialOrd` | -| `>=` | `expr >= expr` | Greater than or equal to comparison | `PartialOrd` | -| `^` | `expr ^ expr` | Bitwise exclusive OR | `BitXor` | -| | | expr | expr | Bitwise OR | `BitOr` | -| || | expr || expr | Short-circuiting logical OR | | -| `?` | expr? | Error propagation | - -Table B-1: Operators - -## Non Operator Symbols - -The following list contains all symbols that are not used as operators; that is, they do not have the same behavior as a function or method call. - -Table B-2 shows symbols that appear on their own and are valid in a variety of locations. - -| Symbol | Explanation | -| --------------------------------------- | ----------------------------------------- | -| `..._u8`, `..._usize`, `..._bool`, etc. | Numeric literal of specific type | -| `"..."` | String literal | -| `'...'` | Short string, 31 ASCII characters maximum | -| `_` | “Ignored” pattern binding | - -Table B-2: Stand-Alone Syntax - -Table B-3 shows symbols that are used within the context of a module hierarchy path to access an item. - -| Symbol | Explanation | -| -------------------- | ---------------------------------------------------------------- | -| `ident::ident` | Namespace path | -| `super::path` | Path relative to the parent of the current module | -| `trait::method(...)` | Disambiguating a method call by naming the trait that defines it | - -Table B-3: Path-Related Syntax - -Table B-4 shows symbols that appear in the context of using generic type parameters. - -| Symbol | Explanation | -| ------------------------------ | ------------------------------------------------------------------------------------------------------------ | -| `path<...>` | Specifies parameters to generic type in a type (e.g., `Array`) | -| `path::<...>`, `method::<...>` | Specifies parameters to a generic type, function, or method in an expression; often referred to as turbofish | -| `fn ident<...> ...` | Define generic function | -| `struct ident<...> ...` | Define generic structure | -| `enum ident<...> ...` | Define generic enumeration | -| `impl<...> ...` | Define generic implementation | - -Table B-4: Generics - -Table B-5 shows symbols that appear in the context of specifying attributes on an item. - -| Symbol | Explanation | -| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | -| `#[derive(...)]` | Automatically implements a trait for a type | -| `#[inline]` | Hint to the compiler to allow inlining of annotated function | -| `#[inline(always)]` | Hint to the compiler to systematically inline annotated function | -| `#[inline(never)]` | Hint to the compiler to never inline annotated function | -| `#[must_use]` | Hint to the compiler that the return value of a function or a specific returned type must be used | -| `#[generate_trait]` | Automatically generates a trait for an impl | -| `#[available_gas(...)]` | Set the maximum amount of gas available to execute a function | -| `#[panic_with('...', wrapper_name)]` | Creates a wrapper for the annotated function which will panic if the function returns `None` or `Err`, with the given data as the panic error | -| `#[test]` | Describe a function as a test function | -| `#[cfg(...)]` | Configuration attribute, especially used to configure a `tests` module with `#[cfg(test)]` | -| `#[should_panic]` | Specifies that a test function should necessarily panic | -| `#[starknet::contract]` | Defines a Starknet smart contract | -| `#[starknet::interface]` | Defines a Starknet interface | -| `#[starknet::component]` | Defines a Starknet component | -| `#[starknet::embeddable]` | Defines an isolated embeddable implementation that can be injected in any smart contract | -| `#[embeddable_as(...)]` | Defines an embeddable implementation inside a component | -| `#[storage]` | Defines the storage of a smart contract | -| `#[event]` | Defines an event in a smart contract | -| `#[constructor]` | Defines the constructor in a smart contract | -| `#[abi(embed_v0)]` | Defines an implementation of a trait, exposing the functions of the impl as entrypoints of a contract | -| `#[abi(per_item)]` | Allows individual definition of the entrypoint type of functions inside an impl | -| `#[external(v0)]` | Defines an external function when `#[abi(per_item)]` is used | -| `#[flat]` | Defines a enum variant of the `Event` enum that is not nested, ignoring the variant name in the serialization process, very useful for composability when using Starknet components | -| `#[key]` | Defines an indexed `Event` enum field, allowing for more efficient queries and filtering of events | - -Table B-5: Attributes - -Table B-6 shows symbols that appear in the context of calling or defining macros. - -| Symbol | Explanation | -| ------------------------ | -------------------------------------------------------------------------------------- | -| `print!` | Inline printing | -| `println!` | Print on a new line | -| `consteval_int!` | Declare a constant that is the result of a computation of integers | -| `array!` | Instantiate and fill arrays | -| `panic!` | Calls `panic` function and allows to provide a message error longer than 31 characters | -| `assert!` | Evaluates a Boolean and panics if `false` | -| `assert_eq!` | Evaluates an equality, and panics if not equal | -| `assert_ne!` | Evaluates an equality, and panics if equal | -| `assert_lt!` | Evaluates a comparison, and panics if greater or equal | -| `assert_le!` | Evaluates a comparison, and panics if greater | -| `assert_gt!` | Evaluates a comparison, and panics if lower or equal | -| `assert_ge!` | Evaluates a comparison, and panics if lower | -| `format!` | Format a string and returns a `ByteArray` with the contents | -| `write!` | Write formatted strings in a formatter | -| `writeln!` | Write formatted strings in a formatter on a new line | -| `get_dep_component!` | Returns the requested component state from a snapshot of the state inside a component | -| `get_dep_component_mut!` | Returns the requested component state from a reference of the state inside a component | -| `component!` | Macro used in Starknet contracts to embed a component inside a contract | - - -Table B-6: Macros - -Table B-7 shows symbols that create comments. - -| Symbol | Explanation | -| ------ | ------------ | -| `//` | Line comment | - -Table B-7: Comments - -Table B-8 shows symbols that appear in the context of using tuples. - -| Symbol | Explanation | -| ----------------- | ------------------------------------------------------------------------------------------- | -| `()` | Empty tuple (aka unit), both literal and type | -| `(expr)` | Parenthesized expression | -| `(expr,)` | Single-element tuple expression | -| `(type,)` | Single-element tuple type | -| `(expr, ...)` | Tuple expression | -| `(type, ...)` | Tuple type | -| `expr(expr, ...)` | Function call expression; also used to initialize tuple `struct`s and tuple `enum` variants | - -Table B-8: Tuples - -Table B-9 shows the contexts in which curly braces are used. - -| Context | Explanation | -| ------------ | ---------------- | -| `{...}` | Block expression | -| `Type {...}` | `struct` literal | - -Table B-9: Curly Braces -# Appendix C - Derivable Traits - -In various places in the book, we’ve discussed the `derive` attribute, which you can apply to a struct or enum definition. The `derive` attribute generates code to implement a default trait on the type you’ve annotated with the `derive` syntax. - -In this appendix, we provide a comprehensive reference detailing all the traits in the standard library compatible with the `derive` attribute. - -These traits listed here are the only ones defined by the core library that can be implemented on your types using `derive`. Other traits defined in the standard library don’t have sensible default behavior, so it’s up to you to implement them in a way that makes sense for what you’re trying to accomplish. - -## Drop and Destruct - -When moving out of scope, variables need to be moved first. This is where the `Drop` trait intervenes. You can find more details about its usage [here](ch04-01-what-is-ownership.md#no-op-destruction-the-drop-trait). - -Moreover, Dictionaries need to be squashed before going out of scope. Calling the `squash` method on each of them manually can quickly become redundant. `Destruct` trait allows Dictionaries to be automatically squashed when they get out of scope. You can also find more information about `Destruct` [here](ch04-01-what-is-ownership.md#destruction-with-a-side-effect-the-destruct-trait). - -## `Clone` and `Copy` for Duplicating Values - -The `Clone` trait provides the functionality to explicitly create a deep copy of a value. - -Deriving `Clone` implements the `clone` method, which, in turn, calls clone on each of the type's components. This means all the fields or values in the type must also implement `Clone` to derive `Clone`. - -Here is a simple example: - -```rust -#[derive(Clone, Drop)] -struct A { - item: felt252 -} - -fn main() { - let first_struct = A { item: 2 }; - let second_struct = first_struct.clone(); - assert!(second_struct.item == 2, "Not equal"); -} -``` - -The `Copy` trait allows for the duplication of values. You can derive `Copy` on any type whose parts all implement `Copy`. - -Example: - -```rust -#[derive(Copy, Drop)] -struct A { - item: felt252 -} - -fn main() { - let first_struct = A { item: 2 }; - let second_struct = first_struct; - // Copy Trait prevents first_struct from moving into second_struct - assert!(second_struct.item == 2, "Not equal"); - assert!(first_struct.item == 2, "Not Equal"); -} -``` - -## `Debug` for Printing and Debugging - -The `Debug` trait enables debug formatting in format strings, which you indicate by adding `:?` within `{}` placeholders. - -It allows you to print instances of a type for debugging purposes, so you and other programmers using this type can inspect an instance at a particular point in a program’s execution. - -For example, if you want to print the value of a variable of type `Point`, you can do it as follows: - -```rust -#[derive(Copy, Drop, Debug)] -struct Point { - x: u8, - y: u8 -} - -fn main() { - let p = Point { x: 1, y: 3 }; - println!("{:?}", p); -} -``` - -```shell -scarb cairo-run -Point { x: 1, y: 3 } -``` - -The `Debug` trait is required, for example, when using the `assert_xx!` macros in tests. Theses macros print the values of instances given as arguments if the equality or comparison assertion fails so programmers can see why the two instances weren’t equal. - -## `Default` for Default Values - -The `Default` trait allows creation of a default value of a type. The most common default value is zero. All primitive types in the standard library implement `Default`. - -If you want to derive `Default` on a composite type, each of its elements must already implement `Default`. If you have an [`enum`](ch06-01-enums.md) type, you must declare its default value by using the `#[default]` attribute on one of its variants. - -An example: - -```rust -#[derive(Default, Drop)] -struct A { - item1: felt252, - item2: u64 -} - -#[derive(Default, Drop, PartialEq)] -enum CaseWithDefault { - A: felt252, - B: u128, - #[default] - C: u64, -} - -fn main() { - let defaulted: A = Default::default(); - assert!(defaulted.item1 == 0_felt252, "item1 mismatch"); - assert!(defaulted.item2 == 0_u64, "item2 mismatch"); - - let default_case: CaseWithDefault = Default::default(); - assert!(default_case == CaseWithDefault::C(0_u64), "case mismatch"); -} -``` - -## `PartialEq` for Equality Comparisons - -The `PartialEq` trait allows for comparison between instances of a type for equality, thereby enabling the `==` and `!=` operators. - -When `PartialEq` is derived on structs, two instances are equal only if all their fields are equal; they are not equal if any field is different. When derived for enums, each variant is equal to itself and not equal to the other variants. - -You can write your own implementation of the `PartialEq` trait for your type, if you can't derive it or if you want to implement your custom rules. In the following example, we write an implementation for `PartialEq` in which we consider that two rectangles are equal if they have the same area: - -```rust -#[derive(Copy, Drop)] -struct Rectangle { - width: u64, - height: u64, -} - -impl PartialEqImpl of PartialEq { - fn eq(lhs: @Rectangle, rhs: @Rectangle) -> bool { - (*lhs.width) * (*lhs.height) == (*rhs.width) * (*rhs.height) - } - - fn ne(lhs: @Rectangle, rhs: @Rectangle) -> bool { - (*lhs.width) * (*lhs.height) != (*rhs.width) * (*rhs.height) - } -} - -fn main() { - let rect1 = Rectangle { width: 30, height: 50 }; - let rect2 = Rectangle { width: 50, height: 30 }; - - println!("Are rect1 and rect2 equal? {}", rect1 == rect2); -} -``` - -The `PartialEq` trait is required when using the `assert_eq!` macro in tests, which needs to be able to compare two instances of a type for equality. - -Here is an example: - -```rust -#[derive(PartialEq, Drop)] -struct A { - item: felt252 -} - -fn main() { - let first_struct = A { item: 2 }; - let second_struct = A { item: 2 }; - assert!(first_struct == second_struct, "Structs are different"); -} -``` - -## Serializing with `Serde` - -`Serde` provides trait implementations for `serialize` and `deserialize` functions for data structures defined in your crate. It allows you to transform your structure into an array (or the opposite). - -> **[Serialization](https://en.wikipedia.org/wiki/Serialization)** is a process of transforming data structures into a format that can be easily stored or transmitted. Let's say you are running a program and would like to persist its state to be able to resume it later. To do this, you could take each of the objects your program is using and save their information, for example in a file. This is a simplified version of serialization. Now if you want to resume your program with this saved state, you would perform **deserialization**, which means loading the state of the objects from the saved source. - -For example: - -```rust -#[derive(Serde, Drop)] -struct A { - item_one: felt252, - item_two: felt252, -} - -fn main() { - let first_struct = A { item_one: 2, item_two: 99, }; - let mut output_array = array![]; - let serialized = first_struct.serialize(ref output_array); - panic(output_array); -} - -``` - -If you run the `main` function, the output will be: - -```shell -Run panicked with [2, 99 ('c'), ]. -``` - -We can see here that our struct `A` has been serialized into the output array. Note that the `serialize` function takes as argument a snapshot of the type you want to convert into an array. This is why deriving `Drop` for `A` is required here, as the `main` function keeps ownership of the `first_struct` struct. - -Also, we can use the `deserialize` function to convert the serialized array back into our `A` struct. - -Here is an example: - -```rust -#[derive(Serde, Drop)] -struct A { - item_one: felt252, - item_two: felt252, -} - -fn main() { - let first_struct = A { item_one: 2, item_two: 99, }; - let mut output_array = array![]; - let mut serialized = first_struct.serialize(ref output_array); - let mut span_array = output_array.span(); - let deserialized_struct: A = Serde::
::deserialize(ref span_array).unwrap(); -} -``` - -Here we are converting a serialized array span back to the struct `A`. `deserialize` returns an `Option` so we need to unwrap it. When using `deserialize` we also need to specify the type we want to deserialize into. - -## Hashing with `Hash` - -It is possible to derive the `Hash` trait on structs and enums. This allows them to be hashed easily using any available hash function. For a struct or an enum to derive the `Hash` attribute, all fields or variants need to be hashable themselves. - -You can refer to the [Hashes section](ch11-04-hash.md) to get more information about how to hash complex data types. - -## Starknet Storage with `starknet::Store` - -The `starknet::Store` trait is relevant only when building on [Starknet](ch13-00-introduction-to-starknet-smart-contracts.md). It allows for a type to be used in smart contract storage by automatically implementing the necessary read and write functions. - -You can find detailed information about the inner workings of Starknet storage in the [Contract storage section](ch14-01-contract-storage.md). -# Appendix D - The Cairo Prelude - -## Prelude - -The Cairo prelude is a collection of commonly used modules, functions, data -types, and traits that are automatically brought into scope of every module in a -Cairo crate without needing explicit import statements. Cairo's prelude provides -the basic building blocks developers need to start Cairo programs and writing -smart contracts. - -The core library prelude is defined in the _[lib.cairo](https://github.com/starkware-libs/cairo/blob/main/corelib/src/lib.cairo)_ -file of the corelib crate and contains Cairo's primitive data types, traits, -operators, and utility functions. This includes: - -- Data types: integers, bools, arrays, dicts, etc. -- Traits: behaviors for arithmetic, comparison, and serialization operations -- Operators: arithmetic, logical, bitwise -- Utility functions - helpers for arrays, maps, boxing, etc. - -The core library prelude delivers the fundamental programming -constructs and operations needed for basic Cairo programs, without requiring the -explicit import of elements. Since the core library prelude is automatically -imported, its contents are available for use in any Cairo crate without explicit -imports. This prevents repetition and provides a better devX. This is what -allows you to use `ArrayTrait::append()` or the `Default` trait without bringing -them explicitly into scope. - -You can choose which prelude to use. For example, adding `edition = "2023_11"` in the _Scarb.toml_ configuration file will load the prelude from November 2023. Note that when you create a new project using `scarb new` command, the _Scarb.toml_ file will automatically include `edition = "2023_11"`. - -The compiler currently exposes 2 different versions of the prelude: - -- A general version, with a lot of traits that are made available, corresponding to `edition = "2023_01"`. -- A restricted version, including the most essential traits needed for general Cairo programming, corresponding to `edition = 2023_11`. -# Appendix E - Common Error Messages - -You might encounter error messages when writing Cairo code. Some of them occur very frequently, which is why we will be listing the most common error messages in this appendix to help you resolve common issues. - -- `Variable not dropped.`: this error message means that you are trying to make a variable with a type that do not implement the `Drop` trait go out of scope, withtout destroying it. Make sure that variables that need to be dropped at the end of the execution of a function implement the `Drop` trait or the `Destruct` trait. See [Ownership](ch04-01-what-is-ownership.md#destroying-values---example-with-feltdict) section. - -- `Variable was previously moved.`: this error message means that you are trying to use a variable whose ownership has already been transferred to another function. When a variable doesn't implement the `Copy` trait, it is passed by value to functions, and ownership of the variable is transferred to the function. Such a variable cannot be used anymore in the current context after its ownership has been transferred. It is often useful to use the `clone` method in this situation. - -- `error: Trait has no implementation in context: core::fmt::Display::`: this error message is encountered if you try to print an instance of a custom data type with `{}` placeholders in a `print!` or `println!` macro. To mitigate this issue, you need to either manually implement the `Display` trait for your type, or use the `Debug` trait by applying `derive(Debug)` to your type, allowing to print your instance by adding `:?` in `{}` placeholders. - -- `Got an exception while executing a hint: Hint Error: Failed to deserialize param #x.`: this error means that the execution failed because an entrypoint was called without the expected arguments. Make sure that the arguments you provide when calling an entrypoint are correct. There is a classic issue with `u256` variables, which are actually structs of 2 `u128`. Therefore, when calling a function that takes a `u256` as argument, you need to pass 2 values. - -- `Item path::item is not visible in this context.`: this error message lets us know that the path to bring an item into scope is correct, but there is a vibility issue. In cairo, all items are private to parent modules by default. To resolve this issue, make sure that all the modules on the path to items and items themselves are declared with `pub(crate)` or `pub` to have access to them. - -- `Identifier not found.`: this error message is a bit aspecific but might indicate that: - - A variable is being used before it has been declared. Make sure to declare variables with the `let` keyword. - - The path to bring an item into scope is wrongly defined. Make sure to use valid paths. - -## Starknet Components Related Error Messages - -You might encounter some errors when trying to implement components. -Unfortunately, some of them lack meaningful error messages to help debug. This -section aims to provide you with some pointers to help you debug your code. - -- `Trait not found. Not a trait.`: this error can occur when you're not importing the component's impl block - correctly in your contract. Make sure to respect the following syntax: - - ```rust,noplayground - #[abi(embed_v0)] - impl IMPL_NAME = PATH_TO_COMPONENT::EMBEDDED_NAME - ``` - -- `Plugin diagnostic: name is not a substorage member in the contract's Storage. Consider adding to Storage: (...)`: the compiler helps you a lot debugging this by giving you recommendation on the action to take. Basically, you forgot to add the component's storage to your contract's storage. Make sure to add the path to the component's storage annotated with the `#[substorage(v0)]` attribute to your contract's storage. - -- `Plugin diagnostic: name is not a nested event in the contract's Event enum. Consider adding to the Event enum:` similar to the previous error, the compiler tells you that you forgot to add the component's events to your contract's events. Make sure to add the path to the component's events to your contract's events. -# Appendix F - Useful Development Tools - -In this appendix, we talk about some useful development tools that the Cairo -project provides. We’ll look at automatic formatting, quick ways to apply -warning fixes, a linter, and integrating with IDEs. - -## Automatic Formatting with `scarb fmt` - -Scarb projects can be formatted using the `scarb fmt` command. -If you're using the Cairo binaries directly, you can run `cairo-format` instead. -Many collaborative projects use `scarb fmt` to prevent arguments about which -style to use when writing Cairo: everyone formats their code using the tool. - -To format any Cairo project, enter the following inside the project directory: - -```bash -scarb fmt -``` - -## IDE Integration Using `cairo-language-server` - -To help IDE integration, the Cairo community recommends using the -[`cairo-language-server`][cairo-language-server]. This tool is a set of -compiler-centric utilities that speaks the [Language Server Protocol][lsp], which is a specification for IDEs and programming languages to -communicate with each other. Different clients can use `cairo-language-server`, such as -[the Cairo extension for Visual Studio Code][vscode-cairo]. - -[lsp]: http://langserver.org/ -[vscode-cairo]: https://marketplace.visualstudio.com/items?itemName=starkware.cairo1 - -Visit the `vscode-cairo` [page][vscode-cairo] -to install it on VSCode. You will get abilities such as autocompletion, jump to -definition, and inline errors. - -[cairo-language-server]: https://github.com/starkware-libs/cairo/tree/main/crates/cairo-lang-language-server - -> Note: If you have Scarb installed, it should work out of the box with the Cairo VSCode extension, without a manual installation of the language server. -# Appendix G - Installing the Cairo Binaries - -If you want to have access to the Cairo binaries, for anything that you could not achieve by purely using Scarb you can install them by following the instructions below. - -### Prerequisites - -You will need to have [Rust](https://www.rust-lang.org) and [Git](https://git-scm.com/) installed. - -To install Rust, you first need the [`rustup`](https://www.rust-lang.org/tools/install) tool. It allows you to install Rust using the following command: -```bash -# Install stable Rust -rustup override set stable && rustup update -``` - -Follow the link for information on how to install [Git](https://git-scm.com/downloads). - -The next step is to install Cairo. We will download Cairo manually, using Cairo repository or with an installation script. You’ll need an internet connection for the download. - -## Installing Cairo with a Script ([Installer](https://github.com/franalgaba/cairo-installer) by [Fran](https://github.com/franalgaba)) - -### Install - -If you wish to install a specific release of Cairo rather than the latest head, set the `CAIRO_GIT_TAG` environment variable (e.g. `export CAIRO_GIT_TAG=v2.5.1`). - -```bash -curl -L https://github.com/franalgaba/cairo-installer/raw/main/bin/cairo-installer | bash -``` - -After installing, follow [these instructions](#set-up-your-shell-environment-for-cairo) to set up your shell environment. - -### Update - -``` -rm -fr ~/.cairo -curl -L https://github.com/franalgaba/cairo-installer/raw/main/bin/cairo-installer | bash -``` - -### Uninstall - -Cairo is installed within `$CAIRO_ROOT` (default: ~/.cairo). To uninstall, just remove it: - -```bash -rm -fr ~/.cairo -``` - -then remove these three lines from .bashrc: - -```bash -export PATH="$HOME/.cairo/target/release:$PATH" -``` - -and finally, restart your shell: - -```bash -exec $SHELL -``` - -### Set Up your Shell Environment for Cairo - -- Define environment variable `CAIRO_ROOT` to point to the path where - Cairo will store its data. `$HOME/.cairo` is the default. - If you installed Cairo via Git checkout, we recommend - to set it to the same location as where you cloned it. -- Add the `cairo-*` executables to your `PATH` if it's not already there - -The below setup should work for the vast majority of users for common use cases. - -- For **bash**: - - Stock Bash startup files vary widely between distributions in which of them source - which, under what circumstances, in what order and what additional configuration they perform. - As such, the most reliable way to get Cairo in all environments is to append Cairo - configuration commands to both `.bashrc` (for interactive shells) - and the profile file that Bash would use (for login shells). - - First, add the commands to `~/.bashrc` by running the following in your terminal: - - ```bash - echo 'export CAIRO_ROOT="$HOME/.cairo"' >> ~/.bashrc - echo 'command -v cairo-compile >/dev/null || export PATH="$CAIRO_ROOT/target/release:$PATH"' >> ~/.bashrc - ``` - - Then, if you have `~/.profile`, `~/.bash_profile` or `~/.bash_login`, add the commands there as well. - If you have none of these, add them to `~/.profile`. - - - to add to `~/.profile`: - - ```bash - echo 'export CAIRO_ROOT="$HOME/.cairo"' >> ~/.profile - echo 'command -v cairo-compile >/dev/null || export PATH="$CAIRO_ROOT/target/release:$PATH"' >> ~/.profile - ``` - - - to add to `~/.bash_profile`: - ```bash - echo 'export CAIRO_ROOT="$HOME/.cairo"' >> ~/.bash_profile - echo 'command -v cairo-compile >/dev/null || export PATH="$CAIRO_ROOT/target/release:$PATH"' >> ~/.bash_profile - ``` - -- For **Zsh**: - - ```zsh - echo 'export CAIRO_ROOT="$HOME/.cairo"' >> ~/.zshrc - echo 'command -v cairo-compile >/dev/null || export PATH="$CAIRO_ROOT/target/release:$PATH"' >> ~/.zshrc - ``` - - If you wish to get Cairo in non-interactive login shells as well, also add the commands to `~/.zprofile` or `~/.zlogin`. - -- For **Fish shell**: - - If you have Fish 3.2.0 or newer, execute this interactively: - - ```fish - set -Ux CAIRO_ROOT $HOME/.cairo - fish_add_path $CAIRO_ROOT/target/release - ``` - - Otherwise, execute the snippet below: - - ```fish - set -Ux CAIRO_ROOT $HOME/.cairo - set -U fish_user_paths $CAIRO_ROOT/target/release $fish_user_paths - ``` - -In MacOS, you might also want to install [Fig](https://fig.io/) which -provides alternative shell completions for many command line tools with an -IDE-like popup interface in the terminal window. -(Note that their completions are independent of Cairo's codebase -so they might be slightly out of sync for bleeding-edge interface changes.) - -### Restart your Shell - -for the `PATH` changes to take effect. - -```sh -exec "$SHELL" -``` - -## Installing Cairo Manually ([Guide](https://github.com/auditless/cairo-template) by [Abdel](https://github.com/abdelhamidbakhta)) - -### Step 1: Install Cairo 1.0 - -If you are using an x86 Linux system and can use the release binary, download Cairo here: . - -For everyone else, we recommend compiling Cairo from source as follows: - -```bash -# Start by defining environment variable CAIRO_ROOT -export CAIRO_ROOT="${HOME}/.cairo" - -# Create .cairo folder if it doesn't exist yet -mkdir $CAIRO_ROOT - -# Clone the Cairo compiler in $CAIRO_ROOT (default root) -cd $CAIRO_ROOT && git clone git@github.com:starkware-libs/cairo.git . - -# OPTIONAL/RECOMMENDED: If you want to install a specific version of the compiler -# Fetch all tags (versions) -git fetch --all --tags -# View tags (you can also do this in the Cairo compiler repository) -git describe --tags `git rev-list --tags` -# Checkout the version you want -git checkout tags/v2.5.1 - -# Generate release binaries -cargo build --all --release -``` - -. - -**NOTE: Keeping Cairo up to date** - -Now that your Cairo compiler is in a cloned repository, all you will need to do -is pull the latest changes and rebuild as follows: - -```bash -cd $CAIRO_ROOT && git fetch && git pull && cargo build --all --release -``` - -### Step 2: Add Cairo 1.0 Executables to Your Path - -```bash -export PATH="$CAIRO_ROOT/target/release:$PATH" -``` - -**NOTE: If installing from a Linux binary, adapt the destination path accordingly.** - -### Step 3: Setup Language Server - -#### VS Code Extension - -- If you have the previous Cairo 0 extension installed, you can disable/uninstall it. -- Install the Cairo 1 extension for proper syntax highlighting and code navigation. You can find the link to the extension [here](https://marketplace.visualstudio.com/items?itemName=starkware.cairo1&ssr=false), or just search for "Cairo 1.0" in the VS Code marketplace. -- The extension will work out of the box once you will have [Scarb](./ch01-03-hello-scarb.md) installed. - -#### Cairo Language Server without Scarb - -If you don't want to depend on Scarb, you can still use the Cairo Language Server with the compiler binary. -From [Step 1](#installing-cairo-with-a-script-installer-by-fran), the `cairo-language-server` binary should be built and executing this command will copy its path into your clipboard. - -```bash -which cairo-language-server | pbcopy -``` - -Update the `cairo1.languageServerPath` of the Cairo 1.0 extension by pasting the path. -# Appendix A - System Calls - -This chapter is based on the StarkNet documentation available at [StarkNet Docs](https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/system-calls-cairo1/). - -Writing smart contracts requires various associated operations, such as calling another contract or accessing the contract’s storage, that standalone programs do not require. - -The Starknet contract language supports these operations by using system calls. System calls enable a contract to require services from the Starknet OS. You can use system calls in a function to get information that depends on the broader state of Starknet, which would otherwise be inaccessible, rather than local variables that appear in the function’s scope. - -Here is a list of the system calls available in Cairo 1.0: - -- [get_block_hash](#get_block_hash) -- [get_execution_info](#get_execution_info) -- [call_contract](#call_contract) -- [deploy](#deploy) -- [emit_event](#emit_event) -- [library_call](#library_call) -- [send_message_to_L1](#send_message_to_l1) -- [replace_class](#replace_class) -- [storage_read](#storage_read) -- [storage_write](#storage_write) - -## `get_block_hash` - -#### Syntax - -```rust -extern fn get_block_hash_syscall( - block_number: u64 -) -> SyscallResult implicits(GasBuiltin, System) nopanic; -``` - -#### Description - -Gets the hash of a specific StarkNet block within the range of `[first_v0_12_0_block, current_block - 10]`. - -#### Return Values - -Returns the hash of the given block. - -#### Error Messages - -- `Block number out of range`: `block_number` is greater than _`current_block`_`- 10`. -- `0`: `block_number` is less than the first block number of v0.12.0. - -#### Common Library - -- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/0c882679fdb24a818cad19f2c18decbf6ef66153/corelib/src/starknet/syscalls.cairo#L37) - -## `get_execution_info` - -#### Syntax - -```rust -extern fn get_execution_info_syscall() -> SyscallResult> implicits( - GasBuiltin, System -) nopanic; -``` - -#### Description - -Gets information about the original transaction. - -In Cairo 1.0, all block/transaction/execution context getters are batched into this single system call. - -#### Arguments - -None. - -#### Return Values - -Returns a [struct](https://github.com/starkware-libs/cairo/blob/efbf69d4e93a60faa6e1363fd0152b8fcedbb00a/corelib/src/starknet/info.cairo#L8) containing the execution info. - -#### Common Library - -- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L35) - -## `call_contract` - -#### Syntax - -```rust -extern fn call_contract_syscall( - address: ContractAddress, entry_point_selector: felt252, calldata: Span -) -> SyscallResult> implicits(GasBuiltin, System) nopanic; -``` - -#### Description - -Calls a given contract. This system call expects the address of the called contract, a selector for a function within that contract, and call arguments. - -> **Note:** -> -> An internal call can’t return Err(\_) as this is not handled by the sequencer and the Starknet OS. -> -> If call_contract_syscall fails, this can’t be caught and will therefore result in the entire transaction being reverted. - -#### Arguments - -- _`address`_: The address of the contract you want to call. -- _`entry_point_selector`_: A selector for a function within that contract, can be computed with the `selector!` macro. -- _`calldata`_: The calldata array. - -#### Return Values - -The call response, of type `SyscallResult>`. - -#### Common Library - -- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L10) - -> **Note:** -> This is considered a lower-level syntax for calling contracts. -> If the interface of the called contract is available, then you can use a more straightforward syntax. - -## `deploy` - -#### Syntax - -```rust -extern fn deploy_syscall( - class_hash: ClassHash, - contract_address_salt: felt252, - calldata: Span, - deploy_from_zero: bool, -) -> SyscallResult<(ContractAddress, Span::)> implicits(GasBuiltin, System) nopanic; -``` - -#### Description - -Deploys a new instance of a previously declared class. - -#### Arguments - -- _`class_hash`_: The class hash of the contract to be deployed. -- _`contract_address_salt`_: The salt, an arbitrary value provided by the sender. It is used in the computation of the contract’s address. -- _`calldata`_: The constructor’s calldata. An array of felts. -- _`deploy_from_zero`_: A flag used for the contract address computation. If not set, the caller address will be used as the new contract’s deployer address, otherwise 0 is used. - -#### Return Values - -A tuple wrapped with SyscallResult where: - -- The first element is the address of the deployed contract, of type `ContractAddress`. - -- The second element is the response array from the contract’s constructor, of type `Span::`. - -#### Common Library - -- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/4821865770ac9e57442aef6f0ce82edc7020a4d6/corelib/src/starknet/syscalls.cairo#L22) - -## `emit_event` - -#### Syntax - -```rust -extern fn emit_event_syscall( - keys: Span, data: Span -) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; -``` - -#### Description - -Emits an event with a given set of keys and data. - -For more information and a higher-level syntax for emitting events, see [Starknet events](https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/starknet-events/). - -#### Arguments - -- _`keys`_: The event’s keys. These are analogous to Ethereum’s event topics, you can use the starknet_getEvents method to filter by these keys. - -- _`data`_: The event’s data. - -#### Return Values - -None. - -#### Example - -The following example emits an event with two keys, the strings `status` and `deposit` and three data elements: `1`, `2`, and `3`. - -```rust -let keys = ArrayTrait::new(); -keys.append('key'); -keys.append('deposit'); -let values = ArrayTrait::new(); -values.append(1); -values.append(2); -values.append(3); -emit_event_syscall(keys, values).unwrap_syscall(); -``` - -#### Common Library - -- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L30) - -## `library_call` - -#### Syntax - -```rust -extern fn library_call_syscall( - class_hash: ClassHash, function_selector: felt252, calldata: Span -) -> SyscallResult> implicits(GasBuiltin, System) nopanic; -``` - -#### Description - -Calls the requested function in any previously declared class. The class is only used for its logic. - -This system call replaces the known delegate call functionality from Ethereum, with the important difference that there is only one contract involved. - -#### Arguments - -- _`class_hash`_: The hash of the class you want to use. - -- _`function_selector`_: A selector for a function within that class, can be computed with the `selector!` macro. - -- _`calldata`_: The calldata. - -#### Return Values - -The call response, of type `SyscallResult>`. - -#### Common Library - -- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L43) - -## `send_message_to_L1` - -#### Syntax - -```rust -extern fn send_message_to_l1_syscall( - to_address: felt252, payload: Span -) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; -``` - -#### Description - -Sends a message to L1. - -This system call includes the message parameters as part of the proof’s output and exposes these parameters to the `StarknetCore` contract on L1 once the state update, including the transaction, is received. - -For more information, see Starknet’s [messaging mechanism](https://docs.starknet.io/documentation/architecture_and_concepts/Network_Architecture/messaging-mechanism/). - -#### Arguments - -- _`to_address`_: The recipient’s L1 address. - -- _`payload`_: The array containing the message payload. - -#### Return Values - -None. - -#### Example - -The following example sends a message whose content is `(1,2)` to the L1 contract whose address is `3423542542364363`. - -```rust -let payload = ArrayTrait::new(); -payload.append(1); -payload.append(2); -send_message_to_l1_syscall(payload).unwrap_syscall(); -``` - -#### Common Library - -- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L51) - -## `replace_class` - -#### Syntax - -```rust -extern fn replace_class_syscall( - class_hash: ClassHash -) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; -``` - -#### Description - -Once `replace_class` is called, the class of the calling contract (i.e. the contract whose address is returned by `get_contract_address` at the time the syscall is called) will be replaced by the class whose hash is given by the class_hash argument. - -> **Note:** -> -> After calling `replace_class`, the code currently executing from the old class will finish running. -> -> The new class will be used from the next transaction onwards or if the contract is called via the `call_contract` syscall in the same transaction (after the replacement). - -#### Arguments - -- _`class_hash`_: The hash of the class you want to use as a replacement. - -#### Return Values - -None. - -#### Common Library - -- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L77) - -## `storage_read` - -#### Syntax - -```rust -extern fn storage_read_syscall( - address_domain: u32, address: StorageAddress, -) -> SyscallResult implicits(GasBuiltin, System) nopanic; -``` - -#### Description - -Gets the value of a key in the storage of the calling contract. - -This system call provides direct access to any possible key in storage, in contrast with `var.read()`, which enables you to read storage variables that are defined explicitly in the contract. - -For information on accessing storage by using the storage variables, see [storage variables](https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/contract-storage/#storage_variables). - -#### Arguments - -- _`address_domain`_: The domain of the key, used to separate between different data availability modes. This separation is used in Starknet to offer different data availability modes. Currently, only the onchain mode (where all updates go to L1), indicated by domain `0`, is supported. Other address domains which will be introduced in the future will behave differently in terms of publication (in particular, they will not be posted on L1, creating a tradeoff between cost and security). - -- _`address`_: The requested storage address. - -#### Return Values - -The value of the key, of type `SyscallResult`. - -#### Example - -```rust -use starknet::storage_access::storage_base_address_from_felt252; - -... - -let storage_address = storage_base_address_from_felt252(3534535754756246375475423547453) -storage_read_syscall(0, storage_address).unwrap_syscall() -``` - -#### Common Library - -- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L60) - -## `storage_write` - -#### Syntax - -```rust -extern fn storage_write_syscall( - address_domain: u32, address: StorageAddress, value: felt252 -) -> SyscallResult<()> implicits(GasBuiltin, System) nopanic; -``` - -#### Description - -Sets the value of a key in the storage of the calling contract. - -This system call provides direct access to any possible key in storage, in contrast with `var.write()`, which enables you to write to storage variables that are defined explicitly in the contract. - -For information on accessing storage by using the storage variables, see [storage variables](https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/contract-storage/#storage_variables). - -#### Arguments - -- _`address_domain`_: The domain of the key, used to separate between different data availability modes. This separation is used in Starknet to offer different data availability modes. Currently, only the onchain mode (where all updates go to L1), indicated by domain `0`, is supported. Other address domains which will be introduced in the future will behave differently in terms of publication (in particular, they will not be posted on L1, creating a tradeoff between cost and security). - -- _`address`_: The requested storage address. - -- _`value`_: The value to write to the key. - -#### Return Values - -None. - -#### Common Library - -- [syscalls.cairo](https://github.com/starkware-libs/cairo/blob/cca08c898f0eb3e58797674f20994df0ba641983/corelib/src/starknet/syscalls.cairo#L70) -# Introduction - -## What is Cairo? - -Cairo is a programming language designed for a virtual CPU of the same name. The unique aspect of this processor is that it was not created for the physical constraints of our world but for cryptographic ones, making it capable of efficiently proving the execution of any program running on it. This means that you can perform time consuming operations on a machine you don't trust, and check the result very quickly on a cheaper machine. -While Cairo 0 used to be directly compiled to CASM, the Cairo CPU assembly, Cairo 1 is a higher level language. It first compiles to Sierra, an intermediate representation of Cairo which will compile later down to a safe subset of CASM. The point of Sierra is to ensure your CASM will always be provable, even when the computation fails. - -## What Can you Do with It? - -Cairo allows you to compute trustworthy values on untrusted machines. One major usecase is Starknet, a solution to Ethereum scaling. Ethereum is a decentralized blockchain platform that enables the creation of decentralized applications where every single interaction between a user and a d-app is verified by all the participants. Starknet is a Layer 2 built on top of Ethereum. Instead of having all the participants of the network to verify all user interactions, only one node, called the prover, executes the programs and generates proofs that the computations were done correctly. These proofs are then verified by an Ethereum smart contract, requiring significantly less computational power compared to executing the interactions themselves. This approach allows for increased throughput and reduced transaction costs while preserving Ethereum security. - -## What Are the Differences with Other Programming Languages? - -Cairo is quite different from traditional programming languages, especially when it comes to overhead costs and its primary advantages. Your program can be executed in two different ways: - -- When executed by the prover, it is similar to any other language. Because Cairo is virtualized, and because the operations were not specifically designed for maximum efficiency, this can lead to some performance overhead but it is not the most relevant part to optimize. - -- When the generated proof is verified by a verifier, it is a bit different. This has to be as cheap as possible since it could potentially be verified on many very small machines. Fortunately verifying is faster than computing and Cairo has some unique advantages to improve it even more. A notable one is non-determinism. This is a topic you will cover in more detail later in this book, but the idea is that you can theoretically use a different algorithm for verifying than for computing. Currently, writing custom non-deterministic code is not supported for the developers, but the standard library leverages non-determinism for improved performance. For example sorting an array in Cairo costs the same price as copying it. Because the verifier doesn't sort the array, it just checks that it is sorted, which is cheaper. - -Another aspect that sets the language apart is its memory model. In Cairo, memory access is immutable, meaning that once a value is written to memory, it cannot be changed. Cairo 1 provides abstractions that help developers work with these constraints, but it does not fully simulate mutability. Therefore, developers must think carefully about how they manage memory and data structures in their programs to optimize performance. - -## References - -- Cairo CPU Architecture: -- Cairo, Sierra and Casm: -- State of non determinism: -# Foreword - -In 2020, StarkWare released Cairo 0, a Turing-complete programming language supporting verifiable computation. Cairo started as an assembly language and gradually became more expressive. The learning curve was initially steep, as Cairo 0.x was a low-level language that did not entirely abstract the underlying cryptographic primitives required to build a proof for the execution of a program. - -With the release of Cairo 1, the developer experience has considerably improved, abstracting away the underlying immutable memory model of the Cairo architecture where possible. Strongly inspired by Rust, Cairo 1 has been built to help you create provable programs without specific knowledge of its underlying architecture so that you can focus on the program itself, increasing the overall security of Cairo programs. Powered by a Rust VM, the execution of Cairo programs is now _blazingly_ fast, allowing you to build an extensive test suite without compromising on performance. - -Blockchain developers that want to deploy contracts on Starknet will use the Cairo programming language to code their smart contracts. This allows the Starknet OS to generate execution traces for transactions to be proved by a prover, which is then verified on Ethereum L1 prior to updating the state root of Starknet. - -However, Cairo is not only for blockchain developers. As a general purpose programming language, it can be used for any computation that would benefit from being proved on one computer and verified on other machines with lower hardware requirements. - -This book is designed for developers with a basic understanding of programming concepts. It is a friendly and approachable text intended to help you level up your knowledge of Cairo, but also help you develop your programming skills in general. So, dive in and get ready to learn all there is to know about Cairo! - -## Acknowledgements - -This book would not have been possible without the help of the Cairo community. We would like to thank every contributor for their contributions to this book! - -We would like to thank the Rust community for the [Rust Book][doc rust], which has been a great source of inspiration for this book. Many examples and explanations have been adapted from the Rust Book to fit the Cairo programming language, as the two languages share many similarities. - -[doc rust]: https://doc.rust-lang.org/book/ -# Getting Started - -Let’s start your Cairo journey! There’s a lot to learn, but every journey starts somewhere. In this chapter, we’ll discuss: - -- Installing Scarb, which is Cairo's build toolchain and package manager, on Linux, macOS, and Windows. -- Writing a program that prints `Hello, world!`. -- Using basic Scarb commands to create a project and execute a program. - -## Getting Help - -If you have any questions about Starknet or Cairo, you can ask them in the [Starknet Discord server][discord]. The community is friendly and always willing to help. - -[discord]: https://discord.gg/starknet-community - -## Interacting with the Cairo Chatbot - -Cairo has its own chatbot, which can help you with Cairo-related questions. The chatbot is trained on the Cairo book, and uses RAG to efficiently retrieve information to provide help. You can find the chatbot on the [Cairo-Chatbot][cairo gpt] website. - -[cairo gpt]: https://cairo-chatbot.vercel.app/ -# Installation - -Cairo can be installed by simply downloading [Scarb][scarb doc]. Scarb bundles the Cairo compiler and the Cairo language server together in an easy-to-install package so that you can start writing Cairo code right away. - -Scarb is also Cairo's package manager and is heavily inspired by [Cargo][cargo doc], Rust’s build system and package manager. - -Scarb handles a lot of tasks for you, such as building your code (either pure Cairo or Starknet contracts), downloading the libraries your code depends on, building those libraries, and provides LSP support for the VSCode Cairo 1 extension. - -As you write more complex Cairo programs, you might add dependencies, and if you start a project using Scarb, managing external code and dependencies will be a lot easier to do. - -Let's start by installing Scarb. - -[scarb doc]: https://docs.swmansion.com/scarb/docs -[cargo doc]: https://doc.rust-lang.org/cargo/ - -## Installing Scarb - -### Requirements - -Scarb requires a Git executable to be available in the `PATH` environment variable. - -### Installation - -To install Scarb, please refer to the [installation instructions][scarb download]. We strongly recommend that you install -Scarb [via asdf][scarb asdf], a CLI tool that can manage multiple language runtime versions on a per-project basis. -This will ensure that the version of Scarb you use to work on a project always matches the one defined in the project settings, avoiding problems related to version mismatches. - -Please refer to the [asdf documentation][asdf doc] to install all prerequisites. - -Once you have asdf installed locally, you can download Scarb plugin with the following command: - -```bash -asdf plugin add scarb -``` - -This will allow you to download specific versions: - -```bash -asdf install scarb 2.6.3 -``` - -and set a global version: - -```bash -asdf global scarb 2.6.3 -``` - -Otherwise, you can simply run the following command in your terminal, and follow the onscreen instructions. This will install the latest stable release of Scarb. - -```bash -curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | sh -``` - -
-In both cases, you can verify installation by running the following command in a new terminal session, it should print both Scarb and Cairo language versions, e.g: - -```bash -$ scarb --version -scarb 2.6.3 (e6f921dfd 2024-03-13) -cairo: 2.6.3 (https://crates.io/crates/cairo-lang-compiler/2.6.3) -sierra: 1.5.0 -``` - -[scarb download]: https://docs.swmansion.com/scarb/download -[scarb asdf]: https://docs.swmansion.com/scarb/download.html#install-via-asdf -[asdf doc]: https://asdf-vm.com/guide/getting-started.html - -## Installing the VSCode Extension - -Cairo has a VSCode extension that provides syntax highlighting, code completion, and other useful features. You can install it from the [VSCode Marketplace][vsc extension]. -Once installed, go into the extension settings, and make sure to tick the `Enable Language Server` and `Enable Scarb` options. - -[vsc extension]: https://marketplace.visualstudio.com/items?itemName=starkware.cairo1 - -{{#quiz ../quizzes/ch01-01-installation.toml}} -# Hello, World - -Now that you’ve installed Cairo through Scarb, it’s time to write your first Cairo program. -It’s traditional when learning a new language to write a little program that -prints the text `Hello, world!` to the screen, so we’ll do the same here! - -> Note: This book assumes basic familiarity with the command line. Cairo makes -> no specific demands about your editing or tooling or where your code lives, so -> if you prefer to use an integrated development environment (IDE) instead of -> the command line, feel free to use your favorite IDE. The Cairo team has developed -> a VSCode extension for the Cairo language that you can use to get the features from -> the language server and code highlighting. See [Appendix F][devtools] -> for more details. - -[devtools]: ./appendix-06-useful-development-tools.md - -## Creating a Project Directory - -You’ll start by making a directory to store your Cairo code. It doesn’t matter -to Cairo where your code lives, but for the exercises and projects in this book, -we suggest making a _cairo_projects_ directory in your home directory and keeping all -your projects there. - -Open a terminal and enter the following commands to make a _cairo_projects_ directory. - -For Linux, macOS, and PowerShell on Windows, enter this: - -```shell -mkdir ~/cairo_projects -cd ~/cairo_projects -``` - -For Windows CMD, enter this: - -```cmd -> mkdir "%USERPROFILE%\cairo_projects" -> cd /d "%USERPROFILE%\cairo_projects" -``` - -> Note: From now on, for each example shown in the book, we assume that -> you will be working from a Scarb project directory. If you are not using Scarb, and try to run the examples from a different directory, you might need to adjust the commands accordingly or create a Scarb project. - -## Creating a Project with Scarb - -Let’s create a new project using Scarb. - -Navigate to your _cairo_projects_ directory (or wherever you decided to store your code). Then run the following: - -```bash -scarb new hello_world -``` - -It creates a new directory and project called _hello_world_. We’ve named our project _hello_world_, and Scarb creates its files in a directory of the same name. - -Go into the _hello_world_ directory with the command `cd hello_world`. You’ll see that Scarb has generated two files and one directory for us: a _Scarb.toml_ file and a _src_ directory with a _lib.cairo_ file inside. - -It has also initialized a new Git repository along with a `.gitignore` file - -> Note: Git is a common version control system. You can stop using version control system by using the `--no-vcs` flag. -> Run `scarb new --help` to see the available options. - -Open _Scarb.toml_ in your text editor of choice. It should look similar to the code in Listing 1-1. - -Filename: Scarb.toml - -```toml -[package] -name = "hello_world" -version = "0.1.0" -edition = "2023_11" - -# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest - -[dependencies] -# foo = { path = "vendor/foo" } -``` - -Listing 1-1: Contents of _Scarb.toml_ generated by `scarb new` - -This file is in the [TOML][toml doc] (Tom’s Obvious, Minimal Language) format, which is Scarb’s configuration format. - -The first line, `[package]`, is a section heading that indicates that the following statements are configuring a package. As we add more information to this file, we’ll add other sections. - -The next three lines set the configuration information Scarb needs to compile your program: the name of the package and the version of Scarb to use, and the edition of the prelude to use. The prelude is the collection of the most commonly used items that are automatically imported into every Cairo program. You can learn more about the prelude in [Appendix D][prelude]. - -The last line, `[dependencies]`, is the start of a section for you to list any of your project’s dependencies. In Cairo, packages of code are referred to as crates. We won’t need any other crates for this project. - -> Note: If you're building contracts for Starknet, you will need to add the `starknet` dependency as mentioned in the [Scarb documentation][starknet package]. - -The other file created by Scarb is _src/lib.cairo_, let's delete all the content and put in the following content, we will explain the reason later. - -```rust,noplayground -mod hello_world; -``` - -Then create a new file called _src/hello_world.cairo_ and put the following code in it: - -Filename: src/hello_world.cairo - -```rust,file=hello_world.cairo -fn main() { - println!("Hello, World!"); -} -``` - -We have just created a file called _lib.cairo_, which contains a module declaration referencing another module named `hello_world`, as well as the file _hello_world.cairo_, containing the implementation details of the `hello_world` module. - -Scarb requires your source files to be located within the _src_ directory. - -The top-level project directory is reserved for README files, license information, configuration files, and any other non-code-related content. -Scarb ensures a designated location for all project components, maintaining a structured organization. - -If you started a project that doesn’t use Scarb, you can convert it to a project that does use Scarb. Move the project code into the _src_ directory and create an appropriate _Scarb.toml_ file. You can also use `scarb init` command to generate the _src_ folder and the _Scarb.toml_ it contains. - -```txt -├── Scarb.toml -├── src -│   ├── lib.cairo -│   └── hello_world.cairo -``` - - A sample Scarb project structure - -[toml doc]: https://toml.io/ -[prelude]: ./appendix-04-cairo-prelude.md -[starknet package]: https://docs.swmansion.com/scarb/docs/extensions/starknet/starknet-package.html - -## Building a Scarb Project - -From your _hello_world_ directory, build your project by entering the following command: - -```bash -$ scarb build - Compiling hello_world v0.1.0 (file:///projects/Scarb.toml) - Finished release target(s) in 0 seconds -``` - -This command creates a `sierra` file in _target/dev_, let's ignore the `sierra` file for now. - -If you have installed Cairo correctly, you should be able to run the `main` function of your program with the `scarb cairo-run` command and see the following output: - -```shell -$ scarb cairo-run -Running hello_world -Hello, World! -Run completed successfully, returning [] -``` - -Regardless of your operating system, the string `Hello, world!` should be printed to -the terminal. - -If `Hello, world!` did print, congratulations! You’ve officially written a Cairo -program. That makes you a Cairo programmer — welcome! - -## Anatomy of a Cairo Program - -Let’s review this “Hello, world!” program in detail. Here’s the first piece of -the puzzle: - -```rust,noplayground -fn main() { - -} -``` - -These lines define a function named `main`. The `main` function is special: it -is always the first code that runs in every executable Cairo program. Here, the -first line declares a function named `main` that has no parameters and returns -nothing. If there were parameters, they would go inside the parentheses `()`. - -The function body is wrapped in `{}`. Cairo requires curly brackets around all -function bodies. It’s good style to place the opening curly bracket on the same -line as the function declaration, adding one space in between. - -> Note: If you want to stick to a standard style across Cairo projects, you can -> use the automatic formatter tool available with `scarb fmt` to format your code in a -> particular style (more on `scarb fmt` in -> [Appendix F][devtools]). The Cairo team has included this tool -> with the standard Cairo distribution, as `cairo-run` is, so it should already be -> installed on your computer! - -The body of the `main` function holds the following code: - -```rust,noplayground - println!("Hello, World!"); -``` - -This line does all the work in this little program: it prints text to the -screen. There are four important details to notice here. - -First, Cairo style is to indent with four spaces, not a tab. - -Second, `println!` calls a Cairo macro. If it had called a function instead, it would be entered as `println` (without the `!`). -We’ll discuss Cairo macros in more detail in the ["Macros"][macros] chapter. For now, you just need to know that using a `!` means that you’re calling a macro instead of a normal function and that macros don’t always follow the same rules as functions. - -Third, you see the `"Hello, world!"` string. We pass this string as an argument to `println!`, and the string is printed to the screen. - -Fourth, we end the line with a semicolon (`;`), which indicates that this -expression is over and the next one is ready to begin. Most lines of Cairo code -end with a semicolon. - -[devtools]: ./appendix-06-useful-development-tools.md -[macros]: ./ch11-05-macros.md - -{{#quiz ../quizzes/ch01-02-hello-world.toml}} - -# Summary - -Let’s recap what we’ve learned so far about Scarb: - -- We can install one or multiple Scarb versions, either the latest stable or a specific one, using asdf. -- We can create a project using `scarb new`. -- We can build a project using `scarb build` to generate the compiled Sierra code. -- We can execute a Cairo program using the `scarb cairo-run` command. - -An additional advantage of using Scarb is that the commands are the same no matter which operating system you’re working on. So, at this point, we’ll no longer provide specific instructions for Linux and macOS versus Windows. - -You’re already off to a great start on your Cairo journey! This is a great time to build a more substantial program to get used to reading and writing Cairo code. -# Common Programming Concepts - -This chapter covers concepts that appear in almost every programming language and how they work in Cairo. Many programming languages have much in common at their core. None of the concepts presented in this chapter are unique to Cairo, but we’ll discuss them in the context of Cairo and explain the conventions around using these concepts. - -Specifically, you’ll learn about variables, basic types, functions, comments, and control flow. These foundations will be in every Cairo program, and learning them early will give you a strong core to start from. -# Variables and Mutability - -Cairo uses an immutable memory model, meaning that once a memory cell is written to, -it can't be overwritten but only read from. To reflect this immutable memory model, -variables in Cairo are immutable by default. -However, the language abstracts this model and gives you the option to make your -variables mutable. Let’s explore how and why Cairo enforces immutability, and how -you can make your variables mutable. - -When a variable is immutable, once a value is bound to a name, you can’t change -that value. To illustrate this, generate a new project called _variables_ in -your _cairo_projects_ directory by using `scarb new variables`. - -Then, in your new _variables_ directory, open _src/lib.cairo_ and replace its -code with the following code, which won’t compile just yet: - -Filename: src/lib.cairo - -```rust,does_not_compile -fn main() { - let x = 5; - println!("The value of x is: {}", x); - x = 6; - println!("The value of x is: {}", x); -} - -``` - -Save and run the program using `scarb cairo-run`. You should receive an error message -regarding an immutability error, as shown in this output: - -```shell -$ scarb cairo-run - Compiling no_listing_01_variables_are_immutable v0.1.0 (listings/ch02-common-programming-concepts/no_listing_01_variables_are_immutable/Scarb.toml) -error: Cannot assign to an immutable variable. - --> listings/ch02-common-programming-concepts/no_listing_01_variables_are_immutable/src/lib.cairo:6:5 - x = 6; - ^***^ - -error: could not compile `no_listing_01_variables_are_immutable` due to previous error -error: `scarb metadata` exited with error - -``` - -This example shows how the compiler helps you find errors in your programs. -Compiler errors can be frustrating, but they only mean your program -isn’t safely doing what you want it to do yet; they do _not_ mean that you’re -not a good programmer! Experienced Caironautes still get compiler errors. - -You received the error message `Cannot assign to an immutable variable.` -because you tried to assign a second value to the immutable `x` variable. - -It’s important that we get compile-time errors when we attempt to change a -value that’s designated as immutable because this specific situation can lead to -bugs. If one part of our code operates on the assumption that a value will -never change and another part of our code changes that value, it’s possible -that the first part of the code won’t do what it was designed to do. The cause -of this kind of bug can be difficult to track down after the fact, especially -when the second piece of code changes the value only _sometimes_. - -Cairo, unlike most other languages, has immutable memory. This makes a -whole class of bugs impossible, because values will never change unexpectedly. -This makes code easier to reason about. - -But mutability can be very useful, and can make code more convenient to write. -Although variables are immutable by default, you can make them mutable by -adding `mut` in front of the variable name. Adding `mut` also conveys -intent to future readers of the code by indicating that other parts of the code -will be changing the value associated to this variable. - - - -However, you might be wondering at this point what exactly happens when a variable -is declared as `mut`, as we previously mentioned that Cairo's memory is immutable. -The answer is that the _value_ is immutable, but the _variable_ isn't. The value -associated to the variable can be changed. Assigning to a mutable variable in Cairo -is essentially equivalent to redeclaring it to refer to another value in another memory cell, -but the compiler handles that for you, and the keyword `mut` makes it explicit. -Upon examining the low-level Cairo Assembly code, it becomes clear that -variable mutation is implemented as syntactic sugar, which translates mutation operations -into a series of steps equivalent to variable shadowing. The only difference is that at the Cairo -level, the variable is not redeclared so its type cannot change. - -For example, let’s change _src/lib.cairo_ to the following: - -```rust -fn main() { - let mut x = 5; - println!("The value of x is: {}", x); - x = 6; - println!("The value of x is: {}", x); -} -``` - -When we run the program now, we get this: - -```shell -$ scarb cairo-run - Compiling no_listing_02_adding_mut v0.1.0 (listings/ch02-common-programming-concepts/no_listing_02_adding_mut/Scarb.toml) - Finished release target(s) in 1 second - Running no_listing_02_adding_mut -The value of x is: 5 -The value of x is: 6 -Run completed successfully, returning [] - -``` - -We’re allowed to change the value bound to `x` from `5` to `6` when `mut` is -used. Ultimately, deciding whether to use mutability or not is up to you and -depends on what you think is clearest in that particular situation. - -## Constants - -Like immutable variables, _constants_ are values that are bound to a name and -are not allowed to change, but there are a few differences between constants -and variables. - -First, you aren’t allowed to use `mut` with constants. Constants aren’t just -immutable by default—they’re always immutable. You declare constants using the -`const` keyword instead of the `let` keyword, and the type of the value _must_ -be annotated. We’ll cover types and type annotations in the next section, -[“Data Types”][data-types], so don’t worry about the details -right now. Just know that you must always annotate the type. - -Constant variables can be declared with any usual data type, including structs, enums and fixed-size arrays. - -Constants can only be declared in the global scope, which makes -them useful for values that many parts of code need to know about. - -The last difference is that constants may natively be set only to a constant expression, -not the result of a value that could only be computed at runtime. - -Here’s an example of constants declaration: - -```rust,noplayground -struct AnyStruct { - a: u256, - b: u32 -} - -enum AnyEnum { - A: felt252, - B: (usize, u256) -} - -const ONE_HOUR_IN_SECONDS: u32 = 3600; -const STRUCT_INSTANCE: AnyStruct = AnyStruct { a: 0, b: 1 }; -const ENUM_INSTANCE: AnyEnum = AnyEnum::A('any enum'); -const BOOL_FIXED_SIZE_ARRAY: [bool; 2] = [true, false]; -``` - -Nonetheless, it is possible to use the `consteval_int!` macro to create a `const` variable that is the result of some computation: - -```rust, noplayground - const ONE_HOUR_IN_SECONDS: u32 = consteval_int!(60 * 60); -``` - -We will dive into more detail about macros in the [dedicated section](./ch11-05-macros.md). - -Cairo's naming convention for constants is to use all uppercase with underscores between words. - -Constants are valid for the entire time a program runs, within the scope in -which they were declared. This property makes constants useful for values in -your application domain that multiple parts of the program might need to know -about, such as the maximum number of points any player of a game is allowed to -earn, or the speed of light. - -Naming hardcoded values used throughout your program as constants is useful in -conveying the meaning of that value to future maintainers of the code. It also -helps to have only one place in your code you would need to change if the -hardcoded value needed to be updated in the future. - -[data-types]: ./ch02-02-data-types.md - -## Shadowing - -Variable shadowing refers to the declaration of a -new variable with the same name as a previous variable. Caironautes say that the -first variable is _shadowed_ by the second, which means that the second -variable is what the compiler will see when you use the name of the variable. -In effect, the second variable overshadows the first, taking any uses of the -variable name to itself until either it itself is shadowed or the scope ends. -We can shadow a variable by using the same variable’s name and repeating the -use of the `let` keyword as follows: - -```rust -fn main() { - let x = 5; - let x = x + 1; - { - let x = x * 2; - println!("Inner scope x value is: {}", x); - } - println!("Outer scope x value is: {}", x); -} -``` - -This program first binds `x` to a value of `5`. Then it creates a new variable -`x` by repeating `let x =`, taking the original value and adding `1` so the -value of `x` is then `6`. Then, within an inner scope created with the curly -brackets, the third `let` statement also shadows `x` and creates a new -variable, multiplying the previous value by `2` to give `x` a value of `12`. -When that scope is over, the inner shadowing ends and `x` returns to being `6`. -When we run this program, it will output the following: - -```shell -$ scarb cairo-run - Compiling no_listing_03_shadowing v0.1.0 (listings/ch02-common-programming-concepts/no_listing_03_shadowing/Scarb.toml) - Finished release target(s) in 1 second - Running no_listing_03_shadowing -Inner scope x value is: 12 -Outer scope x value is: 6 -Run completed successfully, returning [] - -``` - -Shadowing is different from marking a variable as `mut` because we’ll get a -compile-time error if we accidentally try to reassign to this variable without -using the `let` keyword. By using `let`, we can perform a few transformations -on a value but have the variable be immutable after those transformations have -been completed. - -Another distinction between `mut` and shadowing is that when we use the `let` keyword again, -we are effectively creating a new variable, which allows us to change the type of the -value while reusing the same name. As mentioned before, variable shadowing and mutable variables -are equivalent at the lower level. -The only difference is that by shadowing a variable, the compiler will not complain -if you change its type. For example, say our program performs a type conversion between the -`u64` and `felt252` types. - -```rust -fn main() { - let x: u64 = 2; - println!("The value of x is {} of type u64", x); - let x: felt252 = x.into(); // converts x to a felt, type annotation is required. - println!("The value of x is {} of type felt252", x); -} -``` - -The first `x` variable has a `u64` type while the second `x` variable has a `felt252` type. -Shadowing thus spares us from having to come up with different names, such as `x_u64` -and `x_felt252`; instead, we can reuse the simpler `x` name. However, if we try to use -`mut` for this, as shown here, we’ll get a compile-time error: - -```rust,does_not_compile -fn main() { - let mut x: u64 = 2; - println!("The value of x is: {}", x); - x = 'a short string'; - println!("The value of x is: {}", x); -} -``` - -The error says we were expecting a `u64` (the original type) but we got a different type: - -```shell -$ scarb cairo-run - Compiling no_listing_05_mut_cant_change_type v0.1.0 (listings/ch02-common-programming-concepts/no_listing_05_mut_cant_change_type/Scarb.toml) -error: The value does not fit within the range of type core::integer::u64. - --> listings/ch02-common-programming-concepts/no_listing_05_mut_cant_change_type/src/lib.cairo:6:9 - x = 'a short string'; - ^**************^ - -error: could not compile `no_listing_05_mut_cant_change_type` due to previous error -error: `scarb metadata` exited with error - -``` - -{{#quiz ../quizzes/ch02-01-variables-and-mutability.toml}} - -Now that we’ve explored how variables work, let’s look at more data types they can have. -# Data Types - -Every value in Cairo is of a certain _data type_, which tells Cairo what kind of -data is being specified so it knows how to work with that data. This section covers two subsets of data types: scalars and compounds. - -Keep in mind that Cairo is a _statically typed_ language, which means that it -must know the types of all variables at compile time. The compiler can usually infer the desired type based on the value and its usage. In cases when many types are possible, we can use a cast method where we specify the desired output type. - -```rust -fn main() { - let x: felt252 = 3; - let y: u32 = x.try_into().unwrap(); -} -``` - -You’ll see different type annotations for other data types. - -## Scalar Types - -A _scalar_ type represents a single value. Cairo has three primary scalar types: -felts, integers, and booleans. You may recognize -these from other programming languages. Let’s jump into how they work in Cairo. - -### Felt Type - -In Cairo, if you don't specify the type of a variable or argument, its type defaults to a field element, represented by the keyword `felt252`. In the context of Cairo, when we say “a field element” we mean an integer in the range \\( 0 \leq x < P \\), -where \\( P \\) is a very large prime number currently equal to \\( {2^{251}} + 17 \cdot {2^{192}} + 1 \\). When adding, subtracting, or multiplying, if the result falls outside the specified range of the prime number, an overflow (or underflow) occurs, and an appropriate multiple of \\( P \\) is added or subtracted to bring the result back within the range (i.e., the result is computed \\( \mod P \\) ). - -The most important difference between integers and field elements is division: Division of field elements (and therefore division in Cairo) is unlike regular CPUs division, where -integer division \\( \frac{x}{y} \\) is defined as \\( \left\lfloor \frac{x}{y} \right\rfloor \\) -where the integer part of the quotient is returned (so you get \\( \frac{7}{3} = 2 \\)) and it may or may not satisfy the equation \\( \frac{x}{y} \cdot y == x \\), -depending on the divisibility of `x` by `y`. - -In Cairo, the result of \\( \frac{x}{y} \\) is defined to always satisfy the equation \\( \frac{x}{y} \cdot y == x \\). If y divides x as integers, you will get the expected result in Cairo (for example \\( \frac{6}{2} \\) will indeed result in `3`). -But when y does not divide x, you may get a surprising result: for example, since \\( 2 \cdot \frac{P + 1}{2} = P + 1 \equiv 1 \mod P \\), the value of \\( \frac{1}{2} \\) in Cairo is \\( \frac{P + 1}{2} \\) (and not 0 or 0.5), as it satisfies the above equation. - -### Integer Types - -The felt252 type is a fundamental type that serves as the basis for creating all types in the core library. -However, it is highly recommended for programmers to use the integer types instead of the `felt252` type whenever possible, as the `integer` types come with added security features that provide extra protection against potential vulnerabilities in the code, such as overflow and underflow checks. By using these integer types, programmers can ensure that their programs are more secure and less susceptible to attacks or other security threats. -An `integer` is a number without a fractional component. This type declaration indicates the number of bits the programmer can use to store the integer. -Table 3-1 shows the built-in integer types in Cairo. We can use any of these variants to declare the type of an integer value. - -| Length | Unsigned | -| ------- | -------- | -| 8-bit | `u8` | -| 16-bit | `u16` | -| 32-bit | `u32` | -| 64-bit | `u64` | -| 128-bit | `u128` | -| 256-bit | `u256` | -| 32-bit | `usize` | - -
-
Table 3-1: Integer Types in Cairo.
- -Each variant has an explicit size. Note that for now, the `usize` type is just an alias for `u32`; however, it might be useful when in the future Cairo can be compiled to MLIR. -As variables are unsigned, they can't contain a negative number. This code will cause the program to panic: - -```rust -fn sub_u8s(x: u8, y: u8) -> u8 { - x - y -} - -fn main() { - sub_u8s(1, 3); -} -``` - -All integer types previously mentioned fit into a `felt252`, except for `u256` which needs 4 more bits to be stored. Under the hood, `u256` is basically a struct with 2 fields: `u256 {low: u128, high: u128}`. - -Cairo also provides support for signed integers, starting with the prefix `i`. These integers can represent both positive and negative values, with sizes ranging from `i8` to `i128`. -Each signed variant can store numbers from \\( -({2^{n - 1}}) \\) to \\( {2^{n - 1}} - 1 \\) inclusive, where `n` is the number of bits that variant uses. So an i8 can store numbers from \\( -({2^7}) \\) to \\( {2^7} - 1 \\), which equals `-128` to `127`. - -You can write integer literals in any of the forms shown in Table 3-2. Note -that number literals that can be multiple numeric types allow a type suffix, -such as `57_u8`, to designate the type. -It is also possible to use a visual separator `_` for number literals, in order to improve code readability. - -| Numeric literals | Example | -| ---------------- | --------- | -| Decimal | `98222` | -| Hex | `0xff` | -| Octal | `0o04321` | -| Binary | `0b01` | - -
-
Table 3-2: Integer Literals in Cairo.
- -So how do you know which type of integer to use? Try to estimate the max value your int can have and choose the good size. -The primary situation in which you’d use `usize` is when indexing some sort of collection. - -### Numeric Operations - -Cairo supports the basic mathematical operations you’d expect for all the integer -types: addition, subtraction, multiplication, division, and remainder. Integer -division truncates toward zero to the nearest integer. The following code shows -how you’d use each numeric operation in a `let` statement: - -```rust -fn main() { - // addition - let sum = 5_u128 + 10_u128; - - // subtraction - let difference = 95_u128 - 4_u128; - - // multiplication - let product = 4_u128 * 30_u128; - - // division - let quotient = 56_u128 / 32_u128; //result is 1 - let quotient = 64_u128 / 32_u128; //result is 2 - - // remainder - let remainder = 43_u128 % 5_u128; // result is 3 -} -``` - -Each expression in these statements uses a mathematical operator and evaluates -to a single value, which is then bound to a variable. - -[Appendix B][operators] contains a list of all operators that Cairo provides. - -[operators]: ./appendix-02-operators-and-symbols.md#operators - -### The Boolean Type - -As in most other programming languages, a Boolean type in Cairo has two possible -values: `true` and `false`. Booleans are one `felt252` in size. The Boolean type in -Cairo is specified using `bool`. For example: - -```rust -fn main() { - let t = true; - - let f: bool = false; // with explicit type annotation -} -``` - -When declaring a `bool` variable, it is mandatory to use either `true` or `false` literals as value. Hence, it is not allowed to use integer literals (i.e. `0` instead of false) for `bool` declarations. - -The main way to use Boolean values is through conditionals, such as an `if` -expression. We’ll cover how `if` expressions work in Cairo in the ["Control Flow"][control-flow] section. - -[control-flow]: ./ch02-05-control-flow.md - -### String Types - -Cairo doesn't have a native type for strings but provides two ways to handle them: short strings using simple quotes and ByteArray using double quotes. - -#### Short strings - -A short string is an ASCII string where each character is encoded on one byte (see the [ASCII table][ascii]). For example: - -- `'a'` is equivalent to `0x61` -- `'b'` is equivalent to `0x62` -- `'c'` is equivalent to `0x63` -- `0x616263` is equivalent to `'abc'`. - -Cairo uses the `felt252` for short strings. As the `felt252` is on 251 bits, a short string is limited to 31 characters (31 \* 8 = 248 bits, which is the maximum multiple of 8 that fits in 251 bits). - -You can choose to represent your short string with an hexadecimal value like `0x616263` or by directly writing the string using simple quotes like `'abc'`, which is more convenient. - -Here are some examples of declaring short strings in Cairo: - -```rust -# fn main() { - let my_first_char = 'C'; - let my_first_char_in_hex = 0x43; - - let my_first_string = 'Hello world'; - let my_first_string_in_hex = 0x48656C6C6F20776F726C64; -# -# let long_string: ByteArray = "this is a string which has more than 31 characters"; -# } -``` - -[ascii]: https://www.asciitable.com/ - -#### Byte Array Strings - -With the `ByteArray` struct added in Cairo 2.4.0, you are not limited to 31 characters anymore. These `ByteArray` strings are written in double quotes like in the following example: - -```rust -# fn main() { -# let my_first_char = 'C'; -# let my_first_char_in_hex = 0x43; -# -# let my_first_string = 'Hello world'; -# let my_first_string_in_hex = 0x48656C6C6F20776F726C64; -# - let long_string: ByteArray = "this is a string which has more than 31 characters"; -# } -``` - -## Type Casting - -In Cairo, you can convert scalar types from one type to another by using the `try_into` and `into` methods provided by the `TryInto` and `Into` traits from the core library. - -The `try_into` method allows for safe type casting when the target type might not fit the source value. Keep in mind that `try_into` returns an `Option` type, which you'll need to unwrap to access the new value. - -On the other hand, the `into` method can be used for type casting when success is guaranteed, such as when the source type is smaller than the destination type. - -To perform the conversion, call `var.into()` or `var.try_into()` on the source value to cast it to another type. The new variable's type must be explicitly defined, as demonstrated in the example below. - -```rust -fn main() { - let my_felt252 = 10; - // Since a felt252 might not fit in a u8, we need to unwrap the Option type - let my_u8: u8 = my_felt252.try_into().unwrap(); - let my_u16: u16 = my_u8.into(); - let my_u32: u32 = my_u16.into(); - let my_u64: u64 = my_u32.into(); - let my_u128: u128 = my_u64.into(); - // As a felt252 is smaller than a u256, we can use the into() method - let my_u256: u256 = my_felt252.into(); - let my_usize: usize = my_felt252.try_into().unwrap(); - let my_other_felt252: felt252 = my_u8.into(); - let my_third_felt252: felt252 = my_u16.into(); -} -``` - -## The Tuple Type - -A _tuple_ is a general way of grouping together a number of values with a -variety of types into one compound type. Tuples have a fixed length: once -declared, they cannot grow or shrink in size. - -We create a tuple by writing a comma-separated list of values inside -parentheses. Each position in the tuple has a type, and the types of the -different values in the tuple don’t have to be the same. We’ve added optional -type annotations in this example: - -```rust -fn main() { - let tup: (u32, u64, bool) = (10, 20, true); -} -``` - -The variable `tup` binds to the entire tuple because a tuple is considered a -single compound element. To get the individual values out of a tuple, we can -use pattern matching to destructure a tuple value, like this: - -```rust -fn main() { - let tup = (500, 6, true); - - let (x, y, z) = tup; - - if y == 6 { - println!("y is 6!"); - } -} -``` - -This program first creates a tuple and binds it to the variable `tup`. It then -uses a pattern with `let` to take `tup` and turn it into three separate -variables, `x`, `y`, and `z`. This is called _destructuring_ because it breaks -the single tuple into three parts. Finally, the program prints `y is 6!` as the value of -`y` is `6`. - -We can also declare the tuple with value and types, and destructure it at the same time. -For example: - -```rust -fn main() { - let (x, y): (felt252, felt252) = (2, 3); -} -``` - -## The Unit Type () - -A _unit type_ is a type which has only one value `()`. -It is represented by a tuple with no elements. -Its size is always zero, and it is guaranteed to not exist in the compiled code. - -You might be wondering why you would even need a unit type? In Cairo, everything is an expression, and an expression that returns nothing actually returns `()` implicitly. - -{{#quiz ../quizzes/ch02-02-data-types.toml}} -# Functions - -Functions are prevalent in Cairo code. You’ve already seen one of the most -important functions in the language: the `main` function, which is the entry -point of many programs. You’ve also seen the `fn` keyword, which allows you to -declare new functions. - -Cairo code uses _snake case_ as the conventional style for function and variable -names, in which all letters are lowercase and underscores separate words. -Here’s a program that contains an example function definition: - -```rust -fn another_function() { - println!("Another function."); -} - -fn main() { - println!("Hello, world!"); - another_function(); -} -``` - -We define a function in Cairo by entering `fn` followed by a function name and a -set of parentheses. The curly brackets tell the compiler where the function -body begins and ends. - -We can call any function we’ve defined by entering its name followed by a set -of parentheses. Because `another_function` is defined in the program, it can be -called from inside the `main` function. Note that we defined `another_function` -_before_ the `main` function in the source code; we could have defined it after -as well. Cairo doesn’t care where you define your functions, only that they’re -defined somewhere in a scope that can be seen by the caller. - -Let’s start a new project with Scarb named _functions_ to explore functions -further. Place the `another_function` example in _src/lib.cairo_ and run it. You -should see the following output: - -```shell -$ scarb cairo-run - Compiling no_listing_15_functions v0.1.0 (listings/ch02-common-programming-concepts/no_listing_15_functions/Scarb.toml) - Finished release target(s) in 1 second - Running no_listing_15_functions -Hello, world! -Another function. -Run completed successfully, returning [] - -``` - -The lines execute in the order in which they appear in the `main` function. -First the `Hello, world!` message prints, and then `another_function` is called -and its message is printed. - -## Parameters - -We can define functions to have _parameters_, which are special variables that -are part of a function’s signature. When a function has parameters, you can -provide it with concrete values for those parameters. Technically, the concrete -values are called _arguments_, but in casual conversation, people tend to use -the words _parameter_ and _argument_ interchangeably for either the variables -in a function’s definition or the concrete values passed in when you call a -function. - -In this version of `another_function` we add a parameter: - -```rust -fn main() { - another_function(5); -} - -fn another_function(x: felt252) { - println!("The value of x is: {}", x); -} -``` - -Try running this program; you should get the following output: - -```shell -$ scarb cairo-run - Compiling no_listing_16_single_param v0.1.0 (listings/ch02-common-programming-concepts/no_listing_16_single_param/Scarb.toml) - Finished release target(s) in 1 second - Running no_listing_16_single_param -The value of x is: 5 -Run completed successfully, returning [] - -``` - -The declaration of `another_function` has one parameter named `x`. The type of -`x` is specified as `felt252`. When we pass `5` in to `another_function`, the -`println!` macro puts `5` where the pair of curly brackets containing `x` was in the format string. - -In function signatures, you _must_ declare the type of each parameter. This is -a deliberate decision in Cairo’s design: requiring type annotations in function -definitions means the compiler almost never needs you to use them elsewhere in -the code to figure out what type you mean. The compiler is also able to give -more helpful error messages if it knows what types the function expects. - -When defining multiple parameters, separate the parameter declarations with -commas, like this: - -```rust -fn main() { - print_labeled_measurement(5, "h"); -} - -fn print_labeled_measurement(value: u128, unit_label: ByteArray) { - println!("The measurement is: {value}{unit_label}"); -} -``` - -This example creates a function named `print_labeled_measurement` with two -parameters. The first parameter is named `value` and is a `u128`. The second is -named `unit_label` and is of type `ByteArray` - Cairo's internal type to represent string literals. The function then prints text containing both the `value` and the `unit_label`. - -Let’s try running this code. Replace the program currently in your _functions_ -project’s _src/lib.cairo_ file with the preceding example and run it using `scarb cairo-run`: - -```shell -$ scarb cairo-run - Compiling no_listing_17_multiple_params v0.1.0 (listings/ch02-common-programming-concepts/no_listing_17_multiple_params/Scarb.toml) - Finished release target(s) in 1 second - Running no_listing_17_multiple_params -The measurement is: 5h -Run completed successfully, returning [] - -``` - -Because we called the function with `5` as the value for value and `"h"` as the value for `unit_label`, the program output contains those values. - -### Named Parameters - -In Cairo, named parameters allow you to specify the names of arguments when you call a function. This makes the function calls more readable and self-descriptive. -If you want to use named parameters, you need to specify the name of the parameter and the value you want to pass to it. The syntax is `parameter_name: value`. If you pass a variable that has the same name as the parameter, you can simply write `:parameter_name` instead of `parameter_name: variable_name`. - -Here is an example: - -```rust -fn foo(x: u8, y: u8) {} - -fn main() { - let first_arg = 3; - let second_arg = 4; - foo(x: first_arg, y: second_arg); - let x = 1; - let y = 2; - foo(:x, :y) -} -``` - -## Statements and Expressions - -Function bodies are made up of a series of statements optionally ending in an -expression. So far, the functions we’ve covered haven’t included an ending -expression, but you have seen an expression as part of a statement. Because -Cairo is an expression-based language, this is an important distinction to -understand. Other languages don’t have the same distinctions, so let’s look at -what statements and expressions are and how their differences affect the bodies -of functions. - -- **Statements** are instructions that perform some action and do not return - a value. -- **Expressions** evaluate to a resultant value. Let’s look at some examples. - -We’ve actually already used statements and expressions. Creating a variable and -assigning a value to it with the `let` keyword is a statement. In Listing 2-1, -`let y = 6;` is a statement. - -```rust -fn main() { - let y = 6; -} -``` - -Listing 2-1: A `main` function declaration containing one statement - -Function definitions are also statements; the entire preceding example is a statement in itself. - -Statements do not return values. Therefore, you can’t assign a `let` statement -to another variable, as the following code tries to do; you’ll get an error: - -```rust, noplayground -fn main() { - let x = (let y = 6); -} -``` - -When you run this program, the error you’ll get looks like this: - -```shell -$ scarb cairo-run - Compiling no_listing_18_statements_dont_return_values v0.1.0 (listings/ch02-common-programming-concepts/no_listing_20_statements_dont_return_values/Scarb.toml) -error: Missing token TerminalRParen. - --> listings/ch02-common-programming-concepts/no_listing_20_statements_dont_return_values/src/lib.cairo:3:14 - let x = (let y = 6); - ^ - -error: Missing token TerminalSemicolon. - --> listings/ch02-common-programming-concepts/no_listing_20_statements_dont_return_values/src/lib.cairo:3:14 - let x = (let y = 6); - ^ - -error: Missing token TerminalSemicolon. - --> listings/ch02-common-programming-concepts/no_listing_20_statements_dont_return_values/src/lib.cairo:3:23 - let x = (let y = 6); - ^ - -error: Skipped tokens. Expected: statement. - --> listings/ch02-common-programming-concepts/no_listing_20_statements_dont_return_values/src/lib.cairo:3:23 - let x = (let y = 6); - ^^ - -warn: Unused variable. Consider ignoring by prefixing with `_`. - --> listings/ch02-common-programming-concepts/no_listing_20_statements_dont_return_values/src/lib.cairo:3:9 - let x = (let y = 6); - ^ - -warn: Unused variable. Consider ignoring by prefixing with `_`. - --> listings/ch02-common-programming-concepts/no_listing_20_statements_dont_return_values/src/lib.cairo:3:18 - let x = (let y = 6); - ^ - -error: could not compile `no_listing_18_statements_dont_return_values` due to previous error -error: `scarb metadata` exited with error - -``` - -The `let y = 6` statement does not return a value, so there isn’t anything for -`x` to bind to. This is different from what happens in other languages, such as -C and Ruby, where the assignment returns the value of the assignment. In those -languages, you can write `x = y = 6` and have both `x` and `y` have the value -`6`; that is not the case in Cairo. - -Expressions evaluate to a value and make up most of the rest of the code that -you’ll write in Cairo. Consider a math operation, such as `5 + 6`, which is an -expression that evaluates to the value `11`. Expressions can be part of -statements: in Listing 2-1, the `6` in the statement `let y = 6;` is an -expression that evaluates to the value `6`. - -Calling a function is an expression since it always evaluates to a value: the function's explicit return value, if specified, or the 'unit' type `()` otherwise. - -A new scope block created with curly brackets is an expression, for example: - -```rust -fn main() { - let y = { - let x = 3; - x + 1 - }; - - println!("The value of y is: {}", y); -} -``` - -This expression: - -```rust, noplayground - let y = { - let x = 3; - x + 1 - }; -``` - -is a block that, in this case, evaluates to `4`. That value gets bound to `y` -as part of the `let` statement. Note that the `x + 1` line doesn’t have a -semicolon at the end, which is unlike most of the lines you’ve seen so far. -Expressions do not include ending semicolons. If you add a semicolon to the end -of an expression, you turn it into a statement, and it will then not return a -value. Keep this in mind as you explore function return values and expressions -next. - -## Functions with Return Values - -Functions can return values to the code that calls them. We don’t name return -values, but we must declare their type after an arrow (`->`). In Cairo, the -return value of the function is synonymous with the value of the final -expression in the block of the body of a function. You can return early from a -function by using the `return` keyword and specifying a value, but most -functions return the last expression implicitly. Here’s an example of a -function that returns a value: - -```rust -fn five() -> u32 { - 5 -} - -fn main() { - let x = five(); - println!("The value of x is: {}", x); -} -``` - -There are no function calls, or even `let` statements in the `five` -function—just the number `5` by itself. That’s a perfectly valid function in -Cairo. Note that the function’s return type is specified too, as `-> u32`. Try -running this code; the output should look like this: - -```shell -$ scarb cairo-run - Compiling no_listing_20_function_return_values v0.1.0 (listings/ch02-common-programming-concepts/no_listing_22_function_return_values/Scarb.toml) - Finished release target(s) in 1 second - Running no_listing_20_function_return_values -The value of x is: 5 -Run completed successfully, returning [] - -``` - -The `5` in `five` is the function’s return value, which is why the return type -is `u32`. Let’s examine this in more detail. There are two important bits: -first, the line `let x = five();` shows that we’re using the return value of a -function to initialize a variable. Because the function `five` returns a `5`, -that line is the same as the following: - -```rust, noplayground -let x = 5; -``` - -Second, the `five` function has no parameters and defines the type of the -return value, but the body of the function is a lonely `5` with no semicolon -because it’s an expression whose value we want to return. -Let’s look at another example: - -```rust -fn main() { - let x = plus_one(5); - - println!("The value of x is: {}", x); -} - -fn plus_one(x: u32) -> u32 { - x + 1 -} -``` - -Running this code will print `x = 6`. But if we place a -semicolon at the end of the line containing `x + 1`, changing it from an -expression to a statement, we’ll get an error: - -```rust,does_not_compile -fn main() { - let x = plus_one(5); - - println!("The value of x is: {}", x); -} - -fn plus_one(x: u32) -> u32 { - x + 1; -} -``` - -```shell -$ scarb cairo-run - Compiling no_listing_22_function_return_invalid v0.1.0 (listings/ch02-common-programming-concepts/no_listing_24_function_return_invalid/Scarb.toml) -error: Unexpected return type. Expected: "core::integer::u32", found: "()". - --> listings/ch02-common-programming-concepts/no_listing_24_function_return_invalid/src/lib.cairo:9:28 -fn plus_one(x: u32) -> u32 { - ^ - -error: could not compile `no_listing_22_function_return_invalid` due to previous error -error: `scarb metadata` exited with error - -``` - -The main error message, `Unexpected return type`, reveals the core issue with this -code. The definition of the function `plus_one` says that it will return an -`u32`, but statements don’t evaluate to a value, which is expressed by `()`, -the unit type. Therefore, nothing is returned, which contradicts the function -definition and results in an error. - -{{#quiz ../quizzes/ch02-03-functions.toml}} -# Comments - -All programmers strive to make their code easy to understand, but sometimes extra explanation is warranted. In these cases, programmers leave comments in their source code that the compiler will ignore but people reading the source code may find useful. - -Here’s a simple comment: - -```rust,noplayground -// hello, world -``` - -In Cairo, the idiomatic comment style starts a comment with two slashes, and the comment continues until the end of the line. For comments that extend beyond a single line, you’ll need to include `//` on each line, like this: - -```rust,noplayground -// So we’re doing something complicated here, long enough that we need -// multiple lines of comments to do it! Whew! Hopefully, this comment will -// explain what’s going on. -``` - -Comments can also be placed at the end of lines containing code: - -```rust -fn main() -> felt252 { - 1 + 4 // return the sum of 1 and 4 -} -``` - -But you’ll more often see them used in this format, with the comment on a separate line above the code it’s annotating: - -```rust -fn main() -> felt252 { - // this function performs a simple addition - 1 + 4 -} -``` - -### Item-level Documentation - -Item-level documentation comments refer to specific items such as functions, implementations, traits, etc. They are prefixed with three slashes (`///`). These comments provide a detailed description of the item, examples of usage, and any conditions that might cause a panic. In case of functions, the comments may also include separate sections for parameter and return value descriptions. - -```rust,noplayground -/// Returns the sum of `arg1` and `arg2`. -/// `arg1` cannot be zero. -/// -/// # Panics -/// -/// This function will panic if `arg1` is `0`. -/// -/// # Examples -/// -/// ``` -/// let a: felt252 = 2; -/// let b: felt252 = 3; -/// let c: felt252 = add(a, b); -/// assert(c == a + b, "Should equal a + b"); -/// ``` -fn add(arg1: felt252, arg2: felt252) -> felt252 { - assert(arg1 != 0, 'Cannot be zero'); - arg1 + arg2 -} -``` - -### Module Documentation - -Module documentation comments provide an overview of the entire module, including its purpose and examples of use. These comments are meant to be placed above the module they're describing and are prefixed with `//!`. This type of documentation gives a broad understanding of what the module does and how it can be used. - -```rust,noplayground -//! # my_module and implementation -//! -//! This is an example description of my_module and some of its features. -//! -//! # Examples -//! -//! ``` -//! mod my_other_module { -//! use path::to::my_module; -//! -//! fn foo() { -//! my_module.bar(); -//! } -//! } -//! ``` -mod my_module { // rest of implementation... -} -``` - -{{#quiz ../quizzes/ch02-04-comments.toml}} -# Control Flow - -The ability to run some code depending on whether a condition is true and to run some code repeatedly while a condition is true are basic building blocks in most programming languages. The most common constructs that let you control the flow of execution of Cairo code are if expressions and loops. - -## `if` Expressions - -An if expression allows you to branch your code depending on conditions. You provide a condition and then state, “If this condition is met, run this block of code. If the condition is not met, do not run this block of code.” - -Create a new project called _branches_ in your _cairo_projects_ directory to explore the `if` expression. In the _src/lib.cairo_ file, input the following: - -```rust -fn main() { - let number = 3; - - if number == 5 { - println!("condition was true and number = {}", number); - } else { - println!("condition was false and number = {}", number); - } -} -``` - -All `if` expressions start with the keyword `if`, followed by a condition. In this case, the condition checks whether or not the variable `number` has a value equal to 5. We place the block of code to execute if the condition is `true` immediately after the condition inside curly brackets. - -Optionally, we can also include an `else` expression, which we chose to do here, to give the program an alternative block of code to execute should the condition evaluate to `false`. If you don’t provide an `else` expression and the condition is `false`, the program will just skip the `if` block and move on to the next bit of code. - -Try running this code; you should see the following output: - -```shell -$ scarb cairo-run - Compiling no_listing_24_if v0.1.0 (listings/ch02-common-programming-concepts/no_listing_27_if/Scarb.toml) - Finished release target(s) in 1 second - Running no_listing_24_if -condition was false and number = 3 -Run completed successfully, returning [] - -``` - -Let’s try changing the value of `number` to a value that makes the condition `true` to see what happens: - -```rust, noplayground - let number = 5; -``` - -```shell -$ scarb cairo-run -condition was true and number = 5 -Run completed successfully, returning [] -``` - -It’s also worth noting that the condition in this code must be a `bool`. If the condition isn’t a `bool`, we’ll get an error. For example, try running the following code: - -```rust -fn main() { - let number = 3; - - if number { - println!("number was three"); - } -} -``` - -The `if` condition evaluates to a value of 3 this time, and Cairo throws an error: - -```shell -$ scarb build - Compiling no_listing_28_bis_if_not_bool v0.1.0 (listings/ch02-common-programming-concepts/no_listing_28_bis_if_not_bool/Scarb.toml) -error: Mismatched types. The type `core::bool` cannot be created from a numeric literal. - --> listings/ch02-common-programming-concepts/no_listing_28_bis_if_not_bool/src/lib.cairo:4:18 - let number = 3; - ^ - -error: could not compile `no_listing_28_bis_if_not_bool` due to previous error - -``` - -The error indicates that Cairo inferred the type of `number` to be a `bool` -based on its later use as a condition of the `if` statement. It tries to create -a `bool` from the value `3`, but Cairo doesn't support instantiating a `bool` -from a numeric literal anyway - you can only use `true` or `false` to create a -`bool`. Unlike languages such as Ruby and JavaScript, Cairo will not -automatically try to convert non-Boolean types to a Boolean. If we want the `if` -code block to run only when a number is not equal to 0, for example, we can -change the if expression to the following: - -```rust -fn main() { - let number = 3; - - if number != 0 { - println!("number was something other than zero"); - } -} - -``` - -Running this code will print `number was something other than zero`. - -## Handling Multiple Conditions with `else if` - -You can use multiple conditions by combining `if` and `else` in an `else if` expression. For example: - -```rust -fn main() { - let number = 3; - - if number == 12 { - println!("number is 12"); - } else if number == 3 { - println!("number is 3"); - } else if number - 2 == 1 { - println!("number minus 2 is 1"); - } else { - println!("number not found"); - } -} -``` - -This program has four possible paths it can take. After running it, you should see the following output: - -```shell -$ scarb cairo-run - Compiling no_listing_25_else_if v0.1.0 (listings/ch02-common-programming-concepts/no_listing_30_else_if/Scarb.toml) - Finished release target(s) in 1 second - Running no_listing_25_else_if -number is 3 -Run completed successfully, returning [] - -``` - -When this program executes, it checks each `if` expression in turn and executes the first body for which the condition evaluates to `true`. Note that even though `number - 2 == 1` is `true`, we don’t see the output `number minus 2 is 1` nor do we see the `number not found` text from the `else` block. That’s because Cairo only executes the block for the first true condition, and once it finds one, it doesn’t even check the rest. Using too many `else if` expressions can clutter your code, so if you have more than one, you might want to refactor your code. [Chapter 6][match] describes a powerful Cairo branching construct called `match` for these cases. - -[match]: ./ch06-02-the-match-control-flow-construct.md - -## Using `if` in a `let` Statement - -Because `if` is an expression, we can use it on the right side of a `let` statement to assign the outcome to a variable. - -```rust -fn main() { - let condition = true; - let number = if condition { - 5 - } else { - 6 - }; - - if number == 5 { - println!("condition was true and number is {}", number); - } -} -``` - -```shell -$ scarb cairo-run - Compiling no_listing_26_if_let v0.1.0 (listings/ch02-common-programming-concepts/no_listing_31_if_let/Scarb.toml) - Finished release target(s) in 1 second - Running no_listing_26_if_let -condition was true and number is 5 -Run completed successfully, returning [] - -``` - -The `number` variable will be bound to a value based on the outcome of the `if` expression, which will be 5 here. - -## Repetition with Loops - -It’s often useful to execute a block of code more than once. For this task, Cairo provides a simple loop syntax, which will run through the code inside the loop body to the end and then start immediately back at the beginning. To experiment with loops, let’s create a new project called _loops_. - -Cairo has two kinds of loops: `loop` and `while`. - -### Repeating Code with `loop` - -The `loop` keyword tells Cairo to execute a block of code over and over again forever or until you explicitly tell it to stop. - -As an example, change the _src/lib.cairo_ file in your _loops_ directory to look like this: - -```rust -fn main() { - loop { - println!("again!"); - if (false) { - break; - } - } -} -``` - -> Note: This program would not compile without a break condition. For the purpose of the example, we added a `break` statement that will never be reached, but satisfies the compiler. - -When we run this program, we’ll see `again!` printed over and over continuously until either the program runs out of gas or we stop the program manually. Most terminals support the keyboard shortcut ctrl-c to interrupt a program that is stuck in a continual loop. Give it a try: - -```shell -$ scarb cairo-run --available-gas=20000000 - Compiling loops v0.1.0 (file:///projects/loops) - Finished release target(s) in 0 seconds - Running loops -again! -again! -again! -^Cagain! -``` - -The symbol `^C` represents where you pressed ctrl-c. You may or may not see the word `again!` printed after the ^C, depending on where the code was in the loop when it received the interrupt signal. - -> Note: Cairo prevents us from running program with infinite loops by including a gas meter. The gas meter is a mechanism that limits the amount of computation that can be done in a program. By setting a value to the `--available-gas` flag, we can set the maximum amount of gas available to the program. Gas is a unit of measurement that expresses the computation cost of an instruction. When the gas meter runs out, the program will stop. In the previous case, we set the gas limit high enough for the program to run for quite some time. - -> It is particularly important in the context of smart contracts deployed on Starknet, as it prevents from running infinite loops on the network. -> If you're writing a program that needs to run a loop, you will need to execute it with the `--available-gas` flag set to a value that is large enough to run the program. - -Now, try running the same program again, but this time with the `--available-gas` flag set to `200000` instead of `2000000000000`. You will see the program only prints `again!` 3 times before it stops, as it ran out of gas to keep executing the loop. - -Fortunately, Cairo also provides a way to break out of a loop using code. You can place the `break` keyword within the loop to tell the program when to stop executing the loop. - -```rust -fn main() { - let mut i: usize = 0; - loop { - if i > 10 { - break; - } - println!("i = {}", i); - i += 1; - } -} -``` - -The `continue` keyword tells the program to go to the next iteration of the loop and to skip the rest of the code in this iteration. -Let's add a `continue` statement to our loop to skip the `println!` statement when `i` is equal to `5`. - -```rust -fn main() { - let mut i: usize = 0; - loop { - if i > 10 { - break; - } - if i == 5 { - i += 1; - continue; - } - println!("i = {}", i); - i += 1; - } -} -``` - -Executing this program will not print the value of `i` when it is equal to `5`. - -### Returning Values from Loops - -One of the uses of a `loop` is to retry an operation you know might fail, such -as checking whether an operation has succeeded. You might also need to pass -the result of that operation out of the loop to the rest of your code. To do -this, you can add the value you want returned after the `break` expression you -use to stop the loop; that value will be returned out of the loop so you can -use it, as shown here: - -```rust -fn main() { - let mut counter = 0; - - let result = loop { - if counter == 10 { - break counter * 2; - } - counter += 1; - }; - - println!("The result is {}", result); -} -``` - -Before the loop, we declare a variable named `counter` and initialize it to -`0`. Then we declare a variable named `result` to hold the value returned from -the loop. On every iteration of the loop, we check whether the `counter` is equal to `10`, and then add `1` to the `counter` variable. -When the condition is met, we use the `break` keyword with the value `counter * 2`. After the loop, we use a -semicolon to end the statement that assigns the value to `result`. Finally, we -print the value in `result`, which in this case is `20`. - -### Conditional Loops with `while` - -A program will often need to evaluate a condition within a loop. -While the condition is `true`, the loop runs. -When the condition ceases to be `true`, the program calls `break`, stopping the loop. -It’s possible to implement behavior like this using a combination of `loop`, `if`, `else`, and `break`; you could try that now in a program, if you’d like. -However, this pattern is so common that Cairo has a built-in language construct for it, called a `while` loop. - -In Listing 2-2, we use `while` to loop the program three times, counting down each time after printing the value of `number`, and then, after the loop, print a message and exit. - -```rust -fn main() { - let mut number = 3; - - while number != 0 { - println!("{number}!"); - number -= 1; - }; - - println!("LIFTOFF!!!"); -} -``` - -Listing 2-2: Using a `while` loop to run code while a condition holds `true`. - -This construct eliminates a lot of nesting that would be necessary if you used `loop`, `if`, `else`, and `break`, and it’s clearer. -While a condition evaluates to `true`, the code runs; otherwise, it exits the loop. - -{{#quiz ../quizzes/ch02-05-control-flow.toml}} - -## Summary - -You made it! This was a sizable chapter: you learned about variables, data types, functions, comments, -`if` expressions and loops! To practice with the concepts discussed in this chapter, -try building programs to do the following: - -- Generate the _n_-th Fibonacci number. -- Compute the factorial of a number _n_. - -Now, we’ll review the common collection types in Cairo in the next chapter. -# Common Collections - -Cairo provides a set of common collection types that can be used to store and manipulate data. These collections are designed to be efficient, flexible, and easy to use. This section introduces the primary collection types available in Cairo: Arrays and Dictionaries. -# Arrays - -An array is a collection of elements of the same type. You can create and use array methods by using the `ArrayTrait` trait from the core library. - -An important thing to note is that arrays have limited modification options. Arrays are, in fact, queues whose values can't be modified. -This has to do with the fact that once a memory slot is written to, it cannot be overwritten, but only read from it. You can only append items to the end of an array and remove items from the front. - -## Creating an Array - -Creating an array is done with the `ArrayTrait::new()` call. Here's an example of creating an array and appending 3 elements to it:: - -```rust -fn main() { - let mut a = ArrayTrait::new(); - a.append(0); - a.append(1); - a.append(2); -} -``` - -When required, you can pass the expected type of items inside the array when instantiating the array like this, or explicitly define the type of the variable. - -```rust, noplayground -let mut arr = ArrayTrait::::new(); -``` - -```rust, noplayground -let mut arr:Array = ArrayTrait::new(); -``` - -## Updating an Array - -### Adding Elements - -To add an element to the end of an array, you can use the `append()` method: - -```rust -# fn main() { -# let mut a = ArrayTrait::new(); -# a.append(0); -# a.append(1); - a.append(2); -# } -``` - -### Removing Elements - -You can only remove elements from the front of an array by using the `pop_front()` method. -This method returns an `Option` that can be unwrapped, containing the removed element, or `Option::None` if the array is empty. - -```rust -fn main() { - let mut a = ArrayTrait::new(); - a.append(10); - a.append(1); - a.append(2); - - let first_value = a.pop_front().unwrap(); - println!("The first value is {}", first_value); -} -``` - -The above code will print `The first value is 10` as we remove the first element that was added. - -In Cairo, memory is immutable, which means that it is not possible to modify the elements of an array once they've been added. You can only add elements to the end of an array and remove elements from the front of an array. These operations do not require memory mutation, as they involve updating pointers rather than directly modifying the memory cells. - -## Reading Elements from an Array - -To access array elements, you can use `get()` or `at()` array methods that return different types. Using `arr.at(index)` is equivalent to using the subscripting operator `arr[index]`. - -### `get()` Method - -The `get` function returns an `Option>`, which means it returns an option to a Box type (Cairo's smart-pointer type) containing a snapshot to the element at the specified index if that element exists in the array. If the element doesn't exist, `get` returns `None`. This method is useful when you expect to access indices that may not be within the array's bounds and want to handle such cases gracefully without panics. Snapshots will be explained in more detail in the ["References and Snapshots"][snapshots] chapter. - -Here is an example with the `get()` method: - -```rust -fn main() -> u128 { - let mut arr = ArrayTrait::::new(); - arr.append(100); - let index_to_access = - 1; // Change this value to see different results, what would happen if the index doesn't exist? - match arr.get(index_to_access) { - Option::Some(x) => { - *x - .unbox() // Don't worry about * for now, if you are curious see Chapter 4.2 #desnap operator - // It basically means "transform what get(idx) returned into a real value" - }, - Option::None => { panic!("out of bounds") } - } -} -``` - -[snapshots]: ./ch04-02-references-and-snapshots.md#snapshots - -### `at()` Method - -The `at` function, on the other hand, directly returns a snapshot to the element at the specified index using the `unbox()` operator to extract the value stored in a box. If the index is out of bounds, a panic error occurs. You should only use `at` when you want the program to panic if the provided index is out of the array's bounds, which can prevent unexpected behavior. - -Here is an example with the `at()` method: - -```rust -fn main() { - let mut a = ArrayTrait::new(); - a.append(0); - a.append(1); - - let first = *a.at(0); - let second = *a.at(1); -} -``` - -In this example, the variable named `first` will get the value `0` because that -is the value at index `0` in the array. The variable named `second` will get -the value `1` from index `1` in the array. - -If you want to use the subscripting operator `arr[index]`, you will need to explicitly define the type of the elements of the array, otherwise it will not compile. For example: - -```rust -fn main() { - let mut a: Array = ArrayTrait::new(); - a.append(0); - a.append(1); - - let first = a[0]; - let second = a[1]; -} -``` - -In summary, use `at` when you want to panic on out-of-bounds access attempts, and use `get` when you prefer to handle such cases gracefully without panicking. - -## Size-related Methods - -To determine the number of elements in an array, use the `len()` method. The return value is of type `usize`. - -If you want to check if an array is empty or not, you can use the `is_empty()` method, which returns `true` if the array is empty and `false` otherwise. - -## `array!` Macro - -Sometimes, we need to create arrays with values that are already known at compile time. The basic way of doing that is redundant. You would first declare the array and then append each value one by one. `array!` is a simpler way of doing this task by combining the two steps. -At compile-time, the compiler will expand the macro to generate the code that appends the items sequentially. - -Without `array!`: - -```rust - let mut arr = ArrayTrait::new(); - arr.append(1); - arr.append(2); - arr.append(3); - arr.append(4); - arr.append(5); -``` - -With `array!`: - -```rust - let arr = array![1, 2, 3, 4, 5]; -``` - -## Storing Multiple Types with Enums - -If you want to store elements of different types in an array, you can use an `Enum` to define a custom data type that can hold multiple types. Enums will be explained in more detail in the ["Enums and Pattern Matching"][enums] chapter. - -```rust -#[derive(Copy, Drop)] -enum Data { - Integer: u128, - Felt: felt252, - Tuple: (u32, u32), -} - -fn main() { - let mut messages: Array = array![]; - messages.append(Data::Integer(100)); - messages.append(Data::Felt('hello world')); - messages.append(Data::Tuple((10, 30))); -} -``` - -[enums]: ./ch06-00-enums-and-pattern-matching.md - -## Span - -`Span` is a struct that represents a snapshot of an `Array`. It is designed to provide safe and controlled access to the elements of an array without modifying the original array. Span is particularly useful for ensuring data integrity and avoiding borrowing issues when passing arrays between functions or when performing read-only operations, as introduced in ["References and Snapshots"][references]. - -All methods provided by `Array` can also be used with `Span`, except for the `append()` method. - -[references]: ./ch04-02-references-and-snapshots.md - -### Turning an Array into Span - -To create a `Span` of an `Array`, call the `span()` method: - -```rust -# fn main() { -# let mut array: Array = ArrayTrait::new(); - array.span(); -# } -``` - -{{#quiz ../quizzes/ch03-01-arrays.toml}} -# Dictionaries - -Cairo provides in its core library a dictionary-like type. The `Felt252Dict` data type represents a collection of key-value pairs where each key is unique and associated with a corresponding value. This type of data structure is known differently across different programming languages such as maps, hash tables, associative arrays and many others. - -The `Felt252Dict` type is useful when you want to organize your data in a certain way for which using an `Array` and indexing doesn't suffice. Cairo dictionaries also allow the programmer to easily simulate the existence of mutable memory when there is none. - -## Basic Use of Dictionaries - -It is normal in other languages when creating a new dictionary to define the data types of both key and value. In Cairo, the key type is restricted to `felt252`, leaving only the possibility to specify the value data type, represented by `T` in `Felt252Dict`. - -The core functionality of a `Felt252Dict` is implemented in the trait `Felt252DictTrait` which includes all basic operations. Among them we can find: - -1. `insert(felt252, T) -> ()` to write values to a dictionary instance and -2. `get(felt252) -> T` to read values from it. - -These functions allow us to manipulate dictionaries like in any other language. In the following example, we create a dictionary to represent a mapping between individuals and their balance: - -```rust -fn main() { - let mut balances: Felt252Dict = Default::default(); - - balances.insert('Alex', 100); - balances.insert('Maria', 200); - - let alex_balance = balances.get('Alex'); - assert!(alex_balance == 100, "Balance is not 100"); - - let maria_balance = balances.get('Maria'); - assert!(maria_balance == 200, "Balance is not 200"); -} -``` - -We can create a new instance of `Felt252Dict` by using the `default` method of the `Default` trait and add two individuals, each one with their own balance, using the `insert` method. Finally, we check the balance of our users with the `get` method. These methods are defined in the `Felt252DictTrait` trait in the core library. - -Throughout the book we have talked about how Cairo's memory is immutable, meaning you can only write to a memory cell once but the `Felt252Dict` type represents a way to overcome this obstacle. We will explain how this is implemented later on in ["Dictionaries Underneath"][dict underneath]. - -Building upon our previous example, let us show a code example where the balance of the same user changes: - -```rust -fn main() { - let mut balances: Felt252Dict = Default::default(); - - // Insert Alex with 100 balance - balances.insert('Alex', 100); - // Check that Alex has indeed 100 associated with him - let alex_balance = balances.get('Alex'); - assert!(alex_balance == 100, "Alex balance is not 100"); - - // Insert Alex again, this time with 200 balance - balances.insert('Alex', 200); - // Check the new balance is correct - let alex_balance_2 = balances.get('Alex'); - assert!(alex_balance_2 == 200, "Alex balance is not 200"); -} -``` - -Notice how in this example we added the 'Alex' individual twice, each time using a different balance and each time that we checked for its balance it had the last value inserted! `Felt252Dict` effectively allows us to "rewrite" the stored value for any given key. - -Before heading on and explaining how dictionaries are implemented it is worth mentioning that once you instantiate a `Felt252Dict`, behind the scenes all keys have their associated values initialized as zero. This means that if for example, you tried to get the balance of an inexistent user you will get 0 instead of an error or an undefined value. This also means there is no way to delete data from a dictionary. Something to take into account when incorporating this structure into your code. - -Until this point, we have seen all the basic features of `Felt252Dict` and how it mimics the same behavior as the corresponding data structures in any other language, that is, externally of course. Cairo is at its core a non-deterministic Turing-complete programming language, very different from any other popular language in existence, which as a consequence means that dictionaries are implemented very differently as well! - -In the following sections, we are going to give some insights about `Felt252Dict` inner mechanisms and the compromises that were taken to make them work. After that, we are going to take a look at how to use dictionaries with other data structures as well as use the `entry` method as another way to interact with them. - -[dict underneath]: ./ch03-02-dictionaries.md#dictionaries-underneath - -## Dictionaries Underneath - -One of the constraints of Cairo's non-deterministic design is that its memory system is immutable, so in order to simulate mutability, the language implements `Felt252Dict` as a list of entries. Each of the entries represents a time when a dictionary was accessed for reading/updating/writing purposes. An entry has three fields: - -1. A `key` field that identifies the key for this key-value pair of the dictionary. -2. A `previous_value` field that indicates which previous value was held at `key`. -3. A `new_value` field that indicates the new value that is held at `key`. - -If we try implementing `Felt252Dict` using high-level structures we would internally define it as `Array>` where each `Entry` has information about what key-value pair it represents and the previous and new values it holds. The definition of `Entry` would be: - -```rust,noplayground -struct Entry { - key: felt252, - previous_value: T, - new_value: T, -} -``` - -For each time we interact with a `Felt252Dict`, a new `Entry` will be registered: - -- A `get` would register an entry where there is no change in state, and previous and new values are stored with the same value. -- An `insert` would register a new `Entry` where the `new_value` would be the element being inserted, and the `previous_value` the last element inserted before this. In case it is the first entry for a certain key, then the previous value will be zero. - -The use of this entry list shows how there isn't any rewriting, just the creation of new memory cells per `Felt252Dict` interaction. Let's show an example of this using the `balances` dictionary from the previous section and inserting the users 'Alex' and 'Maria': - -```rust -# struct Entry { -# key: felt252, -# previous_value: T, -# new_value: T, -# } -# -# fn main() { -# let mut balances: Felt252Dict = Default::default(); - balances.insert('Alex', 100_u64); - balances.insert('Maria', 50_u64); - balances.insert('Alex', 200_u64); - balances.get('Maria'); -# } -``` - -These instructions would then produce the following list of entries: - -| key | previous | new | -| :---: | -------- | --- | -| Alex | 0 | 100 | -| Maria | 0 | 50 | -| Alex | 100 | 200 | -| Maria | 50 | 50 | - -Notice that since 'Alex' was inserted twice, it appears twice and the `previous` and `current` values are set properly. Also reading from 'Maria' registered an entry with no change from previous to current values. - -This approach to implementing `Felt252Dict` means that for each read/write operation, there is a scan for the whole entry list in search of the last entry with the same `key`. Once the entry has been found, its `new_value` is extracted and used on the new entry to be added as the `previous_value`. This means that interacting with `Felt252Dict` has a worst-case time complexity of `O(n)` where `n` is the number of entries in the list. - -If you pour some thought into alternate ways of implementing `Felt252Dict` you'd surely find them, probably even ditching completely the need for a `previous_value` field, nonetheless, since Cairo is not your normal language this won't work. -One of the purposes of Cairo is, with the STARK proof system, to generate proofs of computational integrity. This means that you need to verify that program execution is correct and inside the boundaries of Cairo restrictions. One of those boundary checks consists of "dictionary squashing" and that requires information on both previous and new values for every entry. - -## Squashing Dictionaries - -To verify that the proof generated by a Cairo program execution that used a `Felt252Dict` is correct, we need to check that there wasn't any illegal tampering with the dictionary. This is done through a method called `squash_dict` that reviews each entry of the entry list and checks that access to the dictionary remains coherent throughout the execution. - -The process of squashing is as follows: given all entries with certain key `k`, taken in the same order as they were inserted, verify that the ith entry `new_value` is equal to the ith + 1 entry `previous_value`. - -For example, given the following entry list: - -| key | previous | new | -| :-----: | -------- | --- | -| Alex | 0 | 150 | -| Maria | 0 | 100 | -| Charles | 0 | 70 | -| Maria | 100 | 250 | -| Alex | 150 | 40 | -| Alex | 40 | 300 | -| Maria | 250 | 190 | -| Alex | 300 | 90 | - -After squashing, the entry list would be reduced to: - -| key | previous | new | -| :-----: | -------- | --- | -| Alex | 0 | 90 | -| Maria | 0 | 190 | -| Charles | 0 | 70 | - -In case of a change on any of the values of the first table, squashing would have failed during runtime. - -## Dictionary Destruction - -If you run the examples from ["Basic Use of Dictionaries"][basic dictionaries] section, you'd notice that there was never a call to squash dictionary, but the program compiled successfully nonetheless. What happened behind the scene was that squash was called automatically via the `Felt252Dict` implementation of the `Destruct` trait. This call occurred just before the `balance` dictionary went out of scope. - -The `Destruct` trait represents another way of removing instances out of scope apart from `Drop`. The main difference between these two is that `Drop` is treated as a no-op operation, meaning it does not generate new CASM while `Destruct` does not have this restriction. The only type which actively uses the `Destruct` trait is `Felt252Dict`, for every other type `Destruct` and `Drop` are synonyms. You can read more about these traits in [Drop and Destruct][drop destruct] section of Appendix C. - -Later in ["Dictionaries as Struct Members"][dictionaries in structs] section, we will have a hands-on example where we implement the `Destruct` trait for a custom type. - -[basic dictionaries]: ./ch03-02-dictionaries.md#basic-use-of-dictionaries -[drop destruct]: ./appendix-03-derivable-traits.md#drop-and-destruct -[dictionaries in structs]: ./ch11-01-custom-data-structures.html#dictionaries-as-struct-members - -## More Dictionaries - -Up to this point, we have given a comprehensive overview of the functionality of `Felt252Dict` as well as how and why it is implemented in a certain way. If you haven't understood all of it, don't worry because in this section we will have some more examples using dictionaries. - -We will start by explaining the `entry` method which is part of a dictionary basic functionality included in `Felt252DictTrait` which we didn't mention at the beginning. Soon after, we will see examples of how to use `Felt252Dict` with other [complex types][nullable dictionaries values] such as `Array`. - -[nullable dictionaries values]: ./ch03-02-dictionaries.md#dictionaries-of-types-not-supported-natively - -## Entry and Finalize - -In the ["Dictionaries Underneath"][dict underneath] section, we explained how `Felt252Dict` internally worked. It was a list of entries for each time the dictionary was accessed in any manner. It would first find the last entry given a certain `key` and then update it accordingly to whatever operation it was executing. The Cairo language gives us the tools to replicate this ourselves through the `entry` and `finalize` methods. - -The `entry` method comes as part of `Felt252DictTrait` with the purpose of creating a new entry given a certain key. Once called, this method takes ownership of the dictionary and returns the entry to update. The method signature is as follows: - -```rust,noplayground -fn entry(self: Felt252Dict, key: felt252) -> (Felt252DictEntry, T) nopanic -``` - -The first input parameter takes ownership of the dictionary while the second one is used to create the appropriate entry. It returns a tuple containing a `Felt252DictEntry`, which is the type used by Cairo to represent dictionary entries, and a `T` representing the value held previously. -The `nopanic` notation simply indicates that the function is guaranteed to never panic. - -The next thing to do is to update the entry with the new value. For this, we use the `finalize` method which inserts the entry and returns ownership of the dictionary: - -```rust,noplayground -fn finalize(self: Felt252DictEntry, new_value: T) -> Felt252Dict -``` - -This method receives the entry and the new value as parameters, and returns the updated dictionary. - -Let us see an example using `entry` and `finalize`. Imagine we would like to implement our own version of the `get` method from a dictionary. We should then do the following: - -1. Create the new entry to add using the `entry` method. -2. Insert back the entry where the `new_value` equals the `previous_value`. -3. Return the value. - -Implementing our custom get would look like this: - -```rust,noplayground -use core::dict::Felt252DictEntryTrait; - -fn custom_get, +Drop, +Copy>( - ref dict: Felt252Dict, key: felt252 -) -> T { - // Get the new entry and the previous value held at `key` - let (entry, prev_value) = dict.entry(key); - - // Store the value to return - let return_value = prev_value; - - // Update the entry with `prev_value` and get back ownership of the dictionary - dict = entry.finalize(prev_value); - - // Return the read value - return_value -} -``` - -The `ref` keyword means that the ownership of the variable will be given back at the end of -the function. This concept will be explained in more detail in the ["References and Snapshots"][references] section. - -Implementing the `insert` method would follow a similar workflow, except for inserting a new value when finalizing. If we were to implement it, it would look like the following: - -```rust,noplayground -use core::dict::Felt252DictEntryTrait; - -fn custom_insert, +Destruct, +Drop>( - ref dict: Felt252Dict, key: felt252, value: T -) { - // Get the last entry associated with `key` - // Notice that if `key` does not exist, `_prev_value` will - // be the default value of T. - let (entry, _prev_value) = dict.entry(key); - - // Insert `entry` back in the dictionary with the updated value, - // and receive ownership of the dictionary - dict = entry.finalize(value); -} -``` - -As a finalizing note, these two methods are implemented in a similar way to how `insert` and `get` are implemented for `Felt252Dict`. This code shows some example usage: - -```rust -# use core::dict::Felt252DictEntryTrait; -# -# fn custom_get, +Drop, +Copy>( -# ref dict: Felt252Dict, key: felt252 -# ) -> T { -# // Get the new entry and the previous value held at `key` -# let (entry, prev_value) = dict.entry(key); -# -# // Store the value to return -# let return_value = prev_value; -# -# // Update the entry with `prev_value` and get back ownership of the dictionary -# dict = entry.finalize(prev_value); -# -# // Return the read value -# return_value -# } -# -# fn custom_insert, +Destruct, +Drop>( -# ref dict: Felt252Dict, key: felt252, value: T -# ) { -# // Get the last entry associated with `key` -# // Notice that if `key` does not exist, `_prev_value` will -# // be the default value of T. -# let (entry, _prev_value) = dict.entry(key); -# -# // Insert `entry` back in the dictionary with the updated value, -# // and receive ownership of the dictionary -# dict = entry.finalize(value); -# } -# -fn main() { - let mut dict: Felt252Dict = Default::default(); - - custom_insert(ref dict, '0', 100); - - let val = custom_get(ref dict, '0'); - - assert!(val == 100, "Expecting 100"); -} -# -# -``` - -[dict underneath]: ./ch03-02-dictionaries.md#dictionaries-underneath -[references]: ./ch04-02-references-and-snapshots.md - -## Dictionaries of Types not Supported Natively - -One restriction of `Felt252Dict` that we haven't talked about is the trait `Felt252DictValue`. -This trait defines the `zero_default` method which is the one that gets called when a value does not exist in the dictionary. -This is implemented by some common data types, such as most unsigned integers, `bool` and `felt252` - but it is not implemented for more complex types such as arrays, structs (including `u256`), and other types from the core library. -This means that making a dictionary of types not natively supported is not a straightforward task, because you would need to write a couple of trait implementations in order to make the data type a valid dictionary value type. -To compensate this, you can wrap your type inside a `Nullable`. - -`Nullable` is a smart pointer type that can either point to a value or be `null` in the absence of value. It is usually used in Object Oriented Programming Languages when a reference doesn't point anywhere. The difference with `Option` is that the wrapped value is stored inside a `Box` data type. The `Box` type is a smart pointer that allows us to use a dedicated `boxed_segment` memory segment for our data, and access this segment using a pointer that can only be manipulated in one place at a time. See [Smart Pointers Chapter](./ch11-02-smart-pointers.md) for more information. - -Let's show using an example. We will try to store a `Span` inside a dictionary. For that, we will use `Nullable` and `Box`. Also, we are storing a `Span` and not an `Array` because the latter does not implement the `Copy` trait which is required for reading from a dictionary. - -```rust,noplayground -use core::nullable::{NullableTrait, match_nullable, FromNullableResult}; - -fn main() { - // Create the dictionary - let mut d: Felt252Dict>> = Default::default(); - - // Create the array to insert - let a = array![8, 9, 10]; - - // Insert it as a `Span` - d.insert(0, NullableTrait::new(a.span())); - -//... -``` - -In this code snippet, the first thing we did was to create a new dictionary `d`. We want it to hold a `Nullable`. After that, we created an array and filled it with values. - -The last step is inserting the array as a span inside the dictionary. Notice that we do this using the `new` function of the `NullableTrait`. - -Once the element is inside the dictionary, and we want to get it, we follow the same steps but in reverse order. The following code shows how to achieve that: - -```rust,noplayground -//... - - // Get value back - let val = d.get(0); - - // Search the value and assert it is not null - let span = match match_nullable(val) { - FromNullableResult::Null => panic!("No value found"), - FromNullableResult::NotNull(val) => val.unbox(), - }; - - // Verify we are having the right values - assert!(*span.at(0) == 8, "Expecting 8"); - assert!(*span.at(1) == 9, "Expecting 9"); - assert!(*span.at(2) == 10, "Expecting 10"); -} -``` - -Here we: - -1. Read the value using `get`. -2. Verified it is non-null using the `match_nullable` function. -3. Unwrapped the value inside the box and asserted it was correct. - -The complete script would look like this: - -```rust -use core::nullable::{NullableTrait, match_nullable, FromNullableResult}; - -fn main() { - // Create the dictionary - let mut d: Felt252Dict>> = Default::default(); - - // Create the array to insert - let a = array![8, 9, 10]; - - // Insert it as a `Span` - d.insert(0, NullableTrait::new(a.span())); - - // Get value back - let val = d.get(0); - - // Search the value and assert it is not null - let span = match match_nullable(val) { - FromNullableResult::Null => panic!("No value found"), - FromNullableResult::NotNull(val) => val.unbox(), - }; - - // Verify we are having the right values - assert!(*span.at(0) == 8, "Expecting 8"); - assert!(*span.at(1) == 9, "Expecting 9"); - assert!(*span.at(2) == 10, "Expecting 10"); -} - -``` - -## Using Arrays inside Dictionaries - -In the previous section, we explored how to store and retrieve complex types inside a dictionary using `Nullable` and `Box`. Now, let's take a look at how to store an array inside a dictionary and dynamically modify its contents. - -Storing arrays in dictionaries in Cairo is slightly different from storing other types. This is because arrays are more complex data structures that require special handling to avoid issues with memory copying and references. - -First, let's look at how to create a dictionary and insert an array into it. This process is pretty straightforward and follows a similar pattern to inserting other types of data: - -```rust -fn main() { - let arr = array![20, 19, 26]; - let mut dict: Felt252Dict>> = Default::default(); - dict.insert(0, NullableTrait::new(arr)); - println!("Array inserted successfully."); -} -``` - -However, attempting to read an array from the dictionary using the `get` method will result in a compiler error. This is because `get` tries to copy the array in memory, which is not possible for arrays (as we've already mentioned in the [previous section][nullable dictionaries values], `Array` does not implement the `Copy` trait): - -```rust -use core::nullable::{match_nullable, FromNullableResult}; - -fn main() { - let arr = array![20, 19, 26]; - let mut dict: Felt252Dict>> = Default::default(); - dict.insert(0, NullableTrait::new(arr)); - println!("Array: {:?}", get_array_entry(ref dict, 0)); -} - -fn get_array_entry(ref dict: Felt252Dict>>, index: felt252) -> Span { - let val = dict.get(0); // This will cause a compiler error - let arr = match match_nullable(val) { - FromNullableResult::Null => panic!("No value!"), - FromNullableResult::NotNull(val) => val.unbox() - }; - arr.span() -} -``` - -```shell -$ scarb cairo-run - Compiling no_listing_15_dict_of_array_attempt_get v0.1.0 (listings/ch03-common-collections/no_listing_15_dict_of_array_attempt_get/Scarb.toml) -error: Trait has no implementation in context: core::traits::Copy::>> - --> listings/ch03-common-collections/no_listing_15_dict_of_array_attempt_get/src/lib.cairo:12:20 - let val = dict.get(0); // This will cause a compiler error - ^*^ - -error: could not compile `no_listing_15_dict_of_array_attempt_get` due to previous error -error: `scarb metadata` exited with error - -``` - -To correctly read an array from the dictionary, we need to use dictionary entries. This allows us to get a reference to the array value without copying it: - -```rust,noplayground -fn get_array_entry(ref dict: Felt252Dict>>, index: felt252) -> Span { - let (entry, _arr) = dict.entry(index); - let mut arr = _arr.deref_or(array![]); - let span = arr.span(); - dict = entry.finalize(NullableTrait::new(arr)); - span -} -``` - -> Note: We must convert the array to a `Span` before finalizing the entry, because calling `NullableTrait::new(arr)` moves the array, thus making it impossible to return it from the function. - -To modify the stored array, such as appending a new value, we can use a similar approach. The following `append_value` function demonstrates this: - -```rust,noplayground -fn append_value(ref dict: Felt252Dict>>, index: felt252, value: u8) { - let (entry, arr) = dict.entry(index); - let mut unboxed_val = arr.deref_or(array![]); - unboxed_val.append(value); - dict = entry.finalize(NullableTrait::new(unboxed_val)); -} -``` - -In the `append_value` function, we access the dictionary entry, dereference the array, append the new value, and finalize the entry with the updated array. - -> Note: Removing an item from a stored array can be implemented in a similar manner. - -Below is the complete example demonstrating the creation, insertion, reading, and modification of an array in a dictionary: - -```rust -use core::nullable::NullableTrait; -use core::dict::Felt252DictEntryTrait; - -fn append_value(ref dict: Felt252Dict>>, index: felt252, value: u8) { - let (entry, arr) = dict.entry(index); - let mut unboxed_val = arr.deref_or(array![]); - unboxed_val.append(value); - dict = entry.finalize(NullableTrait::new(unboxed_val)); -} - -fn get_array_entry(ref dict: Felt252Dict>>, index: felt252) -> Span { - let (entry, _arr) = dict.entry(index); - let mut arr = _arr.deref_or(array![]); - let span = arr.span(); - dict = entry.finalize(NullableTrait::new(arr)); - span -} - -fn main() { - let arr = array![20, 19, 26]; - let mut dict: Felt252Dict>> = Default::default(); - dict.insert(0, NullableTrait::new(arr)); - println!("Before insertion: {:?}", get_array_entry(ref dict, 0)); - - append_value(ref dict, 0, 30); - - println!("After insertion: {:?}", get_array_entry(ref dict, 0)); -} -``` - -{{#quiz ../quizzes/ch03-02-dictionaries.toml}} -# Understanding Cairo's Ownership system - -Cairo is a language built around a linear type system that allows us to -statically ensure that in every Cairo program, a value is used exactly once. -This linear type system helps prevent runtime errors by ensuring that operations that could cause such errors, such as writing twice to a memory cell, are detected at compile time. -This is achieved by implementing an ownership system -and forbidding copying and dropping values by default. In this chapter, we’ll -talk about Cairo's ownership system as well as references and snapshots. -# Ownership Using a Linear Type System - -Cairo uses a linear type system. In such a type system, any value (a basic type, a struct, an enum) must be used and must only be used once. 'Used' here means that the value is either _destroyed_ or _moved_. - -_Destruction_ can happen in several ways: - -- a variable goes out of scope. -- a struct is destructured. -- explicit destruction using `destruct()`. - -_Moving_ a value simply means passing that value to another function. - -This results in somewhat similar constraints to the Rust ownership model, but there are some differences. -In particular, the Rust ownership model exists (in part) to avoid data races and concurrent mutable access to a memory value. This is obviously impossible in Cairo since the memory is immutable. -Instead, Cairo leverages its linear type system for two main purposes: - -- Ensuring that all code is provable and thus verifiable. -- Abstracting away the immutable memory of the Cairo VM. - -### Ownership - -In Cairo, ownership applies to _variables_ and not to _values_. A value can safely be referred to by many different variables (even if they are mutable variables), as the value itself is always immutable. -Variables however can be mutable, so the compiler must ensure that constant variables aren't accidentally modified by the programmer. -This makes it possible to talk about ownership of a variable: the owner is the code that can read (and write if mutable) the variable. - -This means that variables (not values) follow similar rules to Rust values: - -- Each variable in Cairo has an owner. -- There can only be one owner at a time. -- When the owner goes out of scope, the variable is destroyed. - -Now that we’re past basic Cairo syntax, we won’t include all the `fn main() {` code in examples, so if you’re following along, make sure to put the following examples inside a main function manually. As a result, our examples will be a bit more concise, letting us focus on the actual details rather than boilerplate code. - -## Variable Scope - -As a first example of the linear type system, we’ll look at the _scope_ of some variables. A -scope is the range within a program for which an item is valid. Take the -following variable: - -```rust,noplayground -let s = 'hello'; -``` - -The variable `s` refers to a short string. The variable is valid from the point at -which it’s declared until the end of the current _scope_. Listing 4-1 shows a -program with comments annotating where the variable `s` would be valid. - -```rust -# //TAG: ignore_fmt -# fn main() { - { // s is not valid here, it’s not yet declared - let s = 'hello'; // s is valid from this point forward - // do stuff with s - } // this scope is now over, and s is no longer valid -# } -``` - -Listing 4-1: A variable and the scope in which it is valid - -In other words, there are two important points in time here: - -- When `s` comes _into_ scope, it is valid. -- It remains valid until it goes _out of_ scope. - -At this point, the relationship between scopes and when variables are valid is similar to that in other programming languages. Now we’ll build on top of this understanding by using the `Array` type we introduced in the previous ["Arrays"][array] section. - -[array]: ./ch03-01-arrays.md - -### Moving values - -As said earlier, _moving_ a value simply means passing that value to another function. When that happens, the variable referring to that value in the original scope is destroyed and can no longer be used, and a new variable is created to hold the same value. - -Arrays are an example of a complex type that is moved when passing it to another function. -Here is a short reminder of what an array looks like: - -```rust -# fn main() { - let mut arr: Array = array![]; - arr.append(1); - arr.append(2); -# } -``` - -How does the type system ensure that the Cairo program never tries to write to the same memory cell twice? -Consider the following code, where we try to remove the front of the array twice: - -```rust,does_not_compile -fn foo(mut arr: Array) { - arr.pop_front(); -} - -fn main() { - let mut arr: Array = array![]; - foo(arr); - foo(arr); -} -``` - -In this case, we try to pass the same value (the array in the `arr` variable) to both function calls. This means our code tries to remove the first element twice, which would try to write to the same memory cell twice - which is forbidden by the Cairo VM, leading to a runtime error. -Thankfully, this code does not actually compile. Once we have passed the array to the `foo` function, the variable `arr` is no longer usable. We get this compile-time error, telling us that we would need Array to implement the Copy Trait: - -```shell -$ scarb cairo-run - Compiling no_listing_02_pass_array_by_value v0.1.0 (listings/ch04-understanding-ownership/no_listing_02_pass_array_by_value/Scarb.toml) -warn: Unhandled `#[must_use]` type `core::option::Option::` - --> listings/ch04-understanding-ownership/no_listing_02_pass_array_by_value/src/lib.cairo:3:5 - arr.pop_front(); - ^*************^ - -error: Variable was previously moved. - --> listings/ch04-understanding-ownership/no_listing_02_pass_array_by_value/src/lib.cairo:9:9 - foo(arr); - ^*^ -note: variable was previously used here: - --> listings/ch04-understanding-ownership/no_listing_02_pass_array_by_value/src/lib.cairo:8:9 - foo(arr); - ^*^ -note: Trait has no implementation in context: core::traits::Copy::> - -error: could not compile `no_listing_02_pass_array_by_value` due to previous error -error: `scarb metadata` exited with error - -``` - -## The `Copy` Trait - -If a type implements the `Copy` trait, passing a value of that type to a function does not move the value. Instead, a new variable is created, referring to the same value. -The important thing to note here is that this is a completely free operation because variables are a Cairo abstraction only and because _values_ in Cairo are always immutable. This, in particular, conceptually differs from the Rust version of the `Copy` trait, where the value is potentially copied in memory. - -All basic types previously described in ["Data Types"][data types] implement by default the `Copy` trait. - -While Arrays and Dictionaries can't be copied, custom types that don't contain either of them can be. -You can implement the `Copy` trait on your type by adding the `#[derive(Copy)]` annotation to your type definition. However, Cairo won't allow a type to be annotated with Copy if the type itself or any of its components doesn't implement the Copy trait. - -```rust,ignore_format -#[derive(Copy, Drop)] -struct Point { - x: u128, - y: u128, -} - -fn main() { - let p1 = Point { x: 5, y: 10 }; - foo(p1); - foo(p1); -} - -fn foo(p: Point) { // do something with p -} -``` - -In this example, we can pass `p1` twice to the foo function because the `Point` type implements the `Copy` trait. This means that when we pass `p1` to `foo`, we are actually passing a copy of `p1`, so `p1` remains valid. In ownership terms, this means that the ownership of `p1` remains with the `main` function. -If you remove the `Copy` trait derivation from the `Point` type, you will get a compile-time error when trying to compile the code. - -_Don't worry about the `Struct` keyword. We will introduce this in [Chapter 5][structs]._ - -[data types]: ./ch02-02-data-types.md -[structs]: ./ch05-00-using-structs-to-structure-related-data.md - -## Destroying Values - Example with FeltDict - -The other way linear types can be _used_ is by being destroyed. Destruction must ensure that the 'resource' is now correctly released. In Rust, for example, this could be closing the access to a file, or locking a mutex. -In Cairo, one type that has such behaviour is `Felt252Dict`. For provability, dicts must be 'squashed' when they are destructed. -This would be very easy to forget, so it is enforced by the type system and the compiler. - -### No-op Destruction: the `Drop` Trait - -You may have noticed that the `Point` type in the previous example also implements the `Drop` trait. -For example, the following code will not compile, because the struct `A` is not moved or destroyed before it goes out of scope: - -```rust,does_not_compile -struct A {} - -fn main() { - A {}; // error: Variable not dropped. -} -``` - -However, types that implement the `Drop` trait are automatically destroyed when going out of scope. This destruction does nothing, it is a no-op - simply a hint to the compiler that this type can safely be destroyed once it's no longer useful. We call this "dropping" a value. - -At the moment, the `Drop` implementation can be derived for all types, allowing them to be dropped when going out of scope, except for dictionaries (`Felt252Dict`) and types containing dictionaries. -For example, the following code compiles: - -```rust -#[derive(Drop)] -struct A {} - -fn main() { - A {}; // Now there is no error. -} -``` - -### Destruction with a Side-effect: the `Destruct` Trait - -When a value is destroyed, the compiler first tries to call the `drop` method on that type. If it doesn't exist, then the compiler tries to call `destruct` instead. This method is provided by the `Destruct` trait. - -As said earlier, dictionaries in Cairo are types that must be "squashed" when destructed, so that the sequence of access can be proven. This is easy for developers to forget, so instead dictionaries implement the `Destruct` trait to ensure that all dictionaries are _squashed_ when going out of scope. -As such, the following example will not compile: - -```rust,does_not_compile -struct A { - dict: Felt252Dict -} - -fn main() { - A { dict: Default::default() }; -} -``` - -If you try to run this code, you will get a compile-time error: - -```shell -$ scarb cairo-run - Compiling no_listing_06_no_destruct_compile_fails v0.1.0 (listings/ch04-understanding-ownership/no_listing_06_no_destruct_compile_fails/Scarb.toml) -error: Variable not dropped. - --> listings/ch04-understanding-ownership/no_listing_06_no_destruct_compile_fails/src/lib.cairo:7:5 - A { dict: Default::default() }; - ^****************************^ -note: Trait has no implementation in context: core::traits::Drop:: -note: Trait has no implementation in context: core::traits::Destruct:: - -error: could not compile `no_listing_06_no_destruct_compile_fails` due to previous error -error: `scarb metadata` exited with error - -``` - -When `A` goes out of scope, it can't be dropped as it implements neither the `Drop` (as it contains a dictionary and can't `derive(Drop)`) nor the `Destruct` trait. To fix this, we can derive the `Destruct` trait implementation for the `A` type: - -```rust -#[derive(Destruct)] -struct A { - dict: Felt252Dict -} - -fn main() { - A { dict: Default::default() }; // No error here -} -``` - -Now, when `A` goes out of scope, its dictionary will be automatically `squashed`, and the program will compile. - -## Copy Array Data with `clone` - -If we _do_ want to deeply copy the data of an `Array`, we can use a common method called `clone`. We’ll discuss method syntax in a dedicated section in [Chapter 5][method syntax], but because methods are a common feature in many programming languages, you’ve probably seen them before. - -Here’s an example of the `clone` method in action. - -```rust -fn main() { - let arr1: Array = array![]; - let arr2 = arr1.clone(); -} -``` - -When you see a call to `clone`, you know that some arbitrary code is being executed and that code may be expensive. It’s a visual indicator that something different is going on. -In this case, the _value_ `arr1` refers to is being copied, resulting in new memory cells being used, and a new _variable_ `arr2` is created, referring to the new copied value. - -[method syntax]: ./ch05-03-method-syntax.md - -## Return Values and Scope - -Returning values is equivalent to _moving_ them. Listing 4-2 shows an example of a -function that returns some value, with similar annotations as those in Listing 4-1. - -Filename: src/lib.cairo - -```rust -#[derive(Drop)] -struct A {} - -fn main() { - let a1 = gives_ownership(); // gives_ownership moves its return - // value into a1 - - let a2 = A {}; // a2 comes into scope - - let a3 = takes_and_gives_back(a2); // a2 is moved into - // takes_and_gives_back, which also - // moves its return value into a3 - -} // Here, a3 goes out of scope and is dropped. a2 was moved, so nothing - // happens. a1 goes out of scope and is dropped. - -fn gives_ownership() -> A { // gives_ownership will move its - // return value into the function - // that calls it - - let some_a = A {}; // some_a comes into scope - - some_a // some_a is returned and - // moves ownership to the calling - // function -} - -// This function takes an instance some_a of A and returns it -fn takes_and_gives_back(some_a: A) -> A { // some_a comes into scope - - some_a // some_a is returned and - // moves ownership to the calling - // function -} -``` - -Listing 4-2: Moving return values - -While this works, moving into and out of every function is a bit tedious. What if we want to let a function use a value but not move the value? It’s quite annoying that anything we pass in also needs to be passed back if we want to use it again, in addition to any data resulting from the body of the function that we might want to return as well. - -Cairo does let us return multiple values using a tuple, as shown in Listing 4-3. - -Filename: src/lib.cairo - -```rust -fn main() { - let arr1: Array = array![]; - - let (arr2, len) = calculate_length(arr1); -} - -fn calculate_length(arr: Array) -> (Array, usize) { - let length = arr.len(); // len() returns the length of an array - - (arr, length) -} -``` - -Listing 4-3: Returning many values - -But this is too much ceremony and a lot of work for a concept that should be common. Luckily for us, Cairo has two features for passing a value without destroying or moving it, called _references_ and _snapshots_. -# References and Snapshots - -The issue with the tuple code in previous Listing 4-3 is that we have to return the -`Array` to the calling function so we can still use the `Array` after the -call to `calculate_length`, because the `Array` was moved into -`calculate_length`. - -## Snapshots - -In the previous chapter, we talked about how Cairo's ownership system prevents -us from using a variable after we've moved it, protecting us from potentially -writing twice to the same memory cell. However, it's not very convenient. -Let's see how we can retain ownership of the variable in the calling function using snapshots. - -In Cairo, a snapshot is an immutable view of a value at a certain point in time. -Recall that memory is immutable, so modifying a value actually creates a new memory cell. -The old memory cell still exists, and snapshots are variables that refer to that "old" value. -In this sense, snapshots are a view "into the past". - -Here is how you would define and use a `calculate_length` function that takes a -snapshot of an array as a parameter instead of taking ownership of the underlying value. In this example, -the `calculate_length` function returns the length of the array passed as a parameter. -As we're passing it as a snapshot, which is an immutable view of the array, we can be sure that -the `calculate_length` function will not mutate the array, and ownership of the array is kept in the `main` function. - -Filename: src/lib.cairo - -```rust -fn main() { - let mut arr1: Array = array![]; - let first_snapshot = @arr1; // Take a snapshot of `arr1` at this point in time - arr1.append(1); // Mutate `arr1` by appending a value - let first_length = calculate_length( - first_snapshot - ); // Calculate the length of the array when the snapshot was taken - let second_length = calculate_length(@arr1); // Calculate the current length of the array - println!("The length of the array when the snapshot was taken is {}", first_length); - println!("The current length of the array is {}", second_length); -} - -fn calculate_length(arr: @Array) -> usize { - arr.len() -} -``` - -> Note: it is only possible to call the `len()` method on an array snapshot because it is defined as such in the `ArrayTrait` trait. If you try to call a method that is not defined for snapshots on a snapshot, you will get a compilation error. However, you can call methods expecting a snapshot on non-snapshot types. - -The output of this program is: - -```shell -$ scarb cairo-run - Compiling no_listing_09_snapshots v0.1.0 (listings/ch04-understanding-ownership/no_listing_09_snapshots/Scarb.toml) - Finished release target(s) in 1 second - Running no_listing_09_snapshots -The length of the array when the snapshot was taken is 0 -The current length of the array is 1 -Run completed successfully, returning [] - -``` - -First, notice that all the tuple code in the variable declaration and the function return value is gone. Second, note -that we pass `@arr1` into `calculate_length` and, in its definition, we take `@Array` rather than `Array`. - -Let’s take a closer look at the function call here: - -```rust -let second_length = calculate_length(@arr1); // Calculate the current length of the array -``` - -The `@arr1` syntax lets us create a snapshot of the value in `arr1`. Because a snapshot is an immutable view of a value at a specific point in time, the usual rules of the linear type system are not enforced. In particular, snapshot variables always implement the `Drop` trait, never the `Destruct` trait, even dictionary snapshots. - -Similarly, the signature of the function uses `@` to indicate that the type of the parameter `arr` is a snapshot. Let’s add some explanatory annotations: - -```rust, noplayground -fn calculate_length( - array_snapshot: @Array // array_snapshot is a snapshot of an Array -) -> usize { - array_snapshot.len() -} // Here, array_snapshot goes out of scope and is dropped. -// However, because it is only a view of what the original array `arr` contains, the original `arr` can still be used. -``` - -The scope in which the variable `array_snapshot` is valid is the same as any function parameter’s scope, but the underlying value of the snapshot is not dropped when `array_snapshot` stops being used. When functions have snapshots as parameters instead of the actual values, we won’t need to return the values in order to give back ownership of the original value, because we never had it. - -### Desnap Operator - -To convert a snapshot back into a regular variable, you can use the `desnap` operator `*`, which serves as the opposite of the `@` operator. - -Only `Copy` types can be desnapped. However, in the general case, because the value is not modified, the new variable created by the `desnap` operator reuses the old value, and so desnapping is a completely free operation, just like `Copy`. - -In the following example, we want to calculate the area of a rectangle, but we don't want to take ownership of the rectangle in the `calculate_area` function, because we might want to use the rectangle again after the function call. Since our function doesn't mutate the rectangle instance, we can pass the snapshot of the rectangle to the function, and then transform the snapshots back into values using the `desnap` operator `*`. - -```rust -#[derive(Drop)] -struct Rectangle { - height: u64, - width: u64, -} - -fn main() { - let rec = Rectangle { height: 3, width: 10 }; - let area = calculate_area(@rec); - println!("Area: {}", area); -} - -fn calculate_area(rec: @Rectangle) -> u64 { - // As rec is a snapshot to a Rectangle, its fields are also snapshots of the fields types. - // We need to transform the snapshots back into values using the desnap operator `*`. - // This is only possible if the type is copyable, which is the case for u64. - // Here, `*` is used for both multiplying the height and width and for desnapping the snapshots. - *rec.height * *rec.width -} -``` - -But, what happens if we try to modify something we’re passing as a snapshot? Try the code in -Listing 4-4. Spoiler alert: it doesn’t work! - -Filename: src/lib.cairo - -```rust,does_not_compile -#[derive(Copy, Drop)] -struct Rectangle { - height: u64, - width: u64, -} - -fn main() { - let rec = Rectangle { height: 3, width: 10 }; - flip(@rec); -} - -fn flip(rec: @Rectangle) { - let temp = rec.height; - rec.height = rec.width; - rec.width = temp; -} -``` - - -Listing 4-4: Attempting to modify a snapshot value - -Here’s the error: - -```shell -$ scarb cairo-run - Compiling listing_04_04 v0.1.0 (listings/ch04-understanding-ownership/listing_04_attempt_modifying_snapshot/Scarb.toml) -error: Invalid left-hand side of assignment. - --> listings/ch04-understanding-ownership/listing_04_attempt_modifying_snapshot/src/lib.cairo:15:5 - rec.height = rec.width; - ^********^ - -error: Invalid left-hand side of assignment. - --> listings/ch04-understanding-ownership/listing_04_attempt_modifying_snapshot/src/lib.cairo:16:5 - rec.width = temp; - ^*******^ - -error: could not compile `listing_04_04` due to previous error -error: `scarb metadata` exited with error - -``` - -The compiler prevents us from modifying values associated to snapshots. - -## Mutable References - -We can achieve the behavior we want in Listing 4-4 by using a _mutable reference_ instead of a snapshot. Mutable references are actually mutable values passed to a function that are implicitly returned at the end of the function, returning ownership to the calling context. By doing so, they allow you to mutate the value passed while keeping ownership of it by returning it automatically at the end of the execution. -In Cairo, a parameter can be passed as _mutable reference_ using the `ref` modifier. - -> **Note**: In Cairo, a parameter can only be passed as _mutable reference_ using the `ref` modifier if the variable is declared as mutable with `mut`. - -In Listing 4-5, we use a mutable reference to modify the value of the `height` and `width` fields of the `Rectangle` instance in the `flip` function. - -```rust -#[derive(Drop)] -struct Rectangle { - height: u64, - width: u64, -} - -fn main() { - let mut rec = Rectangle { height: 3, width: 10 }; - flip(ref rec); - println!("height: {}, width: {}", rec.height, rec.width); -} - -fn flip(ref rec: Rectangle) { - let temp = rec.height; - rec.height = rec.width; - rec.width = temp; -} -``` - -Listing 4-5: Use of a mutable reference to modify a value - -First, we change `rec` to be `mut`. Then we pass a mutable reference of `rec` into `flip` with `ref rec`, and update the function signature to accept a mutable reference with `ref rec: Rectangle`. This makes it very clear that the `flip` function will mutate the value of the `Rectangle` instance passed as parameter. - -The output of the program is: - -```shell -$ scarb cairo-run - Compiling listing_04_05 v0.1.0 (listings/ch04-understanding-ownership/listing_05_mutable_reference/Scarb.toml) - Finished release target(s) in 1 second - Running listing_04_05 -height: 10, width: 3 -Run completed successfully, returning [] - -``` - -As expected, the `height` and `width` fields of the `rec` variable have been swapped. - -{{#quiz ../quizzes/ch04-02-references-and-snapshots.toml}} - -## Small Recap - -Let’s recap what we’ve discussed about the linear type system, ownership, snapshots, and references: - -- At any given time, a variable can only have one owner. -- You can pass a variable by-value, by-snapshot, or by-reference to a function. -- If you pass-by-value, ownership of the variable is transferred to the function. -- If you want to keep ownership of the variable and know that your function won’t mutate it, you can pass it as a snapshot with `@`. -- If you want to keep ownership of the variable and know that your function will mutate it, you can pass it as a mutable reference with `ref`. -# Using Structs to Structure Related Data - -A struct, or structure, is a custom data type that lets you package together and name multiple related values that make up a meaningful group. If you’re familiar with an object-oriented language, a struct is like an object’s data attributes. In this chapter, we’ll compare and contrast tuples with structs to build on what you already know and demonstrate when structs are a better way to group data. - -We’ll demonstrate how to define and instantiate structs. We’ll discuss how to define associated functions, especially the kind of associated functions called methods, to specify behavior associated with a struct type. Structs and enums (discussed in the [next chapter](ch06-01-enums.md)) are the building blocks for creating new types in your program’s domain to take full advantage of Cairo's compile-time type checking. -# Defining and Instantiating Structs - -Structs are similar to tuples, discussed in the [Data Types](ch02-02-data-types.md) section, in that both hold multiple related values. Like tuples, the pieces of a struct can be different types. Unlike with tuples, in a struct you’ll name each piece of data so it’s clear what the values mean. Adding these names means that structs are more flexible than tuples: you don’t have to rely on the order of the data to specify or access the values of an instance. - -To define a struct, we enter the keyword `struct` and name the entire struct. A struct’s name should describe the significance of the pieces of data being grouped together. Then, inside curly brackets, we define the names and types of the pieces of data, which we call fields. For example, Listing 5-1 shows a struct that stores information about a user account. - -Filename: src/lib.cairo - -```rust, noplayground -#[derive(Drop)] -struct User { - active: bool, - username: ByteArray, - email: ByteArray, - sign_in_count: u64, -} -``` - - -Listing 5-1: A `User` struct definition - -To use a struct after we’ve defined it, we create an _instance_ of that struct by specifying concrete values for each of the fields. -We create an instance by stating the name of the struct and then add curly brackets containing _key: value_ pairs, where the keys are the names of the fields and the values are the data we want to store in those fields. We don’t have to specify the fields in the same order in which we declared them in the struct. In other words, the struct definition is like a general template for the type, and instances fill in that template with particular data to create values of the type. - -For example, we can declare two particular users as shown in Listing 5-2. - -Filename: src/lib.cairo - -```rust -#[derive(Drop)] -struct User { - active: bool, - username: ByteArray, - email: ByteArray, - sign_in_count: u64, -} - -fn main() { - let user1 = User { - active: true, username: "someusername123", email: "someone@example.com", sign_in_count: 1 - }; - let user2 = User { - sign_in_count: 1, username: "someusername123", active: true, email: "someone@example.com" - }; -} - -``` - -Listing 5-2: Creating two instances of the `User` struct - -To get a specific value from a struct, we use dot notation. For example, to access `user1`'s email address, we use `user1.email`. If the instance is mutable, we can change a value by using the dot notation and assigning into a particular field. Listing 5-3 shows how to change the value in the `email` field of a mutable `User` instance. - -Filename: src/lib.cairo - -```rust -# #[derive(Drop)] -# struct User { -# active: bool, -# username: ByteArray, -# email: ByteArray, -# sign_in_count: u64, -# } -fn main() { - let mut user1 = User { - active: true, username: "someusername123", email: "someone@example.com", sign_in_count: 1 - }; - user1.email = "anotheremail@example.com"; -} -# -# fn build_user(email: ByteArray, username: ByteArray) -> User { -# User { active: true, username: username, email: email, sign_in_count: 1, } -# } -# -# fn build_user_short(email: ByteArray, username: ByteArray) -> User { -# User { active: true, username, email, sign_in_count: 1, } -# } -# -# -``` - -Listing 5-3: Changing the value in the email field of a `User` instance - -Note that the entire instance must be mutable; Cairo doesn’t allow us to mark only certain fields as mutable. - -As with any expression, we can construct a new instance of the struct as the last expression in the function body to implicitly return that new instance. - -Listing 5-4 shows a `build_user` function that returns a `User` instance with the given email and username. The `active` field gets the value of `true`, and the `sign_in_count` gets a value of `1`. - -Filename: src/lib.cairo - -```rust -# #[derive(Drop)] -# struct User { -# active: bool, -# username: ByteArray, -# email: ByteArray, -# sign_in_count: u64, -# } -# fn main() { -# let mut user1 = User { -# active: true, username: "someusername123", email: "someone@example.com", sign_in_count: 1 -# }; -# user1.email = "anotheremail@example.com"; -# } -# -fn build_user(email: ByteArray, username: ByteArray) -> User { - User { active: true, username: username, email: email, sign_in_count: 1, } -} -# -# fn build_user_short(email: ByteArray, username: ByteArray) -> User { -# User { active: true, username, email, sign_in_count: 1, } -# } -# -# -``` - -Listing 5-4: A `build_user` function that takes an email and username and returns a `User` instance. - -It makes sense to name the function parameters with the same name as the struct fields, but having to repeat the `email` and `username` field names and variables is a bit tedious. If the struct had more fields, repeating each name would get even more annoying. Luckily, there’s a convenient shorthand! - -## Using the Field Init Shorthand - -Because the parameter names and the struct field names are exactly the same in Listing 5-4, we can use the field init shorthand syntax to rewrite `build_user` so it behaves exactly the same but doesn’t have the repetition of `username` and `email`, as shown in Listing 5-5. - -Filename: src/lib.cairo - -```rust -# #[derive(Drop)] -# struct User { -# active: bool, -# username: ByteArray, -# email: ByteArray, -# sign_in_count: u64, -# } -# fn main() { -# let mut user1 = User { -# active: true, username: "someusername123", email: "someone@example.com", sign_in_count: 1 -# }; -# user1.email = "anotheremail@example.com"; -# } -# -# fn build_user(email: ByteArray, username: ByteArray) -> User { -# User { active: true, username: username, email: email, sign_in_count: 1, } -# } -# -fn build_user_short(email: ByteArray, username: ByteArray) -> User { - User { active: true, username, email, sign_in_count: 1, } -} -# -# -``` - -Listing 5-5: A `build_user` function that uses field init shorthand because the `username` and `email` parameters have the same name as struct fields. - -Here, we’re creating a new instance of the `User` struct, which has a field named `email`. We want to set the `email` field’s value to the value in the `email` parameter of the `build_user` function. Because the `email` field and the `email` parameter have the same name, we only need to write `email` rather than `email: email`. - -## Creating Instances from Other Instances with Struct Update Syntax - -It’s often useful to create a new instance of a struct that includes most of -the values from another instance, but changes some. You can do this using -_struct update syntax_. - -First, in Listing 5-6 we show how to create a new `User` instance in `user2` -regularly, without the update syntax. We set a new value for `email` but -otherwise use the same values from `user1` that we created in Listing 5-2. - -Filename: src/lib.cairo - -```rust -# #[derive(Drop)] -# struct User { -# active: bool, -# username: ByteArray, -# email: ByteArray, -# sign_in_count: u64, -# } -# -fn main() { - // --snip-- -# -# let user1 = User { -# email: "someone@example.com", username: "someusername123", active: true, sign_in_count: 1, -# }; - - let user2 = User { - active: user1.active, - username: user1.username, - email: "another@example.com", - sign_in_count: user1.sign_in_count, - }; -} -# -# -``` - - -Listing 5-6: Creating a new `User` instance using all but one of the values from `user1` - -Using struct update syntax, we can achieve the same effect with less code, as -shown in Listing 5-7. The syntax `..` specifies that the remaining fields not -explicitly set should have the same value as the fields in the given instance. - -Filename: src/lib.cairo - -```rust -# use core::byte_array; -# #[derive(Drop)] -# struct User { -# active: bool, -# username: ByteArray, -# email: ByteArray, -# sign_in_count: u64, -# } -# -fn main() { - // --snip-- -# -# let user1 = User { -# email: "someone@example.com", username: "someusername123", active: true, sign_in_count: 1, -# }; - - let user2 = User { email: "another@example.com", ..user1 }; -} -# -# -``` - - -Listing 5-7: Using struct update syntax to set a new -`email` value for a `User` instance but to use the rest of the values from `user1` - -The code in Listing 5-7 also creates an instance of `user2` that has a -different value for `email` but has the same values for the `username`, -`active`, and `sign_in_count` fields as `user1`. The `..user1` part must come last -to specify that any remaining fields should get their values from the -corresponding fields in `user1`, but we can choose to specify values for as -many fields as we want in any order, regardless of the order of the fields in -the struct’s definition. - -Note that the struct update syntax uses `=` like an assignment; this is because it moves the data, -just as we saw in the ["Moving Values"][move] section. In this example, we can no -longer use `user1` as a whole after creating `user2` because the `ByteArray` in the -`username` field of `user1` was moved into `user2`. If we had given `user2` new -`ByteArray` values for both `email` and `username`, and thus only used the -`active` and `sign_in_count` values from `user1`, then `user1` would still be -valid after creating `user2`. Both `active` and `sign_in_count` are types that -implement the `Copy` trait, so the behavior we discussed in the ["`Copy` Trait"][copy] section would apply. - -{{#quiz ../quizzes/ch05-01-defining-and-instantiating-structs.toml}} - -[move]: ch04-01-what-is-ownership.md#moving-values -[copy]: ch04-01-what-is-ownership.md#the-copy-trait -# An Example Program Using Structs - -To understand when we might want to use structs, let’s write a program that calculates the area of a rectangle. We’ll start by using single variables, and then refactor the program until we’re using structs instead. - -Let’s make a new project with Scarb called _rectangles_ that will take the width and height of a rectangle specified in pixels and calculate the area of the rectangle. Listing 5-8 shows a short program with one way of doing exactly that in our project’s _src/lib.cairo_. - -Filename: src/lib.cairo - -```rust -fn main() { - let width = 30; - let height = 10; - let area = area(width, height); - println!("Area is {}", area); -} - -fn area(width: u64, height: u64) -> u64 { - width * height -} -``` - -Listing 5-8: Calculating the area of a rectangle specified by separate width and height variables. - -Now run the program with `scarb cairo-run`: - -```shell -$ scarb cairo-run - Compiling listing_04_06_no_struct v0.1.0 (listings/ch05-using-structs-to-structure-related-data/listing_03_no_struct/Scarb.toml) - Finished release target(s) in 1 second - Running listing_04_06_no_struct -Area is 300 -Run completed successfully, returning [] - -``` - -This code succeeds in figuring out the area of the rectangle by calling the `area` function with each dimension, but we can do more to make this code clear and readable. - -The issue with this code is evident in the signature of `area`: - -```rust,noplayground -fn area(width: u64, height: u64) -> u64 { -``` - -The `area` function is supposed to calculate the area of one rectangle, but the function we wrote has two parameters, and it’s not clear anywhere in our program that the parameters are related. It would be more readable and more manageable to group width and height together. We’ve already discussed one way we might do that in the [Tuple Section of Chapter 2](ch02-02-data-types.html#the-tuple-type). - -## Refactoring with Tuples - -Listing 5-9 shows another version of our program that uses tuples. - -Filename: src/lib.cairo - -```rust -fn main() { - let rectangle = (30, 10); - let area = area(rectangle); - println!("Area is {}", area); -} - -fn area(dimension: (u64, u64)) -> u64 { - let (x, y) = dimension; - x * y -} -``` - -Listing 5-9: Specifying the width and height of the rectangle with a tuple. - -In one way, this program is better. Tuples let us add a bit of structure, and we’re now passing just one argument. But in another way, this version is less clear: tuples don’t name their elements, so we have to index into the parts of the tuple, making our calculation less obvious. - -Mixing up the width and height wouldn’t matter for the area calculation, but if we want to calculate the difference, it would matter! We would have to keep in mind that `width` is the tuple index `0` and `height` is the tuple index `1`. This would be even harder for someone else to figure out and keep in mind if they were to use our code. Because we haven’t conveyed the meaning of our data in our code, it’s now easier to introduce errors. - -## Refactoring with Structs: Adding More Meaning - -We use structs to add meaning by labeling the data. We can transform the tuple we’re using into a struct with a name for the whole as well as names for the parts. - -Filename: src/lib.cairo - -```rust -struct Rectangle { - width: u64, - height: u64, -} - -fn main() { - let rectangle = Rectangle { width: 30, height: 10, }; - let area = area(rectangle); - println!("Area is {}", area); -} - -fn area(rectangle: Rectangle) -> u64 { - rectangle.width * rectangle.height -} -``` - -Listing 5-10: Defining a `Rectangle` struct. - -Here we’ve defined a struct and named it `Rectangle`. Inside the curly brackets, we defined the fields as `width` and `height`, both of which have type `u64`. Then, in `main`, we created a particular instance of `Rectangle` that has a width of `30` and a height of `10`. Our `area` function is now defined with one parameter, which we’ve named `rectangle` which is of type `Rectangle` struct. We can then access the fields of the instance with dot notation, and it gives descriptive names to the values rather than using the tuple index values of `0` and `1`. - -{{#quiz ../quizzes/ch05-02-an-example-program-using-structs.toml}} -# Method Syntax - -_Methods_ are similar to functions: we declare them with the `fn` keyword and a name, they can have parameters and a return value, and they contain some code that’s run when the method is called from somewhere else. Unlike functions, methods are defined within the context of a struct (or an enum which we cover in [Chapter 6][enums]), and their first parameter is always `self`, which represents the instance of the type the method is being called on. - -## Defining Methods - -Let’s change the `area` function that has a `Rectangle` instance as a parameter and instead make an `area` method defined on the `Rectangle` struct, as shown in Listing 5-11 - -```rust, noplayground -#[derive(Copy, Drop)] -struct Rectangle { - width: u64, - height: u64, -} - -trait RectangleTrait { - fn area(self: @Rectangle) -> u64; -} - -impl RectangleImpl of RectangleTrait { - fn area(self: @Rectangle) -> u64 { - (*self.width) * (*self.height) - } -} - -fn main() { - let rect1 = Rectangle { width: 30, height: 50, }; - println!("Area is {}", rect1.area()); -} -``` - -Listing 5-11: Defining an `area` method on the `Rectangle` struct. - -To define the function within the context of `Rectangle`, we start an `impl` (implementation) block for a trait `RectangleTrait` that defines the methods that can be called on a `Rectangle` instance. As impl blocks can only be defined for traits and not types, we need to define this trait first - but it's not meant to be used for anything else. - -Everything within this `impl` block will be associated with the `Rectangle` type. Then we move the `area` function within the `impl` curly brackets and change the first (and in this case, only) parameter to be `self` in the signature and everywhere within the body. In `main`, where we called the `area` function and passed `rect1` as an argument, we can instead use _method syntax_ to call the `area` method on our `Rectangle` instance. The method syntax goes after an instance: we add a dot followed by the method name, parentheses, and any arguments. - -In the signature for `area`, we use `self: @Rectangle` instead of `rectangle: @Rectangle`. -Methods must have a parameter named `self`, for their first parameter, and the type of `self` indicates the type that method can be called on. Methods can take ownership of `self`, but `self` can also be passed by snapshot or by reference, just like any other parameter. - -> There is no direct link between a type and a trait. Only the type of the `self` parameter of a method defines the type from which this method can be called. That means, it is technically possible to define methods on multiple types in a same trait (mixing `Rectangle` and `Circle` methods, for example). But **this is not a recommended practice** as it can lead to confusion. - -The main reason for using methods instead of functions, in addition to providing method syntax, is for organization. We’ve put all the things we can do with an instance of a type in one `impl` block rather than making future users of our code search for capabilities of `Rectangle` in various places in the library we provide. - -## The `generate_trait` Attribute - -If you are familiar with Rust, you may find Cairo's approach confusing because methods cannot be defined directly on types. Instead, you must define a [trait](./ch08-02-traits-in-cairo.md) and an implementation of this trait associated with the type for which the method is intended. -However, defining a trait and then implementing it to define methods on a specific type is verbose, and unnecessary: the trait itself will not be reused. - -So, to avoid defining useless traits, Cairo provides the `#[generate_trait]` attribute to add above a trait implementation, which tells to the compiler to generate the corresponding trait definition for you, and let's you focus on the implementation only. Both approaches are equivalent, but it's considered a best practice to not explicitly define traits in this case. - -The previous example can also be written as follows: - -```rust -#[derive(Copy, Drop)] -struct Rectangle { - width: u64, - height: u64, -} - -#[generate_trait] -impl RectangleImpl of RectangleTrait { - fn area(self: @Rectangle) -> u64 { - (*self.width) * (*self.height) - } -} - -fn main() { - let rect1 = Rectangle { width: 30, height: 50, }; - println!("Area is {}", rect1.area()); -} - -``` - -Let's use this `#[generate_trait]` in the following chapters to make our code cleaner. - -## Snapshots and References - -As the `area` method does not modify the calling instance, `self` is declared as a snapshot of a `Rectangle` instance with the `@` snapshot operator. But, of course, we can also define some methods receiving a mutable reference of this instance, to be able to modify it. - -Let's write a new method `scale` which resizes a rectangle of a `factor` given as parameter: - -```rust -#[generate_trait] -impl RectangleImpl of RectangleTrait { - fn area(self: @Rectangle) -> u64 { - (*self.width) * (*self.height) - } - fn scale(ref self: Rectangle, factor: u64) { - self.width *= factor; - self.height *= factor; - } -} - -fn main() { - let mut rect2 = Rectangle { width: 10, height: 20 }; - rect2.scale(2); - println!("The new size is (width: {}, height: {})", rect2.width, rect2.height); -} -``` - -It is also possible to define a method which takes ownership of the instance by using just `self` as the first parameter but it is rare. This technique is usually used when the method transforms `self` into something else and you want to prevent the caller from using the original instance after the transformation. - -Look at the [Understanding Ownership](ch04-00-understanding-ownership.md) chapter for more details about these important notions. - -## Methods with Several Parameters - -Let’s practice using methods by implementing another method on the `Rectangle` struct. This time we want to write the method `can_hold` which accepts another instance of `Rectangle` and returns `true` if this rectangle can fit completely within self; otherwise, it should return false. - -```rust -#[generate_trait] -impl RectangleImpl of RectangleTrait { - fn area(self: @Rectangle) -> u64 { - *self.width * *self.height - } - - fn scale(ref self: Rectangle, factor: u64) { - self.width *= factor; - self.height *= factor; - } - - fn can_hold(self: @Rectangle, other: @Rectangle) -> bool { - *self.width > *other.width && *self.height > *other.height - } -} - -fn main() { - let rect1 = Rectangle { width: 30, height: 50, }; - let rect2 = Rectangle { width: 10, height: 40, }; - let rect3 = Rectangle { width: 60, height: 45, }; - - println!("Can rect1 hold rect2? {}", rect1.can_hold(@rect2)); - println!("Can rect1 hold rect3? {}", rect1.can_hold(@rect3)); -} -``` - -Here, we expect that `rect1` can hold `rect2` but not `rect3`. - -## Associated functions - -We call _associated functions_ all functions that are defined inside an `impl` block that are associated to a specific type. While this is not enforced by the compiler, it is a good practice to keep associated functions related to the same type in the same `impl` block - for example, all functions related to `Rectangle` will be grouped in the same `impl` block for `RectangleTrait`. - -Methods are a special kind of associated function, but we can also define associated functions that don’t have `self` as their first parameter (and thus are not methods) because they don’t need an instance of the type to work with, but are still associated with that type. - -Associated functions that aren’t methods are often used for constructors that -will return a new instance of the type. These are often called `new`, but -`new` isn’t a special name and isn’t built into the language. For example, we -could choose to provide an associated function named `square` that would have -one dimension parameter and use that as both width and height, thus making it -easier to create a square `Rectangle` rather than having to specify the same -value twice: - -Let's create the function `new` which creates a `Rectangle` from a `width` and a `height`, `square` which creates a square `Rectangle` from a `size` and `avg` which computes the average of two `Rectangle` instances: - -```rust -#[generate_trait] -impl RectangleImpl of RectangleTrait { - fn area(self: @Rectangle) -> u64 { - (*self.width) * (*self.height) - } - - fn new(width: u64, height: u64) -> Rectangle { - Rectangle { width, height } - } - - fn square(size: u64) -> Rectangle { - Rectangle { width: size, height: size } - } - - fn avg(lhs: @Rectangle, rhs: @Rectangle) -> Rectangle { - Rectangle { - width: ((*lhs.width) + (*rhs.width)) / 2, height: ((*lhs.height) + (*rhs.height)) / 2 - } - } -} - -fn main() { - let rect1 = RectangleTrait::new(30, 50); - let rect2 = RectangleTrait::square(10); - - println!( - "The average Rectangle of {:?} and {:?} is {:?}", - @rect1, - @rect2, - RectangleTrait::avg(@rect1, @rect2) - ); -} -``` - -To call the `square` associated function, we use the `::` syntax with the struct name; -`let sq = Rectangle::square(3);` is an example. This function is namespaced by -the struct: the `::` syntax is used for both associated functions and -namespaces created by modules. We’ll discuss modules in [Chapter -7][modules]. - -Note that the `avg` function could also be written as a method with `self` as the first rectangle. In this case, instead of using the method with `RectangleTrait::avg(@rect1, @rect2)`, it would be called with `rect1.avg(rect2)`. - -## Multiple Traits and `impl` Blocks - -Each struct is allowed to have multiple `trait` and `impl` blocks. For example, -the following code is equivalent to the code shown in the _Methods with several parameters_ section, which has each method in its own `trait` and `impl` blocks. - -```rust -#[generate_trait] -impl RectangleCalcImpl of RectangleCalc { - fn area(self: @Rectangle) -> u64 { - (*self.width) * (*self.height) - } -} - -#[generate_trait] -impl RectangleCmpImpl of RectangleCmp { - fn can_hold(self: @Rectangle, other: @Rectangle) -> bool { - *self.width > *other.width && *self.height > *other.height - } -} -``` - -There’s no strong reason to separate these methods into multiple `trait` and `impl` -blocks here, but this is valid syntax. - -{{#quiz ../quizzes/ch05-03-method-syntax.toml}} - -[enums]: ./ch06-01-enums.md -[modules]: ./ch07-02-defining-modules-to-control-scope.md -# Enums and Pattern Matching - -In this chapter, we’ll look at _enumerations_, also referred to as _enums_. -Enums allow you to define a type by enumerating its possible _variants_. First, -we’ll define and use an enum to show how an enum can encode meaning along with -data. Next, we’ll explore a particularly useful enum, called `Option`, which -expresses that a value can be either something or nothing. Finally, we’ll look at -how pattern matching in the `match` expression makes it easy to run different -code for different values of an enum. -# Enums - -Enums, short for "enumerations," are a way to define a custom data type that consists of a fixed set of named values, called _variants_. Enums are useful for representing a collection of related values where each value is distinct and has a specific meaning. - -## Enum Variants and Values - -Here's a simple example of an enum: - -```rust, noplayground -#[derive(Drop)] -enum Direction { - North, - East, - South, - West, -} -``` - -In this example, we've defined an enum called `Direction` with four variants: `North`, `East`, `South`, and `West`. The naming convention is to use PascalCase for enum variants. Each variant represents a distinct value of the `Direction` type. In this particular example, variants don't have any associated value. One variant can be instantiated using this syntax: - -```rust, noplayground -# #[derive(Drop)] -# enum Direction { -# North, -# East, -# South, -# West, -# } -# -# fn main() { - let direction = Direction::North; -# } -# -``` - -Now let's imagine that our variants have associated values, that store the exact degree of the direction. We can define a new `Direction` enum: - -```rust, noplayground -#[derive(Drop)] -enum Direction { - North: u128, - East: u128, - South: u128, - West: u128, -} -# -# fn main() { -# let direction = Direction::North(10); -# } -``` - -and instantiate it as follows: - -```rust, noplayground -# #[derive(Drop)] -# enum Direction { -# North: u128, -# East: u128, -# South: u128, -# West: u128, -# } -# -# fn main() { - let direction = Direction::North(10); -# } -``` - -In this code, each variant is associated with a `u128` value, representing the direction in degrees. In the next example, we will see that it is also possible to associate different data types with each variant. - -It's easy to write code that acts differently depending on the variant of an enum instance, in this example to run specific code according to a direction. You can learn more about it in the [Match Control Flow Construct][match] section. - -[match]: ./ch06-02-the-match-control-flow-construct.md - -## Enums Combined with Custom Types - -Enums can also be used to store more interesting custom data associated with each variant. For example: - -```rust, noplayground -#[derive(Drop)] -enum Message { - Quit, - Echo: felt252, - Move: (u128, u128), -} -``` - -In this example, the `Message` enum has three variants: `Quit`, `Echo`, and `Move`, all with different types: - -- `Quit` doesn't have any associated value. -- `Echo` is a single `felt252`. -- `Move` is a tuple of two `u128` values. - -You could even use a Struct or another enum you defined inside one of your enum variants. - -## Trait Implementations for Enums - -In Cairo, you can define traits and implement them for your custom enums. This allows you to define methods and behaviors associated with the enum. Here's an example of defining a trait and implementing it for the previous `Message` enum: - -```rust, noplayground -trait Processing { - fn process(self: Message); -} - -impl ProcessingImpl of Processing { - fn process(self: Message) { - match self { - Message::Quit => { println!("quitting") }, - Message::Echo(value) => { println!("echoing {}", value) }, - Message::Move((x, y)) => { println!("moving from {} to {}", x, y) }, - } - } -} -``` - -In this example, we implemented the `Processing` trait for `Message`. Here is how it could be used to process a Quit message: - -```rust, noplayground -# -# #[derive(Drop)] -# enum Message { -# Quit, -# Echo: felt252, -# Move: (u128, u128), -# } -# -# trait Processing { -# fn process(self: Message); -# } -# -# impl ProcessingImpl of Processing { -# fn process(self: Message) { -# match self { -# Message::Quit => { println!("quitting") }, -# Message::Echo(value) => { println!("echoing {}", value) }, -# Message::Move((x, y)) => { println!("moving from {} to {}", x, y) }, -# } -# } -# } -# fn main() { - let msg: Message = Message::Quit; - msg.process(); -# } -# -# -``` - -Running this code would print `quitting`. - -## The `Option` Enum and Its Advantages - -The `Option` enum is a standard Cairo enum that represents the concept of an optional value. It has two variants: `Some: T` and `None`. `Some: T` indicates that there's a value of type `T`, while `None` represents the absence of a value. - -```rust,noplayground -enum Option { - Some: T, - None, -} -``` - -The `Option` enum is helpful because it allows you to explicitly represent the possibility of a value being absent, making your code more expressive and easier to reason about. Using `Option` can also help prevent bugs caused by using uninitialized or unexpected `null` values. - -To give you an example, here is a function which returns the index of the first element of an array with a given value, or `None` if the element is not present. - -We are demonstrating two approaches for the above function: - -- Recursive approach with `find_value_recursive`. -- Iterative approach with `find_value_iterative`. - -```rust,noplayground -fn find_value_recursive(mut arr: Span, value: felt252, index: usize) -> Option { - match arr.pop_front() { - Option::Some(index_value) => { if (*index_value == value) { - return Option::Some(index); - } }, - Option::None => { return Option::None; }, - }; - - find_value_recursive(arr, value, index + 1) -} - -fn find_value_iterative(mut arr: Span, value: felt252) -> Option { - let mut result = Option::None; - let mut index = 0; - - while let Option::Some(array_value) = arr - .pop_front() { - if (*array_value == value) { - result = Option::Some(index); - break; - }; - - index += 1; - }; - - result -} -``` - -Enums can be useful in many situations, especially when using the `match` flow construct that we just used. We will describe it in the next section. - -Other enums are used very often, such as the `Result` enum, allowing to handle errors gracefully. We will explain the `Result` enum in detail in the ["Error Handling"][result enum] chapter. - -{{#quiz ../quizzes/ch06-01-enums.toml}} - -[result enum]: ./ch09-02-recoverable-errors.md#the-result-enum -# The Match Control Flow Construct - -Cairo has an extremely powerful control flow construct called `match` that allows you to compare a value against a series of patterns and then execute code based on which pattern matches. Patterns can be made up of literal values, variable names, wildcards, and many other things. The power of `match` comes from the expressiveness of the patterns and the fact that the compiler confirms that all possible cases are handled. - -Think of a `match` expression as being like a coin-sorting machine: coins slide down a track with variously sized holes along it, and each coin falls through the first hole it encounters that it fits into. In the same way, values go through each pattern in a match, and at the first pattern the value “fits”, the value falls into the associated code block to be used during execution. - -Speaking of coins, let’s use them as an example using `match`! We can write a function that takes an unknown US coin and, in a similar way as the counting machine, determines which coin it is and returns its value in cents, as shown in Listing 6-1. - -```rust,noplayground -enum Coin { - Penny, - Nickel, - Dime, - Quarter, -} - -fn value_in_cents(coin: Coin) -> felt252 { - match coin { - Coin::Penny => 1, - Coin::Nickel => 5, - Coin::Dime => 10, - Coin::Quarter => 25, - } -} -``` - -Listing 6-1: An enum and a `match` expression that has the variants of the enum as its patterns - -Let’s break down the `match` expression in the `value_in_cents` function. First, we list the `match` keyword followed by an expression, which in this case is the value `coin`. This seems very similar to a conditional expression used with the `if` statement, but there’s a big difference: with `if`, the condition needs to evaluate to a boolean value, but here it can be any type. The type of `coin` in this example is the `Coin` enum that we defined on the first line. - -Next are the `match` arms. An arm has two parts: a pattern and some code. The first arm here has a pattern that is the value `Coin::Penny` and then the `=>` operator that separates the pattern and the code to run. The code in this case is just the value `1`. Each arm is separated from the next with a comma. - -When the `match` expression executes, it compares the resultant value against the pattern of each arm, in the order they are given. If a pattern matches the value, the code associated with that pattern is executed. If that pattern doesn’t match the value, execution continues to the next arm, much as in a coin-sorting machine. We can have as many arms as we need: in the above example, our `match` has four arms. - -The code associated with each arm is an expression, and the resultant value of the expression in the matching arm is the value that gets returned for the entire match expression. - -We don’t typically use curly brackets if the `match` arm code is short, as it is in our example where each arm just returns a value. If you want to run multiple lines of code in a `match` arm, you must use curly brackets, with a comma following the arm. For example, the following code prints “Lucky penny!” every time the method is called with a `Coin::Penny`, but still returns the last value of the block, `1`: - -```rust,noplayground -fn value_in_cents(coin: Coin) -> felt252 { - match coin { - Coin::Penny => { - println!("Lucky penny!"); - 1 - }, - Coin::Nickel => 5, - Coin::Dime => 10, - Coin::Quarter => 25, - } -} -``` - -## Patterns That Bind to Values - -Another useful feature of `match` arms is that they can bind to the parts of the values that match the pattern. This is how we can extract values out of enum variants. - -As an example, let’s change one of our enum variants to hold data inside it. From 1999 through 2008, the United States minted quarters with different designs for each of the 50 states on one side. No other coins got state designs, so only quarters have this extra value. We can add this information to our `enum` by changing the `Quarter` variant to include a `UsState` value stored inside it, which we’ve done in Listing 6-2. - -```rust,noplayground - -#[derive(Drop, Debug)] // Debug so we can inspect the state in a minute -enum UsState { - Alabama, - Alaska, -} - -#[derive(Drop)] -enum Coin { - Penny, - Nickel, - Dime, - Quarter: UsState, -} -``` - -Listing 6-2: A `Coin` enum in which the `Quarter` variant also holds a `UsState` value - -Let’s imagine that a friend is trying to collect all 50 state quarters. While we sort our loose change by coin type, we’ll also call out the name of the state associated with each quarter so that if it’s one our friend doesn’t have, they can add it to their collection. - -In the `match` expression for this code, we add a variable called `state` to the pattern that matches values of the variant `Coin::Quarter`. When a `Coin::Quarter` matches, the `state` variable will bind to the value of that quarter’s state. Then we can use `state` in the code for that arm, like so: - -```rust,noplayground -fn value_in_cents(coin: Coin) -> felt252 { - match coin { - Coin::Penny => 1, - Coin::Nickel => 5, - Coin::Dime => 10, - Coin::Quarter(state) => { - println!("State quarter from {:?}!", state); - 25 - } - } -} -``` - -Because `state` is an `UsState` enum which implements the `Debug` trait, we can print `state` value with `println!` macro. - -> Note: `{:?}` is a special formatting syntax that allows to print a debug form of the parameter passed to the `println!` macro. You can find more information about it in [Appendix C][debug trait]. - -If we were to call `value_in_cents(Coin::Quarter(UsState::Alaska))`, `coin` would be `Coin::Quarter(UsState::Alaska)`. When we compare that value with each of the match arms, none of them match until we reach `Coin::Quarter(state)`. At that point, the binding for `state` will be the value `UsState::Alaska`. We can then use that binding in `println!` macro, thus getting the inner state value out of the `Coin` enum variant for `Quarter`. - -[debug trait]: ./appendix-03-derivable-traits.html#debug-for-printing-and-debugging - -## Matching with `Option` - -In the previous section, we wanted to get the inner `T` value out of the `Some` case when using `Option`; we can also handle `Option` using `match`, as we did with the `Coin` enum! Instead of comparing coins, we’ll compare the variants of `Option`, but the way the `match` expression works remains the same. - -Let’s say we want to write a function that takes an `Option` and, if there’s a value inside, adds `1` to that value. If there is no value inside, the function should return the `None` value and not attempt to perform any operations. - -This function is very easy to write, thanks to `match`, and will look like Listing 6-3. - -```rust -fn plus_one(x: Option) -> Option { - match x { - Option::Some(val) => Option::Some(val + 1), - Option::None => Option::None, - } -} - -fn main() { - let five: Option = Option::Some(5); - let six: Option = plus_one(five); - let none = plus_one(Option::None); -} -``` - -Listing 6-3: A function that uses a `match` expression on an `Option` - -Let’s examine the first execution of `plus_one` in more detail. When we call `plus_one(five)`, the variable `x` in the body of `plus_one` will have the value `Some(5)`. We then compare that against each `match` arm: - -```rust,noplayground - Option::Some(val) => Option::Some(val + 1), -``` - -Does `Option::Some(5)` value match the pattern `Option::Some(val)`? It does! We have the same variant. The `val` binds to the value contained in `Option::Some`, so `val` takes the value `5`. The code in the `match` arm is then executed, so we add `1` to the value of `val` and create a new `Option::Some` value with our total `6` inside. Because the first arm matched, no other arms are compared. - -Now let’s consider the second call of `plus_one` in our main function, where `x` is `Option::None`. We enter the `match` and compare to the first arm: - -```rust,noplayground - Option::Some(val) => Option::Some(val + 1), -``` - -The `Option::Some(val)` value doesn’t match the pattern `Option::None`, so we continue to the next arm: - -```rust - Option::None => Option::None, -``` - -It matches! There’s no value to add to, so the matching construct ends and returns the `Option::None` value on the right side of `=>`. - -Combining `match` and enums is useful in many situations. You’ll see this pattern a lot in Cairo code: `match` against an enum, bind a variable to the data inside, and then execute code based on it. It’s a bit tricky at first, but once you get used to it, you’ll wish you had it in all languages. It’s consistently a user favorite. - -## Matches Are Exhaustive - -There’s one other aspect of `match` we need to discuss: the arms’ patterns must cover all possibilities. Consider this version of our `plus_one` function, which has a bug and won’t compile: - -```rust,noplayground -fn plus_one(x: Option) -> Option { - match x { - Option::Some(val) => Option::Some(val + 1), - } -} -``` - -We didn’t handle the `None` case, so this code will cause a bug. -Luckily, it’s a bug Cairo knows how to catch. If we try to compile this code, we’ll get this error: - -```shell -$ scarb cairo-run - Compiling no_listing_08_missing_match_arm v0.1.0 (listings/ch06-enums-and-pattern-matching/no_listing_09_missing_match_arm/Scarb.toml) -error: Missing match arm: `None` not covered. - --> listings/ch06-enums-and-pattern-matching/no_listing_09_missing_match_arm/src/lib.cairo:5:5 - match x { - ^*******^ - -error: could not compile `no_listing_08_missing_match_arm` due to previous error -error: `scarb metadata` exited with error - -``` - -Cairo knows that we didn’t cover every possible case, and even knows which pattern we forgot! Matches in Cairo are exhaustive: we must exhaust every last possibility in order for the code to be valid. Especially in the case of `Option`, when Cairo prevents us from forgetting to explicitly handle the `None` case, it protects us from assuming that we have a value when we might have null, thus making the [billion-dollar mistake][null pointer] discussed earlier impossible. - -[null pointer]: https://en.wikipedia.org/wiki/Null_pointer#History - -## Catch-all with the `_` Placeholder - -Using enums, we can also take special actions for a few particular values, but for all other values take one default action. -`_` is a special pattern that matches any value and does not bind to that value. -You can use it by simply adding a new arm with `_` as the pattern for the last arm of the `match` expression. - -Imagine we have a vending machine that only accepts Dime coins. -We want to have a function that processes inserted coins and returns `true` only if the coin is accepted. - -Here's a `vending_machine_accept` function that implements this logic: - -```rust,noplayground -fn vending_machine_accept(coin: Coin) -> bool { - match coin { - Coin::Dime => true, - _ => false, - } -} -``` - -This example also meets the exhaustiveness requirement because we’re explicitly ignoring all other values in the last arm; we haven’t forgotten anything. - -> There's no catch-all pattern in Cairo that allows you to use the value of the pattern. - - - -## Multiple Patterns with the `|` Operator - -In `match` expressions, you can match multiple patterns using the `|` syntax, which is the pattern _or_ operator. - -For example, in the following code we modified the `vending_machine_accept` function to accept both `Dime` and `Quarter` coins in a single arm: - -```rust,noplayground -fn vending_machine_accept(coin: Coin) -> bool { - match coin { - Coin::Dime | Coin::Quarter => true, - _ => false, - } -} -``` - -## Matching Tuples - -It is possible to match tuples. -Let's introduce a new `DayType` enum: - -```rust,noplayground -#[derive(Drop)] -enum DayType { - Week, - Weekend, - Holiday -} -``` - -Now, let's suppose that our vending machine accepts any coin on weekdays, but only accepts quarters and dimes on weekends and holidays. -We can modify the `vending_machine_accept` function to accept a tuple of a `Coin` and a `Weekday` and return `true` only if the given coin is accepted on the specified day: - -```rust,noplayground -fn vending_machine_accept(c: (DayType, Coin)) -> bool { - match c { - (DayType::Week, _) => true, - (_, Coin::Dime) | (_, Coin::Quarter) => true, - (_, _) => false, - } -} -``` - -Writing `(_, _)` for the last arm of a tuple matching pattern might feel superfluous. Hence, we can use the `_ =>` syntax if we want, for example, that our vending machine only accepts quarters on weekdays: - -```rust,noplayground -fn vending_week_machine(c: (DayType, Coin)) -> bool { - match c { - (DayType::Week, Coin::Quarter) => true, - _ => false, - } -} -``` - -## Matching `felt252` and Integer Variables - -You can also match `felt252` and integer variables. This is useful when you want to match against a range of values. -However, there are some restrictions: - -- Only integers that fit into a single `felt252` are supported (i.e. `u256` is not supported). -- The first arm must be 0. -- Each arm must cover a sequential segment, contiguously with other arms. - -Imagine we’re implementing a game where you roll a six-sided die to get a number between 0 and 5. -If you have 0, 1 or 2 you win. If you have 3, you can roll again. For all other values you lose. - -Here's a match that implements that logic: - -```rust,noplayground -fn roll(value: u8) { - match value { - 0 | 1 | 2 => println!("you won!"), - 3 => println!("you can roll again!"), - _ => println!("you lost...") - } -} -``` - -{{#quiz ../quizzes/ch06-02-match.toml}} - -> These restrictions are planned to be relaxed in future versions of Cairo. -# Concise Control Flow with `if let` and `while let` - -## `if let` - -The `if let` syntax lets you combine `if` and `let` into a less verbose way to handle values that match one pattern while ignoring the rest. Consider the program in Listing 6-4 that matches on an `Option::Some` value in the `config_max` variable but only wants to execute code if the value is `Option::Some` variant. - -```rust -# fn main() { - let config_max = Option::Some(5); - match config_max { - Option::Some(max) => println!("The maximum is configured to be {}", max), - _ => (), - } -# } -``` - -Listing 6-4: A `match` that only cares about executing -code when the value is `Option::Some` - -If the value is `Option::Some`, we print out the value in the `Option::Some` variant by binding -the value to the variable `max` in the pattern. We don’t want to do anything -with the `None` value. To satisfy the `match` expression, we have to add `_ => -()` after processing just one variant, which is annoying boilerplate code to -add. - -Instead, we could write this in a shorter way using `if let`. The following -code behaves the same as the `match` in Listing 6-4: - -```rust -# fn main() { - let number = Option::Some(5); - if let Option::Some(max) = number { - println!("The maximum is configured to be {}", max); - } -# } -# -``` - -The syntax `if let` takes a pattern and an expression separated by an equal -sign. It works the same way as a `match`, where the expression is given to the -`match` and the pattern is its first arm. In this case, the pattern is -`Option::Some(max)`, and `max` binds to the value inside `Option::Some`. We can then -use `max` in the body of the `if let` block in the same way we used `max` in -the corresponding `match` arm. The code in the `if let` block isn’t run if the -value doesn’t match the pattern. - -Using `if let` means less typing, less indentation, and less boilerplate code. -However, you lose the exhaustive checking that `match` enforces. Choosing -between `match` and `if let` depends on what you’re doing in your particular -situation and whether gaining conciseness is an appropriate trade-off for -losing exhaustive checking. - -In other words, you can think of `if let` as syntactic sugar for a `match` that -runs code when the value matches one pattern and then ignores all other values. - -We can include an `else` with an `if let`. The block of code that goes with `else` -is the same as the block of code that would go with the `_` case in the `match` -expression. Recall the `Coin` enum definition in Listing 6-2, -where the `Quarter` variant also held a `UsState` value. If we wanted to count -all non-quarter coins we see while also announcing the state of the quarters, -we could do that with a `match` expression, like this: - -```rust -# #[derive(Drop)] -# enum Coin { -# Penny, -# Nickel, -# Dime, -# Quarter, -# } -# -# fn main() { - let coin = Coin::Quarter; - let mut count = 0; - match coin { - Coin::Quarter => println!("You got a quarter!"), - _ => count += 1, - } -# } -``` - -Or we could use an `if let` and `else` expression, like this: - -```rust -# #[derive(Drop)] -# enum Coin { -# Penny, -# Nickel, -# Dime, -# Quarter, -# } -# -# fn main() { - let coin = Coin::Quarter; - let mut count = 0; - if let Coin::Quarter = coin { - println!("You got a quarter!"); - } else { - count += 1; - } -# println!("{}", count); -# } -# -``` - -If you have a situation in which your program has logic that is too verbose to -express using `match`, remember that `if let` is in your Cairo toolbox as well. - -## `while let` - -The `while let` syntax is similar to the `if let` syntax, but it allows you to loop over a collection of values and execute a block of code for each value that matches a specified pattern. In the case below, the pattern is `Option::Some(x)`, which matches any `Some` variant of the `Option` enum. - -```rust -fn main() { - let mut arr = array![1, 2, 3, 4, 5, 6, 7, 8, 9]; - let mut sum = 0; - while let Option::Some(value) = arr.pop_front() { - sum += value; - }; - println!("{}", sum); -} -``` - -Using `while let` provides a more concise and idiomatic way of writing this loop compared to a traditional `while` loop with explicit pattern matching or handling of the `Option` type. However, as with `if let`, you lose the exhaustive checking that a `match` expression provides, so you need to be careful to handle any remaining cases outside the `while let` loop if necessary. -# Managing Cairo Projects with Packages, Crates and Modules - -As you write large programs, organizing your code will become increasingly -important. By grouping related functionality and separating code with distinct -features, you’ll clarify where to find code that implements a particular -feature and where to go to change how a feature works. - -The programs we’ve written so far have been in one module in one file. As a -project grows, you should organize code by splitting it into multiple modules -and then multiple files. As a package grows, you can extract parts into -separate crates that become external dependencies. This chapter covers all -these techniques. - -We’ll also discuss encapsulating implementation details, which lets you reuse -code at a higher level: once you’ve implemented an operation, other code can -call your code without having to know how the -implementation works. - -A related concept is scope: the nested context in which code is written has a -set of names that are defined as “in scope”. When reading, writing, and -compiling code, programmers and compilers need to know whether a particular -name at a particular spot refers to a variable, function, struct, enum, module, -constant, or other item and what that item means. You can create scopes and -change which names are in or out of scope. You can’t have two items with the -same name in the same scope. - -Cairo has a number of features that allow you to manage your code’s -organization. These features, sometimes -collectively referred to as the _module system_, include: - -- **Packages:** A Scarb feature that lets you build, test, and share crates. -- **Crates:** A tree of modules that corresponds to a single compilation unit. - It has a root directory, and a root module defined at the _lib.cairo_ file under this directory. -- **Modules** and **use:** Let you control the organization and scope of items. -- **Paths:** A way of naming an item, such as a struct, function, or module. - -In this chapter, we’ll cover all these features, discuss how they interact, and -explain how to use them to manage scope. By the end, you should have a solid -understanding of the module system and be able to work with scopes like a pro! -# Packages and Crates - -## What is a Crate? - -A crate is a subset of a package that is used in the actual Cairo compilation. This includes: - -- The package source code, identified by the package name and the crate root, which is the main entry point of the package. -- A subset of the package metadata that identifies crate-level settings of the Cairo compiler, for example, the `edition` field in the _Scarb.toml_ file. - -Crates can contain modules, and the modules may be defined in other files that get compiled with the crate, as will be discussed in the subsequent sections. - -## What is the Crate Root? - -The crate root is the _lib.cairo_ source file that the Cairo compiler starts from and makes up the root module of your crate. We’ll explain modules in depth in the ["Defining Modules to Control Scope"][modules] chapter. - -[modules]: ./ch07-02-defining-modules-to-control-scope.md - -## What is a Package? - -A Cairo package is a directory (or equivalent) containing: - -- A _Scarb.toml_ manifest file with a `[package]` section. -- Associated source code. - -This definition implies that a package might contain other packages, with a corresponding _Scarb.toml_ file for each package. - -## Creating a Package with Scarb - -You can create a new Cairo package using the Scarb command-line tool. To create a new package, run the following command: - -```bash -scarb new my_package -``` - -This command will generate a new package directory named _my_package_ with the following structure: - -``` -my_package/ -├── Scarb.toml -└── src - └── lib.cairo -``` - -- _src/_ is the main directory where all the Cairo source files for the package will be stored. -- _lib.cairo_ is the default root module of the crate, which is also the main entry point of the package. -- _Scarb.toml_ is the package manifest file, which contains metadata and configuration options for the package, such as dependencies, package name, version, and authors. You can find documentation about it on the [Scarb reference][manifest]. - -```toml -[package] -name = "my_package" -version = "0.1.0" -edition = "2023_11" - -[dependencies] -# foo = { path = "vendor/foo" } -``` - -As you develop your package, you may want to organize your code into multiple Cairo source files. You can do this by creating additional _.cairo_ files within the _src_ directory or its subdirectories. - -{{#quiz ../quizzes/ch07-01-packages-crates.toml}} - -[manifest]: https://docs.swmansion.com/scarb/docs/reference/manifest.html -# Defining Modules to Control Scope - -In this section, we’ll talk about modules and other parts of the module system, -namely _paths_ that allow you to name items and the `use` keyword that brings a -path into scope. - -First, we’re going to start with a list of rules for easy reference when you’re -organizing your code in the future. Then we’ll explain each of the rules in -detail. - -## Modules Cheat Sheet - -Here we provide a quick reference on how modules, paths and the `use` keyword -work in the compiler, and how most developers organize their -code. We’ll be going through examples of each of these rules throughout this -chapter, but this is a great place to refer to as a reminder of how modules -work. You can create a new Scarb project with `scarb new backyard` to follow along. - -- **Start from the crate root**: When compiling a crate, the compiler first - looks in the crate root file (_src/lib.cairo_) for code to compile. -- **Declaring modules**: In the crate root file, you can declare new modules; - say, you declare a “garden” module with `mod garden;`. The compiler will look - for the module’s code in these places: - - - Inline, within curly brackets that replace the semicolon following `mod garden`. - - ```rust,noplayground - // crate root file (src/lib.cairo) - mod garden { - // code defining the garden module goes here - } - ``` - - - In the file _src/garden.cairo_. - -- **Declaring submodules**: In any file other than the crate root, you can - declare submodules. For example, you might declare `mod vegetables;` in - _src/garden.cairo_. The compiler will look for the submodule’s code within the - directory named for the parent module in these places: - - - Inline, directly following `mod vegetables`, within curly brackets instead - of the semicolon. - - ```rust,noplayground - // src/garden.cairo file - mod vegetables { - // code defining the vegetables submodule goes here - } - ``` - - - In the file _src/garden/vegetables.cairo_. - -- **Paths to code in modules**: Once a module is part of your crate, you can - refer to code in that module from anywhere else in that same crate, using the path - to the code. For example, an `Asparagus` type in the `vegetables` submodule would be found at - `backyard::garden::vegetables::Asparagus`. -- **Private vs public**: Code within a module is private from its parent modules by default. This means that it may only be - accessed by the current module and its descendants. To make a module public, declare it with `pub mod` instead of `mod`. To make items within a public module public as well, use `pub` before their declarations. Cairo also provides the `pub(crate)` keyword, allowing an item or module to be only visible within the crate in which the definition is included. -- **The `use` keyword**: Within a scope, the `use` keyword creates shortcuts to - items to reduce repetition of long paths. In any scope that can refer to - `backyard::garden::vegetables::Asparagus`, you can create a shortcut with - `use backyard::garden::vegetables::Asparagus;` and from then on you only need to - write `Asparagus` to make use of that type in the scope. - -Here we create a crate named `backyard` that illustrates these rules. The -crate’s directory, also named `backyard`, contains these files and directories: - -```text -backyard/ -├── Scarb.toml -└── src - ├── garden - │   └── vegetables.cairo - ├── garden.cairo - └── lib.cairo -``` - -The crate root file in this case is _src/lib.cairo_, and it contains: - -Filename: src/lib.cairo - -```rust -pub mod garden; -use garden::vegetables::Asparagus; - -fn main() { - let plant = Asparagus {}; - println!("I'm growing {:?}!", plant); -} -``` - -The `pub mod garden;` line imports the `garden` module. Using `pub` to make `garden` publicly accessible, or `pub(crate)` if you really want to make `garden` only available for your crate, is optional to run our program here, as the `main` function resides in the same module as `pub mod garden;` declaration. Nevertheless, not declaring `garden` as `pub` will make it not accessible from any other package. -This line tells the compiler to include the code it finds in _src/garden.cairo_, which is: - -Filename: src/garden.cairo - -```rust,noplayground -pub mod vegetables; -``` - -Here, `pub mod vegetables;` means the code in *src/garden/vegetables.cairo* is included too. That code is: - -```rust,noplayground -#[derive(Drop, Debug)] -pub struct Asparagus {} -``` - -The line `use garden::vegetables::Asparagus;` lets us bring the `Asparagus` type into scope, -so we can use it in the `main` function. - -Now let’s get into the details of these rules and demonstrate them in action! - -## Grouping Related Code in Modules - -_Modules_ let us organize code within a crate for readability and easy reuse. -Modules also allow us to control the privacy of items, because code within a module -is private by default. Private items are internal implementation details not -available for outside use. We can choose to make modules and the items within -them public, which exposes them to allow external code to use and depend on them. - -As an example, let’s write a library crate that provides the functionality of a -restaurant. We’ll define the signatures of functions but leave their bodies -empty to concentrate on the organization of the code, rather than the -implementation of a restaurant. - -In the restaurant industry, some parts of a restaurant are referred to as -_front of house_ and others as _back of house_. Front of house is where -customers are; this encompasses where the hosts seat customers, servers take -orders and payment, and bartenders make drinks. Back of house is where the -chefs and cooks work in the kitchen, dishwashers clean up, and managers do -administrative work. - -To structure our crate in this way, we can organize its functions into nested -modules. Create a new package named _restaurant_ by running `scarb new restaurant`; then enter the code in Listing 7-1 into _src/lib.cairo_ to -define some modules and function signatures. Here’s the front of house section: - -Filename: src/lib.cairo - -```rust,noplayground -mod front_of_house { - mod hosting { - fn add_to_waitlist() {} - - fn seat_at_table() {} - } - - mod serving { - fn take_order() {} - - fn serve_order() {} - - fn take_payment() {} - } -} -``` - -Listing 7-1: A `front_of_house` module containing other modules that then contain functions - -We define a module with the `mod` keyword followed by the name of the module -(in this case, `front_of_house`). The body of the module then goes inside curly -brackets. Inside modules, we can place other modules, as in this case with the -modules `hosting` and `serving`. Modules can also hold definitions for other -items, such as structs, enums, constants, traits, and functions. - -By using modules, we can group related definitions together and name why -they’re related. Programmers using this code can navigate the code based on the -groups rather than having to read through all the definitions, making it easier -to find the definitions relevant to them. Programmers adding new functionality -to this code would know where to place the code to keep the program organized. - -Earlier, we mentioned that _src/lib.cairo_ is called the crate -root. The reason for this name is that the content of this file forms a module named after the crate name at the root of the crate’s module structure, known as the _module tree_. - -Listing 7-2 shows the module tree for the structure in Listing 7-1. - -```text -restaurant - └── front_of_house - ├── hosting - │ ├── add_to_waitlist - │ └── seat_at_table - └── serving - ├── take_order - ├── serve_order - └── take_payment -``` - -Listing 7-2: The module tree for the code in Listing 7-1 - -This tree shows how some of the modules nest inside one another; for example, -`hosting` nests inside `front_of_house`. The tree also shows that some modules -are _siblings_ to each other, meaning they’re defined in the same module; -`hosting` and `serving` are siblings defined within `front_of_house`. If module -A is contained inside module B, we say that module A is the _child_ of module B -and that module B is the _parent_ of module A. Notice that the entire module -tree is rooted under the explicit name of the crate _restaurant_. - -The module tree might remind you of the filesystem’s directory tree on your -computer; this is a very apt comparison! Just like directories in a filesystem, -you use modules to organize your code. And just like files in a directory, we -need a way to find our modules. - -{{#quiz ../quizzes/ch07-02-defining-modules-to-control-scope.toml}} -# Paths for Referring to an Item in the Module Tree - -To show Cairo where to find an item in a module tree, we use a path in the same way we use a path when navigating a filesystem. To call a function, we need to know its path. - -A path can take two forms: - -- An _absolute path_ is the full path starting from a crate root. The absolute path begins with the crate name. -- A _relative path_ starts from the current module. - -Both absolute and relative paths are followed by one or more identifiers separated by double colons (`::`). - -To illustrate this notion let's take back our example Listing 7-1 for the restaurant we used in the last chapter. We have a crate named _restaurant_ in which we have a module named `front_of_house` that contains a module named `hosting`. The `hosting` module contains a function named `add_to_waitlist`. We want to call the `add_to_waitlist` function from the `eat_at_restaurant` function. We need to tell Cairo the path to the `add_to_waitlist` function so it can find it. - -Filename: src/lib.cairo - -```rust,noplayground -mod front_of_house { - mod hosting { - fn add_to_waitlist() {} - - fn seat_at_table() {} - } - - mod serving { - fn take_order() {} - - fn serve_order() {} - - fn take_payment() {} - } -} - - -pub fn eat_at_restaurant() { - // Absolute path - restaurant::front_of_house::hosting::add_to_waitlist(); - - // Relative path - front_of_house::hosting::add_to_waitlist(); -} -``` - -Listing 7-3: Calling the `add_to_waitlist` function using absolute and relative paths - -The `eat_at_restaurant` function is part of our library's public API, so we mark it with the `pub` keyword. We’ll go into more detail about `pub` in the ["Exposing Paths with the `pub` Keyword"][pub] section. - -The first time we call the `add_to_waitlist` function in `eat_at_restaurant`, -we use an absolute path. The `add_to_waitlist` function is defined in the same -crate as `eat_at_restaurant`. In Cairo, absolute paths start from the crate root, which you need to refer to by using the crate name. You can imagine a filesystem with the same structure: we’d specify the path _/front_of_house/hosting/add_to_waitlist_ to run the _add_to_waitlist_ program; using the crate name to start from the crate root is like using a slash (`/`) to start from the filesystem root in your shell. - -The second time we call `add_to_waitlist`, we use a relative path. The path starts with `front_of_house`, the name of the module defined at the same level of the module tree as `eat_at_restaurant`. Here the filesystem equivalent would be using the path _./front_of_house/hosting/add_to_waitlist_. Starting with a module name means that the path is relative to the current module. - -Let’s try to compile Listing 7-3 and find out why it won’t compile yet! We get the following error: - -```shell -$ scarb cairo-run - Compiling listing_07_02 v0.1.0 (listings/ch07-managing-cairo-projects-with-packages-crates-and-modules/listing_02_paths/Scarb.toml) -error: Identifier not found. - --> listings/ch07-managing-cairo-projects-with-packages-crates-and-modules/listing_02_paths/src/lib.cairo:22:5 - restaurant::front_of_house::hosting::add_to_waitlist(); - ^********^ - -error: Item `listing_07_02::front_of_house::hosting` is not visible in this context. - --> listings/ch07-managing-cairo-projects-with-packages-crates-and-modules/listing_02_paths/src/lib.cairo:25:21 - front_of_house::hosting::add_to_waitlist(); - ^*****^ - -error: Item `listing_07_02::front_of_house::hosting::add_to_waitlist` is not visible in this context. - --> listings/ch07-managing-cairo-projects-with-packages-crates-and-modules/listing_02_paths/src/lib.cairo:25:30 - front_of_house::hosting::add_to_waitlist(); - ^*************^ - -error: could not compile `listing_07_02` due to previous error -error: `scarb metadata` exited with error - -``` - -The error messages say that module `hosting` and the `add_to_waitlist` function are not visible. In other words, we have the correct paths for the `hosting` module and the `add_to_waitlist` function, but Cairo won’t let us use them because it doesn’t have access to them. In Cairo, all items (functions, methods, structs, enums, modules, and constants) are private to parent modules by default. If you want to make an item like a function or struct private, you put it in a module. - -Items in a parent module can’t use the private items inside child modules, but items in child modules can use the items in their ancestor modules. This is because child modules wrap and hide their implementation details, but the child modules can see the context in which they’re defined. To continue with our metaphor, think of the privacy rules as being like the back office of a restaurant: what goes on in there is private to restaurant customers, but office managers can see and do everything in the restaurant they operate. - -Cairo chose to have the module system function this way so that hiding inner implementation details is the default. That way, you know which parts of the inner code you can change without breaking outer code. However, Cairo does give you the option to expose inner parts of child modules’ code to outer ancestor modules by using the `pub` keyword to make an item public. - -[pub]: ./ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md#exposing-paths-with-the-pub-keyword - -## Exposing Paths with the `pub` Keyword - -Let’s return to the previous error that told us the `hosting` module and the `add_to_waitlist` function are not visible. We want the `eat_at_restaurant` function in the parent module to have access to the `add_to_waitlist` function in the child module, so we mark the `hosting` module with the `pub` keyword, as shown in Listing 7-4. - -Filename: src/lib.cairo - -```rust,noplayground -mod front_of_house { - pub mod hosting { - fn add_to_waitlist() {} - } -} - -pub fn eat_at_restaurant() { - // Absolute path - restaurant::front_of_house::hosting::add_to_waitlist(); - - // Relative path - front_of_house::hosting::add_to_waitlist(); -} -``` - -Listing 7-4: Declaring the `hosting` module as `pub` to use it from `eat_at_restaurant` - -Unfortunately, the code in Listing 7-4 still results in an error. - -What happened? Adding the `pub` keyword in front of `mod hosting;` makes the module public. With this change, if we can access `front_of_house`, we can access `hosting`. But the contents of `hosting` are still private; making the module public doesn’t make its contents public. The `pub` keyword on a module only lets code in its ancestor modules refer to it, not access its inner code. Because modules are containers, there’s not much we can do by only making the module public; we need to go further and choose to make one or more of the items within the module public as well. - -Let’s also make the `add_to_waitlist` function public by adding the `pub` keyword before its definition, as in Listing 7-5. - -Filename: src/lib.cairo - -```rust,noplayground -mod front_of_house { - pub mod hosting { - pub fn add_to_waitlist() {} - } -} - -pub fn eat_at_restaurant() { - // Absolute path - restaurant::front_of_house::hosting::add_to_waitlist(); // ✅ Compiles - - // Relative path - front_of_house::hosting::add_to_waitlist(); // ✅ Compiles -} -``` - -Listing 7-5: Declaring the `hosting` module as `pub` to use it from `eat_at_restaurant` - -Now the code will compile! To see why adding the `pub` keyword lets us use these paths in `add_to_waitlist` with respect to the privacy rules, let’s look at the absolute and the relative paths. - -In the absolute path, we start with the crate root, the root of our crate’s module tree. The `front_of_house` module is defined in the crate root. While `front_of_house` isn’t public, because the `eat_at_restaurant` function is defined in the same module as `front_of_house` (that is, `front_of_house` and `eat_at_restaurant` are siblings), we can refer to `front_of_house` from `eat_at_restaurant`. Next is the `hosting` module marked with `pub`. We can access the parent module of `hosting`, so we can access `hosting` itself. Finally, the `add_to_waitlist` function is marked with `pub` and we can access its parent module, so this function call works! - -In the relative path, the logic is the same as the absolute path except for the first step: rather than starting from the crate root, the path starts from `front_of_house`. The `front_of_house` module is defined within the same module as `eat_at_restaurant`, so the relative path starting from the module in which `eat_at_restaurant` is defined works. Then, because `hosting` and `add_to_waitlist` are marked with `pub`, the rest of the path works, and this function call is valid! - -{{#quiz ../quizzes/ch07-03-paths-in-module-tree-1.toml}} - -## Starting Relative Paths with `super` - -We can construct relative paths that begin in the parent module, rather than the current module or the crate root, by using `super` at the start of the path. This is like starting a filesystem path with the `..` syntax. Using `super` allows us to reference an item that we know is in the parent module, which can make rearranging the module tree easier when the module is closely related to the parent, but the parent might be moved elsewhere in the module tree someday. - -Consider the code in Listing 7-6 that models the situation in which a chef fixes an incorrect order and personally brings it out to the customer. The function `fix_incorrect_order` defined in the `back_of_house` module calls the function `deliver_order` defined in the parent module by specifying the path to `deliver_order` starting with `super`: - -Filename: src/lib.cairo - -```rust,noplayground -fn deliver_order() {} - -mod back_of_house { - fn fix_incorrect_order() { - cook_order(); - super::deliver_order(); - } - - fn cook_order() {} -} -``` - -Listing 7-6: Calling a function using a relative path starting with `super` - -Here you can see directly that you access a parent's module easily using `super`, which wasn't the case previously. -Note that the `back_of_house` is kept private, as external users are not supposed to interact with the back of house directly. - -## Making Structs and Enums Public - -We can also use `pub` to designate structs and enums as public, but there are a few extra details to consider when using `pub` with structs and enums. - -- If we use `pub` before a struct definition, we make the struct public, but the struct’s fields will still be private. We can make each field public or not on a case-by-case basis. -- In contrast, if we make an enum public, all of its variants are then public. We only need the `pub` before the `enum` keyword. - -There’s one more situation involving `pub` that we haven’t covered, and that is our last module system feature: the `use` keyword. We’ll cover `use` by itself first, and then we’ll show how to combine `pub` and `use`. - -{{#quiz ../quizzes/ch07-03-paths-in-module-tree-2.toml}} -# Bringing Paths into Scope with the `use` Keyword - -Having to write out the paths to call functions can feel inconvenient and repetitive. Fortunately, there’s a way to simplify this process: we can create a shortcut to a path with the `use` keyword once, and then use the shorter name everywhere else in the scope. - -In Listing 7-7, we bring the `restaurant::front_of_house::hosting` module into the -scope of the `eat_at_restaurant` function so we only have to specify -`hosting::add_to_waitlist` to call the `add_to_waitlist` function in -`eat_at_restaurant`. - -Filename: src/lib.cairo - -```rust -// Assuming "front_of_house" module is contained in a crate called "restaurant", as mentioned in the section "Defining Modules to Control Scope" -// If the path is created in the same crate, "restaurant" is optional in the use statement - -mod front_of_house { - pub mod hosting { - pub fn add_to_waitlist() {} - } -} - -use restaurant::front_of_house::hosting; - -pub fn eat_at_restaurant() { - hosting::add_to_waitlist(); // ✅ Shorter path -} -``` - -Listing 7-7: Bringing a module into scope with `use` - -Adding `use` and a path in a scope is similar to creating a symbolic link in the filesystem. By adding `use restaurant::front_of_house::hosting;` in the crate root, `hosting` is now a valid name in that scope, just as though the `hosting` module had been defined in the crate root. - -Note that `use` only creates the shortcut for the particular scope in which the `use` occurs. Listing 7-8 moves the `eat_at_restaurant` function into a new child module named `customer`, which is then a different scope than the `use` -statement, so the function body won’t compile: - -Filename: src/lib.cairo - -```rust -mod front_of_house { - pub mod hosting { - pub fn add_to_waitlist() {} - } -} - -use restaurant::front_of_house::hosting; - -mod customer { - pub fn eat_at_restaurant() { - hosting::add_to_waitlist(); - } -} -``` - -Listing 7-8: A `use` statement only applies in the scope it’s in. - -The compiler error shows that the shortcut no longer applies within the `customer` module: - -```shell -$ scarb build - Compiling listing_07_05 v0.1.0 (listings/ch07-managing-cairo-projects-with-packages-crates-and-modules/listing_07_use_and_scope/Scarb.toml) -error: Identifier not found. - --> listings/ch07-managing-cairo-projects-with-packages-crates-and-modules/listing_07_use_and_scope/src/lib.cairo:10:5 -use restaurant::front_of_house::hosting; - ^********^ - -error: Identifier not found. - --> listings/ch07-managing-cairo-projects-with-packages-crates-and-modules/listing_07_use_and_scope/src/lib.cairo:14:9 - hosting::add_to_waitlist(); - ^*****^ - -error: could not compile `listing_07_05` due to previous error - -``` - -## Creating Idiomatic `use` Paths - -In Listing 7-7, you might have wondered why we specified `use restaurant::front_of_house::hosting` -and then called `hosting::add_to_waitlist` in `eat_at_restaurant` rather than specifying the `use` path all the way out to -the `add_to_waitlist` function to achieve the same result, as in Listing 7-9. - -Filename: src/lib.cairo - -```rust -mod front_of_house { - pub mod hosting { - pub fn add_to_waitlist() {} - } -} - -use restaurant::front_of_house::hosting::add_to_waitlist; - -pub fn eat_at_restaurant() { - add_to_waitlist(); -} -``` - -Listing 7-9: Bringing the `add_to_waitlist` function into scope with `use`, which is unidiomatic - -Although both Listing 7-7 and 7-9 accomplish the same task, Listing 7-7 is -the idiomatic way to bring a function into scope with `use`. Bringing the -function’s parent module into scope with `use` means we have to specify the -parent module when calling the function. Specifying the parent module when -calling the function makes it clear that the function isn’t locally defined -while still minimizing repetition of the full path. The code in Listing 7-9 is -unclear as to where `add_to_waitlist` is defined. - -On the other hand, when bringing in structs, enums, traits, and other items with `use`, it’s idiomatic to specify the full path. Listing 7-10 shows the idiomatic way to bring the core library’s `BitSize` trait into the scope, allowing to call `bits` method to retrieve the size in bits of a type. - -```rust -use core::num::traits::BitSize; - -fn main() { - let u8_size: usize = BitSize::::bits(); - println!("A u8 variable has {} bits", u8_size) -} -``` - -Listing 7-10: Bringing `BitSize` trait into scope in an idiomatic way - -There’s no strong reason behind this idiom: it’s just the convention that has -emerged in the Rust community, and folks have gotten used to reading and writing Rust code this way. -As Cairo shares many idioms with Rust, we follow this convention as well. - -The exception to this idiom is if we’re bringing two items with the same name -into scope with `use` statements, because Cairo doesn’t allow that. - -### Providing New Names with the `as` Keyword - -There’s another solution to the problem of bringing two types of the same name -into the same scope with `use`: after the path, we can specify `as` and a new -local name, or _alias_, for the type. Listing 7-11 shows how you can rename an import with `as`: - -Filename: src/lib.cairo - -```rust -use core::array::ArrayTrait as Arr; - -fn main() { - let mut arr = Arr::new(); // ArrayTrait was renamed to Arr - arr.append(1); -} -``` - -Listing 7-11: Renaming a trait when it’s brought into scope with the `as` keyword - -Here, we brought `ArrayTrait` into scope with the alias `Arr`. We can now access the trait's methods with the `Arr` identifier. - -### Importing Multiple Items from the Same Module - -When you want to import multiple items (like functions, structs or enums) -from the same module in Cairo, you can use curly braces `{}` to list all of -the items that you want to import. This helps to keep your code clean and easy -to read by avoiding a long list of individual `use` statements. - -The general syntax for importing multiple items from the same module is: - -```rust -use module::{item1, item2, item3}; -``` - -Here is an example where we import three structures from the same module: - -```rust -// Assuming we have a module called `shapes` with the structures `Square`, `Circle`, and `Triangle`. -mod shapes { - #[derive(Drop)] - pub struct Square { - pub side: u32 - } - - #[derive(Drop)] - pub struct Circle { - pub radius: u32 - } - - #[derive(Drop)] - pub struct Triangle { - pub base: u32, - pub height: u32, - } -} - -// We can import the structures `Square`, `Circle`, and `Triangle` from the `shapes` module like this: -use shapes::{Square, Circle, Triangle}; - -// Now we can directly use `Square`, `Circle`, and `Triangle` in our code. -fn main() { - let sq = Square { side: 5 }; - let cr = Circle { radius: 3 }; - let tr = Triangle { base: 5, height: 2 }; -// ... -} -``` - -Listing 7-12: Importing multiple items from the same module - -## Re-exporting Names in Module Files - -When we bring a name into scope with the `use` keyword, the name available in -the new scope can be imported as if it had been defined in that code’s scope. -This technique is called _re-exporting_ because we’re bringing an item into scope, -but also making that item available for others to bring into their scope, with the `pub` keyword. - -For example, let's re-export the `add_to_waitlist` function in the restaurant example: - -Filename: src/lib.cairo - -```rust -mod front_of_house { - pub mod hosting { - pub fn add_to_waitlist() {} - } -} - -pub use restaurant::front_of_house::hosting; - -fn eat_at_restaurant() { - hosting::add_to_waitlist(); -} -``` - -Listing 7-13: Making a name available for any code to use from a new scope with `pub use` - -Before this change, external code would have to call the `add_to_waitlist` -function by using the path `restaurant::front_of_house::hosting::add_to_waitlist()`. -Now that this `pub use` has re-exported the `hosting` module from the root module, external code -can now use the path `restaurant::hosting::add_to_waitlist()` instead. - -Re-exporting is useful when the internal structure of your code is different -from how programmers calling your code would think about the domain. For -example, in this restaurant metaphor, the people running the restaurant think -about “front of house” and “back of house.” But customers visiting a restaurant -probably won’t think about the parts of the restaurant in those terms. With -`pub use`, we can write our code with one structure but expose a different -structure. Doing so makes our library well organized for programmers working on -the library and programmers calling the library. - -## Using External Packages in Cairo with Scarb - -You might need to use external packages to leverage the functionality provided by the community. Scarb allows you to use dependencies by cloning packages from their Git repositories. To use an external package in your project with Scarb, simply declare the Git repository URL of the dependency you want to add in a dedicated `[dependencies]` section in your _Scarb.toml_ configuration file. Note that the URL might correspond to the main branch, or any specific commit, branch or tag. For this, you will have to pass an extra `rev`, `branch`, or `tag` field, respectively. For example, the following code imports the main branch of _alexandria_math_ crate from _alexandria_ package: - -```rust -[dependencies] -alexandria_math = { git = "https://github.com/keep-starknet-strange/alexandria.git" } -``` - -while the following code imports a specific branch (which is deprecated and should not be used): - -```rust -[dependencies] -alexandria_math = { git = "https://github.com/keep-starknet-strange/alexandria.git", branch = "cairo-v2.3.0-rc0" } -``` - -If you want to import multiple packages in your project, you need to create only one `[dependencies]` section and list all the desired packages beneath it. You can also specify development dependencies by declaring a `[dev-dependencies]` section. - -After that, simply run `scarb build` to fetch all external dependencies and compile your package with all the dependencies included. - -Note that it is also possible to add dependencies with the `scarb add` command, which will automatically edit the _Scarb.toml_ file for you. For development dependencies, just use the `scarb add --dev` command. - -To remove a dependency, simply remove the corresponding line from your _Scarb.toml_ file, or use the `scarb rm` command. - -{{#quiz ../quizzes/ch07-04-bringing-paths-into-scope.toml}} -# Separating Modules into Different Files - -So far, all the examples in this chapter defined multiple modules in one file. -When modules get large, you might want to move their definitions to a separate -file to make the code easier to navigate. - -For example, let’s start from the code in Listing 7-7 that had multiple -restaurant modules. We’ll extract modules into files instead of having all the -modules defined in the crate root file. In this case, the crate root file is -_src/lib.cairo_. - -First, we’ll extract the `front_of_house` module to its own file. Remove the -code inside the curly brackets for the `front_of_house` module, leaving only -the `mod front_of_house;` declaration, so that _src/lib.cairo_ contains the code -shown in Listing 7-14. Note that this won’t compile until we create the -_src/front_of_house.cairo_ file. - -Filename: src/lib.cairo - -```rust,noplayground -mod front_of_house; - -use restaurant::front_of_house::hosting; - -fn eat_at_restaurant() { - hosting::add_to_waitlist(); -} -``` - -Listing 7-14: Declaring the `front_of_house` module whose body will be in _src/front_of_house.cairo_ - -Next, place the code that was in the curly brackets into a new file named -_src/front_of_house.cairo_, as shown in Listing 7-15. The compiler knows to look -in this file because it came across the module declaration in the crate root -with the name `front_of_house`. - -Filename: src/front_of_house.cairo - -```rust,noplayground -pub mod hosting { - pub fn add_to_waitlist() {} -} -``` - -Listing 7-15: Definitions inside the `front_of_house` module in _src/front_of_house.cairo_ - -Note that you only need to load a file using a `mod` declaration _once_ in your -module tree. Once the compiler knows the file is part of the project (and knows -where in the module tree the code resides because of where you’ve put the `mod` -statement), other files in your project should refer to the loaded file’s code -using a path to where it was declared, as covered in the ["Paths for Referring to an Item in the Module Tree"][path] chapter. -In other words, `mod` is _not_ an “include” operation that you may have seen in other -programming languages. - -Next, we’ll extract the `hosting` module to its own file. The process is a bit -different because `hosting` is a child module of `front_of_house`, not of the -root module. We’ll place the file for `hosting` in a new directory that will be -named for its ancestors in the module tree, in this case _src/front_of_house/_. - -To start moving `hosting`, we change _src/front_of_house.cairo_ to contain only the -declaration of the `hosting` module: - -Filename: src/front_of_house.cairo - -```rust,noplayground -pub mod hosting; -``` - -Then we create a _src/front_of_house_ directory and a file _hosting.cairo_ to -contain the definitions made in the `hosting` module: - -Filename: src/front_of_house/hosting.cairo - -```rust,noplayground -pub fn add_to_waitlist() {} -``` - -If we instead put _hosting.cairo_ in the _src_ directory, the compiler would -expect the _hosting.cairo_ code to be in a `hosting` module declared in the crate -root, and not declared as a child of the `front_of_house` module. The -compiler’s rules for which files to check for which modules’ code means the -directories and files more closely match the module tree. - -We’ve moved each module’s code to a separate file, and the module tree remains -the same. The function calls in `eat_at_restaurant` will work without any -modification, even though the definitions live in different files. This -technique lets you move modules to new files as they grow in size. - -Note that the `use restaurant::front_of_house::hosting;` statement in -_src/lib.cairo_ also hasn’t changed, nor does `use` have any impact on what files -are compiled as part of the crate. The `mod` keyword declares modules, and Cairo -looks in a file with the same name as the module for the code that goes into -that module. - -[path]: ./ch07-03-paths-for-referring-to-an-item-in-the-module-tree.md - -## Summary - -Cairo lets you split a package into multiple crates and a crate into modules -so you can refer to items defined in one module from another module. You can do -this by specifying absolute or relative paths. These paths can be brought into -scope with a `use` statement so you can use a shorter path for multiple uses of -the item in that scope. Module code is **private** by default. - -{{#quiz ../quizzes/ch07-05-separate-modules.toml}} -# Generic Types and Traits - -Every programming language has tools for effectively handling the duplication of concepts. In Cairo, one such tool is generics: abstract stand-ins for concrete types or other properties. We can express the behavior of generics or how they relate to other generics without knowing what will be in their place when compiling and running the code. - -Functions can take parameters of some generic type, instead of a concrete type like `u32` or `bool`, in the same way a function takes parameters with unknown values to run the same code on multiple concrete values. In fact, we’ve already used generics in [Chapter 6][option enum] with `Option`. - -In this chapter, you’ll explore how to define your own types, functions, and traits with generics. - -Generics allow us to replace specific types with a placeholder that represents multiple types to remove code duplication. Upon compilation, the compiler creates a new definition for each concrete type that replaces a generic type, reducing development time for the programmer, but code duplication at compile level still exists. This may be of importance if you are writing Starknet contracts and using a generic for multiple types which will cause contract size to increment. - -Then you’ll learn how to use traits to define behavior in a generic way. You can combine traits with generic types to constrain a generic type to accept only those types that have a particular behavior, as opposed to just any type. - -[option enum]: ./ch06-01-enums.html#the-option-enum-and-its-advantages - -## Removing Duplication by Extracting a Function - -Generics allow us to replace specific types with a placeholder that represents multiple types to remove code duplication. Before diving into generics syntax, let’s first look at how to remove duplication in a way that doesn’t involve generic types by extracting a function that replaces specific values with a placeholder that represents multiple values. Then we’ll apply the same technique to extract a generic function! By learning how to identify duplicated code that can be extracted into a function, you'll start to recognize instances where generics can be used to reduce duplication. - -We begin with a short program that finds the largest number in an array of `u8`: - -```rust -fn main() { - let mut number_list: Array = array![34, 50, 25, 100, 65]; - - let mut largest = number_list.pop_front().unwrap(); - - while let Option::Some(number) = number_list - .pop_front() { - if number > largest { - largest = number; - } - }; - - println!("The largest number is {}", largest); -} -``` - -We store an array of `u8` in the variable `number_list` and extract the first number in the array in a variable named `largest`. We then iterate through all the numbers in the array, and if the current number is greater than the number stored in `largest`, we update the value of `largest`. However, if the current number is less than or equal to the largest number seen so far, the variable doesn’t change, and the code moves on to the next number in the list. After considering all the numbers in the array, `largest` should contain the largest number, which in this case is 100. - -We've now been tasked with finding the largest number in two different arrays of numbers. To do so, we can choose to duplicate the previous code and use the same logic at two different places in the program, as follows: - -```rust -fn main() { - let mut number_list: Array = array![34, 50, 25, 100, 65]; - - let mut largest = number_list.pop_front().unwrap(); - - while let Option::Some(number) = number_list - .pop_front() { - if number > largest { - largest = number; - } - }; - - println!("The largest number is {}", largest); - - let mut number_list: Array = array![102, 34, 255, 89, 54, 2, 43, 8]; - - let mut largest = number_list.pop_front().unwrap(); - - while let Option::Some(number) = number_list - .pop_front() { - if number > largest { - largest = number; - } - }; - - println!("The largest number is {}", largest); -} -``` - -Although this code works, duplicating code is tedious and error-prone. We also have to remember to update the code in multiple places when we want to change it. - -To eliminate this duplication, we’ll create an abstraction by defining a function that operates on any array of `u8` passed in a parameter. This solution makes our code clearer and lets us express the concept of finding the largest number in an array abstractly. - -To do that, we extract the code that finds the largest number into a function named `largest`. Then we call the function to find the largest number in the two arrays. We could also use the function on any other array of `u8` values we might have in the future. - -```rust -fn largest(ref number_list: Array) -> u8 { - let mut largest = number_list.pop_front().unwrap(); - - while let Option::Some(number) = number_list - .pop_front() { - if number > largest { - largest = number; - } - }; - - largest -} - -fn main() { - let mut number_list = array![34, 50, 25, 100, 65]; - - let result = largest(ref number_list); - println!("The largest number is {}", result); - - let mut number_list = array![102, 34, 255, 89, 54, 2, 43, 8]; - - let result = largest(ref number_list); - println!("The largest number is {}", result); -} -``` - -The largest function has a parameter called `number_list`, passed by reference, which represents any concrete array of `u8` values we might pass into the function. As a result, when we call the function, the code runs on the specific values that we pass in. - -In summary, here are the steps we took to change the code: - -- Identify duplicate code. -- Extract the duplicate code into the body of the function and specify the inputs and return values of that code in the function signature. -- Update the two instances of duplicated code to call the function instead. - -Next, we’ll use these same steps with generics to reduce code duplication. In the same way that the function body can operate on an abstract `Array` instead of specific `u8` values, generics allow code to operate on abstract types. -# Generic Data Types - -We use generics to create definitions for item declarations, such as structs and functions, which we can then use with many different concrete data types. In Cairo, we can use generics when defining functions, structs, enums, traits, implementations and methods. In this chapter, we are going to take a look at how to effectively use generic types with all of them. - -Generics allow us to write reusable code that works with many types, thus avoiding code duplication, while enhancing code maintainability. - -## Generic Functions - -Making a function generic means it can operate on different types, avoiding the need for multiple, type-specific implementations. This leads to significant code reduction and increases the flexibility of the code. - -When defining a function that uses generics, we place the generics in the function signature, where we would usually specify the data types of the parameter and return value. For example, imagine we want to create a function which given two `Array` of items, will return the largest one. If we need to perform this operation for lists of different types, then we would have to redefine the function each time. Luckily we can implement the function once using generics and move on to other tasks. - -```rust -// Specify generic type T between the angulars -fn largest_list(l1: Array, l2: Array) -> Array { - if l1.len() > l2.len() { - l1 - } else { - l2 - } -} - -fn main() { - let mut l1 = array![1, 2]; - let mut l2 = array![3, 4, 5]; - - // There is no need to specify the concrete type of T because - // it is inferred by the compiler - let l3 = largest_list(l1, l2); -} -``` - -The `largest_list` function compares two lists of the same type and returns the one with more elements and drops the other. If you compile the previous code, you will notice that it will fail with an error saying that there are no traits defined for dropping an array of a generic type. This happens because the compiler has no way to guarantee that an `Array` is droppable when executing the `main` function. In order to drop an array of `T`, the compiler must first know how to drop `T`. This can be fixed by specifying in the function signature of `largest_list` that `T` must implement the `Drop` trait. The correct function definition of `largest_list` is as follows: - -```rust -fn largest_list>(l1: Array, l2: Array) -> Array { - if l1.len() > l2.len() { - l1 - } else { - l2 - } -} -``` - -The new `largest_list` function includes in its definition the requirement that whatever generic type is placed there, it must be droppable. This is what we call _trait bounds_. The `main` function remains unchanged, the compiler is smart enough to deduce which concrete type is being used and if it implements the `Drop` trait. - -### Constraints for Generic Types - -When defining generic types, it is useful to have information about them. Knowing which traits a generic type implements allows us to use it more effectively in a function's logic at the cost of constraining the generic types that can be used with the function. We saw an example of this previously by adding the `TDrop` implementation as part of the generic arguments of `largest_list`. While `TDrop` was added to satisfy the compiler's requirements, we can also add constraints to benefit our function logic. - -Imagine that we want, given a list of elements of some generic type `T`, to find the smallest element among them. Initially, we know that for an element of type `T` to be comparable, it must implement the `PartialOrd` trait. The resulting function would be: - -```rust -// Given a list of T get the smallest one -// The PartialOrd trait implements comparison operations for T -fn smallest_element>(list: @Array) -> T { - // This represents the smallest element through the iteration - // Notice that we use the desnap (*) operator - let mut smallest = *list[0]; - - // The index we will use to move through the list - let mut index = 1; - - // Iterate through the whole list storing the smallest - while index < list - .len() { - if *list[index] < smallest { - smallest = *list[index]; - } - index = index + 1; - }; - - smallest -} - -fn main() { - let list: Array = array![5, 3, 10]; - - // We need to specify that we are passing a snapshot of `list` as an argument - let s = smallest_element(@list); - assert!(s == 3); -} -``` - -The `smallest_element` function uses a generic type `T` that implements the `PartialOrd` trait, takes a snapshot of an `Array` as a parameter and returns a copy of the smallest element. Because the parameter is of type `@Array`, we no longer need to drop it at the end of the execution and so we are not required to implement the `Drop` trait for `T` as well. Why does it not compile then? - -When indexing on `list`, the value results in a snap of the indexed element, and unless `PartialOrd` is implemented for `@T` we need to desnap the element using `*`. The `*` operation requires a copy from `@T` to `T`, which means that `T` needs to implement the `Copy` trait. After copying an element of type `@T` to `T`, there are now variables with type `T` that need to be dropped, requiring `T` to implement the `Drop` trait as well. We must then add both `Drop` and `Copy` traits implementation for the function to be correct. After updating the `smallest_element` function the resulting code would be: - -```rust -fn smallest_element, impl TCopy: Copy, impl TDrop: Drop>( - list: @Array -) -> T { - let mut smallest = *list[0]; - let mut index = 1; - - while index < list - .len() { - if *list[index] < smallest { - smallest = *list[index]; - } - index = index + 1; - }; - - smallest -} -``` - -### Anonymous Generic Implementation Parameter (`+` Operator) - -Until now, we have always specified a name for each implementation of the required generic trait: `TPartialOrd` for `PartialOrd`, `TDrop` for `Drop`, and `TCopy` for `Copy`. - -However, most of the time, we don't use the implementation in the function body; we only use it as a constraint. In these cases, we can use the `+` operator to specify that the generic type must implement a trait without naming the implementation. This is referred to as an _anonymous generic implementation parameter_. - -For example, `+PartialOrd` is equivalent to `impl TPartialOrd: PartialOrd`. - -We can rewrite the `smallest_element` function signature as follows: - -```rust -fn smallest_element, +Copy, +Drop>(list: @Array) -> T { -# let mut smallest = *list[0]; -# let mut index = 1; -# loop { -# if index >= list.len() { -# break smallest; -# } -# if *list[index] < smallest { -# smallest = *list[index]; -# } -# index = index + 1; -# } -# } -``` - -## Structs - -We can also define structs to use a generic type parameter for one or more fields using the `<>` syntax, similar to function definitions. First, we declare the name of the type parameter inside the angle brackets just after the name of the struct. Then we use the generic type in the struct definition where we would otherwise specify concrete data types. The next code example shows the definition `Wallet` which has a `balance` field of type `T`. - -```rust -#[derive(Drop)] -struct Wallet { - balance: T -} - -fn main() { - let w = Wallet { balance: 3 }; -} -``` - -The above code derives the `Drop` trait for the `Wallet` type automatically. It is equivalent to writing the following code: - -```rust -struct Wallet { - balance: T -} - -impl WalletDrop> of Drop>; - -fn main() { - let w = Wallet { balance: 3 }; -} -``` - -We avoid using the `derive` macro for `Drop` implementation of `Wallet` and instead define our own `WalletDrop` implementation. Notice that we must define, just like functions, an additional generic type for `WalletDrop` saying that `T` implements the `Drop` trait as well. We are basically saying that the struct `Wallet` is droppable as long as `T` is also droppable. - -Finally, if we want to add a field to `Wallet` representing its address and we want that field to be different than `T` but generic as well, we can simply add another generic type between the `<>`: - -```rust -#[derive(Drop)] -struct Wallet { - balance: T, - address: U, -} - -fn main() { - let w = Wallet { balance: 3, address: 14 }; -} -``` - -We add to the `Wallet` struct definition a new generic type `U` and then assign this type to the new field member `address`. Notice that the `derive` attribute for the `Drop` trait works for `U` as well. - -## Enums - -As we did with structs, we can define enums to hold generic data types in their variants. For example the `Option` enum provided by the Cairo core library: - -```rust,noplayground -enum Option { - Some: T, - None, -} -``` - -The `Option` enum is generic over a type `T` and has two variants: `Some`, which holds one value of type `T` and `None` that doesn't hold any value. By using the `Option` enum, it is possible for us to express the abstract concept of an optional value and because the value has a generic type `T` we can use this abstraction with any type. - -Enums can use multiple generic types as well, like the definition of the `Result` enum that the core library provides: - -```rust,noplayground -enum Result { - Ok: T, - Err: E, -} -``` - -The `Result` enum has two generic types, `T` and `E`, and two variants: `Ok` which holds the value of type `T` and `Err` which holds the value of type `E`. This definition makes it convenient to use the `Result` enum anywhere we have an operation that might succeed (by returning a value of type `T`) or fail (by returning a value of type `E`). - -## Generic Methods - -We can implement methods on structs and enums, and use the generic types in their definitions, too. Using our previous definition of `Wallet` struct, we define a `balance` method for it: - -```rust -#[derive(Copy, Drop)] -struct Wallet { - balance: T -} - -trait WalletTrait { - fn balance(self: @Wallet) -> T; -} - -impl WalletImpl> of WalletTrait { - fn balance(self: @Wallet) -> T { - return *self.balance; - } -} - -fn main() { - let w = Wallet { balance: 50 }; - assert!(w.balance() == 50); -} -``` - -We first define `WalletTrait` trait using a generic type `T` which defines a method that returns the value of the field `balance` from `Wallet`. Then we give an implementation for the trait in `WalletImpl`. Note that you need to include a generic type in both definitions of the trait and the implementation. - -We can also specify constraints on generic types when defining methods on the type. We could, for example, implement methods only for `Wallet` instances rather than `Wallet`. In the code example, we define an implementation for wallets which have a concrete type of `u128` for the `balance` field. - -```rust -#[derive(Copy, Drop)] -struct Wallet { - balance: T -} - -/// Generic trait for wallets -trait WalletTrait { - fn balance(self: @Wallet) -> T; -} - -impl WalletImpl> of WalletTrait { - fn balance(self: @Wallet) -> T { - return *self.balance; - } -} - -/// Trait for wallets of type u128 -trait WalletReceiveTrait { - fn receive(ref self: Wallet, value: u128); -} - -impl WalletReceiveImpl of WalletReceiveTrait { - fn receive(ref self: Wallet, value: u128) { - self.balance += value; - } -} - -fn main() { - let mut w = Wallet { balance: 50 }; - assert!(w.balance() == 50); - - w.receive(100); - assert!(w.balance() == 150); -} -``` - -The new method `receive` increments the size of `balance` of any instance of a `Wallet`. Notice that we changed the `main` function making `w` a mutable variable in order for it to be able to update its balance. If we were to change the initialization of `w` by changing the type of `balance` the previous code wouldn't compile. - -Cairo allows us to define generic methods inside generic traits as well. Using the past implementation from `Wallet` we are going to define a trait that picks two wallets of different generic types and creates a new one with a generic type of each. First, let's rewrite the struct definition: - -```rust,noplayground -struct Wallet { - balance: T, - address: U, -} -``` - -Next, we are going to naively define the mixup trait and implementation: - -```rust,noplayground -// This does not compile! -trait WalletMixTrait { - fn mixup(self: Wallet, other: Wallet) -> Wallet; -} - -impl WalletMixImpl of WalletMixTrait { - fn mixup(self: Wallet, other: Wallet) -> Wallet { - Wallet { balance: self.balance, address: other.address } - } -} - -``` - -We are creating a trait `WalletMixTrait` with the `mixup` method which given an instance of `Wallet` and `Wallet` creates a new `Wallet`. As `mixup` signature specifies, both `self` and `other` are getting dropped at the end of the function, which is why this code does not compile. If you have been following from the start until now you would know that we must add a requirement for all the generic types specifying that they will implement the `Drop` trait for the compiler to know how to drop instances of `Wallet`. The updated implementation is as follows: - -```rust -trait WalletMixTrait { - fn mixup, U2, +Drop>( - self: Wallet, other: Wallet - ) -> Wallet; -} - -impl WalletMixImpl, U1, +Drop> of WalletMixTrait { - fn mixup, U2, +Drop>( - self: Wallet, other: Wallet - ) -> Wallet { - Wallet { balance: self.balance, address: other.address } - } -} -``` - -We add the requirements for `T1` and `U1` to be droppable on `WalletMixImpl` declaration. Then we do the same for `T2` and `U2`, this time as part of `mixup` signature. We can now try the `mixup` function: - -```rust,noplayground -fn main() { - let w1: Wallet = Wallet { balance: true, address: 10 }; - let w2: Wallet = Wallet { balance: 32, address: 100 }; - - let w3 = w1.mixup(w2); - - assert!(w3.balance); - assert!(w3.address == 100); -} -``` - -We first create two instances: one of `Wallet` and the other of `Wallet`. Then, we call `mixup` and create a new `Wallet` instance. -# Traits in Cairo - -A trait defines a set of methods that can be implemented by a type. These methods can be called on instances of the type when this trait is implemented. -A trait combined with a generic type defines functionality a particular type has and can share with other types. We can use traits to define shared behavior in an abstract way. -We can use _trait bounds_ to specify that a generic type can be any type that has certain behavior. - -> Note: Traits are similar to a feature often called interfaces in other languages, although with some differences. - -While traits can be written to not accept generic types, they are most useful when used with generic types. We already covered generics in the [previous chapter][generics], and we will use them in this chapter to demonstrate how traits can be used to define shared behavior for generic types. - -[generics]: ./ch08-01-generic-data-types.md - -## Defining a Trait - -A type’s behavior consists of the methods we can call on that type. Different types share the same behavior if we can call the same methods on all of those types. Trait definitions are a way to group method signatures together to define a set of behaviors necessary to accomplish some purpose. - -For example, let’s say we have a struct `NewsArticle` that holds a news story in a particular location. We can define a trait `Summary` that describes the behavior of something that can summarize the `NewsArticle` type. - -```rust,noplayground -# #[derive(Drop, Clone)] -# struct NewsArticle { -# headline: ByteArray, -# location: ByteArray, -# author: ByteArray, -# content: ByteArray, -# } -# -pub trait Summary { - fn summarize(self: @NewsArticle) -> ByteArray; -} -# -# impl NewsArticleSummary of Summary { -# fn summarize(self: @NewsArticle) -> ByteArray { -# format!("{:?} by {:?} ({:?})", self.headline, self.author, self.location) -# } -# } -# -# -``` - -Here, we declare a trait using the `trait` keyword and then the trait’s name, which is `Summary` in this case. -We’ve also declared the trait as `pub` so that crates depending on this crate can make use of this trait too, as we’ll see in a few examples. - -Inside the curly brackets, we declare the method signatures that describe the behaviors of the types that implement this trait, which in this case is `fn summarize(self: @NewsArticle) -> ByteArray;`. After the method signature, instead of providing an implementation within curly brackets, we use a semicolon. - -> Note: the `ByteArray` type is the type used to represent strings in Cairo. - -As the trait is not generic, the `self` parameter is not generic either and is of type `@NewsArticle`. This means that the `summarize` method can only be called on instances of `NewsArticle`. - -Now, consider that we want to make a media aggregator library crate named _aggregator_ that can display summaries of data that might be stored in a `NewsArticle` or `Tweet` instance. To do this, we need a summary from each type, and we’ll request that summary by calling a summarize method on an instance of that type. By defining the `Summary` trait on generic type `T`, we can implement the `summarize` method on any type we want to be able to summarize. - -```rust,noplayground -# mod aggregator { - pub trait Summary { - fn summarize(self: @T) -> ByteArray; - } -# -# #[derive(Drop)] -# pub struct NewsArticle { -# pub headline: ByteArray, -# pub location: ByteArray, -# pub author: ByteArray, -# pub content: ByteArray, -# } -# -# impl NewsArticleSummary of Summary { -# fn summarize(self: @NewsArticle) -> ByteArray { -# format!("{} by {} ({})", self.headline, self.author, self.location) -# } -# } -# -# #[derive(Drop)] -# pub struct Tweet { -# pub username: ByteArray, -# pub content: ByteArray, -# pub reply: bool, -# pub retweet: bool, -# } -# -# impl TweetSummary of Summary { -# fn summarize(self: @Tweet) -> ByteArray { -# format!("{}: {}", self.username, self.content) -# } -# } -# } -# -# use aggregator::{Summary, NewsArticle, Tweet}; -# -# fn main() { -# let news = NewsArticle { -# headline: "Cairo has become the most popular language for developers", -# location: "Worldwide", -# author: "Cairo Digger", -# content: "Cairo is a new programming language for zero-knowledge proofs", -# }; -# -# let tweet = Tweet { -# username: "EliBenSasson", -# content: "Crypto is full of short-term maximizing projects. \n @Starknet and @StarkWareLtd are about long-term vision maximization.", -# reply: false, -# retweet: false -# }; // Tweet instantiation -# -# println!("New article available! {}", news.summarize()); -# println!("New tweet! {}", tweet.summarize()); -# } -# -# -``` - -A `Summary` trait that consists of the behavior provided by a `summarize` method - -Each type implementing this trait must provide its own custom behavior for the body of the method. The compiler will enforce that any type that implements the `Summary` trait will have the method `summarize` defined with this signature exactly. - -A trait can have multiple methods in its body: the method signatures are listed one per line and each line ends in a semicolon. - -## Implementing a Trait on a Type - -Now that we’ve defined the desired signatures of the `Summary` trait’s methods, -we can implement it on the types in our media aggregator. The following code shows -an implementation of the `Summary` trait on the `NewsArticle` struct that uses -the headline, the author, and the location to create the return value of -`summarize`. For the `Tweet` struct, we define `summarize` as the username -followed by the entire text of the tweet, assuming that tweet content is -already limited to 280 characters. - - - -```rust,noplayground -# mod aggregator { -# pub trait Summary { -# fn summarize(self: @T) -> ByteArray; -# } -# - #[derive(Drop)] - pub struct NewsArticle { - pub headline: ByteArray, - pub location: ByteArray, - pub author: ByteArray, - pub content: ByteArray, - } - - impl NewsArticleSummary of Summary { - fn summarize(self: @NewsArticle) -> ByteArray { - format!("{} by {} ({})", self.headline, self.author, self.location) - } - } - - #[derive(Drop)] - pub struct Tweet { - pub username: ByteArray, - pub content: ByteArray, - pub reply: bool, - pub retweet: bool, - } - - impl TweetSummary of Summary { - fn summarize(self: @Tweet) -> ByteArray { - format!("{}: {}", self.username, self.content) - } - } -# } -# -# use aggregator::{Summary, NewsArticle, Tweet}; -# -# fn main() { -# let news = NewsArticle { -# headline: "Cairo has become the most popular language for developers", -# location: "Worldwide", -# author: "Cairo Digger", -# content: "Cairo is a new programming language for zero-knowledge proofs", -# }; -# -# let tweet = Tweet { -# username: "EliBenSasson", -# content: "Crypto is full of short-term maximizing projects. \n @Starknet and @StarkWareLtd are about long-term vision maximization.", -# reply: false, -# retweet: false -# }; // Tweet instantiation -# -# println!("New article available! {}", news.summarize()); -# println!("New tweet! {}", tweet.summarize()); -# } -# -# -``` - -Implementing a trait on a type is similar to implementing regular methods. The -difference is that after `impl`, we put a name for the implementation, -then use the `of` keyword, and then specify the name of the trait we are writing the implementation for. -If the implementation is for a generic type, we place the generic type name in the angle brackets after the trait name. - -Note that for the trait method to be accessible, there must be an implementation of that trait visible from the scope where the method is called. If the trait is `pub` and the implementation is not, and the implementation is not visible in the scope where the trait method is called, this will cause a compilation error. - -Within the `impl` block, we put the method signatures -that the trait definition has defined. Instead of adding a semicolon after each -signature, we use curly brackets and fill in the method body with the specific -behavior that we want the methods of the trait to have for the particular type. - -Now that the library has implemented the `Summary` trait on `NewsArticle` and -`Tweet`, users of the crate can call the trait methods on instances of -`NewsArticle` and `Tweet` in the same way we call regular methods. The only -difference is that the user must bring the trait into scope as well as the -types. Here’s an example of how a crate could use our `aggregator` crate: - -```rust -# mod aggregator { -# pub trait Summary { -# fn summarize(self: @T) -> ByteArray; -# } -# -# #[derive(Drop)] -# pub struct NewsArticle { -# pub headline: ByteArray, -# pub location: ByteArray, -# pub author: ByteArray, -# pub content: ByteArray, -# } -# -# impl NewsArticleSummary of Summary { -# fn summarize(self: @NewsArticle) -> ByteArray { -# format!("{} by {} ({})", self.headline, self.author, self.location) -# } -# } -# -# #[derive(Drop)] -# pub struct Tweet { -# pub username: ByteArray, -# pub content: ByteArray, -# pub reply: bool, -# pub retweet: bool, -# } -# -# impl TweetSummary of Summary { -# fn summarize(self: @Tweet) -> ByteArray { -# format!("{}: {}", self.username, self.content) -# } -# } -# } -# -use aggregator::{Summary, NewsArticle, Tweet}; - -fn main() { - let news = NewsArticle { - headline: "Cairo has become the most popular language for developers", - location: "Worldwide", - author: "Cairo Digger", - content: "Cairo is a new programming language for zero-knowledge proofs", - }; - - let tweet = Tweet { - username: "EliBenSasson", - content: "Crypto is full of short-term maximizing projects. \n @Starknet and @StarkWareLtd are about long-term vision maximization.", - reply: false, - retweet: false - }; // Tweet instantiation - - println!("New article available! {}", news.summarize()); - println!("New tweet! {}", tweet.summarize()); -} -# -# -``` - -This code prints the following: - -```shell -$ scarb cairo-run - Compiling no_listing_15_traits v0.1.0 (listings/ch08-generic-types-and-traits/no_listing_15_traits/Scarb.toml) - Finished release target(s) in 1 second - Running no_listing_15_traits -New article available! Cairo has become the most popular language for developers by Cairo Digger (Worldwide) -New tweet! EliBenSasson: Crypto is full of short-term maximizing projects. - @Starknet and @StarkWareLtd are about long-term vision maximization. -Run completed successfully, returning [] - -``` - -Other crates that depend on the _aggregator_ crate can also bring the `Summary` trait into scope to implement `Summary` on their own types. - - - - - - -## Managing and Using External Trait - -To use traits methods, you need to make sure the correct traits/implementation(s) are imported. In some cases you might need to import not only the trait but also the implementation if they are declared in separate modules. -If `CircleGeometry` implementation was in a separate module/file named _circle_, then to define `boundary` method on `Circle` struct, we'd need to import `ShapeGeometry` trait in the _circle_ module. - -If the code was organized into modules like this, where the implementation of a trait was defined in a different module than the trait itself, explicitly importing the relevant trait or implementation is required. - -```rust,noplayground -// Here T is an alias type which will be provided during implementation -pub trait ShapeGeometry { - fn boundary(self: T) -> u64; - fn area(self: T) -> u64; -} - -mod rectangle { - // Importing ShapeGeometry is required to implement this trait for Rectangle - use super::ShapeGeometry; - - #[derive(Copy, Drop)] - pub struct Rectangle { - pub height: u64, - pub width: u64, - } - - // Implementation RectangleGeometry passes in - // to implement the trait for that type - impl RectangleGeometry of ShapeGeometry { - fn boundary(self: Rectangle) -> u64 { - 2 * (self.height + self.width) - } - fn area(self: Rectangle) -> u64 { - self.height * self.width - } - } -} - -mod circle { - // Importing ShapeGeometry is required to implement this trait for Circle - use super::ShapeGeometry; - - #[derive(Copy, Drop)] - pub struct Circle { - pub radius: u64 - } - - // Implementation CircleGeometry passes in - // to implement the imported trait for that type - impl CircleGeometry of ShapeGeometry { - fn boundary(self: Circle) -> u64 { - (2 * 314 * self.radius) / 100 - } - fn area(self: Circle) -> u64 { - (314 * self.radius * self.radius) / 100 - } - } -} - -use rectangle::Rectangle; -use circle::Circle; - -fn main() { - let rect = Rectangle { height: 5, width: 7 }; - println!("Rectangle area: {}", ShapeGeometry::area(rect)); //35 - println!("Rectangle boundary: {}", ShapeGeometry::boundary(rect)); //24 - - let circ = Circle { radius: 5 }; - println!("Circle area: {}", ShapeGeometry::area(circ)); //78 - println!("Circle boundary: {}", ShapeGeometry::boundary(circ)); //31 -} -``` - -Note that in this example, `CircleGeometry` and `RectangleGeometry` implementations don't need to be declared as `pub`. Indeed, `ShapeGeometry` trait, which is public, is used to print the result in the `main` function. The compiler will find the appropriate implementation for the `ShapeGeometry` public trait, regardless of the implementation visibility. - -## Impl Aliases - -Implementations can be aliased when imported. This is most useful when you want to instantiate generic implementations with concrete types. For example, let's say we define a trait `Two` that is used to return the value `2` for a type `T`. We can write a trivial generic implementation of `Two` for all types that implement the `One` trait, simply by adding twice the value of `one` and returning it. However, in our public API, we may only want to expose the `Two` implementation for the `u8` and `u128` types. - -```rust,noplayground -trait Two { - fn two() -> T; -} - -mod one_based { - pub impl TwoImpl< - T, +Copy, +Drop, +Add, impl One: core::num::traits::One - > of super::Two { - fn two() -> T { - One::one() + One::one() - } - } -} - -pub impl U8Two = one_based::TwoImpl; -pub impl U128Two = one_based::TwoImpl; -``` - - Listing 8-1: Using impl aliases to instantiate generic impls with concrete types - -We can define the generic implementation in a private module, use an impl alias to instantiate the generic implementation for these two concrete types, and make these two implementations public, while keeping the generic implementation private and unexposed. This way, we can avoid code duplication using the generic implementation, while keeping the public API clean and simple. - -## Negative Impls - -> Note: This is still an experimental feature and can only be used if `experimental-features = ["negative_impls"]` is enabled in your _Scarb.toml_ file, under the `[package]` section. - -Negative implementations, also known as negative traits or negative bounds, are a mechanism that allows you to express that a type does not implement a certain trait when defining the implementation of a trait over a generic type. Negative impls enable you to write implementations that are applicable only when another implementation does not exist in the current scope. - -For example, let's say we have a trait `Producer` and a trait `Consumer`, and we want to define a generic behavior where all types implement the `Consumer` trait by default. However, we want to ensure that no type can be both a `Consumer` and a `Producer`. We can use negative impls to express this restriction. - -In Listing 8-2, we define a `ProducerType` that implements the `Producer` trait, and two other types, `AnotherType` and `AThirdType`, which do not implement the `Producer` trait. We then use negative impls to create a default implementation of the `Consumer` trait for all types that do not implement the `Producer` trait. - -```rust -#[derive(Drop)] -struct ProducerType {} - -#[derive(Drop, Debug)] -struct AnotherType {} - -#[derive(Drop, Debug)] -struct AThirdType {} - -trait Producer { - fn produce(self: T) -> u32; -} - -trait Consumer { - fn consume(self: T, input: u32); -} - -impl ProducerImpl of Producer { - fn produce(self: ProducerType) -> u32 { - 42 - } -} - -impl TConsumerImpl, +Drop, -Producer> of Consumer { - fn consume(self: T, input: u32) { - println!("{:?} consumed value: {}", self, input); - } -} - -fn main() { - let producer = ProducerType {}; - let another_type = AnotherType {}; - let third_type = AThirdType {}; - let production = producer.produce(); - - // producer.consumer(production); Invalid: ProducerType does not implement Consumer - another_type.consume(production); - third_type.consume(production); -} -``` - - Listing 8-2: Using negative impls to enforce that a type cannot implement both `Producer` and `Consumer` traits simultaneously - -In the `main` function, we create instances of `ProducerType`, `AnotherType`, and `AThirdType`. We then call the `produce` method on the `producer` instance and pass the result to the `consume` method on the `another_type` and `third_type` instances. Finally, we try to call the `consume` method on the `producer` instance, which results in a compile-time error because `ProducerType` does not implement the `Consumer` trait. - -{{#quiz ../quizzes/ch08-02-traits.toml}} -# Error handling - -In this chapter, we will explore various error handling techniques provided by Cairo, which not only allow you to address potential issues in your code, but also make it easier to create programs that are adaptable and maintainable. By examining different approaches to managing errors, such as pattern matching with the `Result` enum, using the `?` operator for more ergonomic error propagation, and employing the `unwrap` or `expect` methods for handling recoverable errors, you'll gain a deeper understanding of Cairo's error handling features. These concepts are crucial for building robust applications that can effectively handle unexpected situations, ensuring your code is ready for production. -# Unrecoverable Errors with `panic` - -In Cairo, unexpected issues may arise during program execution, resulting in runtime errors. While the `panic` function from the core library doesn't provide a resolution for these errors, it does acknowledge their occurrence and terminates the program. There are two primary ways that a panic can be triggered in Cairo: inadvertently, through actions causing the code to panic (e.g., accessing an array beyond its bounds), or deliberately, by invoking the `panic` function. - -When a panic occurs, it leads to an abrupt termination of the program. The `panic` function takes an array as an argument, which can be used to provide an error message and performs an unwind process where all variables are dropped and dictionaries squashed to ensure the soundness of the program to safely terminate the execution. - -Here is how we can call `panic` from inside a program and return the error code `2`: - -Filename: src/lib.cairo - -```rust -fn main() { - let mut data = array![2]; - - if true { - panic(data); - } - println!("This line isn't reached"); -} -``` - -Running the program will produce the following output: - -```shell -$ scarb cairo-run - Compiling no_listing_01_panic v0.1.0 (listings/ch09-error-handling/no_listing_01_panic/Scarb.toml) - Finished release target(s) in 1 second - Running no_listing_01_panic -Run panicked with [2, ]. - -``` - -As you can notice in the output, the call to `println!` macro is never reached, as the program terminates after encountering the `panic` statement. - -An alternative and more idiomatic approach to panic in Cairo would be to use the `panic_with_felt252` function. This function serves as an abstraction of the array-defining process and is often preferred due to its clearer and more concise expression of intent. By using `panic_with_felt252`, developers can panic in a one-liner by providing a `felt252` error message as an argument, making the code more readable and maintainable. - -Let's consider an example: - -```rust -use core::panic_with_felt252; - -fn main() { - panic_with_felt252(2); -} -``` - -Executing this program will yield the same error message as before. In that case, if there is no need for an array and multiple values to be returned within the error, `panic_with_felt252` is a more succinct alternative. - -## `panic!` Macro - -`panic!` macro can be really helpful. The previous example returning the error code `2` shows how convenient `panic!` macro is. There is no need to create an array and pass it as an argument like with the `panic` function. - -```rust -fn main() { - if true { - panic!("2"); - } - println!("This line isn't reached"); -} -``` - -Unlike the `panic_with_felt252` function, using `panic!` allows the input, which is ultimately the panic error, to be a literal longer than 31 bytes. This is because `panic!` takes a string as a parameter. For example, the following line of code will successfully compile: - -```rust, noplayground -panic!("the error for panic! macro is not limited to 31 characters anymore"); -``` - -## `nopanic` Notation - -You can use the `nopanic` notation to indicate that a function will never panic. Only `nopanic` functions can be called in a function annotated as `nopanic`. - -Here is an example: - -```rust,noplayground -fn function_never_panic() -> felt252 nopanic { - 42 -} -``` - -This function will always return `42` and is guaranteed to never panic. Conversely, the following function is not guaranteed to never panic: - -```rust,noplayground -fn function_never_panic() nopanic { - assert(1 == 1, 'what'); -} -``` - -If you try to compile this function that includes code that may panic, you will get the following error: - -```shell -$ scarb cairo-run - Compiling no_listing_04_nopanic_wrong v0.1.0 (listings/ch09-error-handling/no_listing_05_nopanic_wrong/Scarb.toml) -error: Function is declared as nopanic but calls a function that may panic. - --> listings/ch09-error-handling/no_listing_05_nopanic_wrong/src/lib.cairo:4:12 - assert(1 == 1, 'what'); - ^****^ - -error: Function is declared as nopanic but calls a function that may panic. - --> listings/ch09-error-handling/no_listing_05_nopanic_wrong/src/lib.cairo:4:5 - assert(1 == 1, 'what'); - ^********************^ - -error: could not compile `no_listing_04_nopanic_wrong` due to previous error -error: `scarb metadata` exited with error - -``` - -Note that there are two functions that may panic here, `assert` and equality with `==`. We usually don't use `assert` function in practice and use `assert!` macro instead. We will discuss `assert!` macro in more detail in the [Testing Cairo Programs][assert macro] chapter. - -[assert macro]: ./ch10-01-how-to-write-tests.md#checking-results-with-the-assert-macro - -## `panic_with` Attribute - -You can use the `panic_with` attribute to mark a function that returns an `Option` or `Result`. This attribute takes two arguments, which are the data that is passed as the panic reason as well as the name for a wrapping function. It will create a wrapper for your annotated function which will panic if the function returns `None` or `Err`, with the given data as the panic error. - -Example: - -```rust -#[panic_with('value is 0', wrap_not_zero)] -fn wrap_if_not_zero(value: u128) -> Option { - if value == 0 { - Option::None - } else { - Option::Some(value) - } -} - -fn main() { - wrap_if_not_zero(0); // this returns None - wrap_not_zero(0); // this panics with 'value is 0' -} -``` - -{{#quiz ../quizzes/ch09-01-unrecoverable-errors-with-panic.toml}} -# Recoverable Errors with `Result` - -Most errors aren’t serious enough to require the program to stop entirely. Sometimes, when a function fails, it’s for a reason that you can easily interpret and respond to. For example, if you try to add two large integers and the operation overflows because the sum exceeds the maximum representable value, you might want to return an error or a wrapped result instead of causing undefined behavior or terminating the process. - -## The `Result` Enum - -Recall from [Generic data types][generic enums] section in Chapter 8 that the `Result` enum is defined as having two variants, `Ok` and `Err`, as follows: - -```rust,noplayground -enum Result { - Ok: T, - Err: E, -} -``` - -The `Result` enum has two generic types, `T` and `E`, and two variants: `Ok` which holds the value of type `T` and `Err` which holds the value of type `E`. This definition makes it convenient to use the `Result` enum anywhere we have an operation that might succeed (by returning a value of type `T`) or fail (by returning a value of type `E`). - -[generic enums]: ./ch08-01-generic-data-types.md#enums - -## The `ResultTrait` - -The `ResultTrait` trait provides methods for working with the `Result` enum, such as unwrapping values, checking whether the `Result` is `Ok` or `Err`, and panicking with a custom message. The `ResultTraitImpl` implementation defines the logic of these methods. - -```rust,noplayground -trait ResultTrait { - fn expect<+Drop>(self: Result, err: felt252) -> T; - - fn unwrap<+Drop>(self: Result) -> T; - - fn expect_err<+Drop>(self: Result, err: felt252) -> E; - - fn unwrap_err<+Drop>(self: Result) -> E; - - fn is_ok(self: @Result) -> bool; - - fn is_err(self: @Result) -> bool; -} -``` - -The `expect` and `unwrap` methods are similar in that they both attempt to extract the value of type `T` from a `Result` when it is in the `Ok` variant. If the `Result` is `Ok(x)`, both methods return the value `x`. However, the key difference between the two methods lies in their behavior when the `Result` is in the `Err` variant. The `expect` method allows you to provide a custom error message (as a `felt252` value) that will be used when panicking, giving you more control and context over the panic. On the other hand, the `unwrap` method panics with a default error message, providing less information about the cause of the panic. - -The `expect_err` and `unwrap_err` methods have the exact opposite behavior. If the `Result` is `Err(x)`, both methods return the value `x`. However, the key difference between the two methods is in case of `Result::Ok()`. The `expect_err` method allows you to provide a custom error message (as a `felt252` value) that will be used when panicking, giving you more control and context over the panic. On the other hand, the `unwrap_err` method panics with a default error message, providing less information about the cause of the panic. - -A careful reader may have noticed the `<+Drop>` and `<+Drop>` in the first four methods signatures. This syntax represents generic type constraints in the Cairo language, as seen in the previous chapter. These constraints indicate that the associated functions require an implementation of the `Drop` trait for the generic types `T` and `E`, respectively. - -Finally, the `is_ok` and `is_err` methods are utility functions provided by the `ResultTrait` trait to check the variant of a `Result` enum value. - -- `is_ok` takes a snapshot of a `Result` value and returns `true` if the `Result` is the `Ok` variant, meaning the operation was successful. If the `Result` is the `Err` variant, it returns `false`. -- `is_err` takes a snapshot of a `Result` value and returns `true` if the `Result` is the `Err` variant, meaning the operation encountered an error. If the `Result` is the `Ok` variant, it returns `false`. - -These methods are helpful when you want to check the success or failure of an operation without consuming the `Result` value, allowing you to perform additional operations or make decisions based on the variant without unwrapping it. - -You can find the implementation of the `ResultTrait` [here][result corelib]. - -It is always easier to understand with examples. Have a look at this function signature: - -```rust,noplayground -fn u128_overflowing_add(a: u128, b: u128) -> Result; -``` - -It takes two `u128` integers, `a` and `b`, and returns a `Result` where the `Ok` variant holds the sum if the addition does not overflow, and the `Err` variant holds the overflowed value if the addition does overflow. - -Now, we can use this function elsewhere. For instance: - -```rust,noplayground -fn u128_checked_add(a: u128, b: u128) -> Option { - match u128_overflowing_add(a, b) { - Result::Ok(r) => Option::Some(r), - Result::Err(r) => Option::None, - } -} - -``` - -Here, it accepts two `u128` integers, `a` and `b`, and returns an `Option`. It uses the `Result` returned by `u128_overflowing_add` to determine the success or failure of the addition operation. The `match` expression checks the `Result` from `u128_overflowing_add`. If the result is `Ok(r)`, it returns `Option::Some(r)` containing the sum. If the result is `Err(r)`, it returns `Option::None` to indicate that the operation has failed due to overflow. The function does not panic in case of an overflow. - -Let's take another example: - -```rust,noplayground -fn parse_u8(s: felt252) -> Result { - match s.try_into() { - Option::Some(value) => Result::Ok(value), - Option::None => Result::Err('Invalid integer'), - } -} -``` - -In this example, the `parse_u8` function takes a `felt252` and tries to convert it into a `u8` integer using the `try_into` method. If successful, it returns `Result::Ok(value)`, otherwise it returns `Result::Err('Invalid integer')`. - -Our two test cases are: - -```rust,noplayground -# fn parse_u8(s: felt252) -> Result { -# match s.try_into() { -# Option::Some(value) => Result::Ok(value), -# Option::None => Result::Err('Invalid integer'), -# } -# } -# -#[cfg(test)] -mod tests { - use super::parse_u8; - - #[test] - fn test_felt252_to_u8() { - let number: felt252 = 5; - // should not panic - let res = parse_u8(number).unwrap(); - } - - #[test] - #[should_panic] - fn test_felt252_to_u8_panic() { - let number: felt252 = 256; - // should panic - let res = parse_u8(number).unwrap(); - } -} -# -# -``` - -Don't worry about the `#[cfg(test)]` attribute for now. We'll explain in more detail its meaning in the next [Testing Cairo Programs][tests] chapter. - -`#[test]` attribute means the function is a test function, and `#[should_panic]` attribute means this test will pass if the test execution panics. - -The first one tests a valid conversion from `felt252` to `u8`, expecting the `unwrap` method not to panic. The second test function attempts to convert a value that is out of the `u8` range, expecting the `unwrap` method to panic with the error message `Invalid integer`. - -[result corelib]: https://github.com/starkware-libs/cairo/blob/main/corelib/src/result.cairo#L20 -[tests]: ./ch10-01-how-to-write-tests.md - -### The `?` Operator - -The last operator we will talk about is the `?` operator. The `?` operator is used for more idiomatic and concise error handling. When you use the `?` operator on a `Result` or `Option` type, it will do the following: - -- If the value is `Result::Ok(x)` or `Option::Some(x)`, it will return the inner value `x` directly. -- If the value is `Result::Err(e)` or `Option::None`, it will propagate the error or `None` by immediately returning from the function. - -The `?` operator is useful when you want to handle errors implicitly and let the calling function deal with them. - -Here is an example: - -```rust,noplayground -fn do_something_with_parse_u8(input: felt252) -> Result { - let input_to_u8: u8 = parse_u8(input)?; - // DO SOMETHING - let res = input_to_u8 - 1; - Result::Ok(res) -} -``` - -We can see that `do_something_with_parse_u8` function takes a `felt252` value as input and calls `parse_u8` function. The `?` operator is used to propagate the error, if any, or unwrap the successful value. - -And with a little test case: - -```rust,noplayground -# fn parse_u8(s: felt252) -> Result { -# match s.try_into() { -# Option::Some(value) => Result::Ok(value), -# Option::None => Result::Err('Invalid integer'), -# } -# } -# -# fn do_something_with_parse_u8(input: felt252) -> Result { -# let input_to_u8: u8 = parse_u8(input)?; -# // DO SOMETHING -# let res = input_to_u8 - 1; -# Result::Ok(res) -# } -# -# #[cfg(test)] -# mod tests { -# use super::do_something_with_parse_u8; - #[test] - fn test_function_2() { - let number: felt252 = 258; - match do_something_with_parse_u8(number) { - Result::Ok(value) => println!("Result: {}", value), - Result::Err(e) => println!("Error: {}", e), - } - } -# } -# -``` - -The console will print the error `Invalid Integer`. - -### Summary - -We saw that recoverable errors can be handled in Cairo using the `Result` enum, which has two variants: `Ok` and `Err`. The `Result` enum is generic, with types `T` and `E` representing the successful and error values, respectively. The `ResultTrait` provides methods for working with `Result`, such as unwrapping values, checking if the result is `Ok` or `Err`, and panicking with custom messages. - -To handle recoverable errors, a function can return a `Result` type and use pattern matching to handle the success or failure of an operation. The `?` operator can be used to implicitly handle errors by propagating the error or unwrapping the successful value. This allows for more concise and clear error handling, where the caller is responsible for managing errors raised by the called function. - -{{#quiz ../quizzes/ch09-02-error-handling-result.toml}} -# Testing Cairo Programs - -Correctness in our programs is the extent to which our code does what we intend it to do. Cairo is designed with a high degree of concern about the correctness of programs, but correctness is complex and not easy to prove. Cairo's linear type system shoulders a huge part of this burden, but the type system cannot catch everything. As such, Cairo includes support for writing tests. - -Testing is a complex skill: although we can’t cover every detail about how to write good tests in one chapter, we’ll discuss the mechanics of Cairo's testing facilities. We’ll talk about the annotations and macros available to you when writing your tests, the default behavior and options provided for running your tests, and how to organize tests into unit tests and integration tests. -# How To Write Tests - -## The Anatomy of a Test Function - -Tests are Cairo functions that verify that the non-test code is functioning in the expected manner. The bodies of test functions typically perform these three actions: - -- Set up any needed data or state. -- Run the code you want to test. -- Assert the results are what you expect. - -Let’s look at the features Cairo provides for writing tests that take these actions, which include: - -- `#[test]` attribute. -- `assert!`, `assert_eq!`, `assert_ne!`, `assert_lt!`, `assert_le!`, `assert_gt!` and `assert_ge!` macros. -- `#[should_panic]` attribute. - -### The Anatomy of a Test Function - -At its simplest, a test in Cairo is a function that’s annotated with the `#[test]` attribute. Attributes are metadata about pieces of Cairo code; one example is the `#[derive()]` attribute we used with structs in [Chapter 5](ch05-01-defining-and-instantiating-structs.md). To change a function into a test function, add `#[test]` on the line before `fn`. When you run your tests with the `scarb cairo-test` command, Scarb runs Cairo's test runner binary that runs the annotated functions and reports on whether each test function passes or fails. - -Let's create a new project called _adder_ using Scarb with the command `scarb new adder`: - -```shell -adder -├── Scarb.toml -└── src - └── lib.cairo -``` - -In _lib.cairo_, let's remove the existing content and add a `tests` module containing the first test, as shown in Listing 10-1. - -Filename: src/lib.cairo - -```rust -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - let result = 2 + 2; - assert!(result == 4, "result is not 4"); - } -} -``` - -Listing 10-1: A simple test function - -Note the `#[test]` annotation: this attribute indicates this is a test function, so the test runner knows to treat this function as a test. We might also have non-test functions to help set up common scenarios or perform common operations, so we always need to indicate which functions are tests. - -We use the `#[cfg(test)]` attribute for the `tests` module, so that the compiler knows the code it contains needs to be compiled only when running tests. This is actually not an option: if you put a simple test with the `#[test]` attribute in a _lib.cairo_ file, it will not compile. We will talk more about the `#[cfg(test)]` attribute in the next [Testing Organization](ch10-02-test-organization.md) section. - -The example function body uses the `assert!` macro, which contains the result of adding 2 and 2, which equals 4. This assertion serves as an example of the format for a typical test. We'll explain in more detail how `assert!` works later in this chapter. Let’s run it to see that this test passes. - -The `scarb cairo-test` command runs all tests found in our project, and shows the following output: - -```shell -$ scarb cairo-test -testing adder ... -running 1 test -test adder::tests::it_works ... ok (gas usage est.: 22540) -test result: ok. 1 passed; 0 failed; 0 ignored; 0 filtered out; -``` - -`scarb cairo-test` compiled and ran the test. We see the line `running 1 test`. The next line shows the name of the test function, called `it_works`, and that the result of running that test is `ok`. The test runner also provides an estimation of the gas consumption. The overall summary `test result: ok.` means that all the tests passed, and the portion that reads `1 passed; 0 failed` totals the number of tests that passed or failed. - -It’s possible to mark a test as ignored so it doesn’t run in a particular instance; we’ll cover that in the [Ignoring Some Tests Unless Specifically Requested](#ignoring-some-tests-unless-specifically-requested) section later in this chapter. Because we haven’t done that here, the summary shows `0 ignored`. We can also pass an argument to the `scarb cairo-test` command to run only a test whose name matches a string; this is called filtering and we’ll cover that in the [Running Single Tests](#running-single-tests) section. Since we haven’t filtered the tests being run, the end of the summary shows `0 filtered out`. - -Let’s start to customize the test to our own needs. First change the name of the `it_works` function to a different name, such as `exploration`, like so: - -```rust, noplayground -#[test] -fn exploration() { - let result = 2 + 2; - assert!(result == 4, "result is not 4"); -} -``` - -Then run `scarb cairo-test` again. The output now shows `exploration` instead of `it_works`: - -```shell -$ scarb cairo-test -testing adder ... -running 1 test -test adder::tests::exploration ... ok (gas usage est.: 22540) -test result: ok. 1 passed; 0 failed; 0 ignored; 0 filtered out; -``` - -Now we’ll add another test, but this time we’ll make a test that fails! Tests fail when something in the test function panics. Each test is run in a new thread, and when the main thread sees that a test thread has died, the test is marked as failed. Enter the new test as a function named `another`, so your _src/lib.cairo_ file looks like in Listing 10-2. - -Filename: src/lib.cairo - -```rust -#[cfg(test)] -mod tests { - #[test] - fn exploration() { - let result = 2 + 2; - assert!(result == 4, "result is not 4"); - } - - #[test] - fn another() { - let result = 2 + 2; - assert!(result == 6, "Make this test fail"); - } -} - -``` - -Listing 10-2: Adding a second test in _lib.cairo_ that will fail - -Run `scarb cairo-test` and you will see the following output: - -```shell -$ scarb cairo-test - Running cairo-test listing_08_03 - Compiling test(listings/ch10-testing-cairo-programs/listing_10_02/Scarb.toml) - Finished release target(s) in 1 second -testing listing_08_03 ... -running 2 tests -test listing_08_03::tests::exploration ... ok (gas usage est.: 22540) -test listing_08_03::tests::another ... fail (gas usage est.: 24810) -failures: - listing_08_03::tests::another - Panicked with "Make this test fail". - - -``` - -Instead of `ok`, the line `adder::another` shows `fail`. A new section appears between the individual results and the summary. It displays the detailed reason for each test failure. In this case, we get the details that `another` failed because it panicked with `"Make this test fail"` error. - -The summary line is displayed at the end: overall, our test result is `FAILED`. We had one test pass and one test fail. - -Now that you’ve seen what the test results look like in different scenarios, let’s look at some functions that are useful in tests. - -## Checking Results with the `assert!` Macro - -The `assert!` macro, provided by Cairo, is useful when you want to ensure that some condition in a test evaluates to `true`. We give the `assert!` macro the first argument that evaluates to a boolean. If the value is `true`, nothing happens and the test passes. If the value is `false`, the `assert!` macro calls `panic()` to cause the test to fail with a message we defined as the second argument. Using the `assert!` macro helps us check that our code is functioning in the way we intended. - -Remember in [Chapter 5][method syntax], we used a `Rectangle` struct and a `can_hold` method, which are repeated here in Listing 10-3. Let’s put this code in the _src/lib.cairo_ file, then write some tests for it using the `assert!` macro. - -Filename: src/lib.cairo - -```rust -#[derive(Drop)] -struct Rectangle { - width: u64, - height: u64, -} - -trait RectangleTrait { - fn can_hold(self: @Rectangle, other: @Rectangle) -> bool; -} - -impl RectangleImpl of RectangleTrait { - fn can_hold(self: @Rectangle, other: @Rectangle) -> bool { - *self.width > *other.width && *self.height > *other.height - } -} -``` - -Listing 10-3: Using the `Rectangle` struct and its `can_hold` method from Chapter 5 - -The `can_hold` method returns a `bool`, which means it’s a perfect use case for the `assert!` macro. We can write a test that exercises the `can_hold` method by creating a `Rectangle` instance that has a width of `8` and a height of `7` and asserting that it can hold another `Rectangle` instance that has a width of `5` and a height of `1`. - -```rust -# #[derive(Drop)] -# struct Rectangle { -# width: u64, -# height: u64, -# } -# -# trait RectangleTrait { -# fn can_hold(self: @Rectangle, other: @Rectangle) -> bool; -# } -# -# impl RectangleImpl of RectangleTrait { -# fn can_hold(self: @Rectangle, other: @Rectangle) -> bool { -# *self.width > *other.width && *self.height > *other.height -# } -# } -# -#[cfg(test)] -mod tests { - use super::Rectangle; - use super::RectangleTrait; - - #[test] - fn larger_can_hold_smaller() { - let larger = Rectangle { height: 7, width: 8, }; - let smaller = Rectangle { height: 1, width: 5, }; - - assert!(larger.can_hold(@smaller), "rectangle cannot hold"); - } -} -# #[cfg(test)] -# mod tests2 { -# use super::Rectangle; -# use super::RectangleTrait; -# -# #[test] -# fn smaller_cannot_hold_larger() { -# let larger = Rectangle { height: 7, width: 8, }; -# let smaller = Rectangle { height: 1, width: 5, }; -# -# assert!(!smaller.can_hold(@larger), "rectangle cannot hold"); -# } -# } -# -``` - -We’ve named our test `larger_can_hold_smaller`, and we’ve created the two `Rectangle` instances that we need. Then we called the `assert!` macro and passed it the result of calling `larger.can_hold(@smaller)`. This expression is supposed to return `true`, so our test should pass. Let’s find out! - -```shell -$ scarb cairo-test -testing adder ... -running 1 test -test adder::tests::larger_can_hold_smaller ... ok (gas usage est.: 54940) -test result: ok. 1 passed; 0 failed; 0 ignored; 0 filtered out; -``` - -It does pass! Let’s add another test, this time asserting that a smaller rectangle cannot hold a larger rectangle: - -Filename: src/lib.cairo - -```rust -# #[derive(Drop)] -# struct Rectangle { -# width: u64, -# height: u64, -# } -# -# trait RectangleTrait { -# fn can_hold(self: @Rectangle, other: @Rectangle) -> bool; -# } -# -# impl RectangleImpl of RectangleTrait { -# fn can_hold(self: @Rectangle, other: @Rectangle) -> bool { -# *self.width > *other.width && *self.height > *other.height -# } -# } -# -# #[cfg(test)] -# mod tests { -# use super::Rectangle; -# use super::RectangleTrait; -# -# #[test] -# fn larger_can_hold_smaller() { -# let larger = Rectangle { height: 7, width: 8, }; -# let smaller = Rectangle { height: 1, width: 5, }; -# -# assert!(larger.can_hold(@smaller), "rectangle cannot hold"); -# } -# } -# #[cfg(test)] -# mod tests2 { -# use super::Rectangle; -# use super::RectangleTrait; -# - #[test] - fn smaller_cannot_hold_larger() { - let larger = Rectangle { height: 7, width: 8, }; - let smaller = Rectangle { height: 1, width: 5, }; - - assert!(!smaller.can_hold(@larger), "rectangle cannot hold"); - } -# } -# -``` - -Listing 10-4: Adding another test in _lib.cairo_ that will pass - -Because the correct result of the `can_hold` method, in this case, is `false`, we need to negate that result before we pass it to the `assert!` macro. As a result, our test will pass if `can_hold` returns `false`: - -```shell -$ scarb cairo-test - Running cairo-test listing_08_06 - Compiling test(listings/ch10-testing-cairo-programs/listing_10_03/Scarb.toml) - Finished release target(s) in 1 second -testing listing_08_06 ... -running 2 tests -test listing_08_06::tests2::smaller_cannot_hold_larger ... ok (gas usage est.: 24180) -test listing_08_06::tests::larger_can_hold_smaller ... ok (gas usage est.: 23580) -test result: ok. 2 passed; 0 failed; 0 ignored; 0 filtered out; - - -``` - -Two tests that pass! Now let’s see what happens to our test results when we introduce a bug in our code. We’ll change the implementation of the `can_hold` method by replacing the `>` sign with a `<` sign when it compares the widths: - -```rust -impl RectangleImpl of RectangleTrait { - fn can_hold(self: @Rectangle, other: @Rectangle) -> bool { - *self.width < *other.width && *self.height > *other.height - } -} -``` - -Running the tests now produces the following: - -```shell -$ scarb cairo-test -testing adder ... -running 2 tests -test adder::tests::larger_can_hold_smaller ... fail (gas usage est.: 57610) -test adder::tests::smaller_cannot_hold_larger ... ok (gas usage est.: 55140) -failures: - adder::larger_can_hold_smaller - Panicked with "rectangle cannot hold". - -Error: test result: FAILED. 1 passed; 1 failed; 0 ignored -``` - -Our tests caught the bug! Because `larger.width` is `8` and `smaller.width` is `5`, the comparison of the widths in `can_hold` now returns `false` (`8` is not less than `5`) in the `larger_can_hold_smaller` test. Notice that the `smaller_cannot_hold_larger` test still passes: to make this test fail, the height comparison should also be modified in `can_hold` method, replacing the `>` sign with a `<` sign. - -[method syntax]: ./ch05-03-method-syntax.md - -## Testing Equality and Comparisons with the `assert_xx!` Macros - -### `assert_eq!` and `assert_ne!` Macros - -A common way to verify functionality is to test for equality between the result -of the code under test and the value you expect the code to return. You could -do this using the `assert!` macro and passing it an expression using the `==` -operator. However, this is such a common test that the standard library -provides a pair of macros — `assert_eq!` and `assert_ne!` — to perform this test -more conveniently. These macros compare two arguments for equality or -inequality, respectively. They’ll also print the two values if the assertion -fails, which makes it easier to see _why_ the test failed; conversely, the -`assert!` macro only indicates that it got a `false` value for the `==` -expression, without printing the values that led to the `false` value. - -In Listing 10-5, we write a function named `add_two` that adds `2` to its -parameter, then we test this function using `assert_eq!` and `assert_ne!` macros. - -Filename: src/lib.cairo - -```rust, noplayground -fn add_two(a: u32) -> u32 { - a + 2 -} - -#[cfg(test)] -mod tests { - use super::add_two; - - #[test] - fn it_adds_two() { - assert_eq!(4, add_two(2)); - } - - #[test] - fn wrong_check() { - assert_ne!(0, add_two(2)); - } -} -``` - -Listing 10-5: Testing the function `add_two` using `assert_eq!` and `assert_ne!` macros - -Let’s check that it passes! - -```shell -$ scarb cairo-test -testing adder ... -running 2 tests -test adder::tests::wrong_check ... ok (gas usage est.: 132000) -test adder::tests::it_adds_two ... ok (gas usage est.: 131500) -test result: ok. 2 passed; 0 failed; 0 ignored; 0 filtered out; -``` - -In the `it_adds_two` test, we pass `4` as argument to `assert_eq!` macro, which is equal to the result of -calling `add_two(2)`. The line for this test is `test adder::tests::it_adds_two ... ok`, and the `ok` text indicates that our test passed. - -In the `wrong_check` test, we pass `0` as argument to `assert_ne!` macro, which is not equal to the result of -calling `add_two(2)`. Tests that use the `assert_ne!` macro will pass if the two values we give it are _not_ equal and -fail if they’re equal. This macro is most useful for cases when we’re not sure -what a value _will_ be, but we know what the value definitely _shouldn’t_ be. -For example, if we’re testing a function that is guaranteed to change its input -in some way, but how the input is changed depends on the day of -the week that we run our tests, the best thing to assert might be that the -output of the function is not equal to the input. - -Let’s introduce a bug into our code to see what `assert_eq!` looks like when it -fails. Change the implementation of the `add_two` function to instead add `3`: - -```rust, noplayground -fn add_two(a: u32) -> u32 { - a + 3 -} -``` - -Run the tests again: - -```shell -$ scarb cairo-test -testing adder ... -running 2 tests -test adder::tests::wrong_check ... ok (gas usage est.: 132000) -test adder::tests::it_adds_two ... fail (gas usage est.: 166800) -failures: - adder::tests::it_adds_two - Panicked with "assertion `4 == add_two(2)` failed. -4: 4 -add_two(2): 5". - -Error: test result: FAILED. 1 passed; 1 failed; 0 ignored -``` - -Our test caught the bug! The `it_adds_two` test failed with the following -message: `` Panicked with "assertion `4 == add_two(2)` failed ``. -It tells us that the assertion that failed was `` "assertion `left == right` failed`` and the `left` -and `right` values are printed on the next lines as `left: left_value` and `right: right_value`. -This helps us start debugging: the `left` argument was `4` but the `right` argument, where we had -`add_two(2)`, was `5`. You can imagine that this would be especially helpful -when we have a lot of tests going on. - -Note that in some languages and test frameworks, the parameters for equality -assertion functions are called `expected` and `actual`, and the order in which -we specify the arguments matters. However, in Cairo, they’re called `left` and -`right`, and the order in which we specify the value we expect and the value -the code produces doesn’t matter. We could write the assertion in this test as -`assert_eq!(add_two(2), 4)`, which would result in the same failure message -that displays `` assertion failed: `(left == right)` ``. - -Here is a simple example comparing two structs, showing how to use `assert_eq!` and `assert_ne!` macros: - -```rust, noplayground -#[derive(Drop, Debug, PartialEq)] -struct MyStruct { - var1: u8, - var2: u8 -} - -#[cfg(test)] -#[test] -fn test_struct_equality() { - let first = MyStruct { var1: 1, var2: 2 }; - let second = MyStruct { var1: 1, var2: 2 }; - let third = MyStruct { var1: 1, var2: 3 }; - - assert_eq!(first, second); - assert_eq!(first, second, "{:?},{:?} should be equal", first, second); - assert_ne!(first, third); - assert_ne!(first, third, "{:?},{:?} should not be equal", first, third); -} -``` - -Under the surface, `assert_eq!` and `assert_ne!` macros use the operators -`==` and `!=`, respectively. They both take snapshots of values as arguments. When the assertions fail, these macros print their -arguments using debug formatting (`{:?}` syntax), which means the values being compared must -implement `PartialEq` and `Debug` traits. All primitive types and most of -the core library types implement these traits. For structs and enums that -you define yourself, you’ll need to implement `PartialEq` to assert equality of -those types. You’ll also need to implement `Debug` to print the values when the -assertion fails. Because both traits are derivable, this is usually as straightforward as adding the -`#[derive(Drop, Debug, PartialEq)]` annotation to your struct or enum definition. See -[Appendix C](./appendix-03-derivable-traits.md) for more details about these and other derivable traits. - -### `assert_lt!`, `assert_le!`, `assert_gt!` and `assert_ge!` Macros - -Comparisons in tests can be done using the `assert_xx!` macros: - -- `assert_lt!` checks if a given value is lower than another value, and reverts otherwise. -- `assert_le!` checks if a given value is lower or equal than another value, and reverts otherwise. -- `assert_gt!` checks if a given value is greater than another value, and reverts otherwise. -- `assert_ge!` checks if a given value is greater or equal than another value, and reverts otherwise. - -Listing 10-6 demonstrates how to use these macros: - -```rust, noplayground -#[derive(Drop, Copy, Debug, PartialEq)] -struct Dice { - number: u8, -} - -impl DicePartialOrd of PartialOrd { - fn lt(lhs: Dice, rhs: Dice) -> bool { - lhs.number < rhs.number - } - - fn le(lhs: Dice, rhs: Dice) -> bool { - lhs.number <= rhs.number - } - - fn gt(lhs: Dice, rhs: Dice) -> bool { - lhs.number > rhs.number - } - - fn ge(lhs: Dice, rhs: Dice) -> bool { - lhs.number >= rhs.number - } -} - -#[cfg(test)] -#[test] -fn test_struct_equality() { - let first_throw = Dice { number: 5 }; - let second_throw = Dice { number: 2 }; - let third_throw = Dice { number: 6 }; - let fourth_throw = Dice { number: 5 }; - - assert_gt!(first_throw, second_throw); - assert_ge!(first_throw, fourth_throw); - assert_lt!(second_throw, third_throw); - assert_le!( - first_throw, fourth_throw, "{:?},{:?} should be lower or equal", first_throw, fourth_throw - ); -} -``` - -Listing 10-6: Example of tests that use the `assert_xx!` macros for comparisons - -In this example, we roll a `Dice` struct multiple times and compare the results. We need to manually implement the `PartialOrd` trait for our struct so that we can compare `Dice` instances with `lt`, `le`, `gt` and `ge` functions, which are used by `assert_lt!`, `assert_le!`, `assert_gt!` and `assert_ge!` macros, respectively. We also need to derive the `Copy` trait on our `Dice` struct to use the instantiated structs multiple times, as the comparison functions take ownership of the variables. - -## Adding Custom Failure Messages - -You can also add a custom message to be printed with the failure message as -optional arguments to `assert!`, `assert_eq!`, and `assert_ne!` macros. Any -arguments specified after the required arguments are passed along to the -`format!` macro (discussed in the [Printing][formatting] chapter), so you can pass a format string that contains `{}` placeholders and -values to go in those placeholders. Custom messages are useful for documenting -what an assertion means; when a test fails, you’ll have a better idea of what -the problem is with the code. - -Let’s add a custom failure message composed of a format -string with a placeholder filled in with the actual value we got from the -`add_two` function: - -```rust, noplayground - #[test] - fn it_adds_two() { - assert_eq!(4, add_two(2), "Expected {}, got add_two(2)={}", 4, add_two(2)); - } -``` - -Now when we run the test, we’ll get a more informative error message: - -```shell -$ scarb cairo-test -testing adder ... -running 1 test -test adder::tests::it_adds_two ... fail (gas usage est.: 590230) -failures: - adder::tests::it_adds_two - Panicked with "assertion `4 == add_two(2)` failed: Expected 4, got add_two(2)=5 -4: 4 -add_two(2): 5". - -Error: test result: FAILED. 0 passed; 1 failed; 0 ignored -``` - -We can see the value we actually got in the test output, which would help us -debug what happened instead of what we were expecting to happen. - -[formatting]: ./ch11-08-printing.md#formatting - -## Checking for panics with `should_panic` - -In addition to checking return values, it’s important to check that our code handles error conditions as we expect. For example, consider the `Guess` type in Listing 10-7: - -Filename: src/lib.cairo - -```rust, noplayground -#[derive(Drop)] -struct Guess { - value: u64, -} - -pub trait GuessTrait { - fn new(value: u64) -> Guess; -} - -impl GuessImpl of GuessTrait { - fn new(value: u64) -> Guess { - if value < 1 || value > 100 { - panic!("Guess must be >= 1 and <= 100"); - } - - Guess { value, } - } -} -``` - -Listing 10-7: `Guess` struct and its `new` method - -Other code that uses `Guess` depends on the guarantee that `Guess` instances will contain only values between `1` and `100`. We can write a test that ensures that attempting to create a `Guess` instance with a value outside that range panics. - -We do this by adding the attribute `should_panic` to our test function. The test passes if the code inside the function panics; the test fails if the code inside the function doesn’t panic. - -```rust, noplayground -#[cfg(test)] -mod tests { - use super::GuessTrait; - - #[test] - #[should_panic] - fn greater_than_100() { - GuessTrait::new(200); - } -} -``` - -We place the `#[should_panic]` attribute after the `#[test]` attribute and before the test function it applies to. Let’s look at the result to see that this test passes: - -```shell -$ scarb cairo-test -testing guess ... -running 1 test -test guess::tests::greater_than_100 ... ok (gas usage est.: 26850) -test result: ok. 1 passed; 0 failed; 0 ignored; 0 filtered out; -``` - -Looks good! Now let’s introduce a bug in our code by removing the condition that the `new` function will panic if the value is greater than `100`: - -```rust, noplayground -# #[derive(Drop)] -# struct Guess { -# value: u64, -# } -# -# trait GuessTrait { -# fn new(value: u64) -> Guess; -# } -# -impl GuessImpl of GuessTrait { - fn new(value: u64) -> Guess { - if value < 1 { - panic!("Guess must be >= 1 and <= 100"); - } - - Guess { value, } - } -} -# -# -``` - -When we run the test, it will fail: - -```shell -$ scarb cairo-test -testing guess ... -running 1 test -test guess::tests::greater_than_100 ... fail (gas usage est.: 23910) -failures: - guess::tests::greater_than_100 - expected panic but finished successfully. - -Error: test result: FAILED. 0 passed; 1 failed; 0 ignored -``` - -We don’t get a very helpful message in this case, but when we look at the test function, we see that it’s annotated with `#[should_panic]` attribute. The failure we got means that the code in the test function did not cause a panic. - -Tests that use `should_panic` can be imprecise. A `should_panic` test would pass even if the test panics for a different reason from the one we were expecting. To make `should_panic` tests more precise, we can add an optional `expected` parameter to the `#[should_panic]` attribute. The test harness will make sure that the failure message contains the provided text. For example, consider the modified code for `GuessImpl` in Listing 10-8 where the `new` function panics with different messages depending on whether the value is too small or too large: - -Filename: src/lib.cairo - -```rust, noplayground -# #[derive(Drop)] -# struct Guess { -# value: u64, -# } -# -# trait GuessTrait { -# fn new(value: u64) -> Guess; -# } -# -impl GuessImpl of GuessTrait { - fn new(value: u64) -> Guess { - if value < 1 { - panic!("Guess must be >= 1"); - } else if value > 100 { - panic!("Guess must be <= 100"); - } - - Guess { value, } - } -} - -#[cfg(test)] -mod tests { - use super::GuessTrait; - - #[test] - #[should_panic(expected: ("Guess must be <= 100",))] - fn greater_than_100() { - GuessTrait::new(200); - } -} -# -# -``` - -Listing 10-8: `new` implementation that panics with different error messages - -The test will pass because the value we put in the `should_panic` attribute’s `expected` parameter is the string that the `Guess::new` method panics with. We need to specify the entire panic message that we expect. - -To see what happens when a `should_panic` test with an expected message fails, let’s again introduce a bug into our code by swapping the bodies of the `if value < 1` and the `else if value > 100` blocks: - -```rust, noplayground -impl GuessImpl of GuessTrait { - fn new(value: u64) -> Guess { - if value < 1 { - panic!("Guess must be <= 100"); - } else if value > 100 { - panic!("Guess must be >= 1"); - } - - Guess { value, } - } -} - -#[cfg(test)] -mod tests { - use super::GuessTrait; - - #[test] - #[should_panic(expected: ("Guess must be <= 100",))] - fn greater_than_100() { - GuessTrait::new(200); - } -} -``` - -This time when we run the `should_panic` test, it will fail: - -```shell -$ scarb cairo-test -testing guess ... -running 1 test -test guess::tests::greater_than_100 ... fail (gas usage est.: 26690) -failures: - guess::tests::greater_than_100 - Panicked with "Guess must be >= 1". -Error: test result: FAILED. 0 passed; 1 failed; 0 ignored -``` - -The failure message indicates that this test did indeed panic as we expected, but the panic message did not include the expected string. The panic message that we did get in this case was `Guess must be >= 1`. Now we can start figuring out where our bug is! - -## Running Single Tests - -Sometimes, running a full test suite can take a long time. If you’re working on code in a particular area, you might want to run only the tests pertaining to that code. You can choose which tests to run by passing `scarb cairo-test` an option `-f` (for "filter"), followed by the name of the test you want to run as an argument. - -To demonstrate how to run a single test, we’ll first create two test functions, as shown in Listing 10-9, and choose which ones to run. - -Filename: src/lib.cairo - -```rust, noplayground -#[cfg(test)] -mod tests { - #[test] - fn add_two_and_two() { - let result = 2 + 2; - assert!(result == 4, "result is not 4"); - } - - #[test] - fn add_three_and_two() { - let result = 3 + 2; - assert!(result == 5, "result is not 5"); - } -} -``` - -Listing 10-9: Two tests with two different names - -We can pass the name of any test function to `cairo-test` to run only that test using the `-f` flag: - -```shell -$ scarb cairo-test -f add_two_and_two -testing adder ... -running 1 test -test adder::tests::add_two_and_two ... ok (gas usage est.: 22540) -test result: ok. 1 passed; 0 failed; 0 ignored; 1 filtered out; -``` - -Only the test with the name `add_two_and_two` ran; the other test didn’t match that name. The test output lets us know we had one more test that didn’t run by displaying `1 filtered out;` at the end. - -We can also specify part of a test name, and any test whose name contains that value will be run. - -## Ignoring Some Tests Unless Specifically Requested - -Sometimes a few specific tests can be very time-consuming to execute, so you might want to exclude them during most runs of `scarb cairo-test`. Rather than listing as arguments all tests you do want to run, you can instead annotate the time-consuming tests using the `#[ignore]` attribute to exclude them, as shown here: - -```rust, noplayground -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - let result = 2 + 2; - assert!(result == 4, "result is not 4"); - } - - #[test] - #[ignore] - fn expensive_test() { // code that takes an hour to run - } -} -``` - -After `#[test]` we add the `#[ignore]` line to the test we want to exclude. Now when we run our tests, `it_works` runs, but `expensive_test` doesn’t: - -```shell -$ scarb cairo-test -testing adder ... -running 2 tests -test adder::tests::expensive_test ... ignored -test adder::tests::it_works ... ok (gas usage est.: 22540) -test result: ok. 1 passed; 0 failed; 1 ignored; 0 filtered out; -``` - -The `expensive_test` function is listed as ignored. - -When you’re at a point where it makes sense to check the results of the ignored tests and you have time to wait for the results, you can run `scarb cairo-test --include-ignored` to run all tests, whether they’re ignored or not. - -## Testing Recursive Functions or Loops - -When testing recursive functions or loops, the test is instantiated by default with a maximum amount of gas that it can consume. This prevents running infinite loops or consuming too much gas, and can help you benchmark the efficiency of your implementations. This value is assumed reasonably large enough, but you can override it by adding the `#[available_gas()]` attribute to the test function. The following example shows how to use it: - -```rust, noplayground -fn sum_n(n: usize) -> usize { - let mut i = 0; - let mut sum = 0; - while i <= n { - sum += i; - i += 1; - }; - sum -} - -#[cfg(test)] -mod tests { - use super::sum_n; - - #[test] - #[available_gas(2000000)] - fn test_sum_n() { - let result = sum_n(10); - assert!(result == 55, "result is not 55"); - } -} -``` - -## Benchmarking the Gas Usage of a Specific Operation - -When you want to benchmark the gas usage of a specific operation, you can use the following pattern in your test function. - -```rust, noplayground -let initial = testing::get_available_gas(); -gas::withdraw_gas().unwrap(); - /// code we want to bench. -println!("{}\n", initial - testing::get_available_gas()); -``` - -The following example shows how to use it to test the gas function of the `sum_n` function above. - -```rust -fn sum_n(n: usize) -> usize { - let mut i = 0; - let mut sum = 0; - while i <= n { - sum += i; - i += 1; - }; - sum -} - -#[cfg(test)] -mod tests { - use super::sum_n; - use core::testing; - use core::gas; - - #[test] - fn benchmark_sum_n_gas() { - let initial = testing::get_available_gas(); - gas::withdraw_gas().unwrap(); - /// code we want to bench. - let _result = sum_n(10); - println!("consumed gas: {}\n", initial - testing::get_available_gas()); - } -} -``` - -The value printed when running `scarb cairo-test` is the amount of gas that was consumed by the benchmarked operation. - -```shell -$ scarb cairo-test -testing adder ... -running 1 test -consumed gas: 80690 - -test adder::tests::benchmark_sum_n_gas ... ok (gas usage est.: 140100) -test result: ok. 1 passed; 0 failed; 0 ignored; 0 filtered out; -``` - -Here, the gas usage of the `sum_n` function is `80690` (decimal representation of the hex number). The total amount consumed by the test is slightly higher at `140100`, due to some extra steps required to run the entire test function. - -{{#quiz ../quizzes/ch10-01-how_to_write_tests.toml}} -# Testing Organization - -We'll think about tests in terms of two main categories: unit tests and integration tests. Unit tests are small and more focused, testing one module in isolation at a time, and can test private functions. Integration tests use your code in the same way any other external code would, using only the public interface and potentially exercising multiple modules per test. - -Writing both kinds of tests is important to ensure that the pieces of your library are doing what you expect them to, separately and together. - -## Unit Tests - -The purpose of unit tests is to test each unit of code in isolation from the rest of the code to quickly pinpoint where code is and isn’t working as expected. You’ll put unit tests in the `src` directory in each file with the code that they’re testing. - -The convention is to create a module named `tests` in each file to contain the test functions and to annotate the module with `#[cfg(test)]` attribute. - -### The Tests Module and `#[cfg(test)]` - -The `#[cfg(test)]` annotation on the tests module tells Cairo to compile and run the test code only when you run `scarb cairo-test`, not when you run `scarb cairo-run`. This saves compile time when you only want to build the library and saves space in the resulting compiled artifact because the tests are not included. You’ll see that because integration tests go in a different directory, they don’t need the `#[cfg(test)]` annotation. However, because unit tests go in the same files as the code, you’ll use `#[cfg(test)]` to specify that they shouldn’t be included in the compiled result. - -Recall that when we created the new _adder_ project in the first section of this chapter, we wrote this first test: - -```rust -#[cfg(test)] -mod tests { - #[test] - fn it_works() { - let result = 2 + 2; - assert!(result == 4, "result is not 4"); - } -} -``` - -The attribute `cfg` stands for configuration and tells Cairo that the following item should only be included given a certain configuration option. In this case, the configuration option is `test`, which is provided by Cairo for compiling and running tests. By using the `cfg` attribute, Cairo compiles our test code only if we actively run the tests with `scarb cairo-test`. This includes any helper functions that might be within this module, in addition to the functions annotated with `#[test]`. - -## Integration Tests - -Integration tests use your library in the same way any other code would. Their purpose is to test whether many parts of your library work together correctly. Units of code that work correctly on their own could have problems when integrated, so test coverage of the integrated code is important as well. To create integration tests, you first need a `tests` directory. - -### The _tests_ Directory - -```shell -adder -├── Scarb.toml -├── src -│   ├── lib.cairo -│   ├── tests -│   │   └── integration_tests.cairo -│   └── tests.cairo -``` - -First of all, add the following code in your _lib.cairo_ file: - -Filename: src/lib.cairo - -```rust, noplayground -fn it_adds_two(a: u8, b: u8) -> u8 { - a + b -} - -#[cfg(test)] -mod tests; -``` - -Note that we still need to use the `#[cfg(test)]` attribute here, because we are in the _lib.cairo_ file of the _src_ directory. -Then, create a _tests.cairo_ file and fill it as follows: - -Filename: src/tests.cairo - -```rust, noplayground -mod integration_tests; -``` - -Finally, enter this code into the _src/tests/integration_tests.cairo_ file: - -Filename: src/tests/integration_tests.cairo - -```rust, noplayground -use adder::it_adds_two; - -#[test] -fn internal() { - assert!(it_adds_two(2, 2) == 4, "internal_adder failed"); -} -``` - -We need to bring our tested functions into each test file scope. For that reason we add `use adder::it_adds_two` at the top of the code, which we didn’t need in the unit tests. - -Then, to run all of our integration tests, we can just add a filter to only run tests whose path contains "integration_tests". - -```shell -$ scarb test -f integration_tests - Running cairo-test adder - Compiling test(listings/ch10-testing-cairo-programs/no_listing_09_integration_test/Scarb.toml) - Finished release target(s) in 1 second -testing adder ... -running 1 test -test adder::tests::integration_tests::internal ... ok (gas usage est.: 23110) -test result: ok. 1 passed; 0 failed; 0 ignored; 0 filtered out; - - -``` - -The result of the tests is the same as what we've been seeing: one line for each test. - -{{#quiz ../quizzes/ch10-02-testing-organization.toml}} -# Advanced Features - -Now, let's learn about more advanced features offered by Cairo. -# Custom Data Structures - -When you first start programming in Cairo, you'll likely want to use arrays -(`Array`) to store collections of data. However, you will quickly realize -that arrays have one big limitation - the data stored in them is immutable. Once -you append a value to an array, you can't modify it. - -This can be frustrating when you want to use a mutable data structure. For -example, say you're making a game where the players have a level, and they can -level up. You might try to store the level of the players in an array: - -```rust,noplayground - let mut level_players = array![5, 1, 10]; -``` - -But then you realize you can't increase the level at a specific index once it's -set. If a player dies, you cannot remove it from the array unless he happens to -be in the first position. - -Fortunately, Cairo provides a handy built-in [dictionary type](./ch03-02-dictionaries.md) called `Felt252Dict` that allows us to -simulate the behavior of mutable data structures. Let's first explore how to create a struct that contains, among others, a `Felt252Dict`. - -> Note: Several concepts used in this chapter were already presented earlier in the book. We recommend checking out the following chapters if you need to revise them: -> [Structs](ch05-00-using-structs-to-structure-related-data.md), -> [Methods](./ch05-03-method-syntax.md), -> [Generic types](./ch08-00-generic-types-and-traits.md), -> [Traits](./ch08-02-traits-in-cairo.md). - -## Dictionaries as Struct Members - -Defining dictionaries as struct members is possible in Cairo but correctly interacting with them may not be entirely seamless. Let's try implementing a custom _user database_ that will allow us to add users and query them. We will need to define a struct to represent the new type and a trait to define its functionality: - -```rust,noplayground -struct UserDatabase { - users_updates: u64, - balances: Felt252Dict, -} - -trait UserDatabaseTrait { - fn new() -> UserDatabase; - fn update_user<+Drop>(ref self: UserDatabase, name: felt252, balance: T); - fn get_balance<+Copy>(ref self: UserDatabase, name: felt252) -> T; -} -``` - -Our new type `UserDatabase` represents a database of users. It is generic over the balances of the users, giving major flexibility to whoever uses our data type. Its two members are: - -- `users_updates`, the number of users updates in the dictionary. -- `balances`, a mapping of each user to its balance. - -The database core functionality is defined by `UserDatabaseTrait`. The following methods are defined: - -- `new` for easily creating new `UserDatabase` types. -- `update_user` to update the balance of users in the database. -- `get_balance` to find user's balance in the database. - -The only remaining step is to implement each of the methods in `UserDatabaseTrait`, but since we are working with [Generic types](./ch08-00-generic-types-and-traits.md) we also need to correctly establish the requirements of `T` so it can be a valid `Felt252Dict` value type: - -1. `T` should implement the `Copy` since it's required for getting values from a `Felt252Dict`. -2. All value types of a dictionary implement the `Felt252DictValue`, our generic type should do as well. -3. To insert values, `Felt252DictTrait` requires all value types to be droppable (implement the `Drop` trait). - -The implementation, with all restrictions in place, would be as follows: - -```rust,noplayground -impl UserDatabaseImpl> of UserDatabaseTrait { - // Creates a database - fn new() -> UserDatabase { - UserDatabase { users_updates: 0, balances: Default::default() } - } - - // Get the user's balance - fn get_balance<+Copy>(ref self: UserDatabase, name: felt252) -> T { - self.balances.get(name) - } - - // Add a user - fn update_user<+Drop>(ref self: UserDatabase, name: felt252, balance: T) { - self.balances.insert(name, balance); - self.users_updates += 1; - } -} -``` - -Our database implementation is almost complete, except for one thing: the compiler doesn't know how to make a `UserDatabase` go out of scope, since it doesn't implement the `Drop` trait, nor the `Destruct` trait. -Since it has a `Felt252Dict` as a member, it cannot be dropped, so we are forced to implement the `Destruct` trait manually (refer to the [Ownership](ch04-01-what-is-ownership.md#the-drop-trait) chapter for more information). -Using `#[derive(Destruct)]` on top of the `UserDatabase` definition won't work because of the use of [Generic types][generics] in the struct definition. We need to code the `Destruct` trait implementation by ourselves: - -```rust,noplayground -impl UserDatabaseDestruct, +Felt252DictValue> of Destruct> { - fn destruct(self: UserDatabase) nopanic { - self.balances.squash(); - } -} -``` - -Implementing `Destruct` for `UserDatabase` was our last step to get a fully functional database. We can now try it out: - -```rust -# struct UserDatabase { -# users_updates: u64, -# balances: Felt252Dict, -# } -# -# trait UserDatabaseTrait { -# fn new() -> UserDatabase; -# fn update_user<+Drop>(ref self: UserDatabase, name: felt252, balance: T); -# fn get_balance<+Copy>(ref self: UserDatabase, name: felt252) -> T; -# } -# -# impl UserDatabaseImpl> of UserDatabaseTrait { -# // Creates a database -# fn new() -> UserDatabase { -# UserDatabase { users_updates: 0, balances: Default::default() } -# } -# -# // Get the user's balance -# fn get_balance<+Copy>(ref self: UserDatabase, name: felt252) -> T { -# self.balances.get(name) -# } -# -# // Add a user -# fn update_user<+Drop>(ref self: UserDatabase, name: felt252, balance: T) { -# self.balances.insert(name, balance); -# self.users_updates += 1; -# } -# } -# -# impl UserDatabaseDestruct, +Felt252DictValue> of Destruct> { -# fn destruct(self: UserDatabase) nopanic { -# self.balances.squash(); -# } -# } -# -fn main() { - let mut db = UserDatabaseTrait::::new(); - - db.update_user('Alex', 100); - db.update_user('Maria', 80); - - db.update_user('Alex', 40); - db.update_user('Maria', 0); - - let alex_latest_balance = db.get_balance('Alex'); - let maria_latest_balance = db.get_balance('Maria'); - - assert!(alex_latest_balance == 40, "Expected 40"); - assert!(maria_latest_balance == 0, "Expected 0"); -} -# -# -``` - -[generics]: ./ch08-00-generic-types-and-traits.md - -## Simulating a Dynamic Array with Dicts - -First, let's think about how we want our mutable dynamic array to behave. What -operations should it support? - -It should: - -- Allow us to append items at the end. -- Let us access any item by index. -- Allow setting the value of an item at a specific index. -- Return the current length. - -We can define this interface in Cairo like: - -```rust,noplayground -trait VecTrait { - fn new() -> V; - fn get(ref self: V, index: usize) -> Option; - fn at(ref self: V, index: usize) -> T; - fn push(ref self: V, value: T) -> (); - fn set(ref self: V, index: usize, value: T); - fn len(self: @V) -> usize; -} -``` - -This provides a blueprint for the implementation of our dynamic array. We named -it _Vec_ as it is similar to the `Vec` data structure in Rust. - -### Implementing a Dynamic Array in Cairo - -To store our data, we'll use a `Felt252Dict` which maps index numbers (felts) -to values. We'll also store a separate `len` field to track the length. - -Here is what our struct looks like. We wrap the type `T` inside `Nullable` -pointer to allow using any type `T` in our data structure, as explained in the -[Dictionaries][nullable] section: - -```rust,noplayground -struct NullableVec { - data: Felt252Dict>, - len: usize -} -``` - -Since we again have `Felt252Dict` as a struct member, we need to implement the `Destruct` trait to tell the compiler how to make `NullableVec` go out of scope. - -```rust,noplayground -impl DestructNullableVec> of Destruct> { - fn destruct(self: NullableVec) nopanic { - self.data.squash(); - } -} -``` - -The key thing that makes this vector mutable is that we can insert values into -the dictionary to set or update values in our data structure. For example, to -update a value at a specific index, we do: - -```rust,noplayground - fn set(ref self: NullableVec, index: usize, value: T) { - assert!(index < self.len(), "Index out of bounds"); - self.data.insert(index.into(), NullableTrait::new(value)); - } -``` - -This overwrites the previously existing value at that index in the dictionary. - -While arrays are immutable, dictionaries provide the flexibility we need for -modifiable data structures like vectors. - -The implementation of the rest of the interface is straightforward. The -implementation of all the methods defined in our interface can be done as follow -: - -```rust,noplayground -impl NullableVecImpl, +Copy> of VecTrait, T> { - fn new() -> NullableVec { - NullableVec { data: Default::default(), len: 0 } - } - - fn get(ref self: NullableVec, index: usize) -> Option { - if index < self.len() { - Option::Some(self.data.get(index.into()).deref()) - } else { - Option::None - } - } - - fn at(ref self: NullableVec, index: usize) -> T { - assert!(index < self.len(), "Index out of bounds"); - self.data.get(index.into()).deref() - } - - fn push(ref self: NullableVec, value: T) -> () { - self.data.insert(self.len.into(), NullableTrait::new(value)); - self.len = core::integer::u32_wrapping_add(self.len, 1_usize); - } - fn set(ref self: NullableVec, index: usize, value: T) { - assert!(index < self.len(), "Index out of bounds"); - self.data.insert(index.into(), NullableTrait::new(value)); - } - fn len(self: @NullableVec) -> usize { - *self.len - } -} -``` - -The full implementation of the `Vec` structure can be found in the -community-maintained library [Alexandria](https://github.com/keep-starknet-strange/alexandria/tree/main/packages/data_structures/src). - -[nullable]: ./ch03-02-dictionaries.md#dictionaries-of-types-not-supported-natively - -## Simulating a Stack with Dicts - -We will now look at a second example and its implementation details: a Stack. - -A Stack is a LIFO (Last-In, First-Out) collection. The insertion of a new -element and removal of an existing element takes place at the same end, -represented as the top of the stack. - -Let us define what operations we need to create a stack: - -- Push an item to the top of the stack. -- Pop an item from the top of the stack. -- Check whether there are still any elements in the stack. - -From these specifications we can define the following interface : - -```rust,noplayground -trait StackTrait { - fn push(ref self: S, value: T); - fn pop(ref self: S) -> Option; - fn is_empty(self: @S) -> bool; -} -``` - -### Implementing a Mutable Stack in Cairo - -To create a stack data structure in Cairo, we can again use a `Felt252Dict` -to store the values of the stack along with a `usize` field to keep track of the -length of the stack to iterate over it. - -The Stack struct is defined as: - -```rust,noplayground -struct NullableStack { - data: Felt252Dict>, - len: usize, -} -``` - -Next, let's see how our main functions `push` and `pop` are implemented. - -```rust,noplayground -impl NullableStackImpl, +Copy> of StackTrait, T> { - fn push(ref self: NullableStack, value: T) { - self.data.insert(self.len.into(), NullableTrait::new(value)); - self.len += 1; - } - - fn pop(ref self: NullableStack) -> Option { - if self.is_empty() { - return Option::None; - } - self.len -= 1; - Option::Some(self.data.get(self.len.into()).deref()) - } - - fn is_empty(self: @NullableStack) -> bool { - *self.len == 0 - } -} -``` - -The code uses the `insert` and `get` methods to access the values in the -`Felt252Dict`. To push an element to the top of the stack, the `push` -function inserts the element in the dict at index `len` and increases the -`len` field of the stack to keep track of the position of the stack top. To -remove a value, the `pop` function decreases the value of `len` to update the -position of the stack top and then retrieves the last value at position `len`. - -The full implementation of the Stack, along with more data structures that you -can use in your code, can be found in the community-maintained -[Alexandria][alexandria data structures] library, in the "data_structures" crate. - -[alexandria data structures]: https://github.com/keep-starknet-strange/alexandria/tree/main/packages/data_structures/src - -{{#quiz ../quizzes/ch11-01-custom-structs.toml}} - -## Summary - -Well done! Now you have knowledge of arrays, dictionaries and even custom data structures. -While Cairo's memory model is immutable and can make it difficult to implement -mutable data structures, we can fortunately use the `Felt252Dict` type to -simulate mutable data structures. This allows us to implement a wide range of -data structures that are useful for many applications, effectively hiding the -complexity of the underlying memory model. -# Smart Pointers - -A pointer is a general concept for a variable that contains a memory address. This address refers to, or “points at,” some other data. While pointers are a powerful feature, they can also be a source of bugs and security vulnerabilities. For example, a pointer can reference an unassigned memory cell, which means that attempting to access the data at that address would cause the program to crash, making it unprovable. To prevent such issues, Cairo uses _Smart Pointers_. - -Smart pointers are data structures that act like a pointer, but also have additional metadata and capabilities. The concept of smart pointers isn’t unique to Cairo: smart pointers originated in C++ and exist in other languages like Rust as well. In the specific case of Cairo, smart pointers ensure that memory is not addressed in an unsafe way that could cause a program to be unprovable, by providing a safe way to access memory through strict type checking and ownership rules. - -Though we didn’t call them as such at the time, we’ve already encountered a few smart pointers in this book, including `Felt252Dict` and `Array` in Chapter 3. Both these types count as smart pointers because they own a memory segment and allow you to manipulate it. They also have metadata and extra capabilities or guarantees. Arrays keep track of their current length to ensure that existing elements are not overwritten, and that new elements are only appended to the end. - -The Cairo VM memory is composed by multiple segments that can store data, each identified by a unique index. When you create an array, you allocate a new segment in the memory to store the future elements. The array itself is just a pointer to that segment where the elements are stored. - -## The `Box` Type to Manipulate Pointers - -The principal smart pointer type in Cairo is a _box_, denoted as `Box`. Manually defining boxes allow you to store data in a specific memory segment of the Cairo VM called the _boxed segment_. This segment is dedicated to store all boxed values, and what remains in the execution segment is only a pointer to the boxed segment. Whenever you instantiate a new pointer variable of type `Box`, you append the data of type `T` to the boxed segment. - -Boxes have very little performance overhead, other than writing their inner values to the boxed segment. But they don’t have many extra capabilities either. You’ll use them most often in these situations: - -- When you have a type whose size can’t be known at compile time and you want to use a value of that type in a context that requires an exact size -- When you have a large amount of data and you want to transfer ownership but ensure the data won’t be copied when you do so - -We’ll demonstrate the first situation in the [“Enabling Recursive Types with Boxes”][nullable recursive types] section. -In the second case, transferring ownership of a large amount of data can take a long time because the data is copied around in memory. To improve performance in this situation, we can store the large amount of data in the boxed segment using a box type. Then, only the small amount of pointer data is copied around in memory, while the data it references stays in one place on the boxed segment. - -[nullable recursive types]: ./ch11-02-smart-pointers.md#enabling-recursive-types-with-nullable-boxes - -### Using a `Box` to Store Data in the Boxed Segment - -Before we discuss the boxed segment storage use cases for `Box`, we’ll cover the syntax and how to interact with values stored within a `Box`. - -Listing 11-1 shows how to use a box to store a value in the boxed segment: - -```rust -fn main() { - let b = BoxTrait::new(5_u128); - println!("b = {}", b.unbox()) -} -``` - -Listing 11-1: Storing a `u128` value in the boxed segment using a box - -We define the variable `b` to have the value of a `Box` that points to the value `5`, which is stored in the boxed segment. This program will print `b = 5`; in this case, we can access the data in the box similar to how we would if this data was simply in the execution memory. Putting a single value in a box isn’t very useful, so you won’t use boxes by themselves in this way very often. Having values like a single `u128` in the execution memory, where they’re stored by default, is more appropriate in the majority of situations. Let’s look at a case where boxes allow us to define types that we wouldn’t be allowed to if we didn’t have boxes. - -### Enabling Recursive Types with Nullable Boxes - - - -### Using Boxes to Improve Performance - -Passing pointers between functions allows you to reference data without copying the data itself. Using boxes can improve performance as it allows you to pass a pointer to some data from one function to another, without the need to copy the entire data in memory before performing the function call. Instead of having to write `n` values into memory before calling a function, only a single value is written, corresponding to the pointer to the data. If the data stored in the box is very large, the performance improvement can be significant, as you would save `n-1` memory operations before each function call. - -Let's take a look at the code in Listing 11-2, which shows two ways of passing data to a function: by value and by pointer. - -```rust -#[derive(Drop)] -struct Cart { - paid: bool, - items: u256, - buyer: ByteArray -} - -fn pass_data(cart: Cart) { - println!("{} is shopping today and bought {} items", cart.buyer, cart.items); -} - -fn pass_pointer(cart: Box) { - let cart = cart.unbox(); - println!("{} is shopping today and bought {} items", cart.buyer, cart.items); -} - -fn main() { - let new_struct = Cart { paid: true, items: 1, buyer: "Eli" }; - pass_data(new_struct); - - let new_box = BoxTrait::new(Cart { paid: false, items: 2, buyer: "Uri" }); - pass_pointer(new_box); -} -``` - -Listing 11-2: Storing large amounts of data in a box for performance. - -The `main` function includes 2 function calls: - -- `pass_data` that takes a variable of type `Cart`. -- `pass_pointer` that takes a pointer of type `Box`. - -When passing data to a function, the entire data is copied into the last available memory cells right before the function call. Calling `pass_data` will copy all 3 fields of `Cart` to memory, while `pass_pointer` only requires the copy of the `new_box` pointer which is of size 1. - -
- box memory -
-
- CairoVM Memory layout when using boxes -
- -The illustration above demonstrates how the memory behaves in both cases. The first instance of `Cart` is stored in the execution segment, and we need to copy all its fields to memory before calling the `pass_data` function. The second instance of `Cart` is stored in the boxed segment, and the pointer to it is stored in the execution segment. When calling the `pass_pointer` function, only the pointer to the struct is copied to memory right before the function call. In both cases, however, instantiating the struct will store all its values in the execution segment: the boxed segment can only be filled with data taken from the execution segment. - -## The `Nullable` Type for Dictionaries - -`Nullable` is another type of smart pointer that can either point to a value or be `null` in the absence of value. It is defined at the Sierra level. This type is mainly used in dictionaries that contain types that don't implement the `zero_default` method of the `Felt252DictValue` trait (i.e., arrays and structs). - -If we try to access an element that does not exist in a dictionary, the code will fail if the `zero_default` method cannot be called. - -[Chapter 3.2][dictionary nullable span] about dictionaries thoroughly explains how to store a `Span` variable inside a dictionary using the `Nullable` type. Please refer to it for further information. - -[dictionary nullable span]: /ch03-02-dictionaries.md#dictionaries-of-types-not-supported-natively - -{{#quiz ../quizzes/ch11-02-smart_pointers.toml}} -# Operator Overloading - -Operator overloading is a feature in some programming languages that allows the redefinition of standard operators, such as addition (`+`), subtraction (`-`), multiplication (`*`), and division (`/`), to work with user-defined types. This can make the syntax of the code more intuitive, by enabling operations on user-defined types to be expressed in the same way as operations on primitive types. - -In Cairo, operator overloading is achieved through the implementation of specific traits. Each operator has an associated trait, and overloading that operator involves providing an implementation of that trait for a custom type. -However, it's essential to use operator overloading judiciously. Misuse can lead to confusion, making the code more difficult to maintain, for example when there is no semantic meaning to the operator being overloaded. - -Consider an example where two `Potions` need to be combined. `Potions` have two data fields, mana and health. Combining two `Potions` should add their respective fields. - -```rust -struct Potion { - health: felt252, - mana: felt252 -} - -impl PotionAdd of Add { - fn add(lhs: Potion, rhs: Potion) -> Potion { - Potion { health: lhs.health + rhs.health, mana: lhs.mana + rhs.mana, } - } -} - -fn main() { - let health_potion: Potion = Potion { health: 100, mana: 0 }; - let mana_potion: Potion = Potion { health: 0, mana: 100 }; - let super_potion: Potion = health_potion + mana_potion; - // Both potions were combined with the `+` operator. - assert(super_potion.health == 100, ''); - assert(super_potion.mana == 100, ''); -} -``` - -In the code above, we're implementing the `Add` trait for the `Potion` type. The add function takes two arguments: `lhs` and `rhs` (left and right-hand side). The function body returns a new `Potion` instance, its field values being a combination of `lhs` and `rhs`. - -As illustrated in the example, overloading an operator requires specification of the concrete type being overloaded. The overloaded generic trait is `Add`, and we define a concrete implementation for the type `Potion` with `Add`. - -{{#quiz ../quizzes/ch11-03-operator-overloading.toml}} -# Hashes - -At its essence, hashing is a process of converting input data (often called a message) of any length into a fixed-size value, typically referred to as a "hash." This transformation is deterministic, meaning that the same input will always produce the same hash value. Hash functions are a fundamental component in various fields, including data storage, cryptography and data integrity verification. They are very often used when developing smart contracts, especially when working with [Merkle trees][merkle tree wiki]. - -In this chapter, we will present the two hash functions implemented natively in the Cairo core library: `Poseidon` and `Pedersen`. We will discuss when and how to use them, and see examples with Cairo programs. - -[merkle tree wiki]: https://en.wikipedia.org/wiki/Merkle_tree#Uses - -### Hash Functions in Cairo - -The Cairo core library provides two hash functions: Pedersen and Poseidon. - -Pedersen hash functions are cryptographic algorithms that rely on [elliptic curve cryptography][ec wiki]. These functions perform operations on points along an elliptic curve — essentially, doing math with the locations of these points — which are easy to do in one direction and hard to undo. This one-way difficulty is based on the Elliptic Curve Discrete Logarithm Problem (ECDLP), which is a problem so hard to solve that it ensures the security of the hash function. The difficulty of reversing these operations is what makes the Pedersen hash function secure and reliable for cryptographic purposes. - -Poseidon is a family of hash functions designed to be very efficient as algebraic circuits. Its design is particularly efficient for Zero-Knowledge proof systems, including STARKs (so, Cairo). Poseidon uses a method called a 'sponge construction,' which soaks up data and transforms it securely using a process known as the Hades permutation. Cairo's version of Poseidon is based on a three-element state permutation with [specific parameters][poseidon parameters]. - -[ec wiki]: https://en.wikipedia.org/wiki/Elliptic-curve_cryptography -[poseidon parameters]: https://github.com/starkware-industries/poseidon/blob/main/poseidon3.txt - -#### When to Use Them? - -Pedersen was the first hash function used on Starknet, and is still used to compute the addresses of variables in storage (for example, `LegacyMap` uses Pedersen to hash the keys of a storage mapping on Starknet). However, as Poseidon is cheaper and faster than Pedersen when working with STARK proofs system, it's now the recommended hash function to use in Cairo programs. - -### Working with Hashes - -The core library makes it easy to work with hashes. The `Hash` trait is implemented for all types that can be converted to `felt252`, including `felt252` itself. For more complex types like structs, deriving `Hash` allows them to be hashed easily using the hash function of your choice - given that all of the struct's fields are themselves hashable. You cannot derive the `Hash` trait on a struct that contains un-hashable values, such as `Array` or `Felt252Dict`, even if `T` itself is hashable. - -The `Hash` trait is accompanied by the `HashStateTrait` and `HashStateExTrait` that define the basic methods to work with hashes. They allow you to initialize a hash state that will contain the temporary values of the hash after each application of the hash function, update the hash state and finalize it when the computation is completed. `HashStateTrait` and `HashStateExTrait` are defined as follows: - -```rust,noplayground -/// A trait for hash state accumulators. -trait HashStateTrait { - fn update(self: S, value: felt252) -> S; - fn finalize(self: S) -> felt252; -} - -/// Extension trait for hash state accumulators. -trait HashStateExTrait { - /// Updates the hash state with the given value. - fn update_with(self: S, value: T) -> S; -} - -/// A trait for values that can be hashed. -trait Hash> { - /// Updates the hash state with the given value. - fn update_state(state: S, value: T) -> S; -} -``` - -To use hashes in your code, you must first import the relevant traits and functions. In the following example, we will demonstrate how to hash a struct using both the Pedersen and Poseidon hash functions. - -The first step is to initialize the hash with either `PoseidonTrait::new() -> HashState` or `PedersenTrait::new(base: felt252) -> HashState` depending on which hash function we want to work with. Then the hash state can be updated with the `update(self: HashState, value: felt252) -> HashState` or `update_with(self: S, value: T) -> S` functions as many times as required. Then the function `finalize(self: HashState) -> felt252` is called on the hash state and it returns the value of the hash as a `felt252`. - -```rust -use core::poseidon::PoseidonTrait; -use core::hash::{HashStateTrait, HashStateExTrait}; - -#[derive(Drop, Hash)] -struct StructForHash { - first: felt252, - second: felt252, - third: (u32, u32), - last: bool, -} - -fn main() -> felt252 { - let struct_to_hash = StructForHash { first: 0, second: 1, third: (1, 2), last: false }; - - let hash = PoseidonTrait::new().update_with(struct_to_hash).finalize(); - hash -} -``` - -Pedersen is different from Poseidon, as it starts with a base state. This base state must be of `felt252` type, which forces us to either hash the struct with an arbitrary base state using the `update_with` method, or serialize the struct into an array to loop through all of its fields and hash its elements together. - -Here is a short example of Pedersen hashing: - -```rust -# use core::pedersen::PedersenTrait; -# use core::hash::{HashStateTrait, HashStateExTrait}; -# -# #[derive(Drop, Hash, Serde, Copy)] -# struct StructForHash { -# first: felt252, -# second: felt252, -# third: (u32, u32), -# last: bool, -# } -# -fn main() -> (felt252, felt252) { - let struct_to_hash = StructForHash { first: 0, second: 1, third: (1, 2), last: false }; - - // hash1 is the result of hashing a struct with a base state of 0 - let hash1 = PedersenTrait::new(0).update_with(struct_to_hash).finalize(); - - let mut serialized_struct: Array = ArrayTrait::new(); - Serde::serialize(@struct_to_hash, ref serialized_struct); - let first_element = serialized_struct.pop_front().unwrap(); - let mut state = PedersenTrait::new(first_element); - - while let Option::Some(value) = serialized_struct.pop_front() { - state = state.update(value); - }; - - // hash2 is the result of hashing only the fields of the struct - let hash2 = state.finalize(); - - (hash1, hash2) -} -# -# -``` - -### Advanced Hashing: Hashing Arrays with Poseidon - -Let us look at an example of hashing a struct that contains a `Span`. -To hash a `Span` or a struct that contains a `Span` you can use the built-in function `poseidon_hash_span(mut span: Span) -> felt252`. Similarly, you can hash `Array` by calling `poseidon_hash_span` on its span. - -First, let us import the following traits and function: - -```rust,noplayground -use core::poseidon::PoseidonTrait; -use core::poseidon::poseidon_hash_span; -use core::hash::{HashStateTrait, HashStateExTrait}; -``` - -Now we define the struct. As you might have noticed, we didn't derive the `Hash` trait. If you attempt to derive the `Hash` trait for this struct, it will result in an error because the structure contains a field that is not hashable. - -```rust, noplayground -#[derive(Drop)] -struct StructForHashArray { - first: felt252, - second: felt252, - third: Array, -} -``` - -In this example, we initialized a `HashState` (`hash`), updated it and then called the function `finalize()` on the -`HashState` to get the computed hash `hash_felt252`. We used `poseidon_hash_span` on the `Span` of the `Array` to compute its hash. - -```rust -# use core::poseidon::PoseidonTrait; -# use core::poseidon::poseidon_hash_span; -# use core::hash::{HashStateTrait, HashStateExTrait}; -# -# #[derive(Drop)] -# struct StructForHashArray { -# first: felt252, -# second: felt252, -# third: Array, -# } -# -fn main() { - let struct_to_hash = StructForHashArray { first: 0, second: 1, third: array![1, 2, 3, 4, 5] }; - - let mut hash = PoseidonTrait::new().update(struct_to_hash.first).update(struct_to_hash.second); - let hash_felt252 = hash.update(poseidon_hash_span(struct_to_hash.third.span())).finalize(); -} -# -# -``` -# Macros - -The Cairo language has some plugins that allow developers to simplify their code. They are called `inline_macros` and are a way of writing code that generates other code. - -## `consteval_int!` Macro - -In some situations, a developer might need to declare a constant that is the result of a computation of integers. To compute a constant expression and use its result at compile time, it is required to use the `consteval_int!` macro. - -Here is an example of `consteval_int!`: - -```rust,noplayground -const a: felt252 = consteval_int!(2 * 2 * 2); -``` - -This will be interpreted as `const a: felt252 = 8;` by the compiler. - -## `selector!` Macro - -See [Entry Point Selector](./ch15-02-contract-dispatchers-library-dispatchers-and-system-calls.md#entry-point-selector). - -## `print!` and `println!` Macros - -Please refer to the [Printing](./ch11-08-printing.md) page. - -## `array!` Macro - -Please refer to the [Arrays](./ch03-01-arrays.md) page. - -## `panic!` Macro - -See [Unrecoverable Errors with panic](./ch09-01-unrecoverable-errors-with-panic.html#panic-macro) page. - -## `assert!` and `assert_xx!` Macros - -See [How to Write Tests](./ch10-01-how-to-write-tests.md) page. - -## `format!` Macro - -See [Printing](./ch11-08-printing.html#formatting) page. - -## `write!` and `writeln!` Macros - -See [Printing](./ch11-08-printing.html#printing-custom-data-types) page. - -## `get_dep_component!`, `get_dep_component_mut` and `component!` Macros - -Please refer to the [Composability and Components](./ch16-02-00-composability-and-components.md) chapter. -# Inlining in Cairo - -Inlining is a common code optimization technique supported by most compilers. It involves replacing a function call at the call site with the actual code of the called function, eliminating the overhead associated with the function call itself. This can improve performance by reducing the number of instructions executed, but may increase the total size of the program. When you're thinking about whether to inline a function, take into account things like how big it is, what parameters it has, how often it gets called, and how it might affect the size of your compiled code. - -## The `inline` Attribute - -In Cairo, the `inline` attribute suggests whether or not the Sierra code corresponding to the attributed function should be directly injected in the caller function's context, rather than using a `function_call` libfunc to execute that code. - -There are three variants of the `inline` attribute that one can use: - -- `#[inline]` suggests performing an inline expansion. -- `#[inline(always)]` suggests that an inline expansion should always be performed. -- `#[inline(never)]` suggests that an inline expansion should never be performed. - -> Note: the `inline` attribute in every form is a hint, with no requirements on the language to place a copy of the attributed function in the caller. This means that the attribute may be ignored by the compiler. In practice, `#[inline(always)]` will cause inlining in all but the most exceptional cases. - -Many of the Cairo corelib functions are inlined. User-defined functions may also be annotated with the `inline` attribute. Annoting functions with the `#[inline(always)]` attribute reduces the total number of steps required when calling these attributed functions. Indeed, injecting the Sierra code at the caller site avoids the step-cost involved in calling functions and obtaining their arguments. - -However, inlining can also lead to increased code size. Whenever a function is inlined, the call site contains a copy of the function's Sierra code, potentially leading to duplication of code across the compiled code. - -Therefore, inlining should be applied with caution. Using `#[inline]` or `#[inline(always)]` indiscriminately will lead to increased compile time. It is particularly useful to inline small functions, ideally with many arguments. This is because inlining large functions will increase the code length of the program, and handling many arguments will increase the number of steps to execute these functions. - -The more frequently a function is called, the more beneficial inlining becomes in terms of performance. By doing so, the number of steps for the execution will be lower, while the code length will not grow that much or might even decrease in terms of total number of instructions. - -> Inlining is often a tradeoff between number of steps and code length. Use the `inline` attribute cautiously where it is appropriate. - -## Inlining Example - -Let's introduce a short example to illustrate the mechanisms of inlining in Cairo. Listing 11-3 shows a basic program allowing comparison between inlined and non-inlined functions. - -```rust -fn main() -> felt252 { - inlined() + not_inlined() -} - -#[inline(always)] -fn inlined() -> felt252 { - 1 -} - -#[inline(never)] -fn not_inlined() -> felt252 { - 2 -} -``` - -Listing 11-3: A small Cairo program that adds the return value of 2 functions, with one of them being inlined - -Let's take a look at the corresponding Sierra code to see how inlining works under the hood: - -```rust,noplayground -// type declarations -type felt252 = felt252 [storable: true, drop: true, dup: true, zero_sized: false] - -// libfunc declarations -libfunc function_call = function_call -libfunc felt252_const<1> = felt252_const<1> -libfunc store_temp = store_temp -libfunc felt252_add = felt252_add -libfunc felt252_const<2> = felt252_const<2> - -// statements -00 function_call() -> ([0]) -01 felt252_const<1>() -> ([1]) -02 store_temp([1]) -> ([1]) -03 felt252_add([1], [0]) -> ([2]) -04 store_temp([2]) -> ([2]) -05 return([2]) -06 felt252_const<1>() -> ([0]) -07 store_temp([0]) -> ([0]) -08 return([0]) -09 felt252_const<2>() -> ([0]) -10 store_temp([0]) -> ([0]) -11 return([0]) - -// funcs -main::main::main@0() -> (felt252) -main::main::inlined@6() -> (felt252) -main::main::not_inlined@9() -> (felt252) -``` - -The Sierra file is structured in three parts: - -- Type and libfunc declarations. -- Statements that constitute the program. -- Declaration of the functions of the program. - -The Sierra code statements always match the order of function declarations in the Cairo program. Indeed, the declaration of the functions of the program tells us that: - -- `main` function starts at line 0, and returns a `felt252` on line 5. -- `inlined` function starts at line 6, and returns a `felt252` on line 8. -- `not_inlined` function starts at line 9, and returns a `felt252` on line 11. - -All statements corresponding to the `main` function are located between lines 0 and 5: - -```rust,noplayground -00 function_call() -> ([0]) -01 felt252_const<1>() -> ([1]) -02 store_temp([1]) -> ([1]) -03 felt252_add([1], [0]) -> ([2]) -04 store_temp([2]) -> ([2]) -05 return([2]) -``` - -The `function_call` libfunc is called on line 0 to execute the `not_inlined` function. This will execute the code from lines 9 to 10 and store the return value in the variable with id `0`. - -```rust,noplayground -09 felt252_const<2>() -> ([0]) -10 store_temp([0]) -> ([0]) -``` - -This code uses a single data type, `felt252`. It uses two library functions - `felt_const<2>`, which returns the constant `felt252` 2, and `store_temp`, which pushes a constant value to memory. The first line calls the `felt_const<2>` libfunc to create a variable with id `0`. Then, the second line pushes this variable to memory for later use. - -After that, Sierra statements from line 1 to 2 are the actual body of the `inlined` function: - -```rust,noplayground -06 felt252_const<1>() -> ([0]) -07 store_temp([0]) -> ([0]) -``` - -The only difference is that the inlined code will store the `felt252_const` value in a variable with id `1`, because `[0]` refers to a variable previously assigned: - -```rust,noplayground -01 felt252_const<1>() -> ([1]) -02 store_temp([1]) -> ([1]) -``` - -> Note: in both cases (inlined or not), the `return` instruction of the function being called is not executed, as this would lead to prematurely end the execution of the `main` function. Instead, return values of `inlined` and `not_inlined` will be added and the result will be returned. - -Lines 3 to 5 contain the Sierra statements that will add the values contained in variables with ids `0` and `1`, store the result in memory and return it: - -```rust,noplayground -03 felt252_add([1], [0]) -> ([2]) -04 store_temp([2]) -> ([2]) -05 return([2]) -``` - -Now, let's take a look at the Casm code corresponding to this program to really understand the benefits of inlining. - -## Casm Code Explanations - -Here is the Casm code for our previous program example: - -```rust,noplayground -1 call rel 3 -2 ret -3 call rel 9 -4 [ap + 0] = 1, ap++ -5 [ap + 0] = [ap + -1] + [ap + -2], ap++ -6 ret -7 [ap + 0] = 1, ap++ -8 ret -9 [ap + 0] = 2, ap++ -10 ret -11 ret -``` - -Don't hesitate to use [cairovm.codes](https://cairovm.codes/) playground to follow along and see all the execution trace. - -Each instruction and each argument for any instruction increment the Program Counter (known as PC) by 1. This means that `ret` on line 2 is actually the instruction at `PC = 3`, as the argument `3` corresponds to `PC = 2`. - -The `call` and `ret` instructions allow implementation of a function stack: - -- `call` instruction acts like a jump instruction, updating the PC to a given value, whether relatively to the current value using `rel` or absolutely using `abs`. -- `ret` instruction jumps back right after the `call` instruction and continues the execution of the code. - -We can now decompose how these instructions are executed to understand what this code does: - -- `call rel 3`: this instruction increments the PC by 3 and executes the instruction at this location, which is `call rel 9` at `PC = 4`. -- `call rel 9` increments the PC by 9 and executes the instruction at `PC = 13`, which is actually line 9. -- `[ap + 0] = 2, ap++`: `ap` stands for Allocation Pointer, which points to the first memory cell that has not been used by the program so far. This means we store the value `2` in the next free memory cell indicated by the current value of `ap`, after which we increment `ap` by 1. Then, we go to the next line which is `ret`. -- `ret`: jumps back to the line after `call rel 9`, so we go to line 4. -- `[ap + 0] = 1, ap++` : we store the value `1` in `[ap]` and we apply `ap++` so that `[ap - 1] = 1`. This means we now have `[ap-1] = 1, [ap-2] = 2` and we go to the next line. -- `[ap + 0] = [ap + -1] + [ap + -2], ap++`: we sum the values `1` and `2` and store the result in `[ap]`, and we apply `ap++` so the result is `[ap-1] = 3, [ap-2] = 1, [ap-3]=2`. -- `ret`: jumps back to the line after `call rel 3`, so we go to line 2. -- `ret`: last instruction executed as there is no more `call` instruction where to jump right after. This is the actual return instruction of the Cairo `main` function. - -To summarize: - -- `call rel 3` corresponds to the `main` function, which is obviously not inlined. -- `call rel 9` triggers the call the `not_inlined` function, which returns `2` and stores it at the final location `[ap-3]`. -- The line 4 is the inlined code of the `inlined` function, which returns `1` and stores it at the final location `[ap-2]`. We clearly see that there is no `call` instruction in this case, because the body of the function is inserted and directly executed. -- After that, the sum is computed and we ultimately go back to the line 2 which contains the final `ret` instruction that returns the sum, corresponding to the return value of the `main` function. - -It is interesting to note that in both Sierra code and Casm code, the `not_inlined` function will be called and executed before the body of the `inlined` function, even though the Cairo program executes `inlined() + not_inlined()`. - -> The Casm code of our program clearly shows that there is a function call for the `not_inlined` function, while the `inlined` function is correctly inlined. - -## Additional Optimizations - -Let's study another program that shows other benefits that inlining may sometimes provide. Listing 11-4 shows a Cairo program that calls 2 functions and doesn't return anything: - -```rust -fn main() { - inlined(); - not_inlined(); -} - -#[inline(always)] -fn inlined() -> felt252 { - 'inlined' -} - -#[inline(never)] -fn not_inlined() -> felt252 { - 'not inlined' -} -``` - -Listing 11-4: A small Cairo program that calls `inlined` and `not_inlined` and doesn't return any value. - -Here is the corresponding Sierra code: - -```rust,noplayground -// type declarations -type felt252 = felt252 [storable: true, drop: true, dup: true, zero_sized: false] -type Unit = Struct [storable: true, drop: true, dup: true, zero_sized: true] - -// libfunc declarations -libfunc function_call = function_call -libfunc drop = drop -libfunc struct_construct = struct_construct -libfunc felt252_const<29676284458984804> = felt252_const<29676284458984804> -libfunc store_temp = store_temp -libfunc felt252_const<133508164995039583817065828> = felt252_const<133508164995039583817065828> - -// statements -00 function_call() -> ([0]) -01 drop([0]) -> () -02 struct_construct() -> ([1]) -03 return([1]) -04 felt252_const<29676284458984804>() -> ([0]) -05 store_temp([0]) -> ([0]) -06 return([0]) -07 felt252_const<133508164995039583817065828>() -> ([0]) -08 store_temp([0]) -> ([0]) -09 return([0]) - -// funcs -main::main::main@0() -> (Unit) -main::main::inlined@4() -> (felt252) -main::main::not_inlined@7() -> (felt252) -``` - -In this specific case, we can observe that the compiler has applied additional optimizations to the `main` function of our code : the code of the `inlined` function, which is annotated with the `#[inline(always)]` attribute, is actually not copied in the `main` function. Instead, the `main` function starts with the `function_call` libfunc to call the `not_inlined` function, entirely omitting the code of the `inlined` function. - -> Because `inlined` return value is never used, the compiler optimizes the `main` function by skipping the `inlined` function code. This will actually reduce the code length while reducing the number of steps required to execute `main`. - -In contrast, line 0 uses the `function_call` libfunc to execute the `not_inlined` function normally. This means that all the code from lines 7 to 8 will be executed: - -```rust,noplayground -07 felt252_const<133508164995039583817065828>() -> ([0]) -08 store_temp([0]) -> ([0]) -``` - -This value stored in the variable with id `0` is then dropped on line 1, as it is not used in the `main` function: - -```rust,noplayground -01 drop([0]) -> () -``` - -Finally, as the `main` function doesn't return any value, a variable of unit type `()` is created and returned: - -```rust,noplayground -02 struct_construct() -> ([1]) -03 return([1]) -``` - -## Summary - -Inlining is a compiler optimization technique that can be very useful in various situations. Inlining a function allows to get rid of the overhead of calling a function with the `function_call` libfunc by injecting the Sierra code directly in the caller function's context, while potentially optimizing the Sierra code executed to reduce the number of steps. If used effectively, inlining can even reduce code length as shown in the previous example. - -Nevertheless, applying the `inline` attribute to a function with a lot of code and few parameters might result in an increased code size, especially if the inlined function is used many times in the codebase. Use inlining only where it makes sense, and be aware that the compiler handles inlining by default. Therefore, manually applying inlining is not recommended in most situations, but can help improve and fine-tune your code's behavior. -# Printing - -When writing a program, it is quite common to print some data to the console, either for the normal process of the program or for debugging purpose. In this chapter, we describe the options you have to print simple and complex data types. - -## Printing Standard Data Types - -Cairo provides two macros to print standard data types: - -- `println!` which prints on a new line -- `print!` with inline printing - -Both take a `ByteArray` string as first parameter (see [Data Types][byte array]), which can be a simple string to print a message or a string with placeholders to format the way values are printed. - -There are two ways to use these placeholders and both can be mixed: - -- empty curly brackets `{}` are replaced by values given as parameters to the `print!` macro, in the same order. -- curly brackets with variable names are directly replaced by the variable value. - -Here are some examples: - -```rust -fn main() { - let a = 10; - let b = 20; - let c = 30; - - println!("Hello world!"); - println!("{} {} {}", a, b, c); // 10 20 30 - println!("{c} {a} {}", b); // 30 10 20 -} -``` - -> `print!` and `println!` macros use the `Display` trait under the hood, and are therefore used to print the value of types that implement it. This is the case for basic data types, but not for more complex ones. If you try to print complex data type values with these macros, e.g. for debugging purposes, you will get an error. In that case, you can either [manually implement][print with display] the `Display` trait for your type or use the `Debug` trait (see [below][print with debug]). - -[byte array]: ./ch02-02-data-types.md#byte-array-strings -[print with display]: ./ch11-08-printing.md#printing-custom-data-types -[print with debug]: ./ch11-08-printing.md#print-debug-traces - -## Formatting - -Cairo also provides a useful macro to handle string formatting: `format!`. This macro works like `println!`, but instead of printing the output to the screen, it returns a `ByteArray` with the contents. In the following example, we perform string concatenation using either the `+` operator or the -`format!` macro. The version of the code using `format!` is much easier to read, and the code generated by the `format!` macro uses snapshots, so that this call doesn’t take ownership of any of its parameters. - -```rust -fn main() { - let s1: ByteArray = "tic"; - let s2: ByteArray = "tac"; - let s3: ByteArray = "toe"; - let s = s1 + "-" + s2 + "-" + s3; - // using + operator consumes the strings, so they can't be used again! - - let s1: ByteArray = "tic"; - let s2: ByteArray = "tac"; - let s3: ByteArray = "toe"; - let s = format!("{s1}-{s2}-{s3}"); // s1, s2, s3 are not consumed by format! - // or - let s = format!("{}-{}-{}", s1, s2, s3); - - println!("{}", s); -} -``` - -## Printing Custom Data Types - -As previously explained, if you try to print the value of a custom data type with `print!` or `println!` macros, you'll get an error telling you that the `Display` trait is not implemented for your custom type: - -```shell -error: Trait has no implementation in context: core::fmt::Display:: -``` - -The `println!` macro can do many kinds of formatting, and by default, the curly brackets tell `println!` to use formatting known as `Display` - output intended for direct end user consumption. The primitive types we’ve seen so far implement `Display` by default because there’s only one way you’d want to show a `1` or any other primitive type to a user. But with structs, the way `println!` should format the output is less clear because there are more display possibilities: Do we want commas or not? Do we want to print the curly brackets? Should all the fields be shown? Due to this ambiguity, Cairo doesn’t try to guess what we want, and structs don’t have a provided implementation of `Display` to use with `println!` and the `{}` placeholder. - -Here is the `Display` trait to implement: - -```rust,noplayground -trait Display { - fn fmt(self: @T, ref f: Formatter) -> Result<(), Error>; -} -``` - -The second parameter `f` is of type `Formatter`, which is just a struct containing a `ByteArray`, representing the pending result of formatting: - -```rust,noplayground -#[derive(Default, Drop)] -pub struct Formatter { - /// The pending result of formatting. - pub buffer: ByteArray, -} -``` - -Knowing this, here is an example of how to implement the `Display` trait for a custom `Point` struct: - -```rust -use core::fmt::{Display, Formatter, Error}; - -#[derive(Copy, Drop)] -struct Point { - x: u8, - y: u8 -} - -impl PointDisplay of Display { - fn fmt(self: @Point, ref f: Formatter) -> Result<(), Error> { - let str: ByteArray = format!("Point ({}, {})", *self.x, *self.y); - f.buffer.append(@str); - Result::Ok(()) - } -} - -fn main() { - let p = Point { x: 1, y: 3 }; - println!("{}", p); // Point: (1, 3) -} -``` - -Cairo also provides the `write!` and `writeln!` macros to write formatted strings in a formatter. -Here is a short example using `write!` macro to concatenate multiple strings on the same line and then print the result: - -```rust -use core::fmt::Formatter; - -fn main() { - let mut formatter: Formatter = Default::default(); - let a = 10; - let b = 20; - write!(formatter, "hello"); - write!(formatter, "world"); - write!(formatter, " {a} {b}"); - - println!("{}", formatter.buffer); // helloworld 10 20 -} -``` - -It is also possible to implement the `Display` trait for the `Point` struct using these macros, as shown here: - -```rust -use core::fmt::{Display, Formatter, Error}; - -#[derive(Copy, Drop)] -struct Point { - x: u8, - y: u8 -} - -impl PointDisplay of Display { - fn fmt(self: @Point, ref f: Formatter) -> Result<(), Error> { - let x = *self.x; - let y = *self.y; - - writeln!(f, "Point ({x}, {y})") - } -} - -fn main() { - let p = Point { x: 1, y: 3 }; - println!("{}", p); // Point: (1, 3) -} -``` - -> Printing complex data types this way might not be ideal as it requires additional steps to use the `print!` and `println!` macros. If you need to print complex data types, especially when debugging, use the `Debug` trait described below instead. - -## Print Debug Traces - -Cairo provides the `Debug` trait, which can be derived to print the value of variables when debugging. Simply add `:?` within the curly brackets `{}` placeholders in a `print!` or `println!` macro string. - -This trait is very useful and is implemented by default for basic data types. It can also be simply derived for complex data types using the `#[derive(Debug)]` attribute, as long as all types they contain implement it. This eliminates the need to manually implement extra code to print complex data types. - -Note that `assert_xx!` macros used in tests require the provided values to implement the `Debug` trait, as they also print the result in case of assertion failure. - -For more details about the `Debug` trait and its usage for printing values when debugging, please refer to the [Derivable Traits][debug trait] appendix. - -[debug trait]: ./appendix-03-derivable-traits.md#debug-trait-for-printing-and-debugging -# Introduction to Starknet Smart Contracts - -All through the previous sections, you've mostly written programs with a `main` entrypoint. In the coming sections, you will learn to write and deploy Starknet contracts. - -One of the key applications of the Cairo language is writing smart contracts for the Starknet network. Starknet is a permissionless decentralized network that leverages zk-STARKs technology for scalability. As a Layer 2 (L2) scalability solution for Ethereum, Starknet aims to provide fast, secure, and low-cost transactions. It operates as a validity rollup, commonly known as a zero-knowledge rollup, and is built on top of the Cairo VM. - -Starknet contracts are programs specifically designed to run within the Starknet OS. The Starknet OS is a Cairo program itself, which means that any operation executed by the Starknet OS can be proven and succinctly verified. Smart contracts can access Starknet's persistent state through the OS, enabling them to read or modify variables in Starknet’s state, communicate with other contracts, and interact seamlessly with the underlying Layer 1 (L1) network. - -If you want to learn more about the Starknet network itself, its architecture and the tooling available, you should read the [Starknet Book][starknet book]. In this book, we will only focus on writing smart contracts in Cairo. - -[starknet book]: https://book.starknet.io/ - -## Scarb - -Scarb facilitates smart contract development for Starknet. To enable this feature, you'll need to make some configurations in your _Scarb.toml_ file (see [Installation][scarb installation] for how to install Scarb). - -First, add the `starknet` dependency to your _Scarb.toml_ file. Next, enable the Starknet contract compilation of the package by adding a `[[target.starknet-contract]]` section. By default, specifying this target will build a Sierra Contract Class file, which can be deployed on Starknet. If you omit to specify the target, your package will compile but will not produce an output that you can use with Starknet. - -Below is the minimal _Scarb.toml_ file required to compile a crate containing Starknet contracts: - -```toml -[package] -name = "package_name" -version = "0.1.0" - -[dependencies] -starknet = ">=2.6.3" - -[[target.starknet-contract]] -``` - -To compile contracts defined in your package's dependencies, please refer to the [Scarb documentation][compile dep contract]. - -[scarb installation]: ./ch01-01-installation.md -[compile dep contract]: https://docs.swmansion.com/scarb/docs/extensions/starknet/contract-target.html#compiling-external-contracts - -## Starknet Foundry - -Starknet Foundry is a tool chain for Starknet smart contract development. It supports many features, including writing and running tests with advanced features, deploying contracts, interacting with the Starknet network, and more. - -We'll describe Starknet Foundry in more detail in [Chapter 17][testing with snfoundry] when discussing Starknet smart contract testing and security. - -[testing with snfoundry]: ./ch17-02-testing-smart-contracts.md#testing-smart-contracts-with-starknet-foundry -# General Introduction to Smart Contracts - -This chapter will give you a high level introduction to what smart contracts are, what they are used for, and why blockchain developers would use Cairo and Starknet. -If you are already familiar with blockchain programming, feel free to skip this chapter. The last part might still be interesting though. - -## Smart Contracts - -Smart contracts gained popularity and became more widespread with the birth of Ethereum. Smart contracts are essentially programs deployed on a blockchain. The term "smart contract" is somewhat misleading, as they are neither "smart" nor "contracts" but rather code and instructions that are executed based on specific inputs. They primarily consist of two components: storage and functions. Once deployed, users can interact with smart contracts by initiating blockchain transactions containing execution data (which function to call and with what input). Smart contracts can modify and read the storage of the underlying blockchain. A smart contract has its own address and is considered a blockchain account, meaning it can hold tokens. - -The programming language used to write smart contracts varies depending on the blockchain. For example, on Ethereum and the [EVM-compatible ecosystem][evm], the most commonly used language is Solidity, while on Starknet, it is Cairo. The way the code is compiled also differs based on the blockchain. On Ethereum, Solidity is compiled into bytecode. On Starknet, Cairo is compiled into Sierra and then into Cairo Assembly (CASM). - -Smart contracts possess several unique characteristics. They are **permissionless**, meaning anyone can deploy a smart contract on the network (within the context of a decentralized blockchain, of course). Smart contracts are also **transparent**; the data stored by the smart contract is accessible to anyone. The code that composes the contract can also be transparent, enabling **composability**. This allows developers to write smart contracts that use other smart contracts. Smart contracts can only access and interact with data from the blockchain they are deployed on. They require third-party software (called _oracles_) to access external data (the price of a token for instance). - -For developers to build smart contracts that can interact with each other, it is required to know what the other contracts look like. Hence, Ethereum developers started to build standards for smart contract development, the `ERCxx`. The two most used and famous standards are the `ERC20`, used to build tokens like `USDC`, `DAI` or `STARK`, and the `ERC721`, for NFTs (Non-Fungible Tokens) like `CryptoPunks` or `Everai`. - -[evm]: https://ethereum.org/en/developers/docs/evm/ - -## Use Cases - -There are many possible use cases for smart contracts. The only limits are the technical constraints of the blockchain and the creativity of developers. - -### DeFi - -For now, the principal use case for smart contracts is similar to that of Ethereum or Bitcoin, which is essentially handling money. In the context of the alternative payment system promised by Bitcoin, smart contracts on Ethereum enable the creation of decentralized financial applications that no longer rely on traditional financial intermediaries. This is what we call DeFi (decentralized finance). DeFi consists of various projects such as lending/borrowing applications, decentralized exchanges (DEX), on-chain derivatives, stablecoins, decentralized hedge funds, insurance, and many more. - -### Tokenization - -Smart contracts can facilitate the tokenization of real-world assets, such as real estate, art, or precious metals. Tokenization divides an asset into digital tokens, which can be easily traded and managed on blockchain platforms. This can increase liquidity, enable fractional ownership, and simplify the buying and selling process. - -### Voting - -Smart contracts can be used to create secure and transparent voting systems. Votes can be recorded on the blockchain, ensuring immutability and transparency. The smart contract can then automatically tally the votes and declare the results, minimizing the potential for fraud or manipulation. - -### Royalties - -Smart contracts can automate royalty payments for artists, musicians, and other content creators. When a piece of content is consumed or sold, the smart contract can automatically calculate and distribute the royalties to the rightful owners, ensuring fair compensation and reducing the need for intermediaries. - -### Decentralized Identities DIDs - -Smart contracts can be used to create and manage digital identities, allowing individuals to control their personal information and share it with third parties securely. The smart contract could verify the authenticity of a user's identity and automatically grant or revoke access to specific services based on the user's credentials. - -
-
-As Ethereum continues to mature, we can expect the use cases and applications of smart contracts to expand further, bringing about exciting new opportunities and reshaping traditional systems for the better. - -## The Rise of Starknet and Cairo - -Ethereum, being the most widely used and resilient smart contract platform, became a victim of its own success. With the rapid adoption of some previously mentioned use cases, mainly DeFi, the cost of performing transactions became extremely high, rendering the network almost unusable. Engineers and researchers in the ecosystem began working on solutions to address this scalability issue. - -A famous trilemma called The Blockchain Trilemma in the blockchain space states that it is hard to achieve a high level of scalability, decentralization, and security simultaneously; trade-offs must be made. Ethereum is at the intersection of decentralization and security. Eventually, it was decided that Ethereum's purpose would be to serve as a secure settlement layer, while complex computations would be offloaded to other networks built on top of Ethereum. These are called Layer 2s (L2s). - -The two primary types of L2s are optimistic rollups and validity rollups. Both approaches involve compressing and batching numerous transactions together, computing the new state, and settling the result on Ethereum (L1). The difference lies in the way the result is settled on L1. For optimistic rollups, the new state is considered valid by default, but there is a 7-day window for nodes to identify malicious transactions. - -In contrast, validity rollups, such as Starknet, use cryptography to prove that the new state has been correctly computed. This is the purpose of STARKs, this cryptographic technology could permit validity rollups to scale significantly more than optimistic rollups. You can learn more about STARKs from Starkware's Medium [article][starks article], which serves as a good primer. - -> Starknet's architecture is thoroughly described in the [Starknet Book][starknet architecture], which is a great resource to learn more about the Starknet network. - -Remember Cairo? It is, in fact, a language developed specifically to work with STARKs and make them general-purpose. With Cairo, we can write **provable code**. In the context of Starknet, this allows proving the correctness of computations from one state to another. - -Unlike most (if not all) of Starknet's competitors that chose to use the EVM (either as-is or adapted) as a base layer, Starknet employs its own VM. This frees developers from the constraints of the EVM, opening up a broader range of possibilities. Coupled with decreased transaction costs, the combination of Starknet and Cairo creates an exciting playground for developers. Native account abstraction enables more complex logic for accounts, that we call "Smart Accounts", and transaction flows. Emerging use cases include **transparent AI** and machine learning applications. Finally, **blockchain games** can be developed entirely **on-chain**. Starknet has been specifically designed to maximize the capabilities of STARK proofs for optimal scalability. - -> Learn more about Account Abstraction in the [Starknet Book][account abstraction chapter]. - -[starks article]: https://medium.com/starkware/starks-starkex-and-starknet-9a426680745a -[starknet architecture]: https://book.starknet.io/ch03-00-architecture.html -[account abstraction chapter]: https://book.starknet.io/ch04-00-account-abstraction.html - -## Cairo Programs and Starknet Contracts: What Is the Difference? - -Starknet contracts are a special superset of Cairo programs, so the concepts previously learned in this book are still applicable to write Starknet contracts. -As you may have already noticed, a Cairo program must always have a `main` function that serves as the entry point for this program: - -```rust -fn main() {} -``` - -Contracts deployed on the Starknet network are essentially programs that are run by the sequencer, and as such, have access to Starknet's state. Contracts do not have a `main` function but one or multiple functions that can serve as entry points. - -Starknet contracts are defined within [modules][module chapter]. For a module to be handled as a contract by the compiler, it must be annotated with the `#[starknet::contract]` attribute. - -[module chapter]: ./ch07-02-defining-modules-to-control-scope.md -# Anatomy of a Simple Contract - -This chapter will introduce you to the basics of Starknet contracts using a very simple smart contract as example. You will learn how to write a contract that allows anyone to store a single number on the Starknet blockchain. - -Let's consider the following contract for the whole chapter. It might not be easy to understand it all at once, but we will go through it step by step: - -```rust,noplayground -#[starknet::interface] -trait ISimpleStorage { - fn set(ref self: TContractState, x: u128); - fn get(self: @TContractState) -> u128; -} - -#[starknet::contract] -mod SimpleStorage { - #[storage] - struct Storage { - stored_data: u128 - } - - #[abi(embed_v0)] - impl SimpleStorage of super::ISimpleStorage { - fn set(ref self: ContractState, x: u128) { - self.stored_data.write(x); - } - - fn get(self: @ContractState) -> u128 { - self.stored_data.read() - } - } -} -``` - -Listing 13-1: A simple storage contract - -## What Is this Contract? - -Contracts are defined by encapsulating state and logic within a module annotated with the `#[starknet::contract]` attribute. - -The state is defined within the `Storage` struct, and is always initialized empty. Here, our struct contains a single a field called `stored_data` of type `u128` (unsigned integer of 128 bits), indicating that our contract can store any number between 0 and \\( {2^{128}} - 1 \\). - -The logic is defined by functions that interact with the state. Here, our contract defines and publicly exposes the functions `set` and `get` that can be used to modify or retrieve the value of the stored variable. -You can think of it as a single slot in a database that you can query and modify by calling functions of the code that manages the database. - -## The Interface: the Contract's Blueprint - -```rust,noplayground -#[starknet::interface] -trait ISimpleStorage { - fn set(ref self: TContractState, x: u128); - fn get(self: @TContractState) -> u128; -} -``` - -Listing 13-2: A basic contract interface - - -Interfaces represent the blueprint of the contract. They define the functions that the contract exposes to the outside world. In Cairo, they're defined by annotating a trait with the `#[starknet::interface]` attribute. All functions of the trait are considered public functions of any contract that implements this trait, and are callable from the outside world. - -All contract interfaces use a generic type for the `self` parameter, representing the contract state. We chose to name this generic parameter `TContractState` in our interface, but this is not enforced and any name can be chosen. - -In our interface, note the generic type `TContractState` of the `self` argument which is passed by reference to the `set` function. Seeing the `self` argument passed in a contract function tells us that this function can access the state of the contract. The `ref` modifier implies that `self` may be modified, meaning that the storage variables of the contract may be modified inside the `set` function. - -On the other hand, the `get` function takes a snapshot of `TContractState`, which immediately tells us that it does not modify the state (and indeed, the compiler will complain if we try to modify storage inside the `get` function). - -By leveraging the [traits & impls](./ch08-02-traits-in-cairo.md) mechanism from Cairo, we can make sure that the actual implementation of the contract matches its interface. In fact, you will get a compilation error if your contract doesn’t conform with the declared interface. For example, Listing 13-3 shows a wrong implementation of the `ISimpleStorage` interface, containing a slightly different `set` function that doesn't have the same signature. - -```rust,noplayground - #[abi(embed_v0)] - impl SimpleStorage of super::ISimpleStorage { - fn set(ref self: ContractState) {} - fn get(self: @ContractState) -> u128 { - self.stored_data.read() - } - } -``` - -Listing 13-3: A wrong implementation of the interface of the contract. This does not compile, as the signature of `set` doesn't match the trait's. - -Trying to compile a contract using this implementation will result in the following error: - -```shell -$ scarb cairo-run - Compiling listing_99_02 v0.1.0 (listings/ch13-introduction-to-starknet-smart-contracts/listing_02_wrong_impl/Scarb.toml) -error: The number of parameters in the impl function `SimpleStorage::set` is incompatible with `ISimpleStorage::set`. Expected: 2, actual: 1. - --> listings/ch13-introduction-to-starknet-smart-contracts/listing_02_wrong_impl/src/lib.cairo:24:16 - fn set(ref self: ContractState) {} - ^*********************^ - -error: Wrong number of arguments. Expected 2, found: 1 - --> listings/ch13-introduction-to-starknet-smart-contracts/listing_02_wrong_impl/src/lib.cairo[contract]:80:5 - SimpleStorage::set(ref contract_state, ); - ^**************************************^ - -error: could not compile `listing_99_02` due to previous error -error: `scarb metadata` exited with error - -``` - -## Public Functions Defined in an Implementation Block - -Before we explore things further down, let's define some terminology. - -- In the context of Starknet, a _public function_ is a function that is exposed to the outside world. A public function can be called by anyone, either from outside the contract or from within the contract itself. In the example above, `set` and `get` are public functions. - -- What we call an _external_ function is a public function that can be directly invoked through a Starknet transaction and that can mutate the state of the contract. `set` is an external function. - -- A _view_ function is a public function that is typically read-only and cannot mutate the state of the contract. However, this limitation is only enforced by the compiler, and not by Starknet itself. We will discuss the implications of this in a later section. `get` is a view function. - -```rust,noplayground - #[abi(embed_v0)] - impl SimpleStorage of super::ISimpleStorage { - fn set(ref self: ContractState, x: u128) { - self.stored_data.write(x); - } - - fn get(self: @ContractState) -> u128 { - self.stored_data.read() - } - } -``` - -Listing 13-4: `SimpleStorage` implementation - -Since the contract interface is defined as the `ISimpleStorage` trait, in order to match the interface, the public functions of the contract must be defined in an implementation of this trait — which allows us to make sure that the implementation of the contract matches its interface. - -However, simply defining the functions in the implementation block is not enough. The implementation block must be annotated with the `#[abi(embed_v0)]` attribute. This attribute exposes the functions defined in this implementation to the outside world — forget to add it and your functions will not be callable from the outside. All functions defined in a block marked as `#[abi(embed_v0)]` are consequently _public functions_. - -Because the `SimpleStorage` contract is defined as a module, we need to access the interface defined in the parent module. We can either bring it to the current scope with the `use` keyword, or refer to it directly using `super`. - -When writing the implementation of an interface, the `self` parameter in the trait methods **must** be of type `ContractState`. The `ContractState` type is generated by the compiler, and gives access to the storage variables defined in the `Storage` struct. -Additionally, `ContractState` gives us the ability to emit events. The name `ContractState` is not surprising, as it’s a representation of the contract’s state, which is what we think of `self` in the contract interface trait. -When `self` is a snapshot of `ContractState`, only read access is allowed, and emitting events is not possible. - -## Accessing and Modifying the Contract's State - -Two methods are commonly used to access or modify the state of a contract: -- `read`, which returns the value of a storage variable. This method is called on the variable itself and does not take any argument. - -```rust,noplayground - self.stored_data.read() -``` - -- `write`, which allows to write a new value in a storage slot. This method is also called on the variable itself and takes one argument, which is the value to be written. Note that `write` may take more than one argument, depending on the type of the storage variable. For example, writing on a mapping requires 2 arguments: the key and the value to be written. - -```rust,noplayground - self.stored_data.write(x); -``` - -> Reminder: if the contract state is passed as a snapshot with `@` instead of passed by reference with `ref`, attempting to modify the contract state will result in a compilation error. - -This contract does not do much apart from allowing anyone to store a single number that is accessible by anyone in the world. Anyone could call `set` again with a different value and overwrite the current number. Nevertheless, each value stored in the storage of the contract will still be stored in the history of the blockchain. Later in this book, you will see how you can impose access restrictions so that only you can alter the number. -# Building Starknet Smart Contracts - -In the previous section, we gave an introductory example of a smart contract written in Cairo, describing the basic blocks to build smart contracts on Starknet. In this section, we'll be taking a deeper look at all the components of a smart contract, step by step. - -When we discussed [_interfaces_][contract interface], we specified the difference between the two types of _public functions_, i.e., _external functions_ and _view functions_, and we mentioned how to interact with the _storage_ of a contract. - -At this point, you should have multiple questions that come to mind: - -- How can I store more complex data types? -- How do I define internal/private functions? -- How can I emit events? How can I index them? -- Is there a way to reduce the boilerplate? - -Luckily, we'll be answering all these questions in this chapter. Let's consider the `NameRegistry` contract in Listing 14-1 that we'll be using throughout this chapter: - -```rust,noplayground -use starknet::ContractAddress; - -#[starknet::interface] -pub trait INameRegistry { - fn store_name( - ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType - ); - fn get_name(self: @TContractState, address: ContractAddress) -> felt252; - fn get_owner(self: @TContractState) -> NameRegistry::Person; -} - -#[starknet::contract] -mod NameRegistry { - use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; - - #[storage] - struct Storage { - names: LegacyMap::, - owner: Person, - registration_type: LegacyMap::, - total_names: u128, - } - - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - StoredName: StoredName, - } - #[derive(Drop, starknet::Event)] - struct StoredName { - #[key] - user: ContractAddress, - name: felt252, - } - - #[derive(Drop, Serde, starknet::Store)] - pub struct Person { - address: ContractAddress, - name: felt252, - } - - #[derive(Drop, Serde, starknet::Store)] - pub enum RegistrationType { - finite: u64, - infinite - } - - #[constructor] - fn constructor(ref self: ContractState, owner: Person) { - self.names.write(owner.address, owner.name); - self.total_names.write(1); - self.owner.write(owner); - } - - // Public functions inside an impl block - #[abi(embed_v0)] - impl NameRegistry of super::INameRegistry { - fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { - let caller = get_caller_address(); - self._store_name(caller, name, registration_type); - } - - fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { - self.names.read(address) - } - - fn get_owner(self: @ContractState) -> Person { - self.owner.read() - } - } - - // Standalone public function - #[external(v0)] - fn get_contract_name(self: @ContractState) -> felt252 { - 'Name Registry' - } - - // Could be a group of functions about a same topic - #[generate_trait] - impl InternalFunctions of InternalFunctionsTrait { - fn _store_name( - ref self: ContractState, - user: ContractAddress, - name: felt252, - registration_type: RegistrationType - ) { - let total_names = self.total_names.read(); - self.names.write(user, name); - self.registration_type.write(user, registration_type); - self.total_names.write(total_names + 1); - self.emit(StoredName { user: user, name: name }); - } - } - - // Free function - fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { - self.owner.address() - } -} -``` - -Listing 14-1: Our reference contract for this chapter - -[contract interface]: ./ch13-02-anatomy-of-a-simple-contract.md#the-interface-the-contracts-blueprint -# Contract Storage - -The most common way for interacting with a contract’s storage is through storage variables. As stated previously, storage variables allow you to store data that will be stored in the contract's storage that is itself stored on the blockchain. These data are persistent and can be accessed and potentially modified anytime once the contract is deployed. - -Storage variables in Starknet contracts are stored in a special struct called `Storage`: - -```rust, noplayground -# use starknet::ContractAddress; -# -# #[starknet::interface] -# pub trait INameRegistry { -# fn store_name( -# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType -# ); -# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; -# fn get_owner(self: @TContractState) -> NameRegistry::Person; -# } -# -# #[starknet::contract] -# mod NameRegistry { -# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; -# - #[storage] - struct Storage { - names: LegacyMap::, - owner: Person, - registration_type: LegacyMap::, - total_names: u128, - } -# -# #[event] -# #[derive(Drop, starknet::Event)] -# enum Event { -# StoredName: StoredName, -# } -# #[derive(Drop, starknet::Event)] -# struct StoredName { -# #[key] -# user: ContractAddress, -# name: felt252, -# } -# -# #[derive(Drop, Serde, starknet::Store)] -# pub struct Person { -# address: ContractAddress, -# name: felt252, -# } -# -# #[derive(Drop, Serde, starknet::Store)] -# pub enum RegistrationType { -# finite: u64, -# infinite -# } -# -# #[constructor] -# fn constructor(ref self: ContractState, owner: Person) { -# self.names.write(owner.address, owner.name); -# self.total_names.write(1); -# self.owner.write(owner); -# } -# -# // Public functions inside an impl block -# #[abi(embed_v0)] -# impl NameRegistry of super::INameRegistry { -# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { -# let caller = get_caller_address(); -# self._store_name(caller, name, registration_type); -# } -# -# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { -# self.names.read(address) -# } -# -# fn get_owner(self: @ContractState) -> Person { -# self.owner.read() -# } -# } -# -# // Standalone public function -# #[external(v0)] -# fn get_contract_name(self: @ContractState) -> felt252 { -# 'Name Registry' -# } -# -# // Could be a group of functions about a same topic -# #[generate_trait] -# impl InternalFunctions of InternalFunctionsTrait { -# fn _store_name( -# ref self: ContractState, -# user: ContractAddress, -# name: felt252, -# registration_type: RegistrationType -# ) { -# let total_names = self.total_names.read(); -# self.names.write(user, name); -# self.registration_type.write(user, registration_type); -# self.total_names.write(total_names + 1); -# self.emit(StoredName { user: user, name: name }); -# } -# } -# -# // Free function -# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { -# self.owner.address() -# } -# } -# -# -``` - -The `Storage` struct is a [struct][structs chapter] like any other, except that it **must** be annotated with the `#[storage]` attribute. This annotation tells the compiler to generate the required code to interact with the blockchain state, and allows you to read and write data from and to storage. Moreover, this allows you to define storage mappings using the dedicated `LegacyMap` type. - -Variables declared in the `Storage` struct are not stored contiguously but in different locations in the contract's storage. The storage address of a particular variable is determined by the variable's name, and the eventual keys of the variable if it is a mapping. - -[structs chapter]: ./ch05-00-using-structs-to-structure-related-data.md - -## Addresses of Storage Variables - -The address of a storage variable is computed as follows: - -- If the variable is a single value, the address is the `sn_keccak` hash of the ASCII encoding of the variable's name. `sn_keccak` is Starknet's version of the Keccak256 hash function, whose output is truncated to 250 bits. - -- If the variable is composed of multiple values (i.e., a tuple, a struct or an enum), we also use the `sn_keccak` hash of the ASCII encoding of the variable's name to determine the base address in storage. Then, depending on the type, the storage layout will differ. See the ["Storing Custom Types"][custom types storage layout] section. - -- If the variable is a [mapping][storage mappings] with a key `k`, the address of the value at key `k` is `h(sn_keccak(variable_name),k)`, where ℎ is the Pedersen hash and the final value is taken modulo \\( {2^{251}} - 256\\). If the key is composed of more than one `felt252`, the address of the value will be `h(...h(h(sn_keccak(variable_name),k_1),k_2),...,k_n)`, with `k_1,...,k_n` being all `felt252` that constitute the key. In the case of mappings to complex values (e.g., tuples or structs), then this complex value lies in a continuous segment starting from the address calculated with the previous formula. Note that 256 field elements is the current limitation on the maximal size of a complex storage value. - -You can access the address of a storage variable by calling the `address` function on the variable, which returns a `StorageBaseAddress` value. - -```rust, noplayground -# use starknet::ContractAddress; -# -# #[starknet::interface] -# pub trait INameRegistry { -# fn store_name( -# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType -# ); -# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; -# fn get_owner(self: @TContractState) -> NameRegistry::Person; -# } -# -# #[starknet::contract] -# mod NameRegistry { -# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; -# -# #[storage] -# struct Storage { -# names: LegacyMap::, -# owner: Person, -# registration_type: LegacyMap::, -# total_names: u128, -# } -# -# #[event] -# #[derive(Drop, starknet::Event)] -# enum Event { -# StoredName: StoredName, -# } -# #[derive(Drop, starknet::Event)] -# struct StoredName { -# #[key] -# user: ContractAddress, -# name: felt252, -# } -# -# #[derive(Drop, Serde, starknet::Store)] -# pub struct Person { -# address: ContractAddress, -# name: felt252, -# } -# -# #[derive(Drop, Serde, starknet::Store)] -# pub enum RegistrationType { -# finite: u64, -# infinite -# } -# -# #[constructor] -# fn constructor(ref self: ContractState, owner: Person) { -# self.names.write(owner.address, owner.name); -# self.total_names.write(1); -# self.owner.write(owner); -# } -# -# // Public functions inside an impl block -# #[abi(embed_v0)] -# impl NameRegistry of super::INameRegistry { -# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { -# let caller = get_caller_address(); -# self._store_name(caller, name, registration_type); -# } -# -# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { -# self.names.read(address) -# } -# -# fn get_owner(self: @ContractState) -> Person { -# self.owner.read() -# } -# } -# -# // Standalone public function -# #[external(v0)] -# fn get_contract_name(self: @ContractState) -> felt252 { -# 'Name Registry' -# } -# -# // Could be a group of functions about a same topic -# #[generate_trait] -# impl InternalFunctions of InternalFunctionsTrait { -# fn _store_name( -# ref self: ContractState, -# user: ContractAddress, -# name: felt252, -# registration_type: RegistrationType -# ) { -# let total_names = self.total_names.read(); -# self.names.write(user, name); -# self.registration_type.write(user, registration_type); -# self.total_names.write(total_names + 1); -# self.emit(StoredName { user: user, name: name }); -# } -# } -# -# // Free function -# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { - self.owner.address() -# } -# } -# -# -``` - -[custom types storage layout]: ./ch14-01-contract-storage.md#storing-custom-types -[storage mappings]: ./ch14-01-contract-storage.html#storage-mappings - -## Interacting with Storage Variables - -Variables stored in the `Storage` struct can be accessed and modified using the `read` and `write` functions, respectively. As previously mentioned, you can get their address in storage using the `address` function. All these functions are automatically generated by the compiler for each storage variable. - -To read the value of the `owner` storage variable, which is a single value, we call the `read` function on the `owner` variable, passing in no parameters. - -```rust, noplayground -# use starknet::ContractAddress; -# -# #[starknet::interface] -# pub trait INameRegistry { -# fn store_name( -# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType -# ); -# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; -# fn get_owner(self: @TContractState) -> NameRegistry::Person; -# } -# -# #[starknet::contract] -# mod NameRegistry { -# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; -# -# #[storage] -# struct Storage { -# names: LegacyMap::, -# owner: Person, -# registration_type: LegacyMap::, -# total_names: u128, -# } -# -# #[event] -# #[derive(Drop, starknet::Event)] -# enum Event { -# StoredName: StoredName, -# } -# #[derive(Drop, starknet::Event)] -# struct StoredName { -# #[key] -# user: ContractAddress, -# name: felt252, -# } -# -# #[derive(Drop, Serde, starknet::Store)] -# pub struct Person { -# address: ContractAddress, -# name: felt252, -# } -# -# #[derive(Drop, Serde, starknet::Store)] -# pub enum RegistrationType { -# finite: u64, -# infinite -# } -# -# #[constructor] -# fn constructor(ref self: ContractState, owner: Person) { -# self.names.write(owner.address, owner.name); -# self.total_names.write(1); -# self.owner.write(owner); -# } -# -# // Public functions inside an impl block -# #[abi(embed_v0)] -# impl NameRegistry of super::INameRegistry { -# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { -# let caller = get_caller_address(); -# self._store_name(caller, name, registration_type); -# } -# -# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { -# self.names.read(address) -# } -# -# fn get_owner(self: @ContractState) -> Person { - self.owner.read() -# } -# } -# -# // Standalone public function -# #[external(v0)] -# fn get_contract_name(self: @ContractState) -> felt252 { -# 'Name Registry' -# } -# -# // Could be a group of functions about a same topic -# #[generate_trait] -# impl InternalFunctions of InternalFunctionsTrait { -# fn _store_name( -# ref self: ContractState, -# user: ContractAddress, -# name: felt252, -# registration_type: RegistrationType -# ) { -# let total_names = self.total_names.read(); -# self.names.write(user, name); -# self.registration_type.write(user, registration_type); -# self.total_names.write(total_names + 1); -# self.emit(StoredName { user: user, name: name }); -# } -# } -# -# // Free function -# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { -# self.owner.address() -# } -# } -# -# -``` - -To read the value of the storage variable `names`, which is a mapping from `ContractAddress` to `felt252`, we call the `read` function on the `names` variable, passing in the key `address` as a parameter. If the mapping had more than one key, we would pass in the other keys as parameters as well. - -```rust, noplayground -# use starknet::ContractAddress; -# -# #[starknet::interface] -# pub trait INameRegistry { -# fn store_name( -# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType -# ); -# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; -# fn get_owner(self: @TContractState) -> NameRegistry::Person; -# } -# -# #[starknet::contract] -# mod NameRegistry { -# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; -# -# #[storage] -# struct Storage { -# names: LegacyMap::, -# owner: Person, -# registration_type: LegacyMap::, -# total_names: u128, -# } -# -# #[event] -# #[derive(Drop, starknet::Event)] -# enum Event { -# StoredName: StoredName, -# } -# #[derive(Drop, starknet::Event)] -# struct StoredName { -# #[key] -# user: ContractAddress, -# name: felt252, -# } -# -# #[derive(Drop, Serde, starknet::Store)] -# pub struct Person { -# address: ContractAddress, -# name: felt252, -# } -# -# #[derive(Drop, Serde, starknet::Store)] -# pub enum RegistrationType { -# finite: u64, -# infinite -# } -# -# #[constructor] -# fn constructor(ref self: ContractState, owner: Person) { -# self.names.write(owner.address, owner.name); -# self.total_names.write(1); -# self.owner.write(owner); -# } -# -# // Public functions inside an impl block -# #[abi(embed_v0)] -# impl NameRegistry of super::INameRegistry { -# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { -# let caller = get_caller_address(); -# self._store_name(caller, name, registration_type); -# } -# -# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { - self.names.read(address) -# } -# -# fn get_owner(self: @ContractState) -> Person { -# self.owner.read() -# } -# } -# -# // Standalone public function -# #[external(v0)] -# fn get_contract_name(self: @ContractState) -> felt252 { -# 'Name Registry' -# } -# -# // Could be a group of functions about a same topic -# #[generate_trait] -# impl InternalFunctions of InternalFunctionsTrait { -# fn _store_name( -# ref self: ContractState, -# user: ContractAddress, -# name: felt252, -# registration_type: RegistrationType -# ) { -# let total_names = self.total_names.read(); -# self.names.write(user, name); -# self.registration_type.write(user, registration_type); -# self.total_names.write(total_names + 1); -# self.emit(StoredName { user: user, name: name }); -# } -# } -# -# // Free function -# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { -# self.owner.address() -# } -# } -# -# -``` - -To write a new value to the storage slot of a storage variable, we call the `write` function passing in the eventual keys and the value as arguments. As with the `read` function, the number of arguments depends on the storage variable type. Here, we only pass in the value to write to the `owner` variable as it is a simple variable. - -```rust, noplayground -# use starknet::ContractAddress; -# -# #[starknet::interface] -# pub trait INameRegistry { -# fn store_name( -# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType -# ); -# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; -# fn get_owner(self: @TContractState) -> NameRegistry::Person; -# } -# -# #[starknet::contract] -# mod NameRegistry { -# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; -# -# #[storage] -# struct Storage { -# names: LegacyMap::, -# owner: Person, -# registration_type: LegacyMap::, -# total_names: u128, -# } -# -# #[event] -# #[derive(Drop, starknet::Event)] -# enum Event { -# StoredName: StoredName, -# } -# #[derive(Drop, starknet::Event)] -# struct StoredName { -# #[key] -# user: ContractAddress, -# name: felt252, -# } -# -# #[derive(Drop, Serde, starknet::Store)] -# pub struct Person { -# address: ContractAddress, -# name: felt252, -# } -# -# #[derive(Drop, Serde, starknet::Store)] -# pub enum RegistrationType { -# finite: u64, -# infinite -# } -# -# #[constructor] -# fn constructor(ref self: ContractState, owner: Person) { -# self.names.write(owner.address, owner.name); -# self.total_names.write(1); - self.owner.write(owner); -# } -# -# // Public functions inside an impl block -# #[abi(embed_v0)] -# impl NameRegistry of super::INameRegistry { -# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { -# let caller = get_caller_address(); -# self._store_name(caller, name, registration_type); -# } -# -# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { -# self.names.read(address) -# } -# -# fn get_owner(self: @ContractState) -> Person { -# self.owner.read() -# } -# } -# -# // Standalone public function -# #[external(v0)] -# fn get_contract_name(self: @ContractState) -> felt252 { -# 'Name Registry' -# } -# -# // Could be a group of functions about a same topic -# #[generate_trait] -# impl InternalFunctions of InternalFunctionsTrait { -# fn _store_name( -# ref self: ContractState, -# user: ContractAddress, -# name: felt252, -# registration_type: RegistrationType -# ) { -# let total_names = self.total_names.read(); -# self.names.write(user, name); -# self.registration_type.write(user, registration_type); -# self.total_names.write(total_names + 1); -# self.emit(StoredName { user: user, name: name }); -# } -# } -# -# // Free function -# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { -# self.owner.address() -# } -# } -# -# -``` - -In this second example, we need to pass `user` and `name` as arguments, because `names` is a mapping, with `user` as key and `name` as value. - -```rust, noplayground -# use starknet::ContractAddress; -# -# #[starknet::interface] -# pub trait INameRegistry { -# fn store_name( -# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType -# ); -# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; -# fn get_owner(self: @TContractState) -> NameRegistry::Person; -# } -# -# #[starknet::contract] -# mod NameRegistry { -# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; -# -# #[storage] -# struct Storage { -# names: LegacyMap::, -# owner: Person, -# registration_type: LegacyMap::, -# total_names: u128, -# } -# -# #[event] -# #[derive(Drop, starknet::Event)] -# enum Event { -# StoredName: StoredName, -# } -# #[derive(Drop, starknet::Event)] -# struct StoredName { -# #[key] -# user: ContractAddress, -# name: felt252, -# } -# -# #[derive(Drop, Serde, starknet::Store)] -# pub struct Person { -# address: ContractAddress, -# name: felt252, -# } -# -# #[derive(Drop, Serde, starknet::Store)] -# pub enum RegistrationType { -# finite: u64, -# infinite -# } -# -# #[constructor] -# fn constructor(ref self: ContractState, owner: Person) { -# self.names.write(owner.address, owner.name); -# self.total_names.write(1); -# self.owner.write(owner); -# } -# -# // Public functions inside an impl block -# #[abi(embed_v0)] -# impl NameRegistry of super::INameRegistry { -# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { -# let caller = get_caller_address(); -# self._store_name(caller, name, registration_type); -# } -# -# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { -# self.names.read(address) -# } -# -# fn get_owner(self: @ContractState) -> Person { -# self.owner.read() -# } -# } -# -# // Standalone public function -# #[external(v0)] -# fn get_contract_name(self: @ContractState) -> felt252 { -# 'Name Registry' -# } -# -# // Could be a group of functions about a same topic -# #[generate_trait] -# impl InternalFunctions of InternalFunctionsTrait { -# fn _store_name( -# ref self: ContractState, -# user: ContractAddress, -# name: felt252, -# registration_type: RegistrationType -# ) { -# let total_names = self.total_names.read(); - self.names.write(user, name); -# self.registration_type.write(user, registration_type); -# self.total_names.write(total_names + 1); -# self.emit(StoredName { user: user, name: name }); -# } -# } -# -# // Free function -# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { -# self.owner.address() -# } -# } -# -# -``` - -## Storing Custom Types - -The `Store` trait, defined in the `starknet::storage_access` module, is used to specify how a type should be stored in storage. In order for a type to be stored in storage, it **must** implement the `Store` trait. Most types from the core library, such as unsigned integers (`u8`, `u128`, `u256`...), `felt252`, `bool`, `ByteArray`, `ContractAddress`, etc. implement the `Store` trait and can thus be stored without further action. - -But what if you wanted to store a type that you defined yourself, such as an enum or a struct? In that case, you have to explicitly tell the compiler how to store this type. - -In our example, we want to store a `Person` struct in storage, which is only possible by implementing the `Store` trait for the `Person` type. This can be simply achieved by adding a `#[derive(starknet::Store)]` attribute on top of our struct definition. Note that all the members of the struct need to implement the `Store` trait. - -```rust, noplayground -# use starknet::ContractAddress; -# -# #[starknet::interface] -# pub trait INameRegistry { -# fn store_name( -# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType -# ); -# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; -# fn get_owner(self: @TContractState) -> NameRegistry::Person; -# } -# -# #[starknet::contract] -# mod NameRegistry { -# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; -# -# #[storage] -# struct Storage { -# names: LegacyMap::, -# owner: Person, -# registration_type: LegacyMap::, -# total_names: u128, -# } -# -# #[event] -# #[derive(Drop, starknet::Event)] -# enum Event { -# StoredName: StoredName, -# } -# #[derive(Drop, starknet::Event)] -# struct StoredName { -# #[key] -# user: ContractAddress, -# name: felt252, -# } -# - #[derive(Drop, Serde, starknet::Store)] - pub struct Person { - address: ContractAddress, - name: felt252, - } -# -# #[derive(Drop, Serde, starknet::Store)] -# pub enum RegistrationType { -# finite: u64, -# infinite -# } -# -# #[constructor] -# fn constructor(ref self: ContractState, owner: Person) { -# self.names.write(owner.address, owner.name); -# self.total_names.write(1); -# self.owner.write(owner); -# } -# -# // Public functions inside an impl block -# #[abi(embed_v0)] -# impl NameRegistry of super::INameRegistry { -# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { -# let caller = get_caller_address(); -# self._store_name(caller, name, registration_type); -# } -# -# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { -# self.names.read(address) -# } -# -# fn get_owner(self: @ContractState) -> Person { -# self.owner.read() -# } -# } -# -# // Standalone public function -# #[external(v0)] -# fn get_contract_name(self: @ContractState) -> felt252 { -# 'Name Registry' -# } -# -# // Could be a group of functions about a same topic -# #[generate_trait] -# impl InternalFunctions of InternalFunctionsTrait { -# fn _store_name( -# ref self: ContractState, -# user: ContractAddress, -# name: felt252, -# registration_type: RegistrationType -# ) { -# let total_names = self.total_names.read(); -# self.names.write(user, name); -# self.registration_type.write(user, registration_type); -# self.total_names.write(total_names + 1); -# self.emit(StoredName { user: user, name: name }); -# } -# } -# -# // Free function -# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { -# self.owner.address() -# } -# } -# -# -``` - -Similarly, Enums can only be written to storage if they implement the `Store` trait, which can be trivially derived as long as all associated types implement the `Store` trait. - -```rust, noplayground -# use starknet::ContractAddress; -# -# #[starknet::interface] -# pub trait INameRegistry { -# fn store_name( -# ref self: TContractState, name: felt252, registration_type: NameRegistry::RegistrationType -# ); -# fn get_name(self: @TContractState, address: ContractAddress) -> felt252; -# fn get_owner(self: @TContractState) -> NameRegistry::Person; -# } -# -# #[starknet::contract] -# mod NameRegistry { -# use starknet::{ContractAddress, get_caller_address, storage_access::StorageBaseAddress}; -# -# #[storage] -# struct Storage { -# names: LegacyMap::, -# owner: Person, -# registration_type: LegacyMap::, -# total_names: u128, -# } -# -# #[event] -# #[derive(Drop, starknet::Event)] -# enum Event { -# StoredName: StoredName, -# } -# #[derive(Drop, starknet::Event)] -# struct StoredName { -# #[key] -# user: ContractAddress, -# name: felt252, -# } -# -# #[derive(Drop, Serde, starknet::Store)] -# pub struct Person { -# address: ContractAddress, -# name: felt252, -# } -# - #[derive(Drop, Serde, starknet::Store)] - pub enum RegistrationType { - finite: u64, - infinite - } -# -# #[constructor] -# fn constructor(ref self: ContractState, owner: Person) { -# self.names.write(owner.address, owner.name); -# self.total_names.write(1); -# self.owner.write(owner); -# } -# -# // Public functions inside an impl block -# #[abi(embed_v0)] -# impl NameRegistry of super::INameRegistry { -# fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { -# let caller = get_caller_address(); -# self._store_name(caller, name, registration_type); -# } -# -# fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { -# self.names.read(address) -# } -# -# fn get_owner(self: @ContractState) -> Person { -# self.owner.read() -# } -# } -# -# // Standalone public function -# #[external(v0)] -# fn get_contract_name(self: @ContractState) -> felt252 { -# 'Name Registry' -# } -# -# // Could be a group of functions about a same topic -# #[generate_trait] -# impl InternalFunctions of InternalFunctionsTrait { -# fn _store_name( -# ref self: ContractState, -# user: ContractAddress, -# name: felt252, -# registration_type: RegistrationType -# ) { -# let total_names = self.total_names.read(); -# self.names.write(user, name); -# self.registration_type.write(user, registration_type); -# self.total_names.write(total_names + 1); -# self.emit(StoredName { user: user, name: name }); -# } -# } -# -# // Free function -# fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { -# self.owner.address() -# } -# } -# -# -``` - -You might have noticed that we also derived `Drop` and `Serde` on our custom types. Both of them are required for properly serializing arguments passed to entrypoints and deserializing their outputs. - -### Structs Storage Layout - -On Starknet, structs are stored in storage as a sequence of primitive types. -The elements of the struct are stored in the same order as they are defined in the struct definition. The first element of the struct is stored at the base address of the struct, which is computed as specified in ["Addresses of Storage Variables"][storage addresses] section and can be obtained by calling `var.address()`, and subsequent elements are stored at addresses contiguous to the first element. -For example, the storage layout for the `owner` variable of type `Person` will result in the following layout: - -| Fields | Address | -| ------- | ------------------ | -| name | owner.address() | -| address | owner.address() +1 | - -Note that tuples are similarly stored in contract's storage, with the first element of the tuple being stored at the base address, and subsequent elements stored contiguously. - -[storage addresses]: ./ch14-01-contract-storage.html#addresses-of-storage-variables - -### Enums Storage Layout - -When you store an enum variant, what you're essentially storing is the variant's index and eventual associated values. This index starts at 0 for the first variant of your enum and increments by 1 for each subsequent variant. -If your variant has an associated value, this value is stored starting from the address immediately following the address of the index of the variant. -For example, suppose we have the `RegistrationType` enum with the `finite` variant that carries an associated limit date, and the `infinite` variant without associated data. The storage layout for the `finite` variant would look like this: - -| Element | Address | -| ----------------------------------- | ------------------------------- | -| Variant index (0 for finite) | registration_type.address() | -| Associated limit date | registration_type.address() + 1 | - -while the storage layout for the `infinite` would be as follows: - -| Element | Address | -| ----------------------------------- | ------------------------------- | -| Variant index (1 for infinite) | registration_type.address() | - -## Storage Mappings - -Storage mappings are similar to hash tables in that they allow mapping keys to values. However, unlike a typical hash table, the key data itself is not stored - only its hash is used to look up the associated value in the contract's storage. -Mappings do not have a concept of length or whether a key/value pair is set. All values are by default set to 0. The only way to remove an entry from a mapping is to set its value to the default zero value. - -Mappings are only used to compute the location of data in the storage of a -contract given certain keys. They are thus **only allowed as storage variables**. -They cannot be used as parameters or return parameters of contract functions, -and cannot be used as types inside structs. - -
- mappings -
-
- Mapping keys to storage values -
- -To declare a mapping, use the `LegacyMap` type enclosed in angle brackets `<>`, -specifying the key and value types. - -You can also create more complex mappings with multiple keys. You can find in Listing 14-2 the popular `allowances` storage variable of the ERC20 Standard which maps an `owner` and an allowed `spender` to their `allowance` amount using multiple keys passed inside a tuple: - -```rust,noplayground - #[storage] - struct Storage { - allowances: LegacyMap::<(ContractAddress, ContractAddress), u256> - } -``` - -Listing 14-2: Storing a mapping with multiple keys inside a tuple - -The address in storage of a variable stored in a mapping is computed according to the description in the ["Addresses of Storage Variables"][storage addresses] section. - -If the key of a mapping is a struct, each element of the struct constitutes a key. Moreover, the struct should implement the `Hash` trait, which can be derived with the `#[derive(Hash)]` attribute. For example, if you have a struct with two fields, the address will be `h(h(sn_keccak(variable_name),k_1),k_2)` modulo \\( {2^{251}} - 256\\), where `k_1` and `k_2` are the values of the two fields of the struct. - -Similarly, in the case of a nested mapping using a tuple as key, such as `LegacyMap::<(ContractAddress, ContractAddress), u8>`, the address will be computed in the same way, with each element of the tuple being a key: `h(h(sn_keccak(variable_name),k_1),k_2)`. - -[storage addresses]: ./ch14-01-contract-storage.html#addresses-of-storage-variables -# Contract Functions - -In this section, we are going to be looking at the different types of functions you could encounter in Starknet smart contracts. - -Functions can access the contract's state easily via `self: ContractState`, which abstracts away the complexity of underlying system calls (`storage_read_syscall` and `storage_write_syscall`). The compiler provides two modifiers: `ref` and `@` to decorate `self`, which intends to distinguish view and external functions. - -## 1. Constructors - -Constructors are a special type of function that only runs once when deploying a contract, and can be used to initialize the state of a contract. - -```rust,noplayground - #[constructor] - fn constructor(ref self: ContractState, owner: Person) { - self.names.write(owner.address, owner.name); - self.total_names.write(1); - self.owner.write(owner); - } -``` - -Some important rules to note: - -1. A contract can't have more than one constructor. -2. The constructor function must be named `constructor`, and must be annotated with the `#[constructor]` attribute. - -The `constructor` function might take arguments, which are passed when deploying the contract. In our example, we pass some value corresponding to a `Person` type as argument in order to store the `owner` information (address and name) in the contract. - -Note that the `constructor` function **must** take `self` as a first argument, corresponding to the state of the contract, generally passed by reference with the `ref` keyword to be able to modify the contract's state. We will explain `self` and its type shortly. - -## 2. Public Functions - -As stated previously, public functions are accessible from outside of the contract. They are usually defined inside an implementation block annotated with the `#[abi(embed_v0)]` attribute, but might also be defined independently under the `#[external(v0)]` attribute. - -The `#[abi(embed_v0)]` attribute means that all functions embedded inside it are implementations of the Starknet interface of the contract, and therefore potential entry points. - -Annotating an impl block with the `#[abi(embed_v0)]` attribute only affects the visibility (i.e., public vs private/internal) of the functions it contains, but it doesn't inform us on the ability of these functions to modify the state of the contract. - -```rust,noplayground - // Public functions inside an impl block - #[abi(embed_v0)] - impl NameRegistry of super::INameRegistry { - fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { - let caller = get_caller_address(); - self._store_name(caller, name, registration_type); - } - - fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { - self.names.read(address) - } - - fn get_owner(self: @ContractState) -> Person { - self.owner.read() - } - } -``` - -> Similarly to the `constructor` function, all public functions, either standalone functions annotated with the `#[external(v0)]` or functions within an impl block annotated with the `#[abi(embed_v0)]` attribute, **must** take `self` as a first argument. This is not the case for private functions. - -### External Functions - -External functions are _public_ functions where the `self: ContractState` argument is passed by reference with the `ref` keyword, which exposes both the `read` and `write` access to storage variables. This allows modifying the state of the contract via `self` directly. - -```rust,noplayground - fn store_name(ref self: ContractState, name: felt252, registration_type: RegistrationType) { - let caller = get_caller_address(); - self._store_name(caller, name, registration_type); - } -``` - -### View Functions - -View functions are _public_ functions where the `self: ContractState` argument is passed as snapshot, which only allows the `read` access to storage variables, and restricts writes to storage made via `self` by causing compilation errors. The compiler will mark their `state_mutability` to `view`, preventing any state modification through `self` directly. - -```rust,noplayground - fn get_name(self: @ContractState, address: ContractAddress) -> felt252 { - self.names.read(address) - } - -``` - -### State Mutability of Public Functions - -However, as you may have noticed, passing `self` as a snapshot only restricts the storage write access via `self` at compile time. It does not prevent state modification via direct system calls, nor calling another contract that would modify the state. - -The read-only property of view functions is not enforced on Starknet, and sending a transaction targeting a view function _could_ change the state. - -In conclusion, even though external and view functions are distinguished by the Cairo compiler, **all public functions** can be called through an invoke transaction and have the potential to modify states on Starknet. Also, all public functions can be queried via `starknet_call` on Starknet, which will not create a transaction and hence will not change the state. - -> **Warning:** This is different from the EVM where a `staticcall` opcode is provided, which prevents storage modifications in the current context and subcontexts. Hence developers **should not** have the assumption that calling a view function on another contract cannot modify the state. - -### Standalone Public Functions - -It is also possible to define public functions outside of an implementation of a trait, using the `#[external(v0)]` attribute. Doing this will automatically generate the corresponding ABI, allowing these standalone public functions to be callable by anyone from the outside. These functions can also be called from within the contract just like any function in Starknet contracts. The first parameter must be `self`. - -Here, we define a standalone `get_contract_name` function outside of an impl block: - -```rust,noplayground - // Standalone public function - #[external(v0)] - fn get_contract_name(self: @ContractState) -> felt252 { - 'Name Registry' - } -``` - -## 3. Private Functions - -Functions that are not defined with the `#[external(v0)]` attribute or inside a block annotated with the `#[abi(embed_v0)]` attribute are private functions (also called internal functions). They can only be called from within the contract. - -They can be grouped in a dedicated impl block (e.g., in components, to easily import internal functions all at once in the embedding contracts) or just be added as free functions inside the contract module. -Note that these 2 methods are equivalent. Just choose the one that makes your code more readable and easy to use. - -```rust,noplayground - // Could be a group of functions about a same topic - #[generate_trait] - impl InternalFunctions of InternalFunctionsTrait { - fn _store_name( - ref self: ContractState, - user: ContractAddress, - name: felt252, - registration_type: RegistrationType - ) { - let total_names = self.total_names.read(); - self.names.write(user, name); - self.registration_type.write(user, registration_type); - self.total_names.write(total_names + 1); - self.emit(StoredName { user: user, name: name }); - } - } - - // Free function - fn get_owner_storage_address(self: @ContractState) -> StorageBaseAddress { - self.owner.address() - } -``` - -> Wait, what is this `#[generate_trait]` attribute? Where is the trait definition for this implementation? Well, the `#[generate_trait]` attribute is a special attribute that tells the compiler to generate a trait definition for the implementation block. This allows you to get rid of the boilerplate code of defining a trait with generic parameters and implementing it for the implementation block. With this attribute, we can simply define the implementation block directly, without any generic parameter, and use `self: ContractState` in our functions. - -The `#[generate_trait]` attribute is mostly used to define private impl blocks. It might also be used in addition to `#[abi(per_item)]` to define the various entrypoints of a contract (see [next section][abi per item section]). - -> Note: using `#[generate_trait]` in addition to the `#[abi(embed_v0)]` attribute for a public impl block is not recommended, as it will result in a failure to generate the corresponding ABI. Public functions should only be defined in an impl block annotated with `#[generate_trait]` if this block is also annotated with the `#[abi(per_item)]` attribute. - -[abi per item section]: ./ch14-02-contract-functions.md#4-abiper_item-attribute - - -## `[abi(per_item)]` Attribute - -You can also define the entrypoint type of functions individually inside an impl block using the`#[abi(per_item)]` attribute on top of your impl. It is often used with the `#[generate_trait]` attribute, as it allows you to define entrypoints without an explicit interface. In this case, the functions will not be grouped under an impl in the ABI. Note that when using `#[abi(per_item)]` attribute, public functions need to be annotated with the `#[external(v0)]` attribute - otherwise, they will not be exposed and will be considered as private functions. - -Here is a short example: - -```rust,noplayground -#[starknet::contract] -mod AbiAttribute { - #[storage] - struct Storage {} - - #[abi(per_item)] - #[generate_trait] - impl SomeImpl of SomeTrait { - #[constructor] - // this is a constructor function - fn constructor(ref self: ContractState) {} - - #[external(v0)] - // this is a public function - fn external_function(ref self: ContractState, arg1: felt252) {} - - #[l1_handler] - // this is a l1_handler function - fn handle_message(ref self: ContractState, from_address: felt252, arg: felt252) {} - - // this is an internal function - fn internal_function(self: @ContractState) {} - } -} -``` - -In the case of `#[abi(per_item)]` attribute usage without `#[generate_trait]`, it will only be possible to include `constructor`, `l1-handler` and `internal` functions in the trait implementation. Indeed, `#[abi(per_item)]` only works with a trait that is not defined as a Starknet interface. Hence, it will be mandatory to create another trait defined as interface to implement public functions. -# Contract Events - -Events are custom data structures that are emitted by smart contracts during execution. They provide a way for smart contracts to communicate with the external world by logging information about specific occurrences in a contract. - -Events play a crucial role in the integration of smart contracts in real-world applications. Take, for instance, the Non-Fungible Tokens (NFTs) minted on Starknet. An event is emitted each time a token is minted. This event is indexed and stored in some database, allowing applications to display almost instantaneously useful information to users. If the contract doesn't emit an event when minting a new token, it would be less practical, with the need of querying the state of the blockchain to get the data needed. - -## Defining Events - -All the different events in a contract are defined under the `Event` enum, which must implement the `starknet::Event` trait. This trait is defined in the core library as follows: - -```rust,noplayground -trait Event { - fn append_keys_and_data(self: T, ref keys: Array, ref data: Array); - fn deserialize(ref keys: Span, ref data: Span) -> Option; -} -``` - -The `#[derive(starknet::Event)]` attribute causes the compiler to generate an implementation for the above trait, -instantiated with the `Event` type, which in our example is the following enum: - -```rust,noplayground - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - StoredName: StoredName, - } -``` - -Each variant of the `Event` enum has to be a struct or an enum, and each variant needs to implement the `starknet::Event` trait itself. Moreover, the members of these variants must implement the `Serde` trait (_c.f._ [Appendix C: Serializing with Serde][serde appendix]), as keys/data are added to the event using a serialization process. - -The auto-implementation of the `starknet::Event` trait will implement the `append_keys_and_data` function for each variant of our `Event` enum. The generated implementation will append a single key based on the variant name (`StoredName`), and then recursively call `append_keys_and_data` in the impl of the `Event` trait for the variant’s type. - -In our example, the `Event` enum contains only one variant, which is a struct named `StoredName`. We chose to name our variant with the same name as the struct name, but this is not enforced. - -```rust,noplayground - #[derive(Drop, starknet::Event)] - struct StoredName { - #[key] - user: ContractAddress, - name: felt252, - } -``` - -Whenever an enum that derives the `starknet::Event` trait has an enum variant, this enum is nested by default. Therefore, the list of keys corresponding to the variant’s name will include the `sn_keccak` hash of the variant's name itself. This can be superfluous, typically when using embedded components in contracts. Indeed, in such cases, we might want the events defined in the components to be emitted without any additional data, and it could be useful to annotate the enum variant with the `#[flat]` attribute. By doing so, we allow to opt out of the nested behavior and ignore the variant name in the serialization process. On the other hand, nested events have the benefit of distinguishing between the main contract event and different components events, which might be helpful. - -In our contract, we defined an event named `StoredName` that emits the contract address of the caller and the name stored within the contract, where the `user` field is serialized as a key and the `name` field is serialized as data. - -Indexing events fields allows for more efficient queries and filtering of events. To index a field as a key of an event, simply annotate it with the `#[key]` attribute as demonstrated in the example for the `user` key. By doing so, any indexed field will allow queries of events that contain a given value for that field with \\( O(log(n)) \\) time complexity, while non indexed fields require any query to iterate over all events, providing \\( O(n) \\) time complexity. - -When emitting the event with `self.emit(StoredName { user: user, name: name })`, a key corresponding to the name ` StoredName`, specifically `sn_keccak(StoredName)`, is appended to the keys list. `user`is serialized as key, thanks to the `#[key]` attribute, while address is serialized as data. After everything is processed, we end up with the following keys and data: `keys = [sn_keccak("StoredName"),user]` and `data = [name]`. - -[serde appendix]: ./appendix-03-derivable-traits.html#serializing-with-serde - -## Emitting Events - -After defining events, we can emit them using `self.emit`, with the following syntax: - -```rust,noplayground - self.emit(StoredName { user: user, name: name }); -``` - -The `emit` function is called on `self` and takes a reference to `self`, i.e., state modification capabilities are required. Therefore, it is not possible to emit events in view functions. -# Starknet Cross-Contract Interactions - -Interactions between smart contracts are an important feature when creating complex decentralized applications, as it allows for composability and separation of concerns. This chapter sheds light on how to make contracts interact with each other. - -Specifically, you'll learn about ABIs, contract interfaces, the contract and library dispatchers and their low-level system call equivalents! -# ABIs and Contract Interfaces - -Cross-contract interactions between smart contracts on a blockchain is a common practice which enables us to build flexible contracts that can speak with each other. - -Achieving this on Starknet requires something we call an interface. - -## ABI - Application Binary Interface - -On Starknet, the ABI of a contract is a JSON representation of the contract's functions and structures, giving anyone (or any other contract) the ability to form encoded calls to it. It is a blueprint that instructs how functions should be called, what input parameters they expect, and in what format. - -While we write our smart contract logics in high-level Cairo, they are stored on the VM as executable bytecodes which are in binary formats. Since this bytecode is not human readable, it requires interpretation to be understood. This is where ABIs come into play, defining specific methods which can be called to a smart contract for execution. Without an ABI, it becomes practically impossible for external actors to understand how to interact with a contract. - -ABIs are typically used in dApps frontends, allowing it to format data correctly, making it understandable by the smart contract and vice versa. When you interact with a smart contract through a block explorer like [Voyager](https://voyager.online/) or [Starkscan](https://starkscan.co/), they use the contract's ABI to format the data you send to the contract and the data it returns. - -## Interface - -The interface of a contract is a list of the functions it exposes publicly. -It specifies the function signatures (name, parameters, visibility and return value) contained in a smart contract without including the function body. - -Contract interfaces in Cairo are traits annotated with the `#[starknet::interface]` attribute. If you are new to traits, check out the dedicated chapter on [traits](./ch08-02-traits-in-cairo.md). - -One important specification is that this trait must be generic over the `TContractState` type. This is required for functions to access the contract's storage, so that they can read and write to it. - -> Note: The contract constructor is not part of the interface. Nor are internal functions part of the interface. - -Here's a sample interface for an ERC20 token contract. As you can see, it's a generic trait over the `TContractState` type. `view` functions have a self parameter of type `@TContractState`, while `external` functions have a self parameter of type passed by reference `ref self: TContractState`. - -```rust,noplayground -use starknet::ContractAddress; - -#[starknet::interface] -trait IERC20 { - fn name(self: @TContractState) -> felt252; - - fn symbol(self: @TContractState) -> felt252; - - fn decimals(self: @TContractState) -> u8; - - fn total_supply(self: @TContractState) -> u256; - - fn balance_of(self: @TContractState, account: ContractAddress) -> u256; - - fn allowance(self: @TContractState, owner: ContractAddress, spender: ContractAddress) -> u256; - - fn transfer(ref self: TContractState, recipient: ContractAddress, amount: u256) -> bool; - - fn transfer_from( - ref self: TContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256 - ) -> bool; - - fn approve(ref self: TContractState, spender: ContractAddress, amount: u256) -> bool; -} -``` - -Listing 15-1: A simple ERC20 Interface. - -In the next chapter, we will see how we can call contracts from other smart contracts using _dispatchers_ and _syscalls_ . -# Contract Dispatchers, Library Dispatchers and System Calls - -Each time a contract interface is defined, two dispatchers are automatically created and exported by the compiler. Let's consider an interface that we named IERC20, these would be: - -1. The Contract Dispatcher `IERC20Dispatcher` -2. The Library Dispatcher `IERC20LibraryDispatcher` - -The compiler also generates a trait `IERC20DispatcherTrait`, allowing us to call the functions defined in the interface on the dispatcher struct. - -In this chapter, we are going to discuss what these are, how they work and how to use them. - -To effectively break down the concepts in this chapter, we are going to be using the IERC20 interface from the previous chapter (refer to Listing 15-1). - -## Contract Dispatcher - -As mentioned previously, traits annotated with the `#[starknet::interface]` attribute automatically generate a dispatcher and a trait on compilation. -Our `IERC20` interface is expanded into something like this: - -**Note:** The expanded code for our IERC20 interface is a lot longer, but to keep this chapter concise and straight to the point, we focused on one view function `name`, and one external function `transfer`. - -```rust,noplayground -use starknet::{ContractAddress}; - -trait IERC20DispatcherTrait { - fn name(self: T) -> felt252; - fn transfer(self: T, recipient: ContractAddress, amount: u256); -} - -#[derive(Copy, Drop, starknet::Store, Serde)] -struct IERC20Dispatcher { - contract_address: ContractAddress, -} - -impl IERC20DispatcherImpl of IERC20DispatcherTrait { - fn name( - self: IERC20Dispatcher - ) -> felt252 { // starknet::call_contract_syscall is called in here - } - fn transfer( - self: IERC20Dispatcher, recipient: ContractAddress, amount: u256 - ) { // starknet::call_contract_syscall is called in here - } -} -``` - -Listing 15-2: An expanded form of the IERC20Dispatcher trait. - -As you can see, the "classic" dispatcher is just a struct that wraps a contract address and implements the `DispatcherTrait` generated by the compiler, allowing us to call functions from another contract. This means that we can instantiate a struct with the address of the contract we want to call, and then simply call the functions defined in the interface on the dispatcher struct as if they were methods of that type. - -It's also worthy of note that all these are abstracted behind the scenes thanks to the power of Cairo plugins. - -### Calling Contracts using the Contract Dispatcher - -This is an example of a contract named `TokenWrapper` using a dispatcher to call functions defined on an ERC-20 token. Calling `transfer_token` will modify the state of the contract deployed at `contract_address`. - -```rust,noplayground -# use starknet::ContractAddress; -# -# #[starknet::interface] -# trait IERC20 { -# fn name(self: @TContractState) -> felt252; -# -# fn symbol(self: @TContractState) -> felt252; -# -# fn decimals(self: @TContractState) -> u8; -# -# fn total_supply(self: @TContractState) -> u256; -# -# fn balance_of(self: @TContractState, account: ContractAddress) -> u256; -# -# fn allowance(self: @TContractState, owner: ContractAddress, spender: ContractAddress) -> u256; -# -# fn transfer(ref self: TContractState, recipient: ContractAddress, amount: u256) -> bool; -# -# fn transfer_from( -# ref self: TContractState, sender: ContractAddress, recipient: ContractAddress, amount: u256 -# ) -> bool; -# -# fn approve(ref self: TContractState, spender: ContractAddress, amount: u256) -> bool; -# } -# -# #[starknet::interface] -# trait ITokenWrapper { -# fn token_name(self: @TContractState, contract_address: ContractAddress) -> felt252; -# -# fn transfer_token( -# ref self: TContractState, -# contract_address: ContractAddress, -# recipient: ContractAddress, -# amount: u256 -# ) -> bool; -# } -# -# -//**** Specify interface here ****// -#[starknet::contract] -mod TokenWrapper { - use super::IERC20DispatcherTrait; - use super::IERC20Dispatcher; - use super::ITokenWrapper; - use starknet::ContractAddress; - - #[storage] - struct Storage {} - - impl TokenWrapper of ITokenWrapper { - fn token_name(self: @ContractState, contract_address: ContractAddress) -> felt252 { - IERC20Dispatcher { contract_address }.name() - } - - fn transfer_token( - ref self: ContractState, - contract_address: ContractAddress, - recipient: ContractAddress, - amount: u256 - ) -> bool { - IERC20Dispatcher { contract_address }.transfer(recipient, amount) - } - } -} -# -# -``` - -Listing 15-3: A sample contract which uses the Contract Dispatcher. - -As you can see, we had to first import `IERC20DispatcherTrait` and `IERC20Dispatcher` generated by the compiler, which allows us to make calls to the methods implemented for the `IERC20Dispatcher` struct (`name`, `transfer`, etc), passing in the `contract_address` of the contract we want to call in the `IERC20Dispatcher` struct. - -## Library Dispatcher - -The key difference between the contract dispatcher and the library dispatcher lies in the execution context of the logic defined in the class. While regular dispatchers are used to call functions from **contracts** (with an associated state), library dispatchers are used to call **classes** (stateless). - -Let's consider two contracts A and B. - -When A uses `IBDispatcher` to call functions from the **contract** B, the execution context of the logic defined in B is that of B. This means that the value returned by `get_caller_address()` in B will return the address of A, and updating a storage variable in B will update the storage of B. - -When A uses `IBLibraryDispatcher` to call functions from the **class** of B, the execution context of the logic defined in B's class is that of A. This means that the value returned by `get_caller_address()` variable in B will return the address of the caller of A, and updating a storage variable in B's class will update the storage of A (remember that the **class** of B is stateless; there is no state that can be updated!) - -The expanded form of the struct and trait generated by the compiler look like: - -```rust,noplayground -use starknet::ContractAddress; - -trait IERC20DispatcherTrait { - fn name(self: T) -> felt252; - fn transfer(self: T, recipient: ContractAddress, amount: u256); -} - -#[derive(Copy, Drop, starknet::Store, Serde)] -struct IERC20LibraryDispatcher { - class_hash: starknet::ClassHash, -} - -impl IERC20LibraryDispatcherImpl of IERC20DispatcherTrait { - fn name( - self: IERC20LibraryDispatcher - ) -> felt252 { // starknet::syscalls::library_call_syscall is called in here - } - fn transfer( - self: IERC20LibraryDispatcher, recipient: ContractAddress, amount: u256 - ) { // starknet::syscalls::library_call_syscall is called in here - } -} -``` - -Listing 15-4: An expanded form of the IERC20 trait. - -Notice that the main difference between the regular contract dispatcher and the library dispatcher is that the former uses `call_contract_syscall` while the latter uses `library_call_syscall`. - -### Calling Contracts using the Library Dispatcher - -Below's a sample code for calling contracts using the Library Dispatcher. - -```rust,noplayground -use starknet::ContractAddress; - -#[starknet::interface] -trait IContractA { - fn set_value(ref self: TContractState, value: u128); - - fn get_value(self: @TContractState) -> u128; -} - -#[starknet::contract] -mod ContractA { - use super::{IContractADispatcherTrait, IContractALibraryDispatcher}; - use starknet::{ContractAddress, class_hash::class_hash_const}; - - #[storage] - struct Storage { - value: u128 - } - - #[abi(embed_v0)] - impl ContractA of super::IContractA { - fn set_value(ref self: ContractState, value: u128) { - IContractALibraryDispatcher { class_hash: class_hash_const::<0x1234>() } - .set_value(value) - } - - fn get_value(self: @ContractState) -> u128 { - self.value.read() - } - } -} -``` - -Listing 15-5: A sample contract using the Library Dispatcher. - -As you can see, we had to first import in our contract the `IContractADispatcherTrait` and `IContractALibraryDispatcher` which were generated from our interface by the compiler. Then, we can create an instance of `IContractALibraryDispatcher` passing in the `class_hash` of the class we want to make library calls to. From there, we can call the functions defined in that class, executing its logic in the context of our contract. When we call `set_value` on ContractA, it will make a library call to the `set_value` function in IContractA, updating the value of the storage variable `value` in ContractA. - -## Using low-level syscalls - -Another way to call other contracts and classes is to use the `starknet::call_contract_syscall`and `starknet::library_call_syscall` system calls. The dispatchers we described in the previous sections are high-level syntaxes for these low-level system calls. - -Using these syscalls can be handy for customized error handling or to get more control over the serialization/deserialization of the call data and the returned data. Here's an example demonstrating how to use a `call_contract_sycall` to call the `transfer` function of an ERC20 contract: - -```rust,noplayground -use starknet::ContractAddress; -#[starknet::interface] -trait ITokenWrapper { - fn transfer_token( - ref self: TContractState, - address: ContractAddress, - sender: ContractAddress, - recipient: ContractAddress, - amount: u256 - ) -> bool; -} - -#[starknet::contract] -mod TokenWrapper { - use super::ITokenWrapper; - use core::serde::Serde; - use starknet::{SyscallResultTrait, ContractAddress, syscalls}; - - #[storage] - struct Storage {} - - impl TokenWrapper of ITokenWrapper { - fn transfer_token( - ref self: ContractState, - address: ContractAddress, - sender: ContractAddress, - recipient: ContractAddress, - amount: u256 - ) -> bool { - let mut call_data: Array = ArrayTrait::new(); - Serde::serialize(@sender, ref call_data); - Serde::serialize(@recipient, ref call_data); - Serde::serialize(@amount, ref call_data); - - let mut res = syscalls::call_contract_syscall( - address, selector!("transferFrom"), call_data.span() - ) - .unwrap_syscall(); - - Serde::::deserialize(ref res).unwrap() - } - } -} - -``` - -Listing 15-6: A sample contract using syscalls. - -To use this syscall, we passed in the contract address, the selector of the function we want to call (see next section), and the call arguments. - -The call arguments must be provided as an array of `felt252`. To build this array, we serialize the expected function parameters into an `Array` using the `Serde` trait, and then pass this array as calldata. At the end, we are returned a serialized value which we'll need to deserialize ourselves! - -### Entry Point Selector - -In the context of a smart contract, a selector is a unique identifier for a specific entrypoint of a contract. When a transaction is sent to a contract, it includes the selector in the calldata to specify which function should be executed. - -On Starknet, the selector is computed by applying the `sn_keccak` hash function to the string representation of the function name. If the function name is `transfer`, the selector can be computed with `selector!("transfer")` - -Note that in `starknet::call_contract_syscall`, we didn't specify the function name as a string, but rather used the `selector!` macro, which computes the `sn_keccak` hash of the provided function signature. -# Building Advanced Starknet Smart Contracts -# Optimizing Storage Costs - -Bit-packing is a simple concept: use as few bits as possible to store a piece of data. When done well, it can significantly reduce the size of the data you need to store. This is especially important in smart contracts, where storage is expensive. - -When writing Cairo smart contracts, it is important to optimize storage usage to reduce gas costs. Indeed, most of the cost associated with a transaction is related to storage updates; and each storage slot costs gas to write to. -This means that by packing multiple values into fewer slots, you can decrease the gas cost incurred by the users of your smart contract. - -## Integer Structure and Bitwise Operators - -An integer is coded on a certain number of bits, depending on its size (For example, a `u8` integer is coded on 8 bits). - -
- a u8 integer in bits -
-
- Representation of a u8 integer in bits -
- -Intuitively, several integers can be combined into a single integer if the size of this single integer is greater than or equal to the sum of the sizes of the integers (For example, two `u8` and one `u16` in one `u32`). - -But, to do that, we need some bitwise operators: - -- multiplying or dividing an integer by a power of 2 shifts the integer value to the left or to the right respectively - -
- shift operators -
-
- Shifting to the left or to the right an integer value -
- -- applying a mask (`AND` operator) on an integer value isolates some bits of this integer - -
- applying a mask -
-
- Isolate bits with a mask -
- -- adding (`OR` operator) two integers will combine both values into a single one. - -
- combining two values -
-
- Combining two integers -
- -With these bitwise operators, let's see how to combine two `u8` integers into a single `u16` integer (called `packing`) and reversely (called `unpacking`) in the following example: - -
- packing and unpacking integer values -
-
- Packing and unpacking integer values -
- -## Bit-packing in Cairo - -The storage of a Starknet smart contract is a map with 2251 slots, where each slot is a `felt252` which is initialized to 0. - -As we saw earlier, to reduce gas costs due to storage updates, we have to use as few bits as possible, so we have to organize stored variables by packing them. - -For example, consider the following `Sizes` struct with 3 fields of different types: one `u8`, one `u32` and one `u64`. The total size is 8 + 32 + 64 = 104 bits. This is less than a slot size (i.e 251 bits) so we can pack them together to be stored into a single slot. - -Note that, as it also fits in a `u128`, it's a good practice to use the smallest type to pack all your variables, so here a `u128` should be used. - -```rust,noplayground -struct Sizes { - tiny: u8, - small: u32, - medium: u64, -} -``` - -To pack these 3 variables into a `u128` we have to successively shift them to the left, and finally sum them. - -
- Sizes packing -
-
- Sizes packing -
- -To unpack these 3 variables from a `u128` we have to successively shift them to the right and use a mask to isolate them. - -
- Sizes unpacking -
-
- Sizes unpacking -
- -## The `StorePacking` Trait - -Cairo provides the `StorePacking` trait to enable packing struct fields into fewer storage slots. `StorePacking` is a generic trait taking the type you want to pack (`T`) and the destination type (`PackedT`) as parameters. It provides two functions to implement: `pack` and `unpack`. - -Here is the implementation of the example of the previous chapter: - -```rust,noplayground -use starknet::storage_access::StorePacking; - -#[derive(Drop, Serde)] -struct Sizes { - tiny: u8, - small: u32, - medium: u64, -} - -const TWO_POW_8: u128 = 0x100; -const TWO_POW_40: u128 = 0x10000000000; - -const MASK_8: u128 = 0xff; -const MASK_32: u128 = 0xffffffff; - -impl SizesStorePacking of StorePacking { - fn pack(value: Sizes) -> u128 { - value.tiny.into() + (value.small.into() * TWO_POW_8) + (value.medium.into() * TWO_POW_40) - } - - fn unpack(value: u128) -> Sizes { - let tiny = value & MASK_8; - let small = (value / TWO_POW_8) & MASK_32; - let medium = (value / TWO_POW_40); - - Sizes { - tiny: tiny.try_into().unwrap(), - small: small.try_into().unwrap(), - medium: medium.try_into().unwrap(), - } - } -} - -#[starknet::contract] -mod SizeFactory { - use super::Sizes; - use super::SizesStorePacking; //don't forget to import it! - - #[storage] - struct Storage { - remaining_sizes: Sizes - } - - #[abi(embed_v0)] - fn update_sizes(ref self: ContractState, sizes: Sizes) { - // This will automatically pack the - // struct into a single u128 - self.remaining_sizes.write(sizes); - } - - - #[abi(embed_v0)] - fn get_sizes(ref self: ContractState) -> Sizes { - // this will automatically unpack the - // packed-representation into the Sizes struct - self.remaining_sizes.read() - } -} -``` - -
- Optimizing storage by implementing the `StorePacking` trait. -
- -In this code snippet, you see that: - -- `TWO_POW_8` and `TWO_POW_40` are used to shift left in the `pack` function and shift right in the `unpack`function, -- `MASK_8` and `MASK_32` are used to isolate a variable in the `unpack` function, -- all the variables from the storage are converted to `u128` to be able to use bitwise operators. - -This technique can be used for any group of fields that fit within the bit size of the packed storage type. For example, if you have a struct with multiple fields whose bit sizes add up to 256 bits, you can pack them into a single `u256` variable. If the bit sizes add up to 512 bits, you can pack them into a single `u512` variable, and so on. You can define your own structs and logic to pack and unpack them. - -The rest of the work is done magically by the compiler - if a type implements the `StorePacking` trait, then the compiler will know it can use the `StoreUsingPacking` implementation of the `Store` trait in order to pack before writing and unpack after reading from storage. -One important detail, however, is that the type that `StorePacking::pack` spits out also has to implement `Store` for `StoreUsingPacking` to work. Most of the time, we will want to pack into a felt252 or u256 - but if you want to pack into a type of your own, make sure that this one implements the `Store` trait. -# Components: Lego-Like Building Blocks for Smart Contracts - -Developing contracts sharing a common logic and storage can be painful and -bug-prone, as this logic can hardly be reused and needs to be reimplemented in -each contract. But what if there was a way to snap in just the extra -functionality you need inside your contract, separating the core logic of your -contract from the rest? - -Components provide exactly that. They are modular add-ons encapsulating reusable -logic, storage, and events that can be incorporated into multiple contracts. -They can be used to extend a contract's functionality, without having to -reimplement the same logic over and over again. - -Think of components as Lego blocks. They allow you to enrich your contracts by -plugging in a module that you or someone else wrote. This module can be a simple -one, like an ownership component, or more complex like a full-fledged ERC20 -token. - -A component is a separate module that can contain storage, events, and -functions. Unlike a contract, a component cannot be declared or deployed. Its -logic will eventually be part of the contract’s bytecode it has been embedded -in. - -## What's in a Component? - -A component is very similar to a contract. It can contain: - -- Storage variables -- Events -- External and internal functions - -Unlike a contract, a component cannot be deployed on its own. The component's -code becomes part of the contract it's embedded to. - -## Creating Components - -To create a component, first define it in its own module decorated with a -`#[starknet::component]` attribute. Within this module, you can declare a ` -Storage` struct and `Event` enum, as usually done in [contracts][contract anatomy]. - -The next step is to define the component interface, containing the signatures of -the functions that will allow external access to the component's logic. You can -define the interface of the component by declaring a trait with the -`#[starknet::interface]` attribute, just as you would with contracts. This -interface will be used to enable external access to the component's functions -using the [dispatcher][contract dispatcher] pattern. - -The actual implementation of the component's external logic is done in an `impl` -block marked as `#[embeddable_as(name)]`. Usually, this `impl` block will be an -implementation of the trait defining the interface of the component. - -> Note: `name` is the name that we’ll be using in the contract to refer to the -> component. It is different than the name of your impl. - -You can also define internal functions that will not be accessible externally, -by simply omitting the `#[embeddable_as(name)]` attribute above the internal -`impl` block. You will be able to use these internal functions inside the -contract you embed the component in, but not interact with it from outside, as -they're not a part of the abi of the contract. - -Functions within these `impl` block expect arguments like `ref self: -ComponentState` (for state-modifying functions) or `self: -@ComponentState` (for view functions). This makes the impl -generic over `TContractState`, allowing us to use this component in any -contract. - -[contract anatomy]: ./ch13-02-anatomy-of-a-simple-contract.md -[contract dispatcher]: ./ch15-02-contract-dispatchers-library-dispatchers-and-system-calls.md - -### Example: an Ownable Component - -> ⚠️ The example shown below has not been audited and is not intended for -> production use. The authors are not responsible for any damages caused by the -> use of this code. - -The interface of the Ownable component, defining the methods available -externally to manage ownership of a contract, would look like this: - -```rust,noplayground -#[starknet::interface] -trait IOwnable { - fn owner(self: @TContractState) -> ContractAddress; - fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress); - fn renounce_ownership(ref self: TContractState); -} -``` - -The component itself is defined as: - -```rust,noplayground -#[starknet::component] -pub mod ownable_component { - use starknet::ContractAddress; - use starknet::get_caller_address; - use super::Errors; - use core::num::traits::Zero; - - #[storage] - struct Storage { - owner: ContractAddress - } - - #[event] - #[derive(Drop, starknet::Event)] - pub enum Event { - OwnershipTransferred: OwnershipTransferred - } - - #[derive(Drop, starknet::Event)] - struct OwnershipTransferred { - previous_owner: ContractAddress, - new_owner: ContractAddress, - } - - #[embeddable_as(Ownable)] - impl OwnableImpl< - TContractState, +HasComponent - > of super::IOwnable> { - fn owner(self: @ComponentState) -> ContractAddress { - self.owner.read() - } - - fn transfer_ownership( - ref self: ComponentState, new_owner: ContractAddress - ) { - assert(!new_owner.is_zero(), Errors::ZERO_ADDRESS_OWNER); - self.assert_only_owner(); - self._transfer_ownership(new_owner); - } - - fn renounce_ownership(ref self: ComponentState) { - self.assert_only_owner(); - self._transfer_ownership(Zero::zero()); - } - } - - #[generate_trait] - pub impl InternalImpl< - TContractState, +HasComponent - > of InternalTrait { - fn initializer(ref self: ComponentState, owner: ContractAddress) { - self._transfer_ownership(owner); - } - - fn assert_only_owner(self: @ComponentState) { - let owner: ContractAddress = self.owner.read(); - let caller: ContractAddress = get_caller_address(); - assert(!caller.is_zero(), Errors::ZERO_ADDRESS_CALLER); - assert(caller == owner, Errors::NOT_OWNER); - } - - fn _transfer_ownership( - ref self: ComponentState, new_owner: ContractAddress - ) { - let previous_owner: ContractAddress = self.owner.read(); - self.owner.write(new_owner); - self - .emit( - OwnershipTransferred { previous_owner: previous_owner, new_owner: new_owner } - ); - } - } -} -``` - -This syntax is actually quite similar to the syntax used for contracts. The only -differences relate to the `#[embeddable_as]` attribute above the impl and the -genericity of the impl block that we will dissect in details. - -As you can see, our component has two `impl` blocks: one corresponding to the -implementation of the interface trait, and one containing methods that should -not be exposed externally and are only meant for internal use. Exposing the -`assert_only_owner` as part of the interface wouldn't make sense, as it's only -meant to be used internally by a contract embedding the component. - -## A Closer Look at the `impl` Block - -```rust,noplayground - #[embeddable_as(Ownable)] - impl OwnableImpl< - TContractState, +HasComponent - > of super::IOwnable> { -``` - -The `#[embeddable_as]` attribute is used to mark the impl as embeddable inside a -contract. It allows us to specify the name of the impl that will be used in the -contract to refer to this component. In this case, the component will be -referred to as `Ownable` in contracts embedding it. - -The implementation itself is generic over `ComponentState`, with -the added restriction that `TContractState` must implement the `HasComponent` -trait. This allows us to use the component in any contract, as long as the -contract implements the `HasComponent` trait. Understanding this mechanism in -details is not required to use components, but if you're curious about the inner -workings, you can read more in the ["Components Under the Hood"][components inner working] section. - -One of the major differences from a regular smart contract is that access to -storage and events is done via the generic `ComponentState` type -and not `ContractState`. Note that while the type is different, accessing -storage or emitting events is done similarly via `self.storage_var_name.read()` -or `self.emit(...).` - -> Note: To avoid the confusion between the embeddable name and the impl name, we -> recommend keeping the suffix `Impl` in the impl name. - -[components inner working]: ./ch16-02-01-under-the-hood.md - -## Migrating a Contract to a Component - -Since both contracts and components share a lot of similarities, it's actually -very easy to migrate from a contract to a component. The only changes required -are: - -- Adding the `#[starknet::component]` attribute to the module. -- Adding the `#[embeddable_as(name)]` attribute to the `impl` block that will be - embedded in another contract. -- Adding generic parameters to the `impl` block: - - Adding `TContractState` as a generic parameter. - - Adding `+HasComponent` as an impl restriction. -- Changing the type of the `self` argument in the functions inside the `impl` - block to `ComponentState` instead of `ContractState`. - -For traits that do not have an explicit definition and are generated using -`#[generate_trait]`, the logic is the same - but the trait is generic over -`TContractState` instead of `ComponentState`, as demonstrated in -the example with the `InternalTrait`. - -## Using Components Inside a Contract - -The major strength of components is how it allows reusing already built -primitives inside your contracts with a restricted amount of boilerplate. To -integrate a component into your contract, you need to: - -1. Declare it with the `component!()` macro, specifying - - 1. The path to the component `path::to::component`. - 2. The name of the variable in your contract's storage referring to this - component's storage (e.g. `ownable`). - 3. The name of the variant in your contract's event enum referring to this - component's events (e.g. `OwnableEvent`). - -2. Add the path to the component's storage and events to the contract's - `Storage` and `Event`. They must match the names provided in step 1 (e.g. - `ownable: ownable_component::Storage` and `OwnableEvent: -ownable_component::Event`). - - The storage variable **MUST** be annotated with the `#[substorage(v0)]` - attribute. - -3. Embed the component's logic defined inside your contract, by instantiating - the component's generic impl with a concrete `ContractState` using an impl - alias. This alias must be annotated with `#[abi(embed_v0)]` to externally - expose the component's functions. - - As you can see, the InternalImpl is not marked with `#[abi(embed_v0)]`. - Indeed, we don't want to expose externally the functions defined in this - impl. However, we might still want to access them internally. - -For example, to embed the `Ownable` component defined above, we would do the -following: - -```rust,noplayground -#[starknet::contract] -mod OwnableCounter { - use listing_01_ownable::component::ownable_component; - - component!(path: ownable_component, storage: ownable, event: OwnableEvent); - - #[abi(embed_v0)] - impl OwnableImpl = ownable_component::Ownable; - - impl OwnableInternalImpl = ownable_component::InternalImpl; - - #[storage] - struct Storage { - counter: u128, - #[substorage(v0)] - ownable: ownable_component::Storage - } - - - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - OwnableEvent: ownable_component::Event - } - - - #[abi(embed_v0)] - fn foo(ref self: ContractState) { - self.ownable.assert_only_owner(); - self.counter.write(self.counter.read() + 1); - } -} -``` - -The component's logic is now seamlessly part of the contract! We can interact -with the components functions externally by calling them using the -`IOwnableDispatcher` instantiated with the contract's address. - -```rust -#[starknet::interface] -trait IOwnable { - fn owner(self: @TContractState) -> ContractAddress; - fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress); - fn renounce_ownership(ref self: TContractState); -} -``` - -## Stacking Components for Maximum Composability - -The composability of components really shines when combining multiple of them -together. Each adds its features onto the contract. You can rely on -[Openzeppelin's][OpenZeppelin Cairo Contracts] implementation -of components to quickly plug-in all the common functionalities you need a contract -to have. - -Developers can focus on their core contract logic while relying on battle-tested -and audited components for everything else. - -Components can even [depend][component dependencies] on other components by restricting the -`TContractstate` they're generic on to implement the trait of another component. -Before we dive into this mechanism, let's first look at [how components work under the hood][components inner working]. - - -[OpenZeppelin Cairo Contracts]: https://github.com/OpenZeppelin/cairo-contracts -[component dependencies]: ./ch16-02-02-component-dependencies.md -[components inner working]: ./ch16-02-01-under-the-hood.md -# Components: Under the Hood - -Components provide powerful modularity to Starknet contracts. But how does this -magic actually happen behind the scenes? - -This chapter will dive deep into the compiler internals to explain the -mechanisms that enable component composability. - -## A Primer on Embeddable Impls - -Before digging into components, we need to understand _embeddable impls_. - -An impl of a Starknet interface trait (marked with `#[starknet::interface]`) can -be made embeddable. Embeddable impls can be injected into any contract, adding -new entry points and modifying the ABI of the contract. - -Let's look at an example to see this in action: - -```rust,noplayground -#[starknet::interface] -trait SimpleTrait { - fn ret_4(self: @TContractState) -> u8; -} - -#[starknet::embeddable] -impl SimpleImpl of SimpleTrait { - fn ret_4(self: @TContractState) -> u8 { - 4 - } -} - -#[starknet::contract] -mod simple_contract { - #[storage] - struct Storage {} - - #[abi(embed_v0)] - impl MySimpleImpl = super::SimpleImpl; -} -``` - -By embedding `SimpleImpl`, we externally expose `ret4` in the contract's ABI. - -Now that we’re more familiar with the embedding mechanism, we can now see how -components build on this. - -## Inside Components: Generic Impls - -Recall the impl block syntax used in components: - -```rust,noplayground - #[embeddable_as(Ownable)] - impl OwnableImpl< - TContractState, +HasComponent - > of super::IOwnable> { -``` - -The key points: - -- `OwnableImpl` requires the implementation of the - `HasComponent` trait by the underlying contract, which is - automatically generated with the `component!()` macro when using a component - inside a contract. - - The compiler will generate an impl that wraps any function in `OwnableImpl`, - replacing the `self: ComponentState` argument with `self: -TContractState`, where access to the component state is made via the - `get_component` function in the `HasComponent` trait. - - For each component, the compiler generates a `HasComponent` trait. This trait - defines the interface to bridge between the actual `TContractState` of a - generic contract, and `ComponentState`. - - ```rust,noplayground - // generated per component - trait HasComponent { - fn get_component(self: @TContractState) -> @ComponentState; - fn get_component_mut(ref self: TContractState) -> ComponentState; - fn get_contract(self: @ComponentState) -> @TContractState; - fn get_contract_mut(ref self: ComponentState) -> TContractState; - fn emit>(ref self: ComponentState, event: S); - } - ``` - - In our context `ComponentState` is a type specific to the - ownable component, i.e. it has members based on the storage variables defined - in `ownable_component::Storage`. Moving from the generic `TContractState` to - `ComponentState` will allow us to embed `Ownable` in any - contract that wants to use it. The opposite direction - (`ComponentState` to `ContractState`) is useful for - dependencies (see the `Upgradeable` component depending on an `IOwnable` - implementation example in the [Components dependencies ](./ch16-02-02-component-dependencies.md) section). - - To put it briefly, one should think of an implementation of the above - `HasComponent` as saying: **“Contract whose state T has the upgradeable - component”.** - -- `Ownable` is annotated with the `embeddable_as()` attribute: - - `embeddable_as` is similar to `embeddable`; it only applies to impls of - `starknet::interface` traits and allows embedding this impl in a contract - module. That said, `embeddable_as()` has another role in the context of - components. Eventually, when embedding `OwnableImpl` in some contract, we - expect to get an impl with the following functions: - - ```rust,noplayground - fn owner(self: @TContractState) -> ContractAddress; - fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress); - fn renounce_ownership(ref self: TContractState); - ``` - - Note that while starting with a function receiving the generic type - `ComponentState`, we want to end up with a function receiving - `ContractState`. This is where `embeddable_as()` comes in. To see the - full picture, we need to see what is the impl generated by the compiler due to - the `embeddable_as(Ownable)` annotation: - -```rust,noplayground -#[starknet::embeddable] -impl Ownable< - TContractState, +HasComponent, impl TContractStateDrop: Drop -> of super::IOwnable { - fn owner(self: @TContractState) -> ContractAddress { - let component = HasComponent::get_component(self); - OwnableImpl::owner(component,) - } - - fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress) { - let mut component = HasComponent::get_component_mut(ref self); - OwnableImpl::transfer_ownership(ref component, new_owner,) - } - - fn renounce_ownership(ref self: TContractState) { - let mut component = HasComponent::get_component_mut(ref self); - OwnableImpl::renounce_ownership(ref component,) - } -} -``` - - Note that thanks to having an impl of `HasComponent`, the - compiler was able to wrap our functions in a new impl that doesn’t directly - know about the `ComponentState` type. `Ownable`, whose name we chose when - writing `embeddable_as(Ownable)`, is the impl that we will embed in a contract - that wants ownership. - -## Contract Integration - -We've seen how generic impls enable component reusability. Next let's see how a -contract integrates a component. - -The contract uses an **impl alias** to instantiate the component's generic impl -with the concrete `ContractState` of the contract. - -```rust,noplayground - #[abi(embed_v0)] - impl OwnableImpl = ownable_component::Ownable; - - impl OwnableInternalImpl = ownable_component::InternalImpl; -``` - -The above lines use the Cairo impl embedding mechanism alongside the impl alias -syntax. We’re instantiating the generic `OwnableImpl` with the -concrete type `ContractState`. Recall that `OwnableImpl` has the -`HasComponent` generic impl parameter. An implementation of this -trait is generated by the `component!` macro. - -Note that only the using contract -could have implemented this trait since only it knows about both the contract -state and the component state. - -This glues everything together to inject the component logic into the contract. - -## Key Takeaways - -- Embeddable impls allow injecting components logic into contracts by adding - entry points and modifying the contract ABI. -- The compiler automatically generates a `HasComponent` trait implementation - when a component is used in a contract. This creates a bridge between the - contract's state and the component's state, enabling interaction between the - two. -- Components encapsulate reusable logic in a generic, contract-agnostic way. - Contracts integrate components through impl aliases and access them via the - generated `HasComponent` trait. -- Components build on embeddable impls by defining generic component logic that - can be integrated into any contract wanting to use that component. Impl - aliases instantiate these generic impls with the contract's concrete storage - types. -# Component Dependencies - -Working with components becomes more complex when we try to use one component inside another. As mentioned earlier, a component can only be embedded within a contract, meaning that it's not possible to embed a component within another component. However, this doesn't mean that we can't use one component inside another. In this section, we will see how to use a component as a dependency of another component. - -Consider a component called `OwnableCounter` whose purpose is to create a counter that can only be incremented by its owner. This component can be embedded in any contract, so that any contract that uses it will have a counter that can only be incremented by its owner. - -The first way to implement this is to create a single component that contains both counter and ownership features from within a single component. However, this approach is not recommended: our goal is to minimize the amount of code duplication and take advantage of component reusability. Instead, we can create a new component that _depends_ on the `Ownable` component for the ownership features, and internally defines the logic for the counter. - -Listing 16-1 shows the complete implementation, which we'll break down right after: - -```rust,noplayground -use starknet::ContractAddress; - -#[starknet::interface] -trait IOwnableCounter { - fn get_counter(self: @TContractState) -> u32; - fn increment(ref self: TContractState); - fn transfer_ownership(ref self: TContractState, new_owner: ContractAddress); -} - -#[starknet::component] -mod OwnableCounterComponent { - use listing_03_component_dep::owner::{ownable_component, ownable_component::InternalImpl}; - use starknet::ContractAddress; - - #[storage] - struct Storage { - value: u32 - } - - #[embeddable_as(OwnableCounterImpl)] - impl OwnableCounter< - TContractState, - +HasComponent, - +Drop, - impl Owner: ownable_component::HasComponent - > of super::IOwnableCounter> { - fn get_counter(self: @ComponentState) -> u32 { - self.value.read() - } - - fn increment(ref self: ComponentState) { - let ownable_comp = get_dep_component!(@self, Owner); - ownable_comp.assert_only_owner(); - self.value.write(self.value.read() + 1); - } - - fn transfer_ownership( - ref self: ComponentState, new_owner: ContractAddress - ) { - let mut ownable_comp = get_dep_component_mut!(ref self, Owner); - ownable_comp._transfer_ownership(new_owner); - } - } -} -``` - -Listing 16-1: An OwnableCounter Component - -## Specificities - -### Specifying Dependencies on Another Component - -```rust,noplayground - impl OwnableCounter< - TContractState, - +HasComponent, - +Drop, - impl Owner: ownable_component::HasComponent - > of super::IOwnableCounter> { -``` - -In [chapter 8][cairo traits], we introduced trait bounds, which are used to specify that a generic type must implement a certain trait. In the same way, we can specify that a component depends on another component by restricting the `impl` block to be available only for contracts that contain the required component. -In our case, this is done by adding a restriction `impl Owner: ownable_component::HasComponent`, which indicates that this `impl` block is only available for contracts that contain an implementation of the `ownable_component::HasComponent` trait. This essentially means that the `TContractState' type has access to the ownable component. See [Components under the hood][component impl] for more information. - -Although most of the trait bounds were defined using [anonymous parameters][anonymous generic impl operator], the dependency on the `Ownable` component is defined using a named parameter (here, `Owner`). We will need to use this explicit name when accessing the `Ownable`component within the`impl` block. - -While this mechanism is verbose and may not be easy to approach at first, it is a powerful leverage of the trait system in Cairo. The inner workings of this mechanism are abstracted away from the user, and all you need to know is that when you embed a component in a contract, all other components in the same contract can access it. - -[cairo traits]: ./ch08-02-traits-in-cairo.md -[component impl]: ch16-02-01-under-the-hood.md#inside-components-generic-impls -[anonymous generic impl operator]: ./ch08-01-generic-data-types md#anonymous-generic-implementation-parameter--operator - -### Using the Dependency - -Now that we have made our `impl` depend on the `Ownable` component, we can access its functions, storage, and events within the implementation block. To bring the `Ownable` component into scope, we have two choices, depending on whether we intend to mutate the state of the `Ownable` component or not. -If we want to access the state of the `Ownable` component without mutating it, we use the `get_dep_component!` macro. If we want to mutate the state of the `Ownable` component (for example, change the current owner), we use the `get_dep_component_mut!` macro. -Both macros take two arguments: the first is `self`, either as a snapshot or by reference depending on mutability, representing the state of the component using the dependency, and the second is the component to access. - -```rust,noplayground - fn increment(ref self: ComponentState) { - let ownable_comp = get_dep_component!(@self, Owner); - ownable_comp.assert_only_owner(); - self.value.write(self.value.read() + 1); - } -``` - -In this function, we want to make sure that only the owner can call the `increment` function. We need to use -the `assert_only_owner` function from the `Ownable` component. We'll use the `get_dep_component!` macro which will return a snapshot of the requested component state, and call `assert_only_owner` on it, as a method of that component. - -For the `transfer_ownership` function, we want to mutate that state to change the current owner. We need to use the `get_dep_component_mut!` macro, which will return the requested component state as a mutable reference, and call `transfer_ownership` on it. - -```rust,noplayground - fn transfer_ownership( - ref self: ComponentState, new_owner: ContractAddress - ) { - let mut ownable_comp = get_dep_component_mut!(ref self, Owner); - ownable_comp._transfer_ownership(new_owner); - } -``` - -It works exactly the same as `get_dep_component!` except that we need to pass the state as a `ref` so we can -mutate it to transfer the ownership. -# Testing Components - -Testing components is a bit different than testing contracts. -Contracts need to be tested against a specific state, which can be achieved by either deploying the contract in a test, or by simply getting the `ContractState` object and modifying it in the context of your tests. - -Components are a generic construct, meant to be integrated in contracts, that can't be deployed on their own and don't have a `ContractState` object that we could use. So how do we test them? - -Let's consider that we want to test a very simple component called "Counter", that will allow each contract to have a counter that can be incremented. The component is defined in Listing 16-2: - -```rust, noplayground -#[starknet::component] -pub mod CounterComponent { - #[storage] - struct Storage { - value: u32 - } - - #[embeddable_as(CounterImpl)] - impl Counter< - TContractState, +HasComponent - > of super::ICounter> { - fn get_counter(self: @ComponentState) -> u32 { - self.value.read() - } - - fn increment(ref self: ComponentState) { - self.value.write(self.value.read() + 1); - } - } -} -``` - -Listing 16-2: A simple Counter component - -## Testing the Component by Deploying a Mock Contract - -The easiest way to test a component is to integrate it within a mock contract. This mock contract is only used for testing purposes, and only integrates the component you want to test. This allows you to test the component in the context of a contract, and to use a Dispatcher to call the component's entry points. - -We can define such a mock contract as follows: - -```rust, noplayground -#[starknet::contract] -mod MockContract { - use super::counter::CounterComponent; - - component!(path: CounterComponent, storage: counter, event: CounterEvent); - - #[storage] - struct Storage { - #[substorage(v0)] - counter: CounterComponent::Storage, - } - - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - CounterEvent: CounterComponent::Event - } - - #[abi(embed_v0)] - impl CounterImpl = CounterComponent::CounterImpl; -} -``` - -This contract is entirely dedicated to testing the `Counter` component. It embeds the component with the `component!` macro, exposes the component's entry points by annotating the impl aliases with `#[abi(embed_v0)]`. - -We also need to define an interface that will be required to interact externally with this mock contract. - -```rust, noplayground -#[starknet::interface] -pub trait ICounter { - fn get_counter(self: @TContractState) -> u32; - fn increment(ref self: TContractState); -} -``` - -We can now write tests for the component by deploying this mock contract and calling its entry points, as we would with a typical contract. - -```rust, noplayground -use super::MockContract; -use super::counter::{ICounterDispatcher, ICounterDispatcherTrait}; -use starknet::deploy_syscall; -use starknet::SyscallResultTrait; - -fn setup_counter() -> ICounterDispatcher { - let (address, _) = deploy_syscall( - MockContract::TEST_CLASS_HASH.try_into().unwrap(), 0, array![].span(), false - ) - .unwrap_syscall(); - ICounterDispatcher { contract_address: address } -} - -#[test] -fn test_constructor() { - let counter = setup_counter(); - assert_eq!(counter.get_counter(), 0); -} - -#[test] -fn test_increment() { - let counter = setup_counter(); - counter.increment(); - assert_eq!(counter.get_counter(), 1); -} -``` - -## Testing Components Without Deploying a Contract - -In [Components under the hood][components inner working], we saw that components leveraged genericity to define storage and logic that could be embedded in multiple contracts. If a contract embeds a component, a `HasComponent` trait is created in this contract, and the component methods are made available. - -This informs us that if we can provide a concrete `TContractState` that implements the `HasComponent` trait to the `ComponentState` struct, should be able to directly invoke the methods of the component using this concrete `ComponentState` object, without having to deploy a mock. - -Let's see how we can do that by using type aliases. We still need to define a mock contract - let's use the same as above - but this time, we won't need to deploy it. - -First, we need to define a concrete implementation of the generic `ComponentState` type using a type alias. We will use the `MockContract::ContractState` type to do so. - -```rust, noplayground -# use super::counter::{CounterComponent}; -# use super::MockContract; -# use CounterComponent::{CounterImpl}; -# -type TestingState = CounterComponent::ComponentState; - -// You can derive even `Default` on this type alias -impl TestingStateDefault of Default { - fn default() -> TestingState { - CounterComponent::component_state_for_testing() - } -} -# -# #[test] -# fn test_increment() { -# let mut counter: TestingState = Default::default(); -# -# counter.increment(); -# counter.increment(); -# -# assert_eq!(counter.get_counter(), 2); -# } -# -# -``` - -We defined the `TestingState` type as an alias of the `CounterComponent::ComponentState` type. By passing the `MockContract::ContractState` type as a concrete type for `ComponentState`, we aliased a concrete implementation of the `ComponentState` struct to `TestingState`. - -Because `MockContract` embeds `CounterComponent`, the methods of `CounterComponent` defined in the `CounterImpl` block can now be used on a `TestingState` object. - -Now that we have made these methods available, we need to instantiate an object of type `TestingState`, that we will use to test the component. We can do so by calling the `component_state_for_testing` function, which automatically infers that it should return an object of type `TestingState`. - -We can even implement this as part of the `Default` trait, which allows us to return an empty `TestingState` with the `Default::default()` syntax. - -Let's summarize what we've done so far: - -- We defined a mock contract that embeds the component we want to test. -- We defined a concrete implementation of `ComponentState` using a type alias with `MockContract::ContractState`, that we named `TestingState`. -- We defined a function that uses `component_state_for_testing` to return a `TestingState` object. - -We can now write tests for the component by calling its functions directly, without having to deploy a mock contract. This approach is more lightweight than the previous one, and it allows testing internal functions of the component that are not exposed to the outside world trivially. - -```rust, noplayground -# use super::counter::{CounterComponent}; -# use super::MockContract; -# use CounterComponent::{CounterImpl}; -# -# type TestingState = CounterComponent::ComponentState; -# -# // You can derive even `Default` on this type alias -# impl TestingStateDefault of Default { -# fn default() -> TestingState { -# CounterComponent::component_state_for_testing() -# } -# } -# -#[test] -fn test_increment() { - let mut counter: TestingState = Default::default(); - - counter.increment(); - counter.increment(); - - assert_eq!(counter.get_counter(), 2); -} -# -# -``` - -[components inner working]: ./ch16-02-01-under-the-hood.md -# Upgradeable Contracts - -Starknet separates contracts into classes and instances, making it simple to upgrade a contract's logic without affecting its state. - -A contract class is the definition of the semantics of a contract. It includes the entire logic of a contract: the name of the entry points, the addresses of the storage variables, the events that can be emitted, etc. Each class is uniquely identified by its class hash. A class does not have its own storage: it's only a definition of logic. - -Classes are typically identified by a [class hash][class hash doc]. When declaring a class, the network registers it and assigns a unique hash used to identify the class and deploy contract instances from it. - -A contract instance is a deployed contract corresponding to a class, with its own storage. - -Starknet natively supports upgradeable contracts through the `replace_class_syscall` [system call][syscalls doc], enabling simple contract upgrades without affecting the contract's state. - -[class hash doc]: https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/class-hash -[syscalls doc]: https://docs.starknet.io/documentation/architecture_and_concepts/Smart_Contracts/system-calls-cairo1/ - -## Upgrading Contracts - -To upgrade a contract, expose an entry point that executes `replace_class_syscall` with the new class hash as an argument: - -```rust,noplayground -use starknet::{ClassHash, syscalls}; -use starknet::class_hash::class_hash_const; -use core::num::traits::Zero; - -fn _upgrade(new_class_hash: ClassHash) { - assert(!new_class_hash.is_zero(), 'Class hash cannot be zero'); - syscalls::replace_class_syscall(new_class_hash).unwrap(); -} -``` - -Listing 16-3: Exposing `replace_class_syscall` to update the contract's class - -> Note: Thoroughly review changes and potential impacts before upgrading, as it's a delicate procedure with security implications. Don't allow arbitrary addresses to upgrade your contract. - -## Upgradeable Component - -OpenZeppelin Contracts for Cairo provides the `Upgradeable` component that can be embedded into your contract to make it upgradeable. This component is a simple way to add upgradeability to your contract while relying on an audited library. It can be combined with the `Ownable` component to restrict the upgradeability to a single address, so that the contract owner has the exclusive right to upgrade the contract. - -```rust,noplayground -#[starknet::contract] -mod UpgradeableContract { - use openzeppelin::access::ownable::OwnableComponent; - use openzeppelin::upgrades::UpgradeableComponent; - use openzeppelin::upgrades::interface::IUpgradeable; - use starknet::ClassHash; - use starknet::ContractAddress; - - component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); - component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent); - - /// Ownable - #[abi(embed_v0)] - impl OwnableImpl = OwnableComponent::OwnableImpl; - impl OwnableInternalImpl = OwnableComponent::InternalImpl; - - /// Upgradeable - impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl; - - #[storage] - struct Storage { - #[substorage(v0)] - ownable: OwnableComponent::Storage, - #[substorage(v0)] - upgradeable: UpgradeableComponent::Storage - } - - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - #[flat] - OwnableEvent: OwnableComponent::Event, - #[flat] - UpgradeableEvent: UpgradeableComponent::Event - } - - #[constructor] - fn constructor(ref self: ContractState, owner: ContractAddress) { - self.ownable.initializer(owner); - } - - #[abi(embed_v0)] - impl UpgradeableImpl of IUpgradeable { - fn upgrade(ref self: ContractState, new_class_hash: ClassHash) { - // This function can only be called by the owner - self.ownable.assert_only_owner(); - - // Replace the class hash upgrading the contract - self.upgradeable._upgrade(new_class_hash); - } - } -} -``` - -Listing 16-4 Integrating OpenZeppelin's Upgradeable component in a contract - -For more information, please refer to the [OpenZeppelin docs API reference][oz upgradeability api]. - -[oz upgradeability api]: https://docs.openzeppelin.com/contracts-cairo/0.9.0/api/upgrades -# L1-L2 Messaging - -A crucial feature of a Layer 2 is its ability to interact with Layer 1. - -Starknet has its own `L1-L2` messaging system, which is different from its consensus mechanism and the submission of state updates on L1. Messaging is a way for smart-contracts on L1 to interact with smart-contracts on L2 (or the other way around), allowing us to do "cross-chain" transactions. For example, we can do some computations on a chain and use the result of this computation on the other chain. - -Bridges on Starknet all use `L1-L2` messaging. Let's say that you want to bridge tokens from Ethereum to Starknet. You will simply have to deposit your tokens in the L1 bridge contract, which will automatically trigger the minting of the same token on L2. Another good use case for `L1-L2` messaging would be [DeFi pooling][defi pooling doc]. - -On Starknet, it's important to note that the messaging system is **asynchronous** and **asymmetric**. - -- **Asynchronous**: this means that in your contract code (being Solidity or Cairo), you can't wait the result of the message being sent on the other chain within your contract code execution. -- **Asymmetric**: sending a message from Ethereum to Starknet (`L1->L2`) is fully automated by the Starknet sequencer, which means that the message is being automatically delivered to the target contract on L2. However, when sending a message from Starknet to Ethereum (`L2->L1`), only the hash of the message is sent on L1 by the Starknet sequencer. You must then consume the message manually via a transaction on L1. - -Let's dive into the details. - -[defi pooling doc]: https://starkware.co/resource/defi-pooling/ - -## The StarknetMessaging Contract - -The crucial component of the `L1-L2` Messaging system is the [`StarknetCore`][starknetcore etherscan] contract. It is a set of Solidity contracts deployed on Ethereum that allows Starknet to function properly. One of the contracts of `StarknetCore` is called `StarknetMessaging` and it is the contract responsible for passing messages between Starknet and Ethereum. `StarknetMessaging` follows an [interface][IStarknetMessaging] with functions allowing to send message to L2, receiving messages on L1 from L2 and canceling messages. - -```js -interface IStarknetMessaging is IStarknetMessagingEvents { - - function sendMessageToL2( - uint256 toAddress, - uint256 selector, - uint256[] calldata payload - ) external returns (bytes32); - - function consumeMessageFromL2(uint256 fromAddress, uint256[] calldata payload) - external - returns (bytes32); - - function startL1ToL2MessageCancellation( - uint256 toAddress, - uint256 selector, - uint256[] calldata payload, - uint256 nonce - ) external; - - function cancelL1ToL2Message( - uint256 toAddress, - uint256 selector, - uint256[] calldata payload, - uint256 nonce - ) external; -} -``` - - Starknet messaging contract interface - -In the case of `L1->L2` messages, the Starknet sequencer is constantly listening to the logs emitted by the `StarknetMessaging` contract on Ethereum. -Once a message is detected in a log, the sequencer prepares and executes a `L1HandlerTransaction` to call the function on the target L2 contract. This takes up to 1-2 minutes to be done (few seconds for ethereum block to be mined, and then the sequencer must build and execute the transaction). - -`L2->L1` messages are prepared by contracts execution on L2 and are part of the block produced. When the sequencer produces a block, it sends the hash of each message prepared by contracts execution -to the `StarknetCore` contract on L1, where they can then be consumed once the block they belong to is proven and verified on Ethereum (which for now is around 3-4 hours). - -[starknetcore etherscan]: https://etherscan.io/address/0xc662c410C0ECf747543f5bA90660f6ABeBD9C8c4 -[IStarknetMessaging]: https://github.com/starkware-libs/cairo-lang/blob/4e233516f52477ad158bc81a86ec2760471c1b65/src/starkware/starknet/eth/IStarknetMessaging.sol#L6 - -## Sending Messages from Ethereum to Starknet - -If you want to send messages from Ethereum to Starknet, your Solidity contracts must call the `sendMessageToL2` function of the `StarknetMessaging` contract. To receive these messages on Starknet, you will need to annotate functions that can be called from L1 with the `#[l1_handler]` attribute. - -Let's take a simple contract taken from [this tutorial][messaging contract] where we want to send a message to Starknet. -The `_snMessaging` is a state variable already initialized with the address of the `StarknetMessaging` contract. You can check all Starknet contract and sequencer addresses [here][starknet addresses]. - -```js -// Sends a message on Starknet with a single felt. -function sendMessageFelt( - uint256 contractAddress, - uint256 selector, - uint256 myFelt -) - external - payable -{ - // We "serialize" here the felt into a payload, which is an array of uint256. - uint256[] memory payload = new uint256[](1); - payload[0] = myFelt; - - // msg.value must always be >= 20_000 wei. - _snMessaging.sendMessageToL2{value: msg.value}( - contractAddress, - selector, - payload - ); -} -``` - -The function sends a message with a single felt value to the `StarknetMessaging` contract. -Please note that if you want to send more complex data you can. Just be aware that your Cairo contract will only understand `felt252` data type. So you must ensure that the serialization of your data into the `uint256` array follow the Cairo serialization scheme. - -It's important to note that we have `{value: msg.value}`. In fact, the minimum value we've to send here is `20k wei`, due to the fact that the `StarknetMessaging` contract will register -the hash of our message in the storage of Ethereum. - -In addition to those `20k wei`, since the `L1HandlerTransaction` executed by the sequencer is not tied to any account (the message originates from L1), you must also ensure -that you pay enough fees on L1 for your message to be deserialized and processed on L2. - -The fees of the `L1HandlerTransaction` are computed in a regular manner as it would be done for an `Invoke` transaction. For this, you can profile -the gas consumption using `starkli` or `snforge` to estimate the cost of your message execution. - -The signature of the `sendMessageToL2` is: - -```js -function sendMessageToL2( - uint256 toAddress, - uint256 selector, - uint256[] calldata payload - ) external override returns (bytes32); -``` - -The parameters are as follows: - -- `toAddress`: The contract address on L2 that will be called. -- `selector`: The selector of the function of this contract at `toAddress`. This selector (function) must have the `#[l1_handler]` attribute to be callable. -- `payload`: The payload is always an array of `felt252` (which are represented by `uint256` in Solidity). For this reason we've inserted the input `myFelt` into the array. - This is why we need to insert the input data into an array. - -On the Starknet side, to receive this message, we have: - -```rust,noplayground - #[l1_handler] - fn msg_handler_felt(ref self: ContractState, from_address: felt252, my_felt: felt252) { - assert(from_address == self.allowed_message_sender.read(), 'Invalid message sender'); - - // You can now use the data, automatically deserialized from the message payload. - assert(my_felt == 123, 'Invalid value'); - } -``` - -We need to add the `#[l1_handler]` attribute to our function. L1 handlers are special functions that can only be executed by a `L1HandlerTransaction`. There is nothing particular to do to receive transactions from L1, as the message is relayed by the sequencer automatically. In your `#[l1_handler]` functions, it is important to verify the sender of the L1 message to ensure that our contract can only receive messages from a trusted L1 contract. - -[messaging contract]: https://github.com/glihm/starknet-messaging-dev/blob/main/solidity/src/ContractMsg.sol -[starknet addresses]: https://docs.starknet.io/documentation/tools/important_addresses/ - -## Sending Messages from Starknet to Ethereum - -When sending messages from Starknet to Ethereum, you will have to use the `send_message_to_l1` syscall in your Cairo contracts. This syscall allows you to send messages to the `StarknetMessaging` contract on L1. Unlike `L1->L2` messages, `L2->L1` messages must be consumed manually, which means that you will need your Solidity contract to call the `consumeMessageFromL2` function of the `StarknetMessaging` contract explicitly in order to consume the message. - -To send a message from L2 to L1, what we would do on Starknet is: - -```rust,noplayground - fn send_message_felt(ref self: ContractState, to_address: EthAddress, my_felt: felt252) { - // Note here, we "serialize" my_felt, as the payload must be - // a `Span`. - syscalls::send_message_to_l1_syscall(to_address.into(), array![my_felt].span()) - .unwrap(); - } -``` - -We simply build the payload and pass it, along with the L1 contract address, to the syscall function. - -On L1, the important part is to build the same payload sent by the L2. Then you call `consumeMessageFromL2` in you Solidity contract by passing the L2 contract address and the payload. Please be aware that the L2 contract address expected by the `consumeMessageFromL2` is the address of the contract that sends the message on the L2 by calling `send_message_to_l1_syscall`. - -```js -function consumeMessageFelt( - uint256 fromAddress, - uint256[] calldata payload -) - external -{ - let messageHash = _snMessaging.consumeMessageFromL2(fromAddress, payload); - - // You can use the message hash if you want here. - - // We expect the payload to contain only a felt252 value (which is a uint256 in Solidity). - require(payload.length == 1, "Invalid payload"); - - uint256 my_felt = payload[0]; - - // From here, you can safely use `my_felt` as the message has been verified by StarknetMessaging. - require(my_felt > 0, "Invalid value"); -} -``` - -As you can see, in this context we don't have to verify which contract from L2 is sending the message (as we do on the L2 to verify which contract from L1 is sending the message). But we are actually using the `consumeMessageFromL2` of the `StarknetCore` contract to validate the inputs (the contract address on L2 and the payload) to ensure we are only consuming valid messages. - -> **Note:** The `consumeMessageFromL2` function of the `StarknetCore` contract is expected to be called from a Solidity contract, and not directly on the `StarknetCore` contract. The reason of that is because the `StarknetCore` contract is using `msg.sender` to actually compute the hash of the message. And this `msg.sender` must correspond to the `to_address` field that is given to the function `send_message_to_l1_syscall` that is called on Starknet. - -It is important to remember that on L1 we are sending a payload of `uint256`, but the basic data type on Starknet is `felt252`; however, `felt252` are approximately 4 bits smaller than `uint256`. So we have to pay attention to the values contained in the payload of the messages we are sending. If, on L1, we build a message with values above the maximum `felt252`, the message will be stuck and never consumed on L2. - -## Cairo Serde - -Before sending messages between L1 and L2, you must remember that Starknet contracts, written in Cairo, can only understand serialized data. And serialized data is always an array of `felt252`. -In Solidity we have `uint256` type, and `felt252` are approximately 4 bits smaller than `uint256`. So we have to pay attention to the values contained in the payload of the messages we are sending. -If, on L1, we build a message with values above the maximum `felt252`, the message will be stuck and never consumed on L2. - -So for instance, an actual `uint256` value in Cairo is represented by a struct like: - -```rust,does_not_compile -struct u256 { - low: u128, - high: u128, -} -``` - -which will be serialized as **TWO** felts, one for the `low`, and one for the `high`. This means that to send only one `u256` to Cairo, you'll need to send a payload from L1 with **TWO** values. - -```js -uint256[] memory payload = new uint256[](2); -// Let's send the value 1 as a u256 in cairo: low = 1, high = 0. -payload[0] = 1; -payload[1] = 0; -``` - -If you want to learn more about the messaging mechanism, you can visit the [Starknet documentation][starknet messaging doc]. - -You can also find a [detailed guide here][glihm messaging guide] to test the messaging system locally. - -[starknet messaging doc]: https://docs.starknet.io/documentation/architecture_and_concepts/Network_Architecture/messaging-mechanism/ -[glihm messaging guide]: https://github.com/glihm/starknet-messaging-dev -# Price Feeds - -Price feeds enabled by an oracle serve as a bridge between real-world data feed and the blockchain. They provide real time pricing data that is aggregated from multiple trusted external sources ( e.g. crypto exchanges, financial data providers, etc. ) to the blockchain network. - -For the example in this book section, we will use Pragma Oracle to read the price feed for `ETH/USD` asset pair and also showcase a mini application that utilizes this feed. - -[Pragma Oracle](https://www.pragma.build/) is a leading zero knowledge oracle that provides access to off-chain data on Starknet blockchain in a verifiable way. - -## Add Pragma as a Project Dependency - -To get started with integrating Pragma on your Cairo smart contract for price feed data, edit your project's `Scarb.toml` file to include the path to use Pragma. - -```toml -[dependencies] -pragma_lib = { git = "https://github.com/astraly-labs/pragma-lib" } -``` - -## Creating a Price Feed Contract - -After adding the required dependencies for your project, you'll need to define a contract interface that includes the required pragma price feed entry point. - -### Contract Interface - -```rust,noplayground -#[starknet::interface] -pub trait IPriceFeedExample { - fn buy_item(ref self: TContractState); - fn get_asset_price(self: @TContractState, asset_id: felt252) -> u128; -} -``` - -Of the two public functions exposed in the `IPriceFeedExample`, the one necessary to interact with the pragma price feed oracle is the `get_asset_price` function, a view function that takes in the `asset_id` argument and returns a `u128` value. - -### Pragma Dependency Import to Contract - -```rust,noplayground - use pragma_lib::abi::{IPragmaABIDispatcher, IPragmaABIDispatcherTrait}; - use pragma_lib::types::{DataType, PragmaPricesResponse}; -``` - -The snippet above shows the necessary imports you need to add to your contract module in order to interact with the Pragma oracle. - -### Required Price Feed Function Impl in Contract - -```rust,noplayground - fn get_asset_price(self: @ContractState, asset_id: felt252) -> u128 { - // Retrieve the oracle dispatcher - let oracle_dispatcher = IPragmaABIDispatcher { - contract_address: self.pragma_contract.read() - }; - - // Call the Oracle contract, for a spot entry - let output: PragmaPricesResponse = oracle_dispatcher - .get_data_median(DataType::SpotEntry(asset_id)); - - return output.price; - } -``` - -The `get_asset_price` function is responsible for retrieving the price of the asset specified by the `asset_id` argument from Pragma Oracle. The `get_data_median` method is called from the `IPragmaDispatcher` instance by passing the `DataType::SpotEntry(asset_id)` as an argument and its output is assigned to a variable named `output` of type `PragmaPricesResponse`. Finally, the function returns the price of the requested asset as a `u128`. - -## Example Application Using Pragma Price Feed - -```rust,noplayground -#[starknet::contract] -mod PriceFeedExample { - use super::{ContractAddress, IPriceFeedExample}; - use pragma_lib::abi::{IPragmaABIDispatcher, IPragmaABIDispatcherTrait}; - use pragma_lib::types::{DataType, PragmaPricesResponse}; - use openzeppelin::token::erc20::interface::{ERC20ABIDispatcher, ERC20ABIDispatcherTrait}; - use starknet::contract_address::contract_address_const; - use starknet::{get_caller_address}; - - const ETH_USD: felt252 = 19514442401534788; - const EIGHT_DECIMAL_FACTOR: u256 = 100000000; - - #[storage] - struct Storage { - pragma_contract: ContractAddress, - product_price_in_usd: u256, - } - - #[constructor] - fn constructor(ref self: ContractState, pragma_contract: ContractAddress) { - self.pragma_contract.write(pragma_contract); - self.product_price_in_usd.write(100); - } - - #[abi(embed_v0)] - impl PriceFeedExampleImpl of IPriceFeedExample { - fn buy_item(ref self: ContractState) { - let caller_address = get_caller_address(); - let eth_price = self.get_asset_price(ETH_USD).into(); - let product_price = self.product_price_in_usd.read(); - - // Calculate the amount of ETH needed - let eth_needed = product_price * EIGHT_DECIMAL_FACTOR / eth_price; - - let eth_dispatcher = ERC20ABIDispatcher { - contract_address: contract_address_const::< - 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 - >() // ETH Contract Address - }; - - // Transfer the ETH to the caller - eth_dispatcher - .transfer_from( - caller_address, - contract_address_const::< - 0x0237726d12d3c7581156e141c1b132f2db9acf788296a0e6e4e9d0ef27d092a2 - >(), - eth_needed - ); - } - - fn get_asset_price(self: @ContractState, asset_id: felt252) -> u128 { - // Retrieve the oracle dispatcher - let oracle_dispatcher = IPragmaABIDispatcher { - contract_address: self.pragma_contract.read() - }; - - // Call the Oracle contract, for a spot entry - let output: PragmaPricesResponse = oracle_dispatcher - .get_data_median(DataType::SpotEntry(asset_id)); - - return output.price; - } - } -} -``` - -> Note: Pragma returns the value of different token pairs using the decimal factor of 6 or 8. You can convert the value to the required decimal factor by dividing the value by \\( {10^{n}} \\), where `n` is the decimal factor. - -The code above is an example implementation of an applications consuming a price feed from the Pragma oracle. The contract imports necessary modules and interfaces, including the `IPragmaABIDispatcher` for interacting with the Pragma oracle contract and the `ERC20ABIDispatcher` for interacting with the ETH ERC20 token contract. - -The contract has a `const` that stores the token pair ID of `ETH/USD`, and a `Storage` struct that holds two fields `pragma_contract` and `product_price_in_usd`. The constructor function initializes the `pragma_contract` address and sets the `product_price_in_usd` to 100. - -The `buy_item` function is the main entry point for a user to purchase an item. It retrieves the caller's address. It calls the `get_asset_price` function to get the current price of ETH in USD using the `ETH_USD` asset ID. It calculates the amount of ETH needed to buy the product based on the product price in USD at the corresponding ETH price. It then checks if the caller has enough ETH by calling the `balance_of` method on the ERC20 ETH contract. If the caller has enough ETH, it calls the `transfer_from` method of the `eth_dispatcher` instance to transfer the required amount of ETH from the caller to another contract address. - -The `get_asset_price` function is the entry point to interact with the Pragma oracle and has been explained in the section above. - -You can get a detailed guide on consuming data using Pragma price feeds [here](https://docs.pragma.build/Resources/Cairo%201/data-feeds/consuming-data). -# Randomness - -Since all blockchains are fundamentally deterministic and most are public ledgers, generating truly unpredictatable randomness on-chain presents a challenge. This randomness is crucial for fair outcomes in gaming, lotteries, and unique generation of NFTs. To address this, verifiable random functions (VRFs) provided by oracles offer a solution. VRFs guarantee that the randomness can't be predicted or tampered with, ensuring trust and transparency in these applications. - -## Overview on VRFs - -Pseudo-random but secure: VRFs use a secret key and a nonce (a unique input) to generate an output that appears random. While technically 'pseudo-random', it's practically impossible for another party to predict the outcome without knowing the secret key. - -Verifiable output: VRFs produce not only the random number but also a proof that anyone can use to independently verify that the result was generated correctly according to the function's parameters. - -## Generating Randomness with Pragma - -[Pragma](https://www.pragma.build/), an oracle on Starknet provides a solution for generating random numbers using VRFs. -Let's dive into how to use Pragma VRF to generate a random number in a simple dice game contract. - -### Add Pragma as a Dependency - -Edit your cairo project's `Scarb.toml` file to include the path to use Pragma. - -```toml -[dependencies] -pragma_lib = { git = "https://github.com/astraly-labs/pragma-lib" } -``` - -### Interface - -```rust,noplayground -use starknet::ContractAddress; - -#[starknet::interface] -pub trait IPragmaVRF { - fn get_last_random_number(self: @TContractState) -> felt252; - fn request_randomness_from_pragma( - ref self: TContractState, - seed: u64, - callback_address: ContractAddress, - callback_fee_limit: u128, - publish_delay: u64, - num_words: u64, - calldata: Array - ); - fn receive_random_words( - ref self: TContractState, - requester_address: ContractAddress, - request_id: u64, - random_words: Span, - calldata: Array - ); - fn withdraw_extra_fee_fund(ref self: TContractState, receiver: ContractAddress); -} - -#[starknet::interface] -pub trait IDiceGame { - fn guess(ref self: TContractState, guess: u8); - fn toggle_play_window(ref self: TContractState); - fn get_game_window(self: @TContractState) -> bool; - fn process_game_winners(ref self: TContractState); -} -``` - -Listing 16-5 shows a contract interfaces for Pragma VRF and a simple dice game. - -### Description of Key IPragmaVRF Entrypoints and Their Inputs - -The function `request_randomness_from_pragma` initiates a request for verifiable randomness from the Pragma oracle. It does this by emitting an event that triggers the following actions off-chain: - -1. Randomness generation: The oracle generates random values and a corresponding proof. -2. On-chain submission: The oracle submits the generated randomness and proof back to the blockchain via the `receive_random_words` callback function. - -#### `request_randomness_from_pragma` Inputs - -1. `seed`: A value used to initialize the randomness generation process. This should be unique to ensure unpredictable results. -2. `callback_address`: The contract address where the `receive_random_words` function will be called to deliver the generated randomness. It is typically the address of your deployed contract implementing Pragma VRF. -3. `callback_fee_limit`: The maximum amount of gas you're willing to spend on executing the `receive_random_words` callback function. -4. `publish_delay`: The minimum delay (in blocks) between requesting randomness and the oracle fulfilling the request. -5. `num_words`: The number of random values (each represented as a `felt252`) you want to receive in a single callback. -6. `calldata`: Additional data you want to pass to the `receive_random_words` callback function. - -#### `receive_randomn_words` Inputs - -1. `requester_address`: The contract address that initiated the randomness request. -2. `request_id`: A unique identifier assigned to the randomness request. -3. `random_words`: An array (span) of the generated random values (represented as `felt252`). -4. `calldata`: Additional data passed along with the initial randomness request. - -### Dice Game Contract - -This dice game contract allows players to guess a number between 1 & 6 during an active game window. The contract owner then has the ability to toggle the game window to disable new guesses from players. To determine the winning number, the contract owner calls the `request_randomness_from_pragma` function to request a random number from the Pragma VRF oracle. Once the random number is received through the `receive_random_words` callback function, it is stored in the `last_random_number` storage variable. Each player has to call `process_game_winners` function to determine if they have won or lost. The `last_random_number` generated is then reduced to a number between 1 & 6, and compared to the guesses of the players stored in the `user_guesses` mapping, which leads to the emission of an event `GameWinner` or `GameLost`. - -```rust,noplayground -#[starknet::contract] -mod DiceGame { - use starknet::{ - ContractAddress, contract_address_const, get_block_number, get_caller_address, - get_contract_address - }; - use pragma_lib::abi::{IRandomnessDispatcher, IRandomnessDispatcherTrait}; - use openzeppelin::token::erc20::interface::{ERC20ABIDispatcher, ERC20ABIDispatcherTrait}; - use openzeppelin::access::ownable::OwnableComponent; - - component!(path: OwnableComponent, storage: ownable, event: OwnableEvent); - - #[abi(embed_v0)] - impl OwnableImpl = OwnableComponent::OwnableImpl; - impl InternalImpl = OwnableComponent::InternalImpl; - - #[storage] - struct Storage { - user_guesses: LegacyMap, - pragma_vrf_contract_address: ContractAddress, - game_window: bool, - min_block_number_storage: u64, - last_random_number: felt252, - #[substorage(v0)] - ownable: OwnableComponent::Storage - } - - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - GameWinner: ResultAnnouncement, - GameLost: ResultAnnouncement, - #[flat] - OwnableEvent: OwnableComponent::Event - } - - #[derive(Drop, starknet::Event)] - struct ResultAnnouncement { - caller: ContractAddress, - guess: u8, - random_number: u256 - } - - #[constructor] - fn constructor( - ref self: ContractState, - pragma_vrf_contract_address: ContractAddress, - owner: ContractAddress - ) { - self.ownable.initializer(owner); - self.pragma_vrf_contract_address.write(pragma_vrf_contract_address); - self.game_window.write(true); - } - - #[abi(embed_v0)] - impl DiceGame of super::IDiceGame { - fn guess(ref self: ContractState, guess: u8) { - assert(self.game_window.read(), 'GAME_INACTIVE'); - assert(guess >= 1 && guess <= 6, 'INVALID_GUESS'); - - let caller = get_caller_address(); - self.user_guesses.write(caller, guess); - } - - fn toggle_play_window(ref self: ContractState) { - self.ownable.assert_only_owner(); - - let current: bool = self.game_window.read(); - self.game_window.write(!current); - } - - fn get_game_window(self: @ContractState) -> bool { - self.game_window.read() - } - - fn process_game_winners(ref self: ContractState) { - assert(!self.game_window.read(), 'GAME_ACTIVE'); - assert(self.last_random_number.read() != 0, 'NO_RANDOM_NUMBER_YET'); - - let caller = get_caller_address(); - let user_guess: u8 = self.user_guesses.read(caller); - let reduced_random_number: u256 = self.last_random_number.read().into() % 6 + 1; - - if user_guess == reduced_random_number.try_into().unwrap() { - self - .emit( - Event::GameWinner( - ResultAnnouncement { - caller: caller, - guess: user_guess, - random_number: reduced_random_number - } - ) - ); - } else { - self - .emit( - Event::GameLost( - ResultAnnouncement { - caller: caller, - guess: user_guess, - random_number: reduced_random_number - } - ) - ); - } - } - } - - #[abi(embed_v0)] - impl PragmaVRFOracle of super::IPragmaVRF { - fn get_last_random_number(self: @ContractState) -> felt252 { - let last_random = self.last_random_number.read(); - last_random - } - - fn request_randomness_from_pragma( - ref self: ContractState, - seed: u64, - callback_address: ContractAddress, - callback_fee_limit: u128, - publish_delay: u64, - num_words: u64, - calldata: Array - ) { - self.ownable.assert_only_owner(); - - let randomness_contract_address = self.pragma_vrf_contract_address.read(); - let randomness_dispatcher = IRandomnessDispatcher { - contract_address: randomness_contract_address - }; - - // Approve the randomness contract to transfer the callback fee - // You would need to send some ETH to this contract first to cover the fees - let eth_dispatcher = ERC20ABIDispatcher { - contract_address: contract_address_const::< - 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 - >() // ETH Contract Address - }; - eth_dispatcher - .approve( - randomness_contract_address, - (callback_fee_limit + callback_fee_limit / 5).into() - ); - - // Request the randomness - randomness_dispatcher - .request_random( - seed, callback_address, callback_fee_limit, publish_delay, num_words, calldata - ); - - let current_block_number = get_block_number(); - self.min_block_number_storage.write(current_block_number + publish_delay); - } - - fn receive_random_words( - ref self: ContractState, - requester_address: ContractAddress, - request_id: u64, - random_words: Span, - calldata: Array - ) { - // Have to make sure that the caller is the Pragma Randomness Oracle contract - let caller_address = get_caller_address(); - assert( - caller_address == self.pragma_vrf_contract_address.read(), - 'caller not randomness contract' - ); - // and that the current block is within publish_delay of the request block - let current_block_number = get_block_number(); - let min_block_number = self.min_block_number_storage.read(); - assert(min_block_number <= current_block_number, 'block number issue'); - - let random_word = *random_words.at(0); - self.last_random_number.write(random_word); - } - - fn withdraw_extra_fee_fund(ref self: ContractState, receiver: ContractAddress) { - self.ownable.assert_only_owner(); - let eth_dispatcher = ERC20ABIDispatcher { - contract_address: contract_address_const::< - 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 - >() // ETH Contract Address - }; - let balance = eth_dispatcher.balance_of(get_contract_address()); - eth_dispatcher.transfer(receiver, balance); - } - } -} -``` - -Listing 16-6: Simple Dice Game Contract using Pragma VRF. - -#### NB: Fund Your Contract After Deployment to Utilize Pragma VRF - -After deploying your contract that includes Pragma VRF functionalities, ensure it holds sufficient ETH to cover the expenses related to requesting random values. Pragma VRF requires payment for both generating the random numbers and executing the callback function defined in your contract. - -For more information, please refer to the [Pragma](https://docs.pragma.build/Resources/Cairo%201/randomness/randomness) docs. -# Oracle Interactions - -This section focuses on the concept of bringing off-chain data to the Starknet blockchain using oracles. Oracles are third-party services that serve as intermediaries, securely transmitting external data, such as asset prices, weather information, or other real-world data, to blockchains and smart contracts. It also provides practical examples and code snippets demonstrating how developers can interact with a specific oracle named Pragma on Starknet network, covering topics like querying and handling price data, and verifiable random function (VRF) to generate random numbers. -# Other Examples - -This section contains additional examples of Starknet smart contracts, utilizing various features of the Cairo programming language. Your contributions are welcome and encouraged, as we aim to gather as many diverse examples as possible. -# Deploying and Interacting with a Voting contract - -The **`Vote`** contract in Starknet begins by registering voters through the contract's constructor. Three voters are initialized at this stage, and their addresses are passed to an internal function **`_register_voters`**. This function adds the voters to the contract's state, marking them as registered and eligible to vote. - -Within the contract, the constants **`YES`** and **`NO`** are defined to represent the voting options (1 and 0, respectively). These constants facilitate the voting process by standardizing the input values. - -Once registered, a voter is able to cast a vote using the **`vote`** function, selecting either the 1 (YES) or 0 (NO) as their vote. When voting, the state of the contract is updated, recording the vote and marking the voter as having voted. This ensures that the voter is not able to cast a vote again within the same proposal. The casting of a vote triggers the **`VoteCast`** event, logging the action. - -The contract also monitors unauthorized voting attempts. If an unauthorized action is detected, such as a non-registered user attempting to vote or a user trying to vote again, the **`UnauthorizedAttempt`** event is emitted. - -Together, these functions, states, constants, and events create a structured voting system, managing the lifecycle of a vote from registration to casting, event logging, and result retrieval within the Starknet environment. Constants like **`YES`** and **`NO`** help streamline the voting process, while events play a vital role in ensuring transparency and traceability. - -Listing 16-7 shows the `Vote` contract in detail: - -```rust,noplayground -/// @dev Core Library Imports for the Traits outside the Starknet Contract -use starknet::ContractAddress; - -/// @dev Trait defining the functions that can be implemented or called by the Starknet Contract -#[starknet::interface] -trait VoteTrait { - /// @dev Function that returns the current vote status - fn get_vote_status(self: @T) -> (u8, u8, u8, u8); - /// @dev Function that checks if the user at the specified address is allowed to vote - fn voter_can_vote(self: @T, user_address: ContractAddress) -> bool; - /// @dev Function that checks if the specified address is registered as a voter - fn is_voter_registered(self: @T, address: ContractAddress) -> bool; - /// @dev Function that allows a user to vote - fn vote(ref self: T, vote: u8); -} - -/// @dev Starknet Contract allowing three registered voters to vote on a proposal -#[starknet::contract] -mod Vote { - use starknet::ContractAddress; - use starknet::get_caller_address; - - const YES: u8 = 1_u8; - const NO: u8 = 0_u8; - - /// @dev Structure that stores vote counts and voter states - #[storage] - struct Storage { - yes_votes: u8, - no_votes: u8, - can_vote: LegacyMap::, - registered_voter: LegacyMap::, - } - - /// @dev Contract constructor initializing the contract with a list of registered voters and 0 vote count - #[constructor] - fn constructor( - ref self: ContractState, - voter_1: ContractAddress, - voter_2: ContractAddress, - voter_3: ContractAddress - ) { - // Register all voters by calling the _register_voters function - self._register_voters(voter_1, voter_2, voter_3); - - // Initialize the vote count to 0 - self.yes_votes.write(0_u8); - self.no_votes.write(0_u8); - } - - /// @dev Event that gets emitted when a vote is cast - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - VoteCast: VoteCast, - UnauthorizedAttempt: UnauthorizedAttempt, - } - - /// @dev Represents a vote that was cast - #[derive(Drop, starknet::Event)] - struct VoteCast { - voter: ContractAddress, - vote: u8, - } - - /// @dev Represents an unauthorized attempt to vote - #[derive(Drop, starknet::Event)] - struct UnauthorizedAttempt { - unauthorized_address: ContractAddress, - } - - /// @dev Implementation of VoteTrait for ContractState - #[abi(embed_v0)] - impl VoteImpl of super::VoteTrait { - /// @dev Returns the voting results - fn get_vote_status(self: @ContractState) -> (u8, u8, u8, u8) { - let (n_yes, n_no) = self._get_voting_result(); - let (yes_percentage, no_percentage) = self._get_voting_result_in_percentage(); - (n_yes, n_no, yes_percentage, no_percentage) - } - - /// @dev Check whether a voter is allowed to vote - fn voter_can_vote(self: @ContractState, user_address: ContractAddress) -> bool { - self.can_vote.read(user_address) - } - - /// @dev Check whether an address is registered as a voter - fn is_voter_registered(self: @ContractState, address: ContractAddress) -> bool { - self.registered_voter.read(address) - } - - /// @dev Submit a vote - fn vote(ref self: ContractState, vote: u8) { - assert!(vote == NO || vote == YES, "VOTE_0_OR_1"); - let caller: ContractAddress = get_caller_address(); - self._assert_allowed(caller); - self.can_vote.write(caller, false); - - if (vote == NO) { - self.no_votes.write(self.no_votes.read() + 1_u8); - } - if (vote == YES) { - self.yes_votes.write(self.yes_votes.read() + 1_u8); - } - - self.emit(VoteCast { voter: caller, vote: vote, }); - } - } - - /// @dev Internal Functions implementation for the Vote contract - #[generate_trait] - impl InternalFunctions of InternalFunctionsTrait { - /// @dev Registers the voters and initializes their voting status to true (can vote) - fn _register_voters( - ref self: ContractState, - voter_1: ContractAddress, - voter_2: ContractAddress, - voter_3: ContractAddress - ) { - self.registered_voter.write(voter_1, true); - self.can_vote.write(voter_1, true); - - self.registered_voter.write(voter_2, true); - self.can_vote.write(voter_2, true); - - self.registered_voter.write(voter_3, true); - self.can_vote.write(voter_3, true); - } - } - - /// @dev Asserts implementation for the Vote contract - #[generate_trait] - impl AssertsImpl of AssertsTrait { - // @dev Internal function that checks if an address is allowed to vote - fn _assert_allowed(ref self: ContractState, address: ContractAddress) { - let is_voter: bool = self.registered_voter.read((address)); - let can_vote: bool = self.can_vote.read((address)); - - if (!can_vote) { - self.emit(UnauthorizedAttempt { unauthorized_address: address, }); - } - - assert!(is_voter, "USER_NOT_REGISTERED"); - assert!(can_vote, "USER_ALREADY_VOTED"); - } - } - - /// @dev Implement the VotingResultTrait for the Vote contract - #[generate_trait] - impl VoteResultFunctionsImpl of VoteResultFunctionsTrait { - // @dev Internal function to get the voting results (yes and no vote counts) - fn _get_voting_result(self: @ContractState) -> (u8, u8) { - let n_yes: u8 = self.yes_votes.read(); - let n_no: u8 = self.no_votes.read(); - - (n_yes, n_no) - } - - // @dev Internal function to calculate the voting results in percentage - fn _get_voting_result_in_percentage(self: @ContractState) -> (u8, u8) { - let n_yes: u8 = self.yes_votes.read(); - let n_no: u8 = self.no_votes.read(); - - let total_votes: u8 = n_yes + n_no; - - if (total_votes == 0_u8) { - return (0, 0); - } - let yes_percentage: u8 = (n_yes * 100_u8) / (total_votes); - let no_percentage: u8 = (n_no * 100_u8) / (total_votes); - - (yes_percentage, no_percentage) - } - } -} -``` -Listing 16-7: A voting smart contract - -## Deploying, Calling and Invoking the Voting Contract - -Part of the Starknet experience is deploying and interacting with smart contracts. - -Once the contract is deployed, we can interact with it by calling and invoking its functions: - -- Calling contracts: Interacting with external functions that only read from the state. These functions do not alter the state of the network, so they don't require fees or signing. -- Invoking contracts: Interacting with external functions that can write to the state. These functions do alter the state of the network and require fees and signing. - -We will setup a local development node using `katana` to deploy the voting contract. Then, we'll interact with the contract by calling and invoking its functions. You can also use the Goerli Testnet instead of `katana`. However, we recommend using `katana` for local development and testing. You can find the complete tutorial for `katana` in the ["Katana: A Local Node"][katana chapter] chapter of the Starknet Book. - -[katana chapter]: https://book.starknet.io/ch02-04-katana.html - -### The `katana` Local Starknet Node - -`katana` is designed to support local development by the [Dojo team][dojo katana]. It will allow you to do everything you need to do with Starknet, but locally. It is a great tool for development and testing. - -To install `katana` from the source code, please refer to the ["Basic Installation"][katana installation] chapter of the Starknet Book. - -> Note: Please verify that the version of `katana` match the specified version provided below. -> -> ```bash -> $ katana --version -> katana 0.6.0 -> ``` -> -> To upgrade `katana` version, refer to the ["Basic Installation"][katana installation] chapter of the Starknet Book. - -Once you have `katana` installed, you can start the local Starknet node with: - -```bash -katana --accounts 3 --seed 0 --gas-price 250 -``` - -This command will start a local Starknet node with 3 deployed accounts. We will use these accounts to deploy and interact with the voting contract: - -```bash -... -PREFUNDED ACCOUNTS -================== - -| Account address | 0x03ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0 -| Private key | 0x0300001800000000300000180000000000030000000000003006001800006600 -| Public key | 0x01b7b37a580d91bc3ad4f9933ed61f3a395e0e51c9dd5553323b8ca3942bb44e - -| Account address | 0x033c627a3e5213790e246a917770ce23d7e562baa5b4d2917c23b1be6d91961c -| Private key | 0x0333803103001800039980190300d206608b0070db0012135bd1fb5f6282170b -| Public key | 0x04486e2308ef3513531042acb8ead377b887af16bd4cdd8149812dfef1ba924d - -| Account address | 0x01d98d835e43b032254ffbef0f150c5606fa9c5c9310b1fae370ab956a7919f5 -| Private key | 0x07ca856005bee0329def368d34a6711b2d95b09ef9740ebf2c7c7e3b16c1ca9c -| Public key | 0x07006c42b1cfc8bd45710646a0bb3534b182e83c313c7bc88ecf33b53ba4bcbc -... -``` - -Before we can interact with the voting contract, we need to prepare the voter and admin accounts on Starknet. Each voter account must be registered and sufficiently funded for voting. For a more detailed understanding of how accounts operate with Account Abstraction, refer to the ["Account Abstraction"][aa chapter] chapter of the Starknet Book. - -[dojo katana]: https://github.com/dojoengine/dojo/blob/main/crates/katana -[katana installation]: https://book.starknet.io/ch02-01-basic-installation.html#katana-node-installation -[aa chapter]: https://book.starknet.io/ch04-00-account-abstraction.html - -### Smart Wallets for Voting - -Aside from Scarb you will need to have Starkli installed. Starkli is a command line tool that allows you to interact with Starknet. You can find the installation instructions in the ["Basic Installation"][starkli installation] chapter of the Starknet Book. - -> Note: Please verify that the version of `starkli` match the specified version provided below. -> -> ```bash -> $ starkli --version -> 0.2.9 (0535f44) -> ``` -> -> To upgrade `starkli` to `0.2.9`, use the `starkliup -v 0.2.9` command, or simply `starkliup` which installed the latest stable version. - -For each smart wallet we'll use, we must create a Signer within the encrypted keystore and an Account Descriptor. This process is also detailed in the ["Testnet Deployment"][signer creation] chapter of the Starknet Book. - -We can create Signers and Account Descriptors for the accounts we want to use for voting. Let's create a smart wallet for voting in our smart contract. - -Firstly, we create a signer from a private key: - -```bash -starkli signer keystore from-key ~/.starkli-wallets/deployer/account0_keystore.json -``` - -Then, we create the Account Descriptor by fetching the katana account we want to use: - -```bash -starkli account fetch --rpc http://0.0.0.0:5050 --output ~/.starkli-wallets/deployer/account0_account.json -``` - -This command will create a new `account0_account.json` file containing the following details: - -```bash -{ - "version": 1, - "variant": { - "type": "open_zeppelin", - "version": 1, - "public_key": "" - }, - "deployment": { - "status": "deployed", - "class_hash": "", - "address": "" - } -} -``` - -You can retrieve the smart wallet class hash (it will be the same for all your smart wallets) with the following command. Notice the use of the `--rpc` flag and the RPC endpoint provided by `katana`: - -``` -starkli class-hash-at --rpc http://0.0.0.0:5050 -``` - -For the public key, you can use the `starkli signer keystore inspect` command with the directory of the keystore json file: - -```bash -starkli signer keystore inspect ~/.starkli-wallets/deployer/account0_keystore.json -``` - -This process is identical for `account_1` and `account_2` in case you want to have a second and a third voter. - -[starkli installation]: https://book.starknet.io/ch02-01-basic-installation.html#starkli-installation) -[signer creation]: https://book.starknet.io/ch02-05-testnet-deployment.html?highlight=signer#creating-a-signer - -### Contract Deployment - -Before deploying, we need to declare the contract. We can do this with the `starkli declare` command: - -```bash -starkli declare target/dev/starknetbook_chapter_2_Vote.sierra.json --rpc http://0.0.0.0:5050 --account ~/.starkli-wallets/deployer/account0_account.json --keystore ~/.starkli-wallets/deployer/account0_keystore.json -``` - -If the compiler version you're using is older than the one used by Starkli and you encounter a `compiler-version` error while using the command above, you can specify a compiler version to use in the command by adding the `--compiler-version x.y.z` flag. - -If you're still encountering issues with the compiler version, try upgrading Starkli using the command: `starkliup` to make sure you're using the latest version of starkli. - -The class hash of the contract is: `0x06974677a079b7edfadcd70aa4d12aac0263a4cda379009fca125e0ab1a9ba52`. You can declare this contract on Sepolia testnet and see that the class hash will correspond. - -The `--rpc` flag specifies the RPC endpoint to use (the one provided by `katana`). The `--account` flag specifies the account to use for signing the transaction. The account we use here is the one we created in the previous step. The `--keystore` flag specifies the keystore file to use for signing the transaction. - -Since we are using a local node, the transaction will achieve finality immediately. If you are using the Goerli Testnet, you will need to wait for the transaction to be final, which usually takes a few seconds. - -The following command deploys the voting contract and registers voter_0, voter_1, and voter_2 as eligible voters. These are the constructor arguments, so add a voter account that you can later vote with. - -```bash -starkli deploy --rpc http://0.0.0.0:5050 --account ~/.starkli-wallets/deployer/account0_account.json --keystore ~/.starkli-wallets/deployer/account0_keystore.json -``` - -An example command: - -```bash -starkli deploy 0x06974677a079b7edfadcd70aa4d12aac0263a4cda379009fca125e0ab1a9ba52 0x03ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0 0x033c627a3e5213790e246a917770ce23d7e562baa5b4d2917c23b1be6d91961c 0x01d98d835e43b032254ffbef0f150c5606fa9c5c9310b1fae370ab956a7919f5 --rpc http://0.0.0.0:5050 --account ~/.starkli-wallets/deployer/account0_account.json --keystore ~/.starkli-wallets/deployer/account0_keystore.json -``` - -In this case, the contract has been deployed at an specific address: `0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349`. This address will be different for you. We will use this address to interact with the contract. - -### Voter Eligibility Verification - -In our voting contract, we have two functions to validate voter eligibility, `voter_can_vote` and `is_voter_registered`. These are external read functions, which mean they don't alter the state of the contract but only read the current state. - -The `is_voter_registered` function checks whether a particular address is registered as an eligible voter in the contract. The `voter_can_vote` function, on the other hand, checks whether the voter at a specific address is currently eligible to vote, i.e., they are registered and haven't voted already. - -You can call these functions using the `starkli call` command. Note that the `call` command is used for read functions, while the `invoke` command is used for functions that can also write to storage. The `call` command does not require signing, while the `invoke` command does. - -```bash+ -starkli call 0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349 voter_can_vote 0x03ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0 --rpc http://0.0.0.0:5050 -``` - -First we added the address of the contract, then the function we want to call, and finally the input for the function. In this case, we are checking whether the voter at the address `0x03ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0` can vote. - -Since we provided a registered voter address as an input, the result is 1 (boolean true), indicating the voter is eligible to vote. - -Next, let's call the `is_voter_registered` function using an unregistered account address to observe the output: - -```bash -starkli call 0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349 is_voter_registered 0x44444444444444444 --rpc http://0.0.0.0:5050 -``` - -With an unregistered account address, the terminal output is 0 (i.e., false), confirming that the account is not eligible to vote. - -### Casting a Vote - -Now that we have established how to verify voter eligibility, we can vote! To vote, we interact with the `vote` function, which is flagged as external, necessitating the use of the `starknet invoke` command. - -The `invoke` command syntax resembles the `call` command, but for voting, we submit either `1` (for Yes) or `0` (for No) as our input. When we invoke the `vote` function, we are charged a fee, and the transaction must be signed by the voter; we are writing to the contract's storage. - -```bash -//Voting Yes -starkli invoke 0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349 vote 1 --rpc http://0.0.0.0:5050 --account ~/.starkli-wallets/deployer/account0_account.json --keystore ~/.starkli-wallets/deployer/account0_keystore.json - -//Voting No -starkli invoke 0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349 vote 0 --rpc http://0.0.0.0:5050 --account ~/.starkli-wallets/deployer/account0_account.json --keystore ~/.starkli-wallets/deployer/account0_keystore.json -``` - -You will be prompted to enter the password for the signer. Once you enter the password, the transaction will be signed and submitted to the Starknet network. You will receive the transaction hash as output. With the starkli transaction command, you can get more details about the transaction: - -```bash -starkli transaction --rpc http://0.0.0.0:5050 -``` - -This returns: - -```bash -{ - "transaction_hash": "0x5604a97922b6811060e70ed0b40959ea9e20c726220b526ec690de8923907fd", - "max_fee": "0x430e81", - "version": "0x1", - "signature": [ - "0x75e5e4880d7a8301b35ff4a1ed1e3d72fffefa64bb6c306c314496e6e402d57", - "0xbb6c459b395a535dcd00d8ab13d7ed71273da4a8e9c1f4afe9b9f4254a6f51" - ], - "nonce": "0x3", - "type": "INVOKE", - "sender_address": "0x3ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0", - "calldata": [ - "0x1", - "0x5ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349", - "0x132bdf85fc8aa10ac3c22f02317f8f53d4b4f52235ed1eabb3a4cbbe08b5c41", - "0x0", - "0x1", - "0x1", - "0x1" - ] -} -``` - -If you try to vote twice with the same signer you will get an error: - -```bash -Error: code=ContractError, message="Contract error" -``` - -The error is not very informative, but you can get more details when looking at the output in the terminal where you started `katana` (our local Starknet node): - -```bash -... -Transaction execution error: "Error in the called contract (0x03ee9e18edc71a6df30ac3aca2e0b02a198fbce19b7480a63a0d71cbd76652e0): - Error at pc=0:81: - Got an exception while executing a hint: Custom Hint Error: Execution failed. Failure reason: \"USER_ALREADY_VOTED\". - ... -``` - -The key for the error is `USER_ALREADY_VOTED`. - -```bash -assert!(can_vote, "USER_ALREADY_VOTED"); -``` - -We can repeat the process to create Signers and Account Descriptors for the accounts we want to use for voting. Remember that each Signer must be created from a private key, and each Account Descriptor must be created from a public key, a smart wallet address, and the smart wallet class hash (which is the same for each voter). - -```bash -starkli invoke 0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349 vote 0 --rpc http://0.0.0.0:5050 --account ~/.starkli-wallets/deployer/account1_account.json --keystore ~/.starkli-wallets/deployer/account1_keystore.json - -starkli invoke 0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349 vote 1 --rpc http://0.0.0.0:5050 --account ~/.starkli-wallets/deployer/account2_account.json --keystore ~/.starkli-wallets/deployer/account2_keystore.json -``` - -### Visualizing Vote Outcomes - -To examine the voting results, we invoke the `get_vote_status` function, another view function, through the `starknet call` command. - -```bash -starkli call 0x05ea3a690be71c7fcd83945517f82e8861a97d42fca8ec9a2c46831d11f33349 get_vote_status --rpc http://0.0.0.0:5050 -``` - -The output reveals the tally of "Yes" and "No" votes along with their relative percentages. -# Starknet Smart Contracts Security -# General Recommendations - -When developing software, ensuring it functions as intended is usually straightforward. However, preventing unintended usage and vulnerabilities can be more challenging. - -In smart contract development, security is very important. A single error can result in the loss of valuable assets or the improper functioning of certain features. - -Smart contracts are executed in a public environment where anyone can examine the code and interact with it. Any errors or vulnerabilities in the code can be exploited by malicious actors. - -This chapter presents general recommendations for writing secure smart contracts. By incorporating these concepts during development, you can create robust and reliable smart contracts. This reduces the chance of unexpected behavior or vulnerabilities. - -## Disclaimer - -This chapter does not provide an exhaustive list of all possible security issues, and it does not guarantee that your contracts will be completely secure. - -If you are developing smart contracts for production use, it is highly recommended to conduct external audits performed by security experts. - -## Mindset - -Cairo is a highly safe language inspired by Rust. It is designed in a way that forces you to cover all possible cases. Security issues on Starknet mostly arise from the way smart contract flows are designed, not much from the language itself. - -Adopting a security mindset is the initial step in writing secure smart contracts. Try to always consider all possible scenarios when writing code. - -### Viewing Smart Contracts as Finite State Machines - -Transactions in smart contracts are atomic, meaning they either succeed or fail without making any changes. - -Think of smart contracts as state machines: they have a set of initial states defined by the constructor constraints, and external functions represent a set of possible state transitions. A transaction is nothing more than a state transition. - -The `assert!` or `panic!` macros can be used to validate conditions before performing specific actions. You can learn more about these on the [Unrecoverable Errors with panic](./ch09-01-unrecoverable-errors-with-panic.md) page. - -These validations can include: - -- Inputs provided by the caller -- Execution requirements -- Invariants (conditions that must always be true) -- Return values from other function calls - -For example, you could use the `assert!` macro to validate that a user has enough funds to perform a withdraw transaction. If the condition is not met, the transaction will fail and the state of the contract will not change. - -```rust,noplayground - impl Contract of IContract { - fn withdraw(ref self: ContractState, amount: u256) { - let current_balance = self.balance.read(); - - assert!(self.balance.read() >= amount, "Insufficient funds"); - - self.balance.write(current_balance - amount); - } -``` - -Using these functions to check conditions adds constraints that help clearly define the boundaries of possible state transitions for each function in your smart contract. These checks ensure that the behavior of the contract stays within the expected limits. - -## Recommendations - -### Checks Effects Interactions Pattern - -The Checks Effects Interactions pattern is a common design pattern used to prevent reentrancy attacks on Ethereum. While reentrancy is harder to achieve in Starknet, it is still recommended to use this pattern in your smart contracts. - - - -The pattern consists of following a specific order of operations in your functions: - -1. **Checks**: Validate all conditions and inputs before performing any state changes. -2. **Effects**: Perform all state changes. -3. **Interactions**: All external calls to other contracts should be made at the end of the function. - -### Access Control - -Access control is the process of restricting access to certain features or resources. It is a common security mechanism used to prevent unauthorized access to sensitive information or actions. In smart contracts, some functions may often be restricted to specific users or roles. - -You can implement the access control pattern to easily manage permissions. This pattern consists of defining a set of roles and assigning them to specific users. Each function can then be restricted to specific roles. - -```rust,noplayground -#[starknet::contract] -mod access_control_contract { - use starknet::ContractAddress; - use starknet::get_caller_address; - - trait IContract { - fn is_owner(self: @TContractState) -> bool; - fn is_role_a(self: @TContractState) -> bool; - fn only_owner(self: @TContractState); - fn only_role_a(self: @TContractState); - fn only_allowed(self: @TContractState); - fn set_role_a(ref self: TContractState, _target: ContractAddress, _active: bool); - fn role_a_action(ref self: ContractState); - fn allowed_action(ref self: ContractState); - } - - #[storage] - struct Storage { - // Role 'owner': only one address - owner: ContractAddress, - // Role 'role_a': a set of addresses - role_a: LegacyMap:: - } - - #[constructor] - fn constructor(ref self: ContractState) { - self.owner.write(get_caller_address()); - } - - // Guard functions to check roles - - impl Contract of IContract { - #[inline(always)] - fn is_owner(self: @ContractState) -> bool { - self.owner.read() == get_caller_address() - } - - #[inline(always)] - fn is_role_a(self: @ContractState) -> bool { - self.role_a.read(get_caller_address()) - } - - #[inline(always)] - fn only_owner(self: @ContractState) { - assert!(Contract::is_owner(self), "Not owner"); - } - - #[inline(always)] - fn only_role_a(self: @ContractState) { - assert!(Contract::is_role_a(self), "Not role A"); - } - - // You can easily combine guards to perform complex checks - fn only_allowed(self: @ContractState) { - assert!(Contract::is_owner(self) || Contract::is_role_a(self), "Not allowed"); - } - - // Functions to manage roles - - fn set_role_a(ref self: ContractState, _target: ContractAddress, _active: bool) { - Contract::only_owner(@self); - self.role_a.write(_target, _active); - } - - // You can now focus on the business logic of your contract - // and reduce the complexity of your code by using guard functions - - fn role_a_action(ref self: ContractState) { - Contract::only_role_a(@self); - // ... - } - - fn allowed_action(ref self: ContractState) { - Contract::only_allowed(@self); - // ... - } - } -} - -``` -# Testing Smart Contracts - -Testing smart contracts is a critical part of the development process. It is important to ensure that smart contracts behave as expected and that they are secure. - -In a previous section of the Cairo Book, we learned how to write and structure our tests for Cairo programs. We demonstrated how these tests could be run using the `scarb` command-line tool. -While this approach is useful for testing standalone Cairo programs and functions, it lacks functionality for testing smart contracts that require control over the contract state and execution context. Therefore, in this section, we will introduce how to use Starknet Foundry, a smart contract development toolchain for Starknet, to test your Cairo contracts. - -Throughout this chapter, we will be using as an example the `PizzaFactory` contract in Listing 17-1 to demonstrate how to write tests with Starknet Foundry. - -```rust,noplayground -use starknet::ContractAddress; - -#[starknet::interface] -pub trait IPizzaFactory { - fn increase_pepperoni(ref self: TContractState, amount: u32); - fn increase_pineapple(ref self: TContractState, amount: u32); - fn get_owner(self: @TContractState) -> ContractAddress; - fn change_owner(ref self: TContractState, new_owner: ContractAddress); - fn make_pizza(ref self: TContractState); - fn count_pizza(self: @TContractState) -> u32; -} - -#[starknet::contract] -pub mod PizzaFactory { - use super::IPizzaFactory; - use starknet::ContractAddress; - use starknet::get_caller_address; - - #[storage] - pub struct Storage { - pepperoni: u32, - pineapple: u32, - owner: ContractAddress, - pizzas: u32 - } - - #[constructor] - fn constructor(ref self: ContractState, owner: ContractAddress) { - self.pepperoni.write(10); - self.pineapple.write(10); - self.owner.write(owner); - } - - - #[event] - #[derive(Drop, starknet::Event)] - pub enum Event { - PizzaEmission: PizzaEmission - } - - #[derive(Drop, starknet::Event)] - pub struct PizzaEmission { - pub counter: u32 - } - - #[abi(embed_v0)] - impl PizzaFactoryimpl of super::IPizzaFactory { - fn increase_pepperoni(ref self: ContractState, amount: u32) { - assert!(amount != 0, "Amount cannot be 0"); - self.pepperoni.write(self.pepperoni.read() + amount); - } - - fn increase_pineapple(ref self: ContractState, amount: u32) { - assert!(amount != 0, "Amount cannot be 0"); - self.pineapple.write(self.pineapple.read() + amount); - } - - fn make_pizza(ref self: ContractState) { - assert!(self.pepperoni.read() > 0, "Not enough pepperoni"); - assert!(self.pineapple.read() > 0, "Not enough pineapple"); - - let caller: ContractAddress = get_caller_address(); - let owner: ContractAddress = self.get_owner(); - - assert!(caller == owner, "Only the owner can make pizza"); - - self.pepperoni.write(self.pepperoni.read() - 1); - self.pineapple.write(self.pineapple.read() - 1); - self.pizzas.write(self.pizzas.read() + 1); - - self.emit(PizzaEmission { counter: self.pizzas.read() }); - } - - fn get_owner(self: @ContractState) -> ContractAddress { - self.owner.read() - } - - fn change_owner(ref self: ContractState, new_owner: ContractAddress) { - self.set_owner(new_owner); - } - - fn count_pizza(self: @ContractState) -> u32 { - self.pizzas.read() - } - } - - #[generate_trait] - pub impl InternalImpl of InternalTrait { - fn set_owner(ref self: ContractState, new_owner: ContractAddress) { - let caller: ContractAddress = get_caller_address(); - assert!(caller == self.get_owner(), "Only the owner can set ownership"); - - self.owner.write(new_owner); - } - } -} -``` - -Listing 17-1: A pizza factory that needs to be tested - -## Configuring your Scarb project with Starknet Foundry - -The settings of your Scarb project can be configured in the `Scarb.toml` file. To use Starknet Foundry as your testing tool, you will need to add it as a dev dependency in your `Scarb.toml` file. At the time of writing, the latest version of Starknet Foundry is `v0.22.0` - but you should use the latest version. - -```toml,noplayground -[dev-dependencies] -snforge_std = { git = "https://github.com/foundry-rs/starknet-foundry.git", tag = "v0.22.0" } - -[scripts] -test = "snforge test" -``` - -The `scarb test` command is configured to execute `scarb cairo-test` by default. In our settings, we have configured it to execute `snforge test` instead. This will allow us to run our tests using Starknet Foundry when we run the `scarb test` command. - -Once your project is configured, you will need to install Starknet Foundry by following the installation guide from the [Starknet Foundry Documentation](https://foundry-rs.github.io/starknet-foundry/getting-started/installation.html). As usual, we recommend to use `asdf` to manage versions of your development tools. - -## Testing Smart Contracts with Starknet Foundry - -The usual command to run your tests using Starknet Foundry is `snforge test`. However, when we configured our projects, we defined that the `scarb test` command will run the `snforge test` command. Therefore, during the rest of this chapter, consider that the `scarb test` command will be using `snforge test` under the hood. - -The usual testing flow of a contract is as follows: - -1. Declare the class of the contract to test, identified by its name -2. Serialize the constructor calldata into an array -3. Deploy the contract and retrieve its address -4. Interact with the contract's entrypoint to test various scenarios - -### Deploying the Contract to Test - -In Listing 17-2, we wrote a function that deploys the `PizzaFactory` contract and sets up the dispatcher for interactions. - -```rust,noplayground -# use source::pizza::{ -# IPizzaFactoryDispatcher, IPizzaFactorySafeDispatcher, IPizzaFactoryDispatcherTrait, -# PizzaFactory, PizzaFactory::{Event as PizzaEvents, PizzaEmission} -# }; -# use source::pizza::PizzaFactory::{ownerContractMemberStateTrait, InternalTrait}; -# -# use starknet::{ContractAddress, contract_address_const}; -# -# use snforge_std::{ -# declare, ContractClassTrait, ContractClass, start_cheat_caller_address, -# stop_cheat_caller_address, SpyOn, EventSpy, EventAssertions, spy_events, EventFetcher, load, -# cheatcodes::storage::load_felt252 -# }; -# -# fn owner() -> ContractAddress { -# contract_address_const::<'owner'>() -# } -# -fn deploy_pizza_factory() -> (IPizzaFactoryDispatcher, ContractAddress) { - let contract = declare("PizzaFactory").unwrap(); - let owner: ContractAddress = contract_address_const::<'owner'>(); - - let mut constructor_calldata = array![owner.into()]; - - let (contract_address, _) = contract.deploy(@constructor_calldata).unwrap(); - - let dispatcher = IPizzaFactoryDispatcher { contract_address }; - - (dispatcher, contract_address) -} -# -# #[test] -# fn test_constructor() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# -# let pepperoni_count = load(pizza_factory_address, selector!("pepperoni"), 1); -# let pineapple_count = load(pizza_factory_address, selector!("pineapple"), 1); -# assert_eq!(pepperoni_count, array![10]); -# assert_eq!(pineapple_count, array![10]); -# assert_eq!(pizza_factory.get_owner(), owner()); -# } -# -# #[test] -# fn test_change_owner_should_change_owner() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# -# let new_owner: ContractAddress = contract_address_const::<'new_owner'>(); -# assert_eq!(pizza_factory.get_owner(), owner()); -# -# start_cheat_caller_address(pizza_factory_address, owner()); -# -# pizza_factory.change_owner(new_owner); -# -# assert_eq!(pizza_factory.get_owner(), new_owner); -# } -# -# #[test] -# #[should_panic(expected: ("Only the owner can set ownership",))] -# fn test_change_owner_should_panic_when_not_owner() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# let not_owner = contract_address_const::<'not_owner'>(); -# start_cheat_caller_address(pizza_factory_address, not_owner); -# pizza_factory.change_owner(not_owner); -# stop_cheat_caller_address(pizza_factory_address); -# } -# -# #[test] -# #[should_panic(expected: ("Only the owner can make pizza",))] -# fn test_make_pizza_should_panic_when_not_owner() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# let not_owner = contract_address_const::<'not_owner'>(); -# start_cheat_caller_address(pizza_factory_address, not_owner); -# -# pizza_factory.make_pizza(); -# } -# -# #[test] -# fn test_make_pizza_should_increment_pizza_counter() { -# // Setup -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# start_cheat_caller_address(pizza_factory_address, owner()); -# let mut spy = spy_events(SpyOn::One(pizza_factory_address)); -# -# // When -# pizza_factory.make_pizza(); -# -# // Then -# let expected_event = PizzaEvents::PizzaEmission(PizzaEmission { counter: 1 }); -# assert_eq!(pizza_factory.count_pizza(), 1); -# spy.assert_emitted(@array![(pizza_factory_address, expected_event)]); -# } -# -# #[test] -# fn test_set_as_new_owner_direct() { -# let mut state = PizzaFactory::contract_state_for_testing(); -# let owner: ContractAddress = contract_address_const::<'owner'>(); -# state.set_owner(owner); -# assert_eq!(state.owner.read(), owner); -# } -# -# -``` - -Listing 17-2 Deploying the contract to test - -### Testing our Contract - -Determining the behavior that your contract should respect is the first step in writing tests. In the `PizzaFactory` contract, we determined that the contract should have the following behavior: - -- Upon deployment, the contract owner should be set to the address provided in the constructor, and the factory should have 10 units of pepperoni and pineapple, and no pizzas created. -- If someone tries to make a pizza and they are not the owner, the operation should fail. Otherwise, the pizza count should be incremented, and an event should be emitted. -- If someone tries to take ownership of the contract and they are not the owner, the operation should fail. Otherwise, the owner should be updated. - -#### Accessing Storage Variables with `load` - -```rust,noplayground -# use source::pizza::{ -# IPizzaFactoryDispatcher, IPizzaFactorySafeDispatcher, IPizzaFactoryDispatcherTrait, -# PizzaFactory, PizzaFactory::{Event as PizzaEvents, PizzaEmission} -# }; -# use source::pizza::PizzaFactory::{ownerContractMemberStateTrait, InternalTrait}; -# -# use starknet::{ContractAddress, contract_address_const}; -# -# use snforge_std::{ -# declare, ContractClassTrait, ContractClass, start_cheat_caller_address, -# stop_cheat_caller_address, SpyOn, EventSpy, EventAssertions, spy_events, EventFetcher, load, -# cheatcodes::storage::load_felt252 -# }; -# -# fn owner() -> ContractAddress { -# contract_address_const::<'owner'>() -# } -# -# fn deploy_pizza_factory() -> (IPizzaFactoryDispatcher, ContractAddress) { -# let contract = declare("PizzaFactory").unwrap(); -# let owner: ContractAddress = contract_address_const::<'owner'>(); -# -# let mut constructor_calldata = array![owner.into()]; -# -# let (contract_address, _) = contract.deploy(@constructor_calldata).unwrap(); -# -# let dispatcher = IPizzaFactoryDispatcher { contract_address }; -# -# (dispatcher, contract_address) -# } -# -#[test] -fn test_constructor() { - let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); - - let pepperoni_count = load(pizza_factory_address, selector!("pepperoni"), 1); - let pineapple_count = load(pizza_factory_address, selector!("pineapple"), 1); - assert_eq!(pepperoni_count, array![10]); - assert_eq!(pineapple_count, array![10]); - assert_eq!(pizza_factory.get_owner(), owner()); -} -# -# #[test] -# fn test_change_owner_should_change_owner() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# -# let new_owner: ContractAddress = contract_address_const::<'new_owner'>(); -# assert_eq!(pizza_factory.get_owner(), owner()); -# -# start_cheat_caller_address(pizza_factory_address, owner()); -# -# pizza_factory.change_owner(new_owner); -# -# assert_eq!(pizza_factory.get_owner(), new_owner); -# } -# -# #[test] -# #[should_panic(expected: ("Only the owner can set ownership",))] -# fn test_change_owner_should_panic_when_not_owner() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# let not_owner = contract_address_const::<'not_owner'>(); -# start_cheat_caller_address(pizza_factory_address, not_owner); -# pizza_factory.change_owner(not_owner); -# stop_cheat_caller_address(pizza_factory_address); -# } -# -# #[test] -# #[should_panic(expected: ("Only the owner can make pizza",))] -# fn test_make_pizza_should_panic_when_not_owner() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# let not_owner = contract_address_const::<'not_owner'>(); -# start_cheat_caller_address(pizza_factory_address, not_owner); -# -# pizza_factory.make_pizza(); -# } -# -# #[test] -# fn test_make_pizza_should_increment_pizza_counter() { -# // Setup -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# start_cheat_caller_address(pizza_factory_address, owner()); -# let mut spy = spy_events(SpyOn::One(pizza_factory_address)); -# -# // When -# pizza_factory.make_pizza(); -# -# // Then -# let expected_event = PizzaEvents::PizzaEmission(PizzaEmission { counter: 1 }); -# assert_eq!(pizza_factory.count_pizza(), 1); -# spy.assert_emitted(@array![(pizza_factory_address, expected_event)]); -# } -# -# #[test] -# fn test_set_as_new_owner_direct() { -# let mut state = PizzaFactory::contract_state_for_testing(); -# let owner: ContractAddress = contract_address_const::<'owner'>(); -# state.set_owner(owner); -# assert_eq!(state.owner.read(), owner); -# } -# -# -``` - -Listing 17-3: Testing the initial state by loading storage variables - -Once our contract is deployed, we want to assert that the initial values are set as expected. If our contract has an entrypoint that returns the value of a storage variable, we can call this entrypoint. Otherwise, we can use the `load` function from `snforge` to load the value of a storage variable inside our contract, even if not exposed by an entrypoint. - -#### Mocking the Caller Address with `start_cheat_caller_address` - -The security of our factory relies on the owner being the only one able to make pizzas and transfer ownership. To test this, we can use the `start_cheat_caller_address` function to mock the caller address and assert that the contract behaves as expected. - -```rust,noplayground -# use source::pizza::{ -# IPizzaFactoryDispatcher, IPizzaFactorySafeDispatcher, IPizzaFactoryDispatcherTrait, -# PizzaFactory, PizzaFactory::{Event as PizzaEvents, PizzaEmission} -# }; -# use source::pizza::PizzaFactory::{ownerContractMemberStateTrait, InternalTrait}; -# -# use starknet::{ContractAddress, contract_address_const}; -# -# use snforge_std::{ -# declare, ContractClassTrait, ContractClass, start_cheat_caller_address, -# stop_cheat_caller_address, SpyOn, EventSpy, EventAssertions, spy_events, EventFetcher, load, -# cheatcodes::storage::load_felt252 -# }; -# -# fn owner() -> ContractAddress { -# contract_address_const::<'owner'>() -# } -# -# fn deploy_pizza_factory() -> (IPizzaFactoryDispatcher, ContractAddress) { -# let contract = declare("PizzaFactory").unwrap(); -# let owner: ContractAddress = contract_address_const::<'owner'>(); -# -# let mut constructor_calldata = array![owner.into()]; -# -# let (contract_address, _) = contract.deploy(@constructor_calldata).unwrap(); -# -# let dispatcher = IPizzaFactoryDispatcher { contract_address }; -# -# (dispatcher, contract_address) -# } -# -# #[test] -# fn test_constructor() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# -# let pepperoni_count = load(pizza_factory_address, selector!("pepperoni"), 1); -# let pineapple_count = load(pizza_factory_address, selector!("pineapple"), 1); -# assert_eq!(pepperoni_count, array![10]); -# assert_eq!(pineapple_count, array![10]); -# assert_eq!(pizza_factory.get_owner(), owner()); -# } -# -#[test] -fn test_change_owner_should_change_owner() { - let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); - - let new_owner: ContractAddress = contract_address_const::<'new_owner'>(); - assert_eq!(pizza_factory.get_owner(), owner()); - - start_cheat_caller_address(pizza_factory_address, owner()); - - pizza_factory.change_owner(new_owner); - - assert_eq!(pizza_factory.get_owner(), new_owner); -} - -#[test] -#[should_panic(expected: ("Only the owner can set ownership",))] -fn test_change_owner_should_panic_when_not_owner() { - let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); - let not_owner = contract_address_const::<'not_owner'>(); - start_cheat_caller_address(pizza_factory_address, not_owner); - pizza_factory.change_owner(not_owner); - stop_cheat_caller_address(pizza_factory_address); -} -# -# #[test] -# #[should_panic(expected: ("Only the owner can make pizza",))] -# fn test_make_pizza_should_panic_when_not_owner() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# let not_owner = contract_address_const::<'not_owner'>(); -# start_cheat_caller_address(pizza_factory_address, not_owner); -# -# pizza_factory.make_pizza(); -# } -# -# #[test] -# fn test_make_pizza_should_increment_pizza_counter() { -# // Setup -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# start_cheat_caller_address(pizza_factory_address, owner()); -# let mut spy = spy_events(SpyOn::One(pizza_factory_address)); -# -# // When -# pizza_factory.make_pizza(); -# -# // Then -# let expected_event = PizzaEvents::PizzaEmission(PizzaEmission { counter: 1 }); -# assert_eq!(pizza_factory.count_pizza(), 1); -# spy.assert_emitted(@array![(pizza_factory_address, expected_event)]); -# } -# -# #[test] -# fn test_set_as_new_owner_direct() { -# let mut state = PizzaFactory::contract_state_for_testing(); -# let owner: ContractAddress = contract_address_const::<'owner'>(); -# state.set_owner(owner); -# assert_eq!(state.owner.read(), owner); -# } -# -# -``` - -Listing 17-4: Testing ownership of the contract by mocking the caller address - -Using `start_cheat_caller_address`, we call the `change_owner` function first as the owner, and then as a different address. We assert that the operation fails when the caller is not the owner, and that the owner is updated when the caller is the owner. - -#### Capturing Events with `spy_events` - -When a pizza is created, the contract emits an event. To test this, we can use the `spy_events` function to capture the emitted events and assert that the event was emitted with the expected parameters. Naturally, we can also assert that the pizza count was incremented, and that only the owner can make a pizza. - -```rust,noplayground -# use source::pizza::{ -# IPizzaFactoryDispatcher, IPizzaFactorySafeDispatcher, IPizzaFactoryDispatcherTrait, -# PizzaFactory, PizzaFactory::{Event as PizzaEvents, PizzaEmission} -# }; -# use source::pizza::PizzaFactory::{ownerContractMemberStateTrait, InternalTrait}; -# -# use starknet::{ContractAddress, contract_address_const}; -# -# use snforge_std::{ -# declare, ContractClassTrait, ContractClass, start_cheat_caller_address, -# stop_cheat_caller_address, SpyOn, EventSpy, EventAssertions, spy_events, EventFetcher, load, -# cheatcodes::storage::load_felt252 -# }; -# -# fn owner() -> ContractAddress { -# contract_address_const::<'owner'>() -# } -# -# fn deploy_pizza_factory() -> (IPizzaFactoryDispatcher, ContractAddress) { -# let contract = declare("PizzaFactory").unwrap(); -# let owner: ContractAddress = contract_address_const::<'owner'>(); -# -# let mut constructor_calldata = array![owner.into()]; -# -# let (contract_address, _) = contract.deploy(@constructor_calldata).unwrap(); -# -# let dispatcher = IPizzaFactoryDispatcher { contract_address }; -# -# (dispatcher, contract_address) -# } -# -# #[test] -# fn test_constructor() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# -# let pepperoni_count = load(pizza_factory_address, selector!("pepperoni"), 1); -# let pineapple_count = load(pizza_factory_address, selector!("pineapple"), 1); -# assert_eq!(pepperoni_count, array![10]); -# assert_eq!(pineapple_count, array![10]); -# assert_eq!(pizza_factory.get_owner(), owner()); -# } -# -# #[test] -# fn test_change_owner_should_change_owner() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# -# let new_owner: ContractAddress = contract_address_const::<'new_owner'>(); -# assert_eq!(pizza_factory.get_owner(), owner()); -# -# start_cheat_caller_address(pizza_factory_address, owner()); -# -# pizza_factory.change_owner(new_owner); -# -# assert_eq!(pizza_factory.get_owner(), new_owner); -# } -# -# #[test] -# #[should_panic(expected: ("Only the owner can set ownership",))] -# fn test_change_owner_should_panic_when_not_owner() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# let not_owner = contract_address_const::<'not_owner'>(); -# start_cheat_caller_address(pizza_factory_address, not_owner); -# pizza_factory.change_owner(not_owner); -# stop_cheat_caller_address(pizza_factory_address); -# } -# -#[test] -#[should_panic(expected: ("Only the owner can make pizza",))] -fn test_make_pizza_should_panic_when_not_owner() { - let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); - let not_owner = contract_address_const::<'not_owner'>(); - start_cheat_caller_address(pizza_factory_address, not_owner); - - pizza_factory.make_pizza(); -} - -#[test] -fn test_make_pizza_should_increment_pizza_counter() { - // Setup - let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); - start_cheat_caller_address(pizza_factory_address, owner()); - let mut spy = spy_events(SpyOn::One(pizza_factory_address)); - - // When - pizza_factory.make_pizza(); - - // Then - let expected_event = PizzaEvents::PizzaEmission(PizzaEmission { counter: 1 }); - assert_eq!(pizza_factory.count_pizza(), 1); - spy.assert_emitted(@array![(pizza_factory_address, expected_event)]); -} -# -# #[test] -# fn test_set_as_new_owner_direct() { -# let mut state = PizzaFactory::contract_state_for_testing(); -# let owner: ContractAddress = contract_address_const::<'owner'>(); -# state.set_owner(owner); -# assert_eq!(state.owner.read(), owner); -# } -# -# -``` - -Listing 17-5: Testing the events emitted when a pizza is created - -#### Accessing Internal Functions with `contract_state_for_testing` - -All the tests we have seen so far have been using a workflow that involves deploying the contract and interacting with the contract's entrypoints. However, sometimes we may want to test the internals of the contract directly, without deploying the contract. How could this be done, if we were reasoning in purely Cairo terms? - -Recall the struct `ContractState`, which is used as a parameter to all the entrypoints of a contract. To make it short, this struct contains zero-sized fields, corresponding to the storage variables of the contract. The only purpose of these fields is to allow the Cairo compiler to generate the correct code for accessing the storage variables. If we could create an instance of this struct, we could access these storage variables directly, without deploying the contract... - -...and this is exactly what the `contract_state_for_testing` function does! It creates an instance of the `ContractState` struct, allowing us to call any function that takes as parameter a `ContractState` struct, without deploying the contract. To interact with the storage variables properly, we need to manually import the traits that define access to the storage variables. - -```rust,noplayground -# use source::pizza::{ -# IPizzaFactoryDispatcher, IPizzaFactorySafeDispatcher, IPizzaFactoryDispatcherTrait, -# PizzaFactory, PizzaFactory::{Event as PizzaEvents, PizzaEmission} -# }; -use source::pizza::PizzaFactory::{ownerContractMemberStateTrait, InternalTrait}; -# -# use starknet::{ContractAddress, contract_address_const}; -# -# use snforge_std::{ -# declare, ContractClassTrait, ContractClass, start_cheat_caller_address, -# stop_cheat_caller_address, SpyOn, EventSpy, EventAssertions, spy_events, EventFetcher, load, -# cheatcodes::storage::load_felt252 -# }; -# -# fn owner() -> ContractAddress { -# contract_address_const::<'owner'>() -# } -# -# fn deploy_pizza_factory() -> (IPizzaFactoryDispatcher, ContractAddress) { -# let contract = declare("PizzaFactory").unwrap(); -# let owner: ContractAddress = contract_address_const::<'owner'>(); -# -# let mut constructor_calldata = array![owner.into()]; -# -# let (contract_address, _) = contract.deploy(@constructor_calldata).unwrap(); -# -# let dispatcher = IPizzaFactoryDispatcher { contract_address }; -# -# (dispatcher, contract_address) -# } -# -# #[test] -# fn test_constructor() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# -# let pepperoni_count = load(pizza_factory_address, selector!("pepperoni"), 1); -# let pineapple_count = load(pizza_factory_address, selector!("pineapple"), 1); -# assert_eq!(pepperoni_count, array![10]); -# assert_eq!(pineapple_count, array![10]); -# assert_eq!(pizza_factory.get_owner(), owner()); -# } -# -# #[test] -# fn test_change_owner_should_change_owner() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# -# let new_owner: ContractAddress = contract_address_const::<'new_owner'>(); -# assert_eq!(pizza_factory.get_owner(), owner()); -# -# start_cheat_caller_address(pizza_factory_address, owner()); -# -# pizza_factory.change_owner(new_owner); -# -# assert_eq!(pizza_factory.get_owner(), new_owner); -# } -# -# #[test] -# #[should_panic(expected: ("Only the owner can set ownership",))] -# fn test_change_owner_should_panic_when_not_owner() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# let not_owner = contract_address_const::<'not_owner'>(); -# start_cheat_caller_address(pizza_factory_address, not_owner); -# pizza_factory.change_owner(not_owner); -# stop_cheat_caller_address(pizza_factory_address); -# } -# -# #[test] -# #[should_panic(expected: ("Only the owner can make pizza",))] -# fn test_make_pizza_should_panic_when_not_owner() { -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# let not_owner = contract_address_const::<'not_owner'>(); -# start_cheat_caller_address(pizza_factory_address, not_owner); -# -# pizza_factory.make_pizza(); -# } -# -# #[test] -# fn test_make_pizza_should_increment_pizza_counter() { -# // Setup -# let (pizza_factory, pizza_factory_address) = deploy_pizza_factory(); -# start_cheat_caller_address(pizza_factory_address, owner()); -# let mut spy = spy_events(SpyOn::One(pizza_factory_address)); -# -# // When -# pizza_factory.make_pizza(); -# -# // Then -# let expected_event = PizzaEvents::PizzaEmission(PizzaEmission { counter: 1 }); -# assert_eq!(pizza_factory.count_pizza(), 1); -# spy.assert_emitted(@array![(pizza_factory_address, expected_event)]); -# } -# -# #[test] -# fn test_set_as_new_owner_direct() { -# let mut state = PizzaFactory::contract_state_for_testing(); -# let owner: ContractAddress = contract_address_const::<'owner'>(); -# state.set_owner(owner); -# assert_eq!(state.owner.read(), owner); -# } -# -# -``` - -Listing 17-6: Unit testing our contract without deployment - -These imports give us access to our internal functions (notably, `set_owner`), as well as the -read/write access to the `owner` storage variable. Once we have these, we can interact with the -contract directly, changing the address of the owner by calling the `set_owner` method, accessible -through `InternalTrait`, and reading the `owner` storage variable. - -> Note: Both approaches cannot be used at the same time. If you decide to deploy the contract, you interact with it using the dispatcher. If you decide to test the internal functions, you interact with the `ContractState` object directly. - -```bash,noplayground -$ scarb test - Running test source (snforge test) - Compiling source v0.1.0 (listings/ch17-starknet-smart-contracts-security/listing_02_pizza_factory_snfoundry/Scarb.toml) - Finished release target(s) in 1 second - - -Collected 6 test(s) from source package -Running 6 test(s) from src/ -[PASS] source::tests::foundry_test::test_set_as_new_owner_direct (gas: ~130) -[PASS] source::tests::foundry_test::test_constructor (gas: ~296) -[PASS] source::tests::foundry_test::test_change_owner_should_panic_when_not_owner (gas: ~297) -[PASS] source::tests::foundry_test::test_make_pizza_should_panic_when_not_owner (gas: ~297) -[PASS] source::tests::foundry_test::test_make_pizza_should_increment_pizza_counter (gas: ~368) -[PASS] source::tests::foundry_test::test_change_owner_should_change_owner (gas: ~301) -Tests: 6 passed, 0 failed, 0 skipped, 0 ignored, 0 filtered out - -``` - -The output of the tests shows that all the tests passed successfully, along with an estimation of the gas consumed by each test. - -## Summary - -In this chapter, we learned how to test smart contracts using Starknet Foundry. We demonstrated how to deploy a contract and interact with it using the dispatcher. We also showed how to test the contract's behavior by mocking the caller address and capturing events. Finally, we demonstrated how to test the internal functions of the contract directly, without deploying the contract. - -To learn more about Starknet Foundry, refer to the [Starknet Foundry documentation](https://foundry-rs.github.io/starknet-foundry/index.html). -# Static Analysis Tools - -Static analysis refers to the process of examining code without its execution, focusing on its structure, syntax, and properties. It involves analyzing the source code to identify potential issues, vulnerabilities, or violations of specified rules. - -By defining rules, such as coding conventions or security guidelines, developers can utilize static analysis tools to automatically check the code against these standards. - -Reference: - -- [Semgrep Cairo 1.0 support](https://semgrep.dev/blog/2023/semgrep-now-supports-cairo-1-0) -- [Caracal, a Starknet static analyzer](https://github.com/crytic/caracal) -# Introduction -# The Cairo Book - -By the Cairo Community and its [contributors](https://github.com/cairo-book/cairo-book.github.io). Special thanks to [StarkWare](https://starkware.co/) through [OnlyDust](https://www.onlydust.xyz/), and [Voyager](https://voyager.online/) for supporting the creation of this book. - -This version of the text assumes you’re using the [Cairo Compiler](https://github.com/starkware-libs/cairo) [version 2.6.3](https://github.com/starkware-libs/cairo/releases). See the [Installation](ch01-01-installation.md) section of Chapter 1 to install or update Cairo. - -If you want to play around with Cairo code and see how it compiles into Sierra (Intermediate Representation) and CASM (Cairo Assembly), you can use [cairovm.codes](https://cairovm.codes/) playground. diff --git a/client/bun.lockb b/client/bun.lockb index e2b36658a8ea0e45cc3836fed01ef15c9c56563a..4602a163403877b76e04f5dfe94a85669f161a4e 100755 GIT binary patch delta 34897 zcmeIbcUV(P7e1Qo1SKfVii!$Yj^%)WNI(QDcI;hI5m8V;1T5Hsy`o}{j@b2Buy?=$ ziWN{$?AR3xSg`kY-?jH_3?9$-tM~qKpD&LuYt}n6Yu2opJ$sVuI42gCdb_OjLWerZ z`?Bws*mkk>_!*~%7gSo&qMGK6$>n`VI=g#3%ZsQndgX(&Y6ZPYsA79nQ4J7OyQ4aq z>YJEY8LgPDP*l`+H|c8>jg+;1yGbRTb6THP8nK1cccKMJN<;3WYiJ z9UzI&#L9%MfZVR*pnpMtDHBfAd?nmR3Di~_hGI{7;>UUFnugng7>NU*{$d}x?octpTR z@Z`{@&5~RONmH}I7RkY(!6OFw1xF|r@`gTwrx{?50iY2Lmm2;#vT{M$0XYICQLs8H zc%x!f$hVMIBr!F}0UJyiayTL&WOP8dLNOTmHqdK9R)+LOIV%4Yk|HV2By>{lSkqmo zukUWrywvtRk|n>8!2uZFfc1OyTP&*d*}PARz%odhDs#D9vR?}MMCdd{A|e9AXef>( zNRA~yQiB2h{s{S?Py(_QLjxki{BZI9nV`3`tf@PaB(~AcY-ta>p+sD%5{?P-F#3*Ppg*quZV$ z4gNYvvK4zo>S|DEU_f|KWW;0W)Wx6(zwmIsD243nRL&0`5i%+=C^#YtI<@T|97H`; zh_Qtp5f~60jA`eLSW^hCA<37=$3$5v`UVoznRNW2j0;jm^tBtxxWm<+xLZvpubk`~3Aki-vzq)}>z z`qV%tl&8^gfnFZ6GM6QI{ww5HROl4Z9pDl5v^^XlgQJl_hH@au;}ei{jqZn}azPRH z;Q>Pf#;%8MDeBVj&xcMOX>?oS8DtsglfhHO0wKwv{*W{soT$7G30ownM`a;txW90R z3LvSX-93pBD)a$5M|ML((#RIaA87 zgM89w=SlS*LsADi=Og}P=vltxS%)W5gDtp3s3QU*6$;1@zc7X3D#}rhjzUt;cS2f1 z4j$nj8IHB76dIxqeL=&Np9@JkZWCgI(hXCg__?ej{?x+-C_tgVUm%6DyN@&nu0SU~ znae6KB}0~wrr^K5ka|1@^{JuJL6NvkDHI!CNp=*kB|F%bL`H=LD1wnkb1NA<+3m2m zcX{k=Y;3KJr?gu={OM+s_IfwlUdC6P5B-RF-BYPwXlteO>MtC=^uqW~KfkPuXYGwA zN6c>hecy)a6D+EEHXl>`O`>c2vk7Y#?Hgxo=~XvL`PbRB_t8}+tnaQ*eHa^Gx_qk- zdXHz-hQ%zK4_x=-O6-BA zbxPH$ubi8^HhZl_UFqHcuK>U|i$Ejj2OgIxV@L8g!shyi2i= zN5>Qet!m~AO-#$T$X~T%^l8Ut%LXJCGZ$7>ay)o3-@lL5=g&@EGF$_?c%83nUD=mO>V7f#X?Q1gF0Y%vhnv(N>C7U!6$s#R@zFtGoe@4X#Q~VdJ zi0eYI|16siwr5cf9E>$h7Ah1TV3qpLPFl_5xKfo*SSVNtNAB)EUJ zRagHzt0Tbv(`q8vB38xdtN!|3*>+$%7uWV_pz#)< z&4flVK{!z|2O32Ie!{b|>!b*&^_GrWO($qn4}KzVJ~RpjY{KgkTob4dMxRO3XF7Rk z8scpj*@MT>BQ4OtR2YDXbj`3kLY)@hvLCD)~3FN8*&M9`eIM$e!jF!eo*>^5V7 z^f9g;nm$NTS5;!?_Hs>h+UO0mX8M?+jf}U*Q;bG%EHo{un9-OCJGbaFHhF1Gw@OzD zdgiXx^n}(1MPNs()vSTmMbv0=n{Jc(snJ_@*J_$Vqml}J=T=(HoFaKC&?N7(8{iJP zUAk=<>tlPk8AG8vqjVV_hUP76M#>%NlHSMJ!>B1zxC9+NG;@%m;1<_+9-`HxK%;O< zwM*|*C^{BugP{GiwFz27@iKdY6pgeL^me=Wda2KDt<}Uqqj`oqPdlyV9yDr89Au&F zZhhPBUV_hV{haMyni;#LD+5FBpcPVf>rHle37=48hnJ@Q9%)XCgDgbu(PtnpagW|) zr18u+wStx9Ns6nY9wAbCi|rY zRdmj%6KQ(W>_)~&(3CiqQ01yy-BM%1C1sOO1fx;5{de@d%QF) z6XkAM;^LeH%@IY=NzC0H(CAWyhVgy?jV@!UA-g1n!d=v|hiiqtN&1YvUPg04q6b|) zj4mP7Kp!*0!>H^58cB?)rZZB7?Q3G8NvjD>t#i&MoL=A4-qeFv9SK`XC9Vn`(%Aal9y&kvNT+DTQQbttJ$jG}}7swVET)q|jp^gcqoA&`aZSL|!_vmI!N( z=-VFh(!2vneqzmR1z(QpGeAZhEgUP1<7Q~oeM~wmviZpLHZK{{%JufLuc!yK^43Gh*6pF?$hJ`f*zCfcXuGAwK!h=)# zImf(=tWKi^y=f~C!SA%*JT{>1x=b4 z*@Lu3iBc)tGSru)brY>3ltZBPlKjKOOo7&3(y*AAT)};uM%1VeQr+}EsGWvXzrqsL zuhKf}bE}at5?y37M&{SZrI=P8Ms36tDjH2isMeyP^)CCAR`Ud!WF;26GRIqVIncBZL`t%k-On(7H+H z+G&k^Zlj>y$Hhal6{$`lPuK1jXf(=dx*P=0JNh}7yfjnp7+w`A&?G}>TT|+;yz?fl z4>X#y(v(>Sjl9H6ZKXB33k~-L44}h3xm0H-tx+hnMl@2IEl6<}5x4KqdWg1Y8SHky zu*Zm0JhT>K9(C;*G>W&lN7cCH%8{b`?VLi5M&>58)?z)$5j4j>*{2hkUrdGDc7|4{OVR%n=~Z+p{Avpi3pR+e!7 z8#Ep)1kpbqdEylKij>qvGSusdG<4GT{V&qQQ9qBA3mT9@rhaOuxk2kHx)QrxtC(J28+=Q3PbV zR^#$gjt%aaLhMU@#(gj0(o4Nbu9v39D=F-ll(>vXL8CPen-Z+b`(EiYa=na7ycXBm zTn|l0r05dDmLGf3>CoJumD5{d%aHzBpYgy;FnP1rGl7i z)csF4NWP8b4wAHjzL4wx`%-HE|AHa0AOGuibm#$fLXSTsAXh;agIo_;4e~T3y+{(D z$#s$f^mC9($n%{4Pm;=I^LiI~d7Yg2pOMtyWnPga8N9;fRW7gbe3F!(14;F6aQ!CF z=TfIIB&fnIUVtPe?{b|a<==xOgSlLP!1GBG|A_OCIZsjz{wdcDr4k?JE1vNTLrD!i z=R8Rb^!HpRN%CAHtWf}eR_vLkzJA~(wq|OFGQk26XDL;belccsrah)XPkLEf_(#LQ)7Lu|i;1Ai= zky2Ea`jt=!`iUPTr>F4ZB&peHr0Z9HC{GuvViwQ+zafjm-U4pVP>K!W4@t)JA*F@N zfIxPU0%8=Fq5?%Dj>~1-fT5&rtpHC`VJ*)mN%huoog_K98IsEFP@{dy+k-z;a4#wU zA}LY{yj&tLN0O3QNTw4JGBD<2*?! zm(Arx&i_u*LYsqps(+oA*WKh5ekZBmEneX^WNGNHc*Qr64$y58M+#+4{GsxHkisSD zwRpZg=M5$DbqWWbL6Va7@rOKhha>|Hx%7afA@JgQV@P_DgfEKbkVLh{AF9`e%eGv$ zgQQ6LaJ>U0wXdKAHQ0@3bmw|sNc>X_#2;$dpUWYT)WA@#4}+u^Nh%itNe+$VdL$$@ zJeu?4An8St=AU8`&zQn9NRojWTqj8l&g60y=SdPj8a0!5_MAKSNT(#ZZXqnLv_5C8^TCNV02+e3E8dnsaGU z4DqK1%7P$+6(I3XQI!|4fvg6-IoDfICSD}Tp>|yVog{l5kxvom!pj*-a=e=hGN?xb zA<08OE(h@nB#HOuI!WbT&xfu4yTwIR@cQ51BmW=P|L+#}zgyh@ZgFuD{dbFtAkbEq z7JNOI20L21#TVVu{;Jag|KBa{f48{*-Qxati~Ik-Ev_TBtp7_}+{90%ls98__Bo%Y z%sEprrKTo(Xxv@1dc|j-T=}tz^Cq*<;uYsFc)Cu#xlyMPlNMWMw`tP6?a9D`^;h%k zJhHotcbq@bZ^Pu;F<4cVitpy%AveRusI@>sLWa+(S-H%o;UbfSqf>!Bw&-;|?7i2YKRjm2C?@!KN>#jR^ zuae8ouE3>EHHh*!7hQ+FCE(Gq2v-!Oi;mo=Zqojl0ygPR>EHi`%9#-BEWK z8vgsr>6|OKqAk*cM$I;M$uym@|3xRE^UeH|HA6nXII4W$dOpYf^nF{^vu72Doll4> zF(*H^ddn)hoi^cd@7GPg*G6(!prNB-lwayb{l1?Gs`TW_y@HUV1!10F9?x2#8>;HQ zSYeVs;On;I33FeJa@$*FNuQcG4^>=Qqr7@y_<`HO5nE39wh!FsTd=%rOVMyNJ=Cq( zWoWqUA9dG{%X-?nNh{lX1(^}n9mgMPwxQ$O79||#D060g++C|g!tHlJUwO?00< z9?#58k2G}O`K*8I4QF%%;^$6|s3CbQ8s2Sac_`lFf3E&;le14eJVVpr)xr&LAdX%&XgyA<^7N4u9bKYBm;Fh{pfb>Dp2 z!sIhM%L(;bT{!tsuuW*-QFh6&*-@flL3DVpq2V6I1Mhtf-B>2MXJ|S10dtNuS^P)x zj)FhBPA)ci&A#T@?VBnGpL`pzW1BvCVB_$aK1yBY0ox4^pD*8h{o|SRt_kCB8W`SZ zX!z~3GAnkzs%thiy~4oLC+#wy#Flw{|NYQUKGD0bJgH&2u1iRp$tQlem+YXwKX;1r z)NvaoG#WDP_TcK%Ce~c~_lsv&xm|jjz2CsDPMs5z-f`0>=Y7>}YB+m$+I4@%zCBL| z2x%4Do_gyLwC8eQ!kPV_k{h=;xXms4sc^>LYQhG~Vy2%~l{E=)sA+ooQa#bIT8u=3 zfnoK?&7rfsUvzmGZanUjd8x1K$}KC??_9;en$BNq#tWsL7weio?YMTWF6ZmJWw-Ar zbAsc&j~O3)?iah^K%G|ll9x6)8W>JAG`z9r9@mm9ue4F>P1iTv-1PMGiu+$1FKX)K z?zV2y)Tw`OnPXaKXvBuSo#%I+HfD&=1x>&5T~<|@y(sEhhn$5OGoJR~c4?hRqU%q7 zsa;CBez#xS@sd~7>WeBn`aK@nr=V`#Lo=d<`CCeado<}De9(H(bycIpSH^F>``IMT zbnqN8sor8M|LcD~RJ%^fU(O9j!{7l!htr;P-(_a&BZFQ>e5}O^Zn!087 zoZBNtXY?>BZQY!L+BLnD+B?FLincCw`prA7@82=Uabf3B^}v^5P4l>68arAvmcu9n`eI+`{$*@CEpcKYVgDM@_h&G z*SM?^k!}8J)#~K;6??94*p+!9w|HLMmU~-Y9*Vhp;L=*#dbO>qwdqm+7F)ShX{A%n zzHuee*?&RE_=la9y=rEDu!)(Ld}WAx;}#j69Oqh`TjLt$b<1mOuW46XBnTVggEm*M zq-E;Q%KQ~y*}PG^BjAyIYfCot&aFnr6;qe*ojUq``>qR|?{qmlf6@CETb~Sg?Q-%$ zuSTU0P3!P*rt0aJ3Jb`eajt_cb-9*DvQK1(k5h%R#F#yuSmW&G3trzmDq-3;72V(4DE`{%~JTx;cFJGs`1`E^UJo9;3)fAjZL)+(!k`J&T~RUY|t z-MFjiO`WRT%-eO&Jk}i^=v<}SC3SkOv8Ef#e6PD;Gd?ndJ>zJM%27kZ&!UaIk}fov zGQ8rkgOmE%Jj)((v|_1_wqthmPt&#b>C~;v{n}l3H9wO#eBObMO(#rW+--R5s{3}M zTg)r**rnl(!#1MB(qfoeYOg=0VUmw)#tAgQK~Fi`h+IZu7_8yme<5&TDu^G^`d^*<*$d&)U?;szi;< zicK>vCVcyQ%$VTiHyW4s>6zKHd2Yo{y4`i=cbOa%GoY$#wYS>9kdU%(Q&fR#y4Cc2 z?mQu3wBrWvxyGVlg>e%^;<%yVn0~jiPMv*RF>jx4$-{5KAD4GK)4kl31}>WKj?N$M zw69w8sp`}B_K|gJ&aKiT-Q#ilDL32pJkjav^5=i`tUR>eu|{Nx4T~R7D^3|2p5fxs z>dS_OFRE%L2Ulv^dyQ^$AN57E#4Q^)dUT2WBVqKMBez2vFI{ryakH5fUOlsazFl1= zw?#@rqqUuN{e+m#?NYd5x}~2sG@N{B`>s9W$R7)rEH)k=ux9m`wM_y78$HcQ$$s=Q z;?<|!@3YSZB_Ak%TQV%(Z_*772e%#{nf_yDq*GMoIUVhrcR71Lrfr(_`?hHX%e37; zs%zhyI4iW-rj?a99;jbtq3T;h-GY&uXU+DmP}li#)+ycfK4V0~(&i?^&~W8beh*3y z%U*LJr){mU6@6+w7*OW!72g#hMjPW?bH{jke{ha|W>TrbmN^k~7dvdQ>R8#f_`2(M z8?UchR9{y-<&mF(!*r#{FP(bYl%4%U8s9Ph^vUA6F=O$kS}u&)c7JM_ik?5_Wm;re z87pgSwJOlH>~}OPbf|09>qkers0R3bt$Vs@!Suk=!&?{_K5JlDePOuc_NhPK#iwX| zlxNGIb6RcLBP82OrCZ`ZZ*pkGvMuH}u{wIEyUzS&#^;i5J=*3vE=aoG>%rSi-tj}@ zZ&#^!yg)Q;EQUDK&~V)tyG>n=hM87MOLq6!wJ_Ii?A{WOM>stjS>dlaeI7MFU-QL} zw_WN#9ap8shIubKlzHFmS;M?E|4KjJUl>*}Db!`DXjj@QWEHvdws-s6Gcs$e&+Wi; z%R$WfX2MoG(=ns!h4qT`O`SG0t6vS(q_^9y_THRWJA3f!^Z^fUxa^+P*8RraLopq^ z-)VENh=!%z*f~RoqZiGZJE&UA`7QH;Mvgc=#@w|$E8k*)f54(YJMPhKTF^#s>+pD( zSEb%}%hp{#S3hq_`BSeZu4=g9^IQMo!zz}zoL^ittT3j%!g)i(<|DtKs{A8sY2bj< z)$iHIo>)IFI;xfFs5kE4SO2)$x7?k~78YrxCw?E8_@Qfl#n&NeihcgA;X-03MLtCqZQv`X`bX}f|-FZw*QgoE$mul;gnu3FG0 zDLEz7bn<}Zo%P1ACr#Q``*80LI}Y#3{d@ATDYMU<>&G3YJNgAfyE{rmf{hJ{{Kr`5Zi)8c)o?)5wS+|8-&xW}|wTrxDAn7TD()$)AUKNVj=duwC};KYQfA*4fl9 z-}`Ah&AApwn`Q((TXz3VUGIkh7Sjb~o10blx`mdu_;{|n?p~0$`y$`=7t6a;yplR% zzVEOu<3+>K;#YmNU6)_#J{MM&$$GeV{+oqsPxh=||Mi^q&kk7cnlo|Oz)R}ra&wYA zvP*kh9^577LJ6-^?p?k$&m9uf`TYW$T@NR2vaeFYQqMg1E3KIQ24y>C4vX5L?8!dv zSDLb0MBHGtH-d;y01>kh#4VOXM6W~;o|{12VY4@ZFiryToQQkOJsw075i8?CL7@3L_B6~wtz?@V*3^l`Ro%BV-JDw-3sC<+q@M-t;0$)X0}b) zR{5Ou-Ui~@VU$STh7vEBW;=*k$sj_ugLuUb5aE^rqVf(9Z&=U{5P3vo67h~z*a>3k z5fBr1g80DFiD-Qkg#9iMpIFo`5Fd%SMZ_0YdpC&qR1h({L40F5MD#ia!gCLZA8hs> z5XQ$rJO?2t1=et{vIk2dX60TmDuF#ACh!CppM7AA1h#A+7^{_@sbIB4%X@m}-a*F@fj6 z_#6RK1MxWm#_BwnZ^Zn8_#6e3M$Go3U}_^i#Ei`bUYtgmDgt=R`DR z?&%?1YdS`;TMnp0Z9hoKz#H`yOLb5<~W(SCHy91)~IS^f0&^Zu!L}U`t zomDswV(DEF6VHR_$4sazS`r z1Tlckz6iqj0f^^B_%ZiOAd-k!c?pC+%O@i6Aqbz#AOcw2We`@6Kzt)&C~I>CL>dv> zuYd?*pNJUy7=-Ut5X0H#s~~FSfiS%WB82t62I3kK$wZ7`nj8?b@-{g#AqrQ7q~vh>t|vB4RwNeG5eV za}Y7NKulygMD!{E;dvW`j?KOe!uSP<=R{0q?sq^W5wY?Ph^Z`}h`^U1eC~pn&f@NZ zuzCgJ8xb>En|mPAh}eD)#BBD7h_SCh_}&LGmu!;$V%Y&A+}?qx{1Akm1w90jM?@wOi&=$7AeO!dG4T-y#?pys{Q-piV-RsH z>M@9qMBE}`IjfxqBK{+Ym^=_GSq>4sK7sJe2eF#X&Ie)q8N_oU)-v}eAd-k!`2@t@ zET4$LFCcuLg4n>~o`SIY3gR0Pn^>D?Akv7~{tU!s_KAqG-$3|22eFlHeh#A6cMzrp zAhxsK1t6{wkxax+rg;Hk)(;RNFF@>O2S6-#6A+G<(D$;Sm(cT|XOh03Rd|I8OO+rd zz5Ada(qA_9wn@Ocm7B#V0w!m2okZ$zACZ9afVBVzjp5b5j_5o3)( z_K`bo^V&Yd2S6Mm{txZALe*=-jqP~InNW?87Zm`u%=3ghb)f7Ble2KW7bB1$YX0sfW&KNSq$P03nKBBrIL8ZDinu! z&qk8?z|u*4WVXf-pI8)$&n%n77gk#X@s&*`@r~t>_|BY6Abzmf5Q0L*?wbfb1f_~K zECDH~*dmfD6?;NbtzykeLK>;qGLpqq>@~^aD%RE%(pbgTk<_TzXObqW#4cvS6x)P9 zglYjju+X?^$ne2I;bC~L?i4RtUMy%H%-*_ZLO0%FD#hErr+f z$jn>i@Bh|QmWUVV={kI^g@OHWQSh`AweLTq7by(Z=q&?1tw%4$I$sh>>y~nws?%>p z=oJSJ|HKb{=~EwiE$19PBuJ0H(rYEJOONDL5*hr!fpgSMEzYgx9KA=b!?`sQrxPCv z$8QwH*IHiC1X_L0t>YX$$nHul;q^B-{1d-TZOpk1yc|7U>`8BK@!H7C(Ib>zoQvn> zsI!g5$4-%;4^;6_{5+#63Q{z-@`9E~m*sD^wsDRgF)zot?VO{iROQ?b&XoaY$GM%H zD+{hG8lXt-(s8mJl=jjPDt2?OJh&R1+rv5fRm>2i>9v=06_BpaxqY0g2+oCb`ynYw zLzD&3E0J?LYbYyuXby0)GB|pooWgbp9Ce@yFc%z!?J(!6BHfPHP3CoN!1-|Q2rp*~ zt|vgRqnxut+FgF^J(X9k267GW@o`?TI=FU7)9VBzW!C^kAWhLY&AFOLkKyGqAj#=J zfC-#C!#SFi6FGNQz(>4Pur}ZdlERkB3(`!*&kn^`7U$|hlYb#|j&py4+sJ!-9vuED z?14p`yTHpifb$0^8W%ZNkG@{{=Z}uammq1D<0oZ`cSzGqi8xbav;fU|3NNiO z6n-~g2{;O`5ijSCG%YdoDh7^{_!Xk!DG_)X^Ku?Y({G9>k{T5rd!|Mj0b6;vOpr;J zv?s8Qa~8a^7r5=bqU^P8`O;2un11$mi?@3z&Z2%j<7O(@V0o8#TKuzEepcYUYs0;iF*aHqgJ%FBY zaRQuy`T#xD-2k99cT!60F3}ozzd*-ya~`0pdVS>0qz3#fcro$@BnxS zJYu%@gsP@5kgSdgR1@%EskuUF(hgNuPUfPTUm1&jm60~3IWz$Ad47>@=f z15<#hz%*bwFawwg%mQWubAY+PJRk;`4=e!uRQPY0{E-+81OP*Tp+F!I1PlX)1HnKD z5DJU{!hn%LI1m9us@Re{!V?|+LVON4fRDf@;5+aGP@;?mFab)??>|Z+VG5W57JwyC3Mda) z0TqCXKqbH$s0>sAssc7Z8{icX1<=|R4f!`3+5ph~iJr_|2*d((Z=&Drbpg5o-PKr^ zdmzyh=mqo!`T%_aU!XrQ02m1P0fPX4U@*`z@xVQyys|U>Ffs`Z(@#OY(D({qCD0FO z0yG0Y0kqQ7%1)06F9xOq(|~AT2rv`~1Ok|CuF$hL{hp}>;0=5Qz5_o1H3sYmiX8=x z11A7lkM{#nz&L=`U3x5gI1mhk0waJhU?j`V70T=ACp5(YV?YDY)3;}VOn`o!HXA)U z1X%}p^bitl51Rv}k*)~PR<0!Q2ht@06>uJPUV?iE(4+AyP<|Cao2uEsT%Zkbi1yMu zQTT6Q1uzU1N(qo0NwED{x(*@-rpAb%eJ-Wkw?Efr2E%FfI2%7 zn1!-4fT_R*=!bz?<+N11( z0dfC=^bVv=F=W>gUp*9ll(eAdH0V(hdQy@ud!~FNRAm-#1XJB%PSJBP^pFib!IK2g zqelqNxI+Dm+QMB>DwIos))Xa zqVKrq3pDz6j=uS$uNCo~rB0EB1by2|U**#G#Pl6BeZfuNp3^t;^tC@dQ$XLW)58$- zqy>GCcoe9CzFvpS0iFRhq1yltcwTv=s{>VlYQPQfRK5XFRphZ%qKwKs(+ZL*l?6%y z;y^%Z0As)(y;4Ie0os3&A=)E-hx`hB0X_jA0s3P74e%TofMVp}Q@|JLCy@C-9=;7# z(9;v-@hyOMpEn`tE$%(YT;M)%7q|n^V*tdHPVy08hdPfTUjXzS_DkRu@EUjvd;s17 z?}5)iec&5F4(mwy0Z;~kcA)}#qymZq)Qe(}MgTq%5uKn2P|vBiWss(xSwNZr)EQGq zbD$Jp36uuP0aSZEdNa2(Xk})}i6gmnQRjPzCh7qFhQ&=ga6#hJb!b%QP zG->!~xM&Edrxl^o5Ylkb5Ytd==&cfs1BF}mPWIFe1*q|XfDHk1NDIh zfGZ?3n1 zYzB-&Z<|6k2ATj~JWU+sQC)(ZZjE$XpcUuaK!U?BM3L|T$g|}LGfgsD^?Ly15P2Q~ z1OvkXiqs&$4;Tmx1A>4+z#kY2(1!^Dz+ixQ0)3J}b%~1wB7l)J{$WT^$io53SO|;+ zqJT(1&Zn`P3QPgU0iysaL&Gr^7!8a8CISK@_G zd*B`L7I*_Z252p4f`)RDrpxa>#)kPMs# zP5{S%qred$1vm&C0Fr=28vp%BYzI~Xvd8O@CMQ+_QGvCn4F_Xkj>w9 zNY0n*=*TlelDsAZRDi~l#)&xU5e*52)-X>_)3{Sv(y4qZPs`3yuc-saIZw7xPNz7D zgdDC@NK+%SQK}#}NSy2#8KXvMUYvuJ8zr8`pNvz-40+imIeH49p}R!mPoX6*sWM42 zDp#b5_HSvL<%UMdA+kY}lqMzRQTo?16eTK04z9MqADY=TQz;VX*u5{Xd#2JOF6I-v#7)RQ4et_s6h4wNKN^uq^qHE0X58PIT}*6dDbA!jqqQz%hV~ zkr5i9e1Lra)fnZIjVAzI;S}80z$M@n@DfM`(t+au&HJaoN*a|HNE86ifoA|2Cxh~Q zB1yZfUmK+!8*;zu)JuvQ@w5P{0VPmm`$4-hGH$s4_>4mTyZet%s7rg0vXI7r0w@ny z0UAKwg3u1{2lR&D@#h=x6`+sRx&SQ!;sv}Bpbs(?0KJo-e5$krmGKRk!*{{CBE4xS z4rl;+hmuzh3A`+>B#!%zr%sBaJiYdBR1NN?a&d5EBa5l51Q&Of*+NwwkA^hvuBvBe zkGF~Vh&*~&P$Yc}q?o6o*VU-sECZ9kMywbYEx$E z{3oiEGRpog4sH(kj8{Cl1vxICOD6YRyt_YgoE=;ooY{GAm6Zyg&$6c7RaQ*Z5}MY* zg;i;(Dz8HVn@B%wqu@a2Wd#LI)?|NID^X3%5ly5SKDu%7&O^dyr4Rm@6NsG3$f-Q8qw?W|%h5k`#ABO~BOh|`vm;@xROPFP9a+n3 z&kA4u$E{gyObcr>b2F7Ao)c#2S**cu#kGw}*n#&7lEJ1jXp3 zY)}uCv$cHC(TU!UA57*YED)6aop7%W*UA8434Ha>?`_>(T`73k)YXNmYa@0y#xQxwP4s+|5 zv1z@~W%-noi1x#~4{SaK54`qwbim?>ea13owgM#|EMw1lsg?;Jm$9R$X)T|pwLGqR zijRKNThwrKz{tVp&muc&_IPuvy@RP=Si>Fgomur2tW-br zLq5%H?16V$qlRs^q6GTwfCZWxvX;*`b6aBnm+kRV>4I{Sqcpg3Q``EfT&x3D;o~a= zKRsrGS$W~|SOE(MB7#}cW)1rakA!Y(SUF#G@7!88$ye20@LtEx`hs`-n?3S{EAqi( zOaE$e;!;vCE4b3Yq5jVRS+Vy0F=ma{i{EY*o=fI;%=Tofr4`9h1L2Z<#MoBb zUh6(j|4|(^Fvirzrp+v6AVyU_eC%mSn+heS)Nn=#_&_B-Zegwgs(P$^fU2^9A#UQQ zsw2GKni%Y-@=^*0!*+KNTI6H?A7+U(@K$_6{G0%oks1Ezr8Il2s42`QD{J|5v)i^6 zN||_?31V-ZwCJuhGp*#A$uCAL>wmurxxxNt{BVg+a>k0(GtBBj+lm zn0h{cJL#BcUA%sm>}TguLijU*g@s^Y5rS163YB5Osz4zjfn5s5)gm85S5nw>Exhl> zT|ciDl&}lIEax_4$-0H8N|}f;f|JNhK?BzE@pLZtBeocg{um%A(M#%uB0Y({4neGB zGnxaeNhn-9lEnIig712e%_ki(jSp2tTmQ4$;^m9Qt?oY7Vgzb5-NnX^P_?&~kD-f5 zoIlx1u=Ns@_0cA6ZnvkfyHqmj2rCl?IrRwp9tJPv1MAK_H|o{2<`Gx&l6=Je`v99j zB_AJQy9{dZn$g0AV=Q_khU>;LY@D%T&UC2ODett2Qc!w2qEQU>W8`R%Zk96h~pjJbxZoL%1?mrnmWJ#o(v>v>xi3(9;jWc@$dS{05p zsrQM*jBr(TCCNtYCRkrfliJVmH`_KfYtX)*19>lv4IGV|n$;Qhbu{{j_8rF{ z8a2=0b91y->&uU%`&CLk7yE)+DD{P%MG1=Zq%rVZ(pz{n%fy#qs3D(YR@Q3epXG#1 zL>>#MlY<*Rg+d9sowI6<|GXaRSwZwdym@`eWF5xBW~nR|I2K;i$zm%=$HJcgy^MTj zTDKeHYSp!N8v<{#*w?Wt8=+4Ys}hCS2jcOeQn0-@cDG=r+#$%4NNp z$V;Ga_0O|;lVQvIJliz~vcq|HembP@dDdh+;w2x0_k8e!{P(lQw-;+-ZNsOV=f!VD zqWgEa+cm#)t)^m*6Kxv3@C7sl+=j-Z{$0BbLZ{ySP_E ziILn%E#8A?vu$M4Hk+NAfXhWZ9uNa#H9ajZrPt zz(%KR<}eZM%SR06lxGg5qK7=-CE%fa2%&dWvt@@;y-md&C%U3XXETf02!(uHp=bzyxrTcbxw`9Q?+e|K!_x8p2sPof|2@I*HIPJYNoD26qe zu=S|U!;F`}6qZh3MDJ=ow!OV@S+$=zB`&b`lVDvwudz(i2F*qtJ9mSZz;L=;V9_Yy zDxdUdR4OuQ&GMG=w8OB8KUQ0A1UK4x{vVv&L3TZZ!HG*pf6QZJElFe+QVeXfSD^-$bo_s#$ z%fwj=mL3pwm6 z8#q-}mZmNDS{QYe-CT^Un^#%CDHsCzh|LoBJ)X4F$MVTSw~+T&*+MGuFH;edrPwtV zJs0LN8({u63R8H)aJ3Xl*%O(UJSto)q%n~%H9oZqyCDr^Ikn5LYs~Mf@dfBVX3CKk z_}^bi;w+atbz(L;Wp|I=#Trx?F4e*yG>amIQ)x+!mvr@%Nk)WOEE7~jNFmCE?v51jj&=byU&^|hA~{-(wzP| zf#q29b%Q;cYtZ=50TbkyqTWsMl8jJz=+r}9;TKN>-8a}pbPBgw* z`sXSFA44&B|HCcmUv4y57x=(eMWg?IN0U1xPYrnrI~T@Yp2|F2(%L1@Ab!gfPZ^_c{TeFS2wq5{Wwqh5K(cy(}{1b za^=koE-!fz`h8~#?|#2}?~1d7#ocjQizDX}7kG8x-r;uh@4G#Iom$Js29N*n+CFu_ zM(n-Coi)}1>0-CCmJb+qSZZ7QNmD!81kr~o==;@t7P%M$*gu=aljQeIYxxM{iyPN= z>r|iNBPh9sbf;=Bw0Oe$W9wlpA9DQNcR|mm7g}EBt;2IU2J%Q5tnG$tJuAfu*BL8$ z5Cr+UD;#}m`55M&eU;XSZYNIt=@J_HA5YSs%dmXS$xZy`(tez{Y^kc#|BIg){r=NT z@sk7oX;R_mpZ}+y9XYc;D^wLb$v+SpvGknzq*?75!iRT@c+ahnPlc|($bVew$~Ab8 zl3swPi?CUj&y8+%v_BhPwr;psr@jL&*82tQ#0u3A*MF}opC$d&!_P0>xdVOlN1yiK z8nJxI2Cl?yvC2y}Zl$VynO{A#P|kXpczva6qf$tI&8DnYIhzcm2M_UDbB(2}Ry7mw zOu_fns{2ZvHbMGKY3`(6jrG+wgg1q52G4)2$Z~kGu)?d3JpV|*F56;f9=z<$^Kd~xXq20mjgw78 z(71pRL;g%0uuj!rb`5+nhxZhbL&x=Zq7RrIZ6-{x>F-RR#)?TVPiKrQbDE~E%p6qe z(w_K&h)OpJ9}yfpDy*I)?1zL01PqE8Z0{Ey;_C7*d1GB&SnPdOWp>^~ZOUwn)Mjjm zk=h!+Az#~9ZOiHztIOhNglanj!n}rT7?tbU|JoWzd-@ix(11CcuTmFd&(&&URPw`isrYhqf& zRWo+ov`A;n*dwQpSyU82WMHInd&G14-l_aeEG(|+9-!3H~LCQ;o}1=U5z)(MGRX;#W~6N0$Cn8 z2$>7n8<_(c)4fmM*l35NTTGv>!5{QxdKIk9QD-QYo2hp*E9i1mx_R(?uVxy_P8TI7H{sO%C=|#_p+&9_M zE29@c@6scx*L&1Ic8cj{{IDKTaltgwJ*ubKuH$Xxa1_Px6{HmSAT}nrXPm=PNLTP+ zw8K#X{yStoWFsn*0G>vdj;xwyInpyOcyLtjUXG~P?){=-as3_V7FvNxL&}Uw)^gt>Yr?ETmx&V>*Q4Ki z1ohrx%irrrsW-Yy7Y3qp9|76E@%cPP$Hl(s`6|TUTVlBqvD7N^J9-X^%%@7`>#)gM ze!k4I8=>`&kP?#jkzyYiV(Hz{v!i#=vUg1H=-{rM9j(#Dm8iJEeY(6C)BjaV_tnea zH2%^mYd)MrN?kiwTiuN5(<3@IrhiqXs){UpHVU-R|1Aw>iU?p-bCc zdd1L7ha+yDrN{M%?$wKl*cDyE*8(ZN6j^V|V#5MRNN4u*M>71ZjA74j@Rcc0%Q(N$ z_jZ9k+4Cn^)n!le9WM}4InM^mTeC;B)+MS-kLa%5;@WPtc)QYOTYZ%ahQ#04?r;>Q z?(sXU?Abf5-RBWfoGO@V@!k9O>nhIgO|b?bC%pJH5M5-qzOlj4G*wsIm(hILJ=Pq# zk1lgI8YzqHGkDfS{IHx5g&;2PwN~kP-SFal)?x|YZ#6JjH&_up5B7zTvQ6gF`7^PX zQ5s5lY2Xv=WfZ!hO9x-qGE(Q4MHZFSIt&M-rymmmbKliH$bo@){42Vw+V7EK7ZVp8 z8{Iv6&}nqBw}*cRx^$$^5sTlCq=&=S!ON7LjueL`AkFC@_VEy{NJx(wBW1XQk=~2AqyQEt^-iwr-JDbjb2PyiN z469s`vsR=&Jxlzhq7vsU&xRqT!2wzl>bU6s4hOP#R6phcy!7ZNDv+LELCO$x?c1e) zEE`rM8j=nLBPG9})@LwrWoYb;_UTR^Z#6g`0||YB%U0;$e9f9n{^-Krxn#+fSFDN} zA|(y8D!9lnzLG%r`$M8bNYsR!;DVj zd`U~Zp6QUaOp}zlVeX@7ulOE^MtBMlsygs4pR;zD(Q>>mX{pyU57Me{cN2{bR7!$%{Yyb~Rc8fb1`1AKfLO&oChQo_PK z6Vb%d&(w}+?Kx8m_{!l3&$N6QP0G1^DTMPwG~EK)W;BV3zgaGa&+-~S@vJeLM99zQ ztRCk11Wn4}CwV*2be(wptJVzZgS*Nk@_flPB0RlFNfhwEW|$`dO@=4C>Bo0yEzH`b zH#H_(L9}{00!`w@kdt>z=i$}M;r>$`j+U9l+M`u7H78EZK$B2r^Etg?o=a#F1T#QJ zVdbl{*6Zo79FBJ&4bz9CXi}Lq2TDz~qD?zQyER$^Gf#Y01_ zsflJzJ5Luh@!g7cDw_0?sMQQ}mzZuwrdEWzHK}ml(Ap86F{CVeY3Ez5S)*E>W%?4O ztycS?)yb@RDOwm>E*UxF$_(F-jb2Z^nbumNdrY5^XiYKk^EIdw<~fe`hN;OEuQ$u; ztjFhU8|H~a6HAA$L9;N=)_=>pi)M8pB|OaIo$YXRz|vZcGtgRPYPZo|wl#P4Idsey zSu?^NM~anLEyA;vR1GY$`5Fuk_eYVKT2;L~*Wq|QQ=5eLw5klWI_6>vnr98T75SlP z;u_kkVV;9%bQ zuqL({a%0f~-;iXlabtlmDcS3(@U>OW8jfCQG8}9tt-{=kMDrzwMYu1M zs^NR=jW7x<^gY_<_1xwJC0?>_8-@FG5`4uhB~#}Ut>JR3FwbeUM&voo#aNUxp{2=e z-hfu!%p1Nj%<~wnzNxW5jK~Dvqa9w)pai>HvKUsQ$?9cpGp{bA)v`2(yU-GAEn5w> zMyqXBmeME87`wzbB-QIqhNKs7M!26_%JlXPjg4?OCRJBP)blARtNoPe;r=MHGdO%Q zv7F27IVGG6p9p;&fCdKh_N|@&! zniX}%z$m@iH)Oxp(|fhOb+W{b^r|iSRTgW!28^U<_U7OG@*4 z4nXP%F*C}nw>8;$-$4@x7#o_Lsq<(A?R2K)@Q5&@_6A>_!(Pv%4R(NKFw@X#SYELk zIX2ppjshMpnl(%*qr?4Cw8L+O87nsWl8$(d>l=NKj(9y46YY-5RPU7N8*rt^SYaDqMYw>(+I=2$(MA@YaHC|>3bAS8o)0a@Y`a| zCFU8^rY4${W5;Dq^xfinbkggY4{5C=u0Y1+ExsYAyqf-BY;sBk(ov~=rVKgReGTKX)RxQl^CmL(=qq=^( zB_aDp94Twm#jj;(R#hp{VeT82RrLr@tv%L;NrOajDq35!Qi=CnwC1LUqwczUxq!=H zy2p@e?Te)JBU10!7M{2EWp#cl+8cIV?gsl!2b)E>KQvR6c5fin#H{Brsb;1vOWED{ zfVTAvCuMmp{%l9H{EHJMJ%LSQEH4fPg%XErG(_!J#aRANg*zi+fo}j~aEsT-7Gg`PgZ41ZZ_s4f zuydgmJwgDj(6k71$D=j#MTSLqE|6+z^0I7$k6I(l`Gj4o?@?c!YhKTK$huZh86h;Q zBAFnKj@gH9(Z-QZ5epj>{!MMz9kp%Ziw~=c3j14Q&?TIZsNvNIO+e z*wK|8@C!66a1yGsXpJn7Xs5(UE7s=m)YB8~4Kt4!^JB2jjvSU(yY)r*yhy!lj3+-9R)e?sE1&i`K&QMW#~446A#bF>iz!y)t}{ zZhAe3Af-+&>J7sE&t`^-5KcyGZZ4CMb27b$p0DdqLdHyD67DC8Ioif~t3y_(YW1F3McVh%X&$!KlOxp#|{wr?8dZg|n;mqd7Gkdi_5 zm}lubXf;iZBdbyFlJ8NZ*VE%tR&oX89j~YCWoy7W->eDuNAXgOqkF?JWASBQ(p}D7 zkaB|O_?sT)>2}4A2!0tmulR=C^BT`x^(Ec&dfHsIV$DQk*)B$_N;%FT?84t&^$q#S z>yG66X(QjzpCUZNNy)My_#8SD(WJYDd`?aXzhCnW`PpmK{bpU#&qD&@b2^woE{B7E zjwt@*K=wjDhm1v*MNUS_N2KsGv@X&>pM`WHXKVgHNwJ%w%gu9fD?vUa{>M@pT%hem zN`+r*xlqeRI$xyZFGfnaC0bvq^Ow4;_8m_NtH3gCAX1VmwJuUBT!oYh*JypM&KD{C zdd+XpyhuOz&05ct@!Bv+XJnPq&=$>$^q}w3x=6|2t#y&o@LsKpl>B{K&nksFsQGw1 zAyO(hge;4^i{zi5u+9yx2e1`68vkCtA-c#ZI~}5%A-W8|e{+TUlm8CS3uG z_**Fz6w>)wrSO58&nl&X;_%{737s!e^paY)B;zlM0%TOz8Cj(isG)h0(z!6C3`KpU zp^Img(v6<* zGJbt^zDTj}r*)Ci{6M7GeT0;(Vf=Bb6(ywA5>9`oOI;uxFIgic3pq*@Ekz%#b&&z+ zQ?;H|irqBLixho2Qe2&>`K(g%XK5Z8ZyL_g1?K6Dzmu}DE+$_pNYM66wf)~ov0J9? zmm~9|Z`b8gkRj-I{FvVor2E?N7o>bdN(H|nCI5HLXO)uwhvr3!os&P}Xf~we`)lbz z${fq7^#G)N0^&(X9eI($72=N+EUaaqmPL>f(qdWc3-4S6_H+W8bI7xnQ- zY2Qpp!(Ty&oNQ)TQuL|l;?PW;KS%2ev|Nl7M-q@S6f2RrkXw=bbENP`7UVvpG<*^% z^`#>XxxStyA)mjKQt>(RMV{C4f|eJN{BvC6k5u?QQXII26#LuAvdFxUqUV!LEybZC z=)HxI#9yUUSR7s=P)g@#l@iJ_@Y16Yq%`oNmQ}UANZ~`Z9-7!7r}Nc+&Qyei&p&6X zf6i1{&r&icM3)uw&zVZ1@$YA{f6i30=Vm=iNrXg~8S~GX>Yp>!KWD1{FV0kQru%<) zrqX9D?kwbfA{&9jk+`g!^T5RB3x`ZRzN~%5`nw^GS6wL`w(5%+{^<$z-v4^sPp*)6 zejf3t&H6!Q%8j^P`P~hH7e8zA&2KyQ?KwZ`qO)kF@m*I(%{viJWlmk`5_MybvyF49 zYOoivOidH9T-_6~LN(ooSgGcTSfw6{SgroGAF)O)5wTV|4mT{8`UJ)8K8z9a=z+JR{Mo`AVlzCi0x|dVGMVu zV{Am(>{mBL98e98BMz!*BGS}7 z5rTQuHoocPfQ%;rrH1f1l zbryNXsgjWD`X2l*e#ZH#k>ON5&%jLG3v)=Ab52z>9j3`X>2x~G1*bY7%mZP9Ghi+` z)sPIBg#9oVgt_8WmCwSoJpeQIEX*~hIxCF-L72#MFyA`WsBRg0q=%%c+`Ogc)=gn-v$ax#LuigsFH0 zro$zedqn0EOu8@umtlS;HkV;W9EC|1<`<%K1t$C$Oz$f&zY!l{t_xHAD$GOTa}{Rl zahOBG{7!tX!8ADmGxQqFW8x#s17U){f%%j8d;^nk66OMo)2S+b%fxAW3S#WH5H6J= zg#T%X$nPNBYUFnin}oO}L^f6Xdx#!qAZC3J;ZZk)2uz1~?K(sbHSIdYJ|P|p5ulph zfEbiPYQ+tR-0Gna70*I+xCxP0Ex8GiE=0f&5cyTRA0S4YgGd&lpz{0(5q=(`_m2>T z)n*~C3sL+QL=hEp3u5X8h(kgYQ$=n=G`R>d^fp9swO@z_LImG|D5(bDfk?OnaY2aE zs?uGEwwEEs-i0WuGKBEI0ugx+qP!Y;4`P!Lw}g0J)&2>h$5n_~KS5MdH-reh2Jza@ z5HF}{KSS&j;;|6Hs_A`*LEk{ExDWB7dMHH2Zy`GT0uic~`~s0KM8K~Q)m6J+Ax3-$ zkt{?_<@pUF{CkMrzd?kl%|cukqWA-d+A8J&#MJ8$hlGewMIJ&lxdAcsAw;CwFT?{O zf*(QDQ-dEtB;16!AVdRI>34{>KR}HA9ipMi5W@dQh{!)6URERjfY>C&Eg>4K+K(Z6 z+=7_(7^11VAw=M9h}WJ#ysD->f!HU+VkOFO!FbjA zugOacqJgRcoan7oJ14}5dl1P&ys10}MEFk-y$y&qYO@g6g(&WVXs2Ra5L17KI3z@S zRm2aX$$f~Seh?khejy$R5$uL|R}FSUB>Vz#L5L_-={bnDze0?C4x)?75W@dAh{$XZ z(Q0Hih)qJ=5~91R?GMr80mLkSh!}N4h`@&suX!NeQ`0;U`-FHbL~qqJJH((z5G%4n z^i>aqsQ5cXha3>^t0g%g(uD}f2@$8-<%AgV2SlV^=3eh{w}fEcZ&6@b_$ z#A6}Gs-^`Y2Du?t6oeSB9tu(MIfxF0ASS9Mg&@*}2q+BUQ|$^vjK~I&EW~8x34{pu zhv*#$q10v}t_xAT2*flMQv_nF2jY+rGgOhH5KXc}3@r*VOYIlpfe^vPAm*sS#UK)L zKwJ=Fo~jfC(KaW<*dT}nDnkhW0Eo!q5DV4F;t-pJxFy75Rl5X4k6aM5NV#+~GEdX&yh%Kr}d59(jA%>QRNLKrW zcpyY@1&Hlxa0Q5jLJ${(NKuuZhiF?EV(jw}J5`1d{(%sY6(M%3krg2}32{q^y{dL4 zh#o~CW>tdNuWkqtSQO&5$`A+Dw8{|sgm^5(A=UH+h(X05R=falL_HLuVh}`!D#okE zF+(k_VsOzFCLkE*grVLJh8a;DCRvzMhRPlS6J7$QcL>ZGLnR4wU6|r8!ekh#=Zi2? zOTruy=A4mOw5st*X_eN?sO#$&>ZdxrZTP!8kLE^pVrW<62bYl9d+PsEl4rUa*UmU= z<*TTM#`q~-!*5D^Bgj}aN0n%Abk3E3p7~qRF!^S?YML6?-Uu8Ga7VvAU z6nnvJ>Z5mPs^iz(TNQ4BRFzn@gVD(_(pIXD4ULz?Dxhav5A**MODsBXYUnpY|9jd<0oGkVTVJUOlAbvBA+@6)$yba3~<{XW^GW_LC! zxUQ(gUYw@LZAUWIeO_K7IT3mm|0@iIAv??TjPY`F}tC`^QAbmQPL$ z>1qsc)Az(hG4%6kT+9vzjHeuTQ-{sE#B<})l38UT`zdYyqeY1P2OkMl%PWa}dKo{B z$x-#Bs1C;@87#vU`SO!Lt&d5PC*KI<#)*6;X(!gAzje=+T=*k zTwb_BPV-wFKZ$Ene!?rM4VP+8eo`u9!?nkxz?zZJ^JZh#ZNWZ2rlNi;TUE{JpyT{cmd zEiSg2+pO*4OF*^(@=4NUNz&Q0;TB!E6kH$O<791D8tzrn^4W%z>@uJ)X^BP(QXDJ` z29lOfs^-d({>YGDX87#XWO>pA* zB*%OXM51w8b36m%7_57I22K`R7#IR)#{Ysg3)tFJx3xN@CP1{9pnHxf$W{RKyDzvfUf{6!78vCtO0AmIFdYmfKL+#!?*V!6 zXa`6E>(JK&dCH0Bd*aPsXqOPprC=FY4pxAh;770)tOFasMvw?Lfz2QZYyoq@JRrXo z`@ke1KP6896TwI@28;#cfIP}DA1v@|$oeC(5Xjyg1LRSYw%~2h9=rnrf$Yykf$Yga zpb#hk3aW(xuGfpoGeXY+*@tf$N``x2m|uqL@L+`c7r`&FGvH2z!7i; zq=O7UHng)O&VlpbBDe%DgKxoi;CuCXc2~*x!qmMTGzPLav_QU3b{vpxx&!D4-UYHn zmjtCi8Bi9K1LZ*l@I0spDuEY36%Y(Uz>A-?8I6vheAd<-rp z9`pq7fyy8k$OHBQ*)oTKD9{D80&jp8pa!T3YJuwN<$SI-P375+d>}tK0MfuAa2$-q zY#f*fz5Yo$I0I&4J{`;e zQ^82=Mj{`OSDqy-$Dq6*Kk1@Q)gr&EP_=FJekYJ$WqXp>3&??@4QK}ngDupv3M>FK z9cp%dSBcv4z)`Hu7n{)FdGkiU^18j6!-*u4CEppo4#!FQqOF-Vc>Hx0*HsN zN}9Ycz^7m?`Y4dVWrvTSqu&!lvB8&bdY<^4gOrV5E|7BJlq0uX_4flgI=lyZf*8;P ztfq?Y$On{NNjd);n~2iynC zf!NmscY)2{CM|h4fRy~=bitKV$m4*0JKn757|IcF2&91nU_TfLc7bi+ zT?&eWTR{iXTaZa$GuQ~k;gvv+UMrCD1!OI9Jy-|UfYo3X5MK1Pa=cC?QHDaBkUPM3 zkOES{POuy71AD+;a1c}nhk-aO>7zh+fgHpKpQm z>b=0ffSPbTi_;;iljmbr&%FV>ars!k&|dinIA#c2oZiqyo6Ok zD&dzAU5Dcn-7eHlD2~-3XKsitrlm=x$DNqs=2SFeJ0%&I^F@)uox-*RQXHE>M`eZpGyoFv zhDhO~fbh-0%fQa>M7lMQFCMRgSLAptMlv2vL1WMav;ePx=0Fz~!5*+1>;jvB>;?6yZaryPe(R8ODOm$nft6r|jQ?`bOC&~eo#_phfu(?N zpyoHzCCCJ@7z_dZ!5FXzd<_uAP)2c;>aB2Y%l=K0y9DUSNxd)hJ!D` zbTAE!15?3d-~$uE1TY?q2BW}8Famr5J_db&?eGVr#fiQ^91!Qk=>|BG#i@AH8@or6 zDTaff#v zp!uH;C2~4CitQ0_SjvDVwDAUb#Zk`6I01Pa90PJ37Xv9Yg~I$uakG@GTCp?e>EJAo z1eK<5Hv3{K_X@f6?`)Gn=zx&5#-)H4|@#y1KSj4?b`O@iTJYFIx5X z#=w!P{#aLFkp1SdZW;B~z8M_;t>Fw0sTm@-;1WivZDU;3g6tPc?P^!`x9np!jyIeg zL#Y{)3ZqoWOjn>$ZIqfl5vl8}WxxCC%7}CQ*R(j`Pl*~Kp;akjzpQFv;?A8hWkN?h zZEfHvH4cA_DWg=vSXbqsjeHMfxn#Z>&Gs*kbMGj1d#tOJQDL;oGfrByN(R|4#OhPx z=k2G`%hi5bw|BJaIL=i$yItqkqgBh}lx#3cEvJSc`<+}DOBczPJu;Vpzg0s*!}0g@ zXmxoUF|c1I6W9E`H#;@_8n5F{;UU*L0)u7!@RSd&j6JY2gzWs*tZ(Ou#N>;KD%M9g`6>3S&(%E0ek)w>N+mikoz(et!zsNC zWsY^8q+XhYU-tXorcSEA>*S`kfz(wqqJ;LDm?MFAK{^xbPFHeR%+#B*I{G9H1+Wm zy2tNsX;TPl+Vm;P6h%>$UFZ14nvvry3@&c%o;Ykvdw9o6eZoufw~4wrs(9ORm*3 z8#JR=SSCPyb^d@3hi#D^QI5cb)UHEU8xv_DSx;)EO$7nH61*n zNB4y)*F5Taf1#>4kFoq{p?U{BXaptrnQB;`T`P|4e5@XuORko9F?peyfJLqO+9Km@ ziyqhVRr=KQ(;VPcrSu2_F0=f`FaOPVX|LUmEfrePtyuUKbY_<%RxNoL5a zg@lTQ{c68r+X5nQ-Tye1vh4iQ?!HB;%6vTSxLB=3s*dwrEwnPsxV~6bUBH^P-}IN$ zSeqW(e$i?wrdp{Oi;ovD|8;R&swWFvMQe3jY;7AA%3S?=$D+v345u#Tu-^w*<7(Ve z_kah{l4H(I$L~v2i?4~8U17vhHS=ryySGGbgb(_h`{EMw>Tf2+oZJ;U)a;|_3bFQE z=o%K3tfTPyz{+!K9$WQ9JIlt`VWFD4khawW_}uFLth0+ZG}5DqZ*@YgEp~S@N}=ie1blz;C@ePoW_D6@6cZ zlx=x^Z+55QjAY}N;1^l1@+43l4pmOTA^T;2JGtdU4`kI#J))lZ`eU(7>pXVNR zKDxhm=-O^UW0p=foW)@HZJ5^#X4ds6ft_gdhQta>T;-g+S1_^pQdesuD0`AMku$pF zTK?(b&g-9!V*VtxbvakGW?NO;6?BKz#;m||`z3=FfB$pS)e`w`X@A(OX>A7<;`!MX zjK9`Z{gtjN<@#^qi#jgZFN`Y~IIBt_;}G#>+YAi}=XU;fHDM(U*l%{b)u4Ubny(k& zLe9i8F9waat6eMUu>G>Rf^QwVR;BE&j@oI~7@L2-Rjz79?bp?{J~yP|3qj#ri~4To z4hQY4)l-;-_G|5aOX%GEvy76%%o`^nXeygvMaJs zi`W)zbgNwN$L~-dua?UVmVvb1X!jqr>m7W5lxbnE$$R7!Bj@h0gDoppcsO0>P&Q|Z zN~5e%CPmHNj(j0y${MPQNHKq09(J_WkIohc3pRUNRZE?7_S2NWLWl3ka?xurIz_dh ztT8Y}t=@FTqSFZb*Nq6Vxn!5Rev0LhEPcX}ws(P)ZzJjT0 zrI>fx=ql`nFO{l-cFQD5wYIh1)3=tM7`2Vf%e?w>>8zWoZcE9=sp@hnvQ?@ovyMsA zg%aXY;OG0MZEL&anr@2#4o+45)?xWcs+zEcx+h>M+et=Y6_RgQw{M<$H9b{r6Uzj= zBh*3bu#~O4R`Ve*gv_}Uf+Z_cPFy=uRnGNTo=#PN;J@*Gs;ZA(>sLw?q(s6`gT8D# zt#qPUceN0HsI}ik*{}Xb%XY*^lfgZcUVG2E!F16DG@W6*U-%kA(d9SyfHX5u@xL^@Qx8&-QSCk&v7U z+Ht9?JnpPkmNT z%T0J=zhl%<`~HCWjYog@G{|<}7w=QEv8-jkmGoxRN_S-cMW>zy-F|Orj;j$jU-eB4 z&^_YPSaHAlk+Oz01;D6rj`BlyZKKWCis1@kU=n|b~RI< zxle7Ce7yl!BW5okJ*jIwyXW@nVB0Q#=cm%W-Z-hf4XyFlo#k&U{*SHNnVB1k_9m16 zc!#>X2iNV5#@={7+oL+M@jPpTAd-3sKC>o!H?&(|hpn2Nr6ntf1>LLw-Kd(9%;EH} z!L{qrv&x>}{61*gnswOC*d6F|M77-QDp-;w_}|U%Kx6+AH7@1Zy=B|8y=A`GE!opC zOCV$dX9gros7;c5h4Vpa-pwtGYX~6tdmdy|wo{-KIJ%WwQA47jrvymU%%p z!$jD3?4<$S#aeasEYFc~e{$Q6Io{WkjeXmGwQbNV!v|bXH%jXHPXMhIQc$*kdkJX& z^tPm4O3mWe(-FWSFu3QJPqvyJU8*uzhg!*)^F?vlNNtjL&qrM(*)`l4yr7bR(80FHX4?e2$ekPbMtxqt|+ME9C;l+-Bko|Jx z1|dd|Ufq8S(tV?ZeN3=Nz+S9+kq6nYQ+6C}x$AM`Yxd!Vc<;cVDCJM-s<-TWEinwDxgMFR&o{EzBSO_ET`myNftao2OzHc-jdy^B{Yd{l4aq zsiiC3Y*0pyLULuLZ=Q4N=s^Z&LaOphL+a~iko`vJ6N~1xZdqM%tH~~59YvbgvfmLs z_dxeNx03w$=5Dr1o%UO#pL7`C=7;02oY6UWZU;dRmc3y>o4cUaRi8uFj$xjd?WkMV zh%DnDv^U-Sxp7#V_RgR!7ZdsBZTo0f_+Mw^vkDO`+qor{i`lR zQfAHNi_7nq)RW`f3@&h4l{(?-R_pI9to`K0E7mFVhlr@C{nc8?9YDF)!wPD6MQuI7 zT5owpoj&1eUf{3o=W!-oNvw6!wa97Qxu!0ja#hQ2J~8It_m}yq=xNtWiJeZnE<596 zxV0hQ8%BTJww|x-!q_-;xjFOa%)=pfCKS0hT<33(US0aRgWud8t@E#4jvBYw+ilG> zbothP?M&;fExV2BwGcfI`ofZv-Jex@d0;~%i~_m&DR6&Eukx^K5C ziQCg%HAlMWlgj(MtF)SPz|WodLqES(?X%a{C0c%|nxy$vC|a~&`Mkr+wn`hZWzq4# Sfyb&0)A{SaRHM@TZvG!mK$?^Q diff --git a/client/package.json b/client/package.json index 38ac63f..10c7c8d 100644 --- a/client/package.json +++ b/client/package.json @@ -67,7 +67,7 @@ "tailwindcss": "^3.4.11", "typescript": "^5.6.2", "typescript-eslint": "^8.5.0", - "vite": "^5.4.5", + "vite": "^6.0.1", "vite-envs": "^4.4.5", "vite-plugin-glsl": "^1.3.0", "vite-plugin-top-level-await": "^1.4.4", diff --git a/contracts/.cursorrules b/contracts/.cursorrules new file mode 100644 index 0000000..484277f --- /dev/null +++ b/contracts/.cursorrules @@ -0,0 +1,73 @@ +You are an expert in Cairo, game development, ECS (Entity Component System), blockchain technology, Starknet, and the Dojo Framework. + +Key Principles + +- Write clear, concise, and idiomatic Cairo code with accurate examples. +- Use ECS paradigms effectively for game development. +- Prioritize modularity, clean code organization, and efficient resource management in Cairo and Dojo projects. +- Use expressive variable names that convey intent (e.g., `is_ready`, `has_data`). +- Adhere to Cairo's naming conventions: snake_case for variables and functions, PascalCase for types and structs. +- Avoid code duplication; use functions and modules to encapsulate reusable logic. +- Write code with safety, concurrency, and performance in mind, embracing Cairo's ownership and type system. + +Game Development with ECS + +- Implement ECS architecture using Dojo's components, systems, and world. +- Use Dojo's query system for efficient entity management and data access. +- Leverage Dojo's event system for game state changes and inter-system communication. +- Implement game loops and update cycles using Dojo's system execution order. +- Optimize performance by minimizing state changes and leveraging Dojo's batched updates. + +Smart Contract Development + +- Use Starknet-specific annotations and decorators for contract development. +- Implement storage variables and mappings using Starknet's storage model. +- Use events for logging important state changes in smart contracts. +- Implement view and external functions for contract interactions. +- Utilize Starknet's native types (e.g., felt252, ContractAddress) appropriately. + +Blockchain Integration + +- Implement cross-contract communication using contract calls and interfaces. +- Use Starknet's messaging system for L1-L2 communication. +- Implement account abstraction features for enhanced user experience. +- Utilize Starknet's cryptographic primitives for secure operations. + +Dojo Framework + +- Use Sozo for project scaffolding, building, and deployment. +- Leverage Katana for local development and testing of Starknet contracts. +- Utilize Torii for efficient indexing and querying of on-chain data. +- Implement and use actions for game state transitions. +- Use Dojo's authorization system for secure contract interactions. + +Testing and Deployment + +- Write unit tests for Cairo contracts using the `#[test]` attribute. +- Use Dojo's testing utilities for simulating game scenarios. +- Implement integration tests to validate contract interactions and game logic. +- Use Katana for local testing and Starknet's testnet for pre-production deployment. +- Leverage Sozo for managing contract migrations and upgrades. + +Performance Optimization + +- Minimize storage reads and writes in smart contracts. +- Use efficient data structures and algorithms for on-chain computations. +- Implement off-chain computations where possible, using on-chain verification. +- Optimize gas usage by batching transactions and using calldata efficiently. + Ï + Key Conventions + +1. Structure the application into modules: separate concerns like game logic, smart contracts, and off-chain components. +2. Use environment variables for configuration management in off-chain components. +3. Ensure code is well-documented with inline comments and Cairo-doc. + +Ecosystem + +- Use Cairo for smart contract development on Starknet. +- Leverage Scarb for package management and build processes. +- Use Dojo for game development on Starknet. +- Utilize Katana for local Starknet development environment. +- Implement off-chain components using languages like Rust or TypeScript for optimal performance. + +Refer to the Cairo Book, Starknet documentation, and Dojo documentation for in-depth information on best practices and advanced features.Ï diff --git a/contracts/Scarb.toml b/contracts/Scarb.toml index ec025de..7f1daab 100644 --- a/contracts/Scarb.toml +++ b/contracts/Scarb.toml @@ -26,5 +26,12 @@ build-external-contracts = [ [tool.fmt] sort-module-level-items = true +[profile.sepolia] + [scripts] -init = "./scripts/init.sh" +ready_for_deployment = "bash ./scripts/ready_for_deployment.sh" +initialize = "bash ./scripts/default_auth.sh" +upload_manifest = "bash ./scripts/upload_manifest.sh" +ready_for_deployment_zsh = "zsh ./scripts/ready_for_deployment.sh" +initialize_zsh = "zsh ./scripts/default_auth.sh" +upload_manifest_zsh = "zsh ./scripts/upload_manifest.sh" diff --git a/contracts/dojo_dev.toml b/contracts/dojo_dev.toml index 111dbdf..2c9aefc 100644 --- a/contracts/dojo_dev.toml +++ b/contracts/dojo_dev.toml @@ -9,6 +9,6 @@ mappings = {} [env] rpc_url = "http://localhost:5050/" -account_address = "0xb3ff441a68610b30fd5e2abbf3a1548eb6ba6f3559f2862bf2dc757e5828ca" -private_key = "0x2bbf4f9fd0bbb2e60b0316c1fe0b76cf7a4d0198bd493ced9b8df2a3a24d68a" -world_address = "0x263ae44e5414519a5c5a135cccaf3d9d7ee196d37e8de47a178da91f3de9b34" +account_address = "0x127fd5f1fe78a71f8bcd1fec63e3fe2f0486b6ecd5c86a0466c3a21fa5cfcec" +private_key = "0xc5b2fcab997346f3ea1c00b002ecf6f382c5f9c9659a3894eb783c5320f912" +world_address = "0x6f130c8e150882e39cbe878c650c8f35c86579180dbc77d0c1cbe169449b5f6" diff --git a/contracts/dojo_sepolia.toml b/contracts/dojo_sepolia.toml new file mode 100644 index 0000000..e595baf --- /dev/null +++ b/contracts/dojo_sepolia.toml @@ -0,0 +1,15 @@ +[world] +description = "Empty PixeLAW world" +name = "p_war" +seed = "pixelaw" + +[namespace] +default = "pixelaw" +mappings = {} + +[env] +rpc_url = "https://starknet-sepolia.public.blastapi.io/rpc/v0_7" +keystore_path = "accounts/sepolia.deployer.keystore.json" +world_address = "0x6f130c8e150882e39cbe878c650c8f35c86579180dbc77d0c1cbe169449b5f6" + +account_address = "YOUR_ACCOUNT" \ No newline at end of file diff --git a/contracts/scripts/account_from_key.sh b/contracts/scripts/account_from_key.sh new file mode 100755 index 0000000..79e9411 --- /dev/null +++ b/contracts/scripts/account_from_key.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -euo pipefail +pushd $(dirname "$0")/.. + +export DEFAULT_PROFILE=${1:-"sepolia"} + +# Prompt the user for the account address +echo -e "This tool creates a keystore file from a private key, which you could export from your browser-wallet like Braavos or ArgentX \n" +echo -n "Enter the profile [${DEFAULT_PROFILE}]:" +read PROFILE +PROFILE=${PROFILE:-$DEFAULT_PROFILE} + +starkli signer keystore from-key ./accounts/$PROFILE.deployer.keystore.json \ No newline at end of file diff --git a/contracts/scripts/build_sepolia.sh b/contracts/scripts/build_sepolia.sh new file mode 100755 index 0000000..d5422ca --- /dev/null +++ b/contracts/scripts/build_sepolia.sh @@ -0,0 +1,5 @@ +#!/bin/bash +set -euo pipefail +pushd $(dirname "$0")/.. + +sozo build --profile sepolia \ No newline at end of file diff --git a/contracts/scripts/deploy_sepolia.sh b/contracts/scripts/deploy_sepolia.sh new file mode 100755 index 0000000..fe4245d --- /dev/null +++ b/contracts/scripts/deploy_sepolia.sh @@ -0,0 +1,5 @@ +#!/bin/bash +set -euo pipefail +pushd $(dirname "$0")/.. + +sozo migrate --profile sepolia --wait \ No newline at end of file diff --git a/contracts/src/lib.cairo b/contracts/src/lib.cairo index b3c11a1..b54f7a2 100644 --- a/contracts/src/lib.cairo +++ b/contracts/src/lib.cairo @@ -20,10 +20,11 @@ mod models { #[cfg(test)] mod tests { - // mod test_add_color; + mod test_setup; + mod test_add_color; // // mod test_create_world; // mod test_extend_game_end; - mod test_guild; + // mod test_guild; // mod test_reset_to_white; mod utils; } diff --git a/contracts/src/tests/test_add_color.cairo b/contracts/src/tests/test_add_color.cairo index 6559385..0184b6d 100644 --- a/contracts/src/tests/test_add_color.cairo +++ b/contracts/src/tests/test_add_color.cairo @@ -1,6 +1,12 @@ +use p_war::tests::utils::{deploy_p_war}; +use dojo::model::{ModelStorage, ModelValueStorage}; +use dojo::world::{WorldStorage, WorldStorageTrait}; +use dojo::event::EventStorage; +use pixelaw_test_helpers::{setup_core_initialized}; +use starknet::{class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp}}; use p_war::{ models::{ - game::{Game, game}, board::{Board, GameId, Position, board, game_id}, proposal::{Proposal}, + game::{Game}, board::{Board, GameId, Position}, proposal::{Proposal}, allowed_app::AllowedApp, allowed_color::{AllowedColor, PaletteColors}, }, systems::{ @@ -10,11 +16,9 @@ use p_war::{ }, constants::{PROPOSAL_DURATION} }; - use pixelaw::core::{ models::{ - permissions::permissions, pixel::{pixel, Pixel, PixelUpdate}, queue::queue_item, - registry::{app, app_user, app_name, core_actions_address, instruction} + pixel::{Pixel, PixelUpdate}, }, actions::{ actions as core_actions, IActionsDispatcher as ICoreActionsDispatcher, @@ -22,22 +26,21 @@ use pixelaw::core::{ }, utils::{DefaultParameters, Position as PixelawPosition} }; -use starknet::{ - class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp}, -}; const COLOR: u32 = 0xAAAAAAFF; #[test] #[available_gas(999_999_999)] fn test_add_color() { + let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); + let (_world, p_war_actions, propose_action, voting_action, _guild, _allowed_app) = deploy_p_war(ref world); // caller let caller = starknet::contract_address_const::<0x0>(); - let (world, _, p_war_actions, propose_system, voting_system, _) = p_war::tests::utils::setup(); let default_params = DefaultParameters { - for_player: caller, - for_system: caller, + player_override: Option::None, + system_override: Option::None, + area_hint: Option::None, position: PixelawPosition { x: 0, y: 0 }, color: COLOR }; @@ -57,7 +60,7 @@ fn test_add_color() { // arg2: 0, // }; - let index = propose_system + let index = propose_action .create_proposal( game_id: id, proposal_type: 1, target_args_1: NEW_COLOR, target_args_2: 0, ); @@ -68,13 +71,13 @@ fn test_add_color() { // (Game) // ); - let oldest_color_pallette: PaletteColors = world.read_model(id, 0); + let oldest_color_pallette: PaletteColors = world.read_model((id, 0)); // let index = propose_system.toggle_allowed_color(id, NEW_COLOR); let vote_px = 3; - voting_system.vote(id, index, vote_px, true); + voting_action.vote(id, index, vote_px, true); - let proposal: Proposal = world.read_model(id, index); + let proposal: Proposal = world.read_model((id, index)); println!("\n## PROPOSAL INFO ##"); println!("Proposal end: {}", proposal.end); @@ -83,12 +86,13 @@ fn test_add_color() { set_block_timestamp( proposal.end + PROPOSAL_DURATION ); // NOTE: we need to set block timestamp forcely - propose_system.activate_proposal(id, index, array![default_params.position].into()); + propose_action.activate_proposal(id, index, array![default_params.position].into()); // call place_pixel let new_params = DefaultParameters { - for_player: caller, - for_system: caller, + player_override: Option::None, + system_override: Option::None, + area_hint: Option::None, position: PixelawPosition { x: 1, y: 1 }, color: NEW_COLOR }; @@ -96,7 +100,7 @@ fn test_add_color() { p_war_actions.interact(new_params); // check if the oldest color is unusable - let oldest_color_allowed: AllowedColor = world.read_model(id, oldest_color_pallette.color); + let oldest_color_allowed: AllowedColor = world.read_model((id, oldest_color_pallette.color)); println!( "@@@@@ OLDEST_ALLOWED: {}, {} @@@@", diff --git a/contracts/src/tests/test_setup.cairo b/contracts/src/tests/test_setup.cairo new file mode 100644 index 0000000..3b099d2 --- /dev/null +++ b/contracts/src/tests/test_setup.cairo @@ -0,0 +1,9 @@ +use p_war::tests::utils::{deploy_p_war}; +use dojo::world::WorldStorage; +use pixelaw_test_helpers::{setup_core_initialized}; + +#[test] +fn test_setup() { + let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); + let (_world, _p_war_actions, _propose, _voting, _guild, _allowed_app) = deploy_p_war(ref world); +} diff --git a/contracts/src/tests/utils.cairo b/contracts/src/tests/utils.cairo index cbf44c2..aa2ed24 100644 --- a/contracts/src/tests/utils.cairo +++ b/contracts/src/tests/utils.cairo @@ -1,140 +1,231 @@ // import test utils -use dojo::test_utils::{spawn_test_world, deploy_contract}; +use dojo_cairo_test::{ + spawn_test_world, NamespaceDef, TestResource, ContractDefTrait, ContractDef, + WorldStorageTestTrait +}; // import world dispatcher -use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; +use debug::PrintTrait; +use dojo::model::{ModelStorage}; +use dojo::world::{ + world, IWorldDispatcher, IWorldDispatcherTrait, WorldStorageTrait, WorldStorage +}; // import test utils use p_war::{ models::{ - player::{player}, game::{Game, game}, board::{Board, GameId, board, game_id, p_war_pixel}, - proposal::{Proposal, pixel_recovery_rate, proposal, player_vote}, guilds::{guild}, - allowed_app::{AllowedApp, allowed_app}, - allowed_color::{AllowedColor, allowed_color, palette_colors, in_palette, game_palette}, + player::{Player, m_Player}, game::{Game, m_Game}, board::{Board, m_Board, GameId, m_GameId, PWarPixel, m_PWarPixel}, + proposal::{Proposal, m_Proposal}, guilds::{Guild, m_Guild}, + allowed_app::{AllowedApp, m_AllowedApp}, + allowed_color::{AllowedColor, m_AllowedColor, PaletteColors, m_PaletteColors, InPalette, m_InPalette, GamePalette, m_GamePalette}, }, systems::{ actions::{p_war_actions, IActionsDispatcher, IActionsDispatcherTrait}, propose::{propose_actions, IProposeDispatcher, IProposeDispatcherTrait}, voting::{voting_actions, IVotingDispatcher, IVotingDispatcherTrait}, - guilds::{guild_actions, IGuildDispatcher, IGuildDispatcherTrait} + guilds::{guild_actions, IGuildDispatcher, IGuildDispatcherTrait}, + app::{allowed_app_actions, IAllowedAppDispatcher, IAllowedAppDispatcherTrait} } }; -use pixelaw::core::{ - models::{ - permissions::{permissions}, pixel::{pixel, Pixel, PixelUpdate}, queue::queue_item, - registry::{app, app_user, app_name, core_actions_address, instruction}, - }, - actions::{ - actions as core_actions, IActionsDispatcher as ICoreActionsDispatcher, - IActionsDispatcherTrait as ICoreActionsDispatcherTrait - }, - utils::{DefaultParameters, Position} +use pixelaw::core::utils::{ + get_core_actions, encode_rgba, decode_rgba, Direction, Position, DefaultParameters +}; +use pixelaw_test_helpers::{ + update_test_world, setup_core, setup_core_initialized, setup_apps, setup_apps_initialized, + ZERO_ADDRESS, set_caller, drop_all_events, TEST_POSITION, WHITE_COLOR, RED_COLOR }; -use starknet::{class_hash::Felt252TryIntoClassHash, ContractAddress}; -use dojo::model::Model; -use dojo::database::schema::{SchemaIntrospection, TypeTag}; - -pub fn setup() -> ( - IWorldDispatcher, - ICoreActionsDispatcher, - IActionsDispatcher, - IProposeDispatcher, - IVotingDispatcher, - IGuildDispatcher, - ContractAddress -) { - let mut models = array![ - allowed_app::TEST_CLASS_HASH, - allowed_color::TEST_CLASS_HASH, - board::TEST_CLASS_HASH, - game_id::TEST_CLASS_HASH, - game::TEST_CLASS_HASH, - game_palette::TEST_CLASS_HASH, - in_palette::TEST_CLASS_HASH, - palette_colors::TEST_CLASS_HASH, - player::TEST_CLASS_HASH, - player_vote::TEST_CLASS_HASH, - pixel_recovery_rate::TEST_CLASS_HASH, - pixel::TEST_CLASS_HASH, - p_war_pixel::TEST_CLASS_HASH, - proposal::TEST_CLASS_HASH, - app::TEST_CLASS_HASH, - app_name::TEST_CLASS_HASH, - app_user::TEST_CLASS_HASH, - core_actions_address::TEST_CLASS_HASH, - permissions::TEST_CLASS_HASH, - queue_item::TEST_CLASS_HASH, - instruction::TEST_CLASS_HASH, - guild::TEST_CLASS_HASH - ]; - - // deploy world with models - //let world = spawn_test_world(["pixelaw"].span(), models.into()); - let world = spawn_test_world(models); - - println!("world deployed"); - - let core_actions_address = world - .deploy_contract('salt', core_actions::TEST_CLASS_HASH.try_into().unwrap()); - - let core_actions = ICoreActionsDispatcher { contract_address: core_actions_address }; - - // deploy systems contract - let p_war_actions_address = world - .deploy_contract('salty', p_war_actions::TEST_CLASS_HASH.try_into().unwrap()); +use starknet::class_hash::Felt252TryIntoClassHash; + +use zeroable::Zeroable; + +pub fn deploy_p_war(ref world: WorldStorage) -> (WorldStorage, IActionsDispatcher, IProposeDispatcher, IVotingDispatcher, IGuildDispatcher, IAllowedAppDispatcher) { + let ndef = namespace_def(); + let cdefs = contract_defs(); + + update_test_world(ref world, [ndef].span()); + + world.sync_perms_and_inits(cdefs); + + let (p_war_actions, propose, voting, guild, allowed_app) = setup_pwar_apps_initialized(world); + + (world, p_war_actions, propose, voting, guild, allowed_app) +} + +pub fn namespace_def() -> NamespaceDef { + let ndef = NamespaceDef { + namespace: "pixelaw", resources: [ + TestResource::Model(m_Player::TEST_CLASS_HASH), + TestResource::Model(m_Game::TEST_CLASS_HASH), + TestResource::Model(m_Board::TEST_CLASS_HASH), + TestResource::Model(m_GameId::TEST_CLASS_HASH), + TestResource::Model(m_Guild::TEST_CLASS_HASH), + TestResource::Model(m_AllowedApp::TEST_CLASS_HASH), + TestResource::Model(m_AllowedColor::TEST_CLASS_HASH), + TestResource::Model(m_PaletteColors::TEST_CLASS_HASH), + TestResource::Model(m_InPalette::TEST_CLASS_HASH), + TestResource::Model(m_GamePalette::TEST_CLASS_HASH), + TestResource::Model(m_PWarPixel::TEST_CLASS_HASH), + TestResource::Model(m_Proposal::TEST_CLASS_HASH), + TestResource::Contract(p_war_actions::TEST_CLASS_HASH), + TestResource::Contract(propose_actions::TEST_CLASS_HASH), + TestResource::Contract(voting_actions::TEST_CLASS_HASH), + TestResource::Contract(guild_actions::TEST_CLASS_HASH), + TestResource::Contract(allowed_app_actions::TEST_CLASS_HASH), + ].span() + }; + + ndef +} + +pub fn contract_defs() -> Span { + let cdefs: Span = [ + ContractDefTrait::new(@"pixelaw", @"p_war_actions") + .with_writer_of([dojo::utils::bytearray_hash(@"pixelaw")].span()), + ContractDefTrait::new(@"pixelaw", @"propose_actions") + .with_writer_of([dojo::utils::bytearray_hash(@"pixelaw")].span()), + ContractDefTrait::new(@"pixelaw", @"voting_actions") + .with_writer_of([dojo::utils::bytearray_hash(@"pixelaw")].span()), + ContractDefTrait::new(@"pixelaw", @"guild_actions") + .with_writer_of([dojo::utils::bytearray_hash(@"pixelaw")].span()), + ContractDefTrait::new(@"pixelaw", @"allowed_app_actions") + .with_writer_of([dojo::utils::bytearray_hash(@"pixelaw")].span()), + ].span(); + cdefs +} + +pub fn setup_pwar_apps(world: WorldStorage) -> (IActionsDispatcher, IProposeDispatcher, IVotingDispatcher, IGuildDispatcher, IAllowedAppDispatcher) { + let (p_war_actions_address, _) = world.dns(@"p_war_actions").unwrap(); let p_war_actions = IActionsDispatcher { contract_address: p_war_actions_address }; - let propose_address = world - .deploy_contract('salty1', propose_actions::TEST_CLASS_HASH.try_into().unwrap()); - let propose = IProposeDispatcher { contract_address: propose_address }; - - let voting_address = world - .deploy_contract('salty2', voting_actions::TEST_CLASS_HASH.try_into().unwrap()); - let voting = IVotingDispatcher { contract_address: voting_address }; - - let guild_address = world - .deploy_contract('salty3', guild_actions::TEST_CLASS_HASH.try_into().unwrap()); - let guild = IGuildDispatcher { contract_address: guild_address }; - - let allowed_app_address = world - .deploy_contract('salty4', allowed_app_actions::TEST_CLASS_HASH.try_into().unwrap()); - let allowed_app = IAllowedAppDispatcher { contract_address: allowed_app_address }; - - println!("contracts deployed"); - - world.grant_writer(selector_from_tag!("pixelaw-App"), core_actions_address); - world.grant_writer(selector_from_tag!("pixelaw-AppName"), core_actions_address); - world.grant_writer(selector_from_tag!("pixelaw-CoreActionsAddress"), core_actions_address); - world.grant_writer(selector_from_tag!("pixelaw-Pixel"), core_actions_address); - - world.grant_writer(selector_from_tag!("pixelaw-Player"), p_war_actions_address); - world.grant_writer(selector_from_tag!("pixelaw-Game"), p_war_actions_address); - world.grant_writer(selector_from_tag!("pixelaw-Board"), p_war_actions_address); - world.grant_writer(selector_from_tag!("pixelaw-AllowedColor"), p_war_actions_address); - world.grant_writer(selector_from_tag!("pixelaw-PaletteColors"), p_war_actions_address); - world.grant_writer(selector_from_tag!("pixelaw-PixelRecoveryRate"), p_war_actions_address); - world.grant_writer(selector_from_tag!("pixelaw-InPalette"), p_war_actions_address); - world.grant_writer(selector_from_tag!("pixelaw-GamePalette"), p_war_actions_address); - world.grant_writer(selector_from_tag!("pixelaw-PWarPixel"), p_war_actions_address); - - world.grant_writer(selector_from_tag!("pixelaw-Player"), propose_address); - world.grant_writer(selector_from_tag!("pixelaw-Proposal"), propose_address); - world.grant_writer(selector_from_tag!("pixelaw-AllowedColor"), propose_address); - world.grant_writer(selector_from_tag!("pixelaw-GamePalette"), propose_address); - world.grant_writer(selector_from_tag!("pixelaw-InPalette"), propose_address); - world.grant_writer(selector_from_tag!("pixelaw-PaletteColors"), propose_address); - world.grant_writer(selector_from_tag!("pixelaw-Game"), propose_address); - - world.grant_writer(selector_from_tag!("pixelaw-Proposal"), voting_address); - world.grant_writer(selector_from_tag!("pixelaw-Player"), voting_address); - world.grant_writer(selector_from_tag!("pixelaw-PlayerVote"), voting_address); - - world.grant_writer(selector_from_tag!("pixelaw-Guild"), guild_address); - world.grant_writer(selector_from_tag!("pixelaw-Game"), guild_address); - world.grant_writer(selector_from_tag!("pixelaw-Player"), guild_address); - world.grant_writer(selector_from_tag!("pixelaw-AllowedApp"), allowed_app_address); - core_actions.init(); - - println!("grants done"); - - (world, core_actions, p_war_actions, propose, voting, guild, guild_address) + let (propose_address, _) = world.dns(@"propose_actions").unwrap(); + let propose_actions = IProposeDispatcher { contract_address: propose_address }; + + let (voting_address, _) = world.dns(@"voting_actions").unwrap(); + let voting_actions = IVotingDispatcher { contract_address: voting_address }; + + let (guild_address, _) = world.dns(@"guild_actions").unwrap(); + let guild_actions = IGuildDispatcher { contract_address: guild_address }; + + let (allowed_app_address, _) = world.dns(@"allowed_app_actions").unwrap(); + let allowed_app_actions = IAllowedAppDispatcher { contract_address: allowed_app_address }; + + (p_war_actions, propose_actions, voting_actions, guild_actions, allowed_app_actions) } + +pub fn setup_pwar_apps_initialized( + world: WorldStorage +) -> (IActionsDispatcher, IProposeDispatcher, IVotingDispatcher, IGuildDispatcher, IAllowedAppDispatcher) { + let (p_war_actions, propose_actions, voting_actions, guild_actions, allowed_app_actions): (IActionsDispatcher, IProposeDispatcher, IVotingDispatcher, IGuildDispatcher, IAllowedAppDispatcher) = setup_pwar_apps(world); + p_war_actions.init(); + // propose_actions.init(); + // voting_actions.init(); + // guild_actions.init(); + // allowed_app_actions.init(); + + (p_war_actions, propose_actions, voting_actions, guild_actions, allowed_app_actions) +} + +// pub fn setup() -> ( +// IWorldDispatcher, +// ICoreActionsDispatcher, +// IActionsDispatcher, +// IProposeDispatcher, +// IVotingDispatcher, +// IGuildDispatcher, +// ContractAddress +// ) { +// let mut models = array![ +// allowed_app::TEST_CLASS_HASH, +// allowed_color::TEST_CLASS_HASH, +// board::TEST_CLASS_HASH, +// game_id::TEST_CLASS_HASH, +// game::TEST_CLASS_HASH, +// game_palette::TEST_CLASS_HASH, +// in_palette::TEST_CLASS_HASH, +// palette_colors::TEST_CLASS_HASH, +// player::TEST_CLASS_HASH, +// player_vote::TEST_CLASS_HASH, +// pixel_recovery_rate::TEST_CLASS_HASH, +// pixel::TEST_CLASS_HASH, +// p_war_pixel::TEST_CLASS_HASH, +// proposal::TEST_CLASS_HASH, +// app::TEST_CLASS_HASH, +// app_name::TEST_CLASS_HASH, +// app_user::TEST_CLASS_HASH, +// core_actions_address::TEST_CLASS_HASH, +// permissions::TEST_CLASS_HASH, +// queue_item::TEST_CLASS_HASH, +// instruction::TEST_CLASS_HASH, +// guild::TEST_CLASS_HASH +// ]; + +// // deploy world with models +// //let world = spawn_test_world(["pixelaw"].span(), models.into()); +// let world = spawn_test_world(models); + +// println!("world deployed"); + +// let core_actions_address = world +// .deploy_contract('salt', core_actions::TEST_CLASS_HASH.try_into().unwrap()); + +// let core_actions = ICoreActionsDispatcher { contract_address: core_actions_address }; + +// // deploy systems contract +// let p_war_actions_address = world +// .deploy_contract('salty', p_war_actions::TEST_CLASS_HASH.try_into().unwrap()); +// let p_war_actions = IActionsDispatcher { contract_address: p_war_actions_address }; + +// let propose_address = world +// .deploy_contract('salty1', propose_actions::TEST_CLASS_HASH.try_into().unwrap()); +// let propose = IProposeDispatcher { contract_address: propose_address }; + +// let voting_address = world +// .deploy_contract('salty2', voting_actions::TEST_CLASS_HASH.try_into().unwrap()); +// let voting = IVotingDispatcher { contract_address: voting_address }; + +// let guild_address = world +// .deploy_contract('salty3', guild_actions::TEST_CLASS_HASH.try_into().unwrap()); +// let guild = IGuildDispatcher { contract_address: guild_address }; + +// let allowed_app_address = world +// .deploy_contract('salty4', allowed_app_actions::TEST_CLASS_HASH.try_into().unwrap()); +// let allowed_app = IAllowedAppDispatcher { contract_address: allowed_app_address }; + +// println!("contracts deployed"); + +// world.grant_writer(selector_from_tag!("pixelaw-App"), core_actions_address); +// world.grant_writer(selector_from_tag!("pixelaw-AppName"), core_actions_address); +// world.grant_writer(selector_from_tag!("pixelaw-CoreActionsAddress"), core_actions_address); +// world.grant_writer(selector_from_tag!("pixelaw-Pixel"), core_actions_address); + +// world.grant_writer(selector_from_tag!("pixelaw-Player"), p_war_actions_address); +// world.grant_writer(selector_from_tag!("pixelaw-Game"), p_war_actions_address); +// world.grant_writer(selector_from_tag!("pixelaw-Board"), p_war_actions_address); +// world.grant_writer(selector_from_tag!("pixelaw-AllowedColor"), p_war_actions_address); +// world.grant_writer(selector_from_tag!("pixelaw-PaletteColors"), p_war_actions_address); +// world.grant_writer(selector_from_tag!("pixelaw-PixelRecoveryRate"), p_war_actions_address); +// world.grant_writer(selector_from_tag!("pixelaw-InPalette"), p_war_actions_address); +// world.grant_writer(selector_from_tag!("pixelaw-GamePalette"), p_war_actions_address); +// world.grant_writer(selector_from_tag!("pixelaw-PWarPixel"), p_war_actions_address); + +// world.grant_writer(selector_from_tag!("pixelaw-Player"), propose_address); +// world.grant_writer(selector_from_tag!("pixelaw-Proposal"), propose_address); +// world.grant_writer(selector_from_tag!("pixelaw-AllowedColor"), propose_address); +// world.grant_writer(selector_from_tag!("pixelaw-GamePalette"), propose_address); +// world.grant_writer(selector_from_tag!("pixelaw-InPalette"), propose_address); +// world.grant_writer(selector_from_tag!("pixelaw-PaletteColors"), propose_address); +// world.grant_writer(selector_from_tag!("pixelaw-Game"), propose_address); + +// world.grant_writer(selector_from_tag!("pixelaw-Proposal"), voting_address); +// world.grant_writer(selector_from_tag!("pixelaw-Player"), voting_address); +// world.grant_writer(selector_from_tag!("pixelaw-PlayerVote"), voting_address); + +// world.grant_writer(selector_from_tag!("pixelaw-Guild"), guild_address); +// world.grant_writer(selector_from_tag!("pixelaw-Game"), guild_address); +// world.grant_writer(selector_from_tag!("pixelaw-Player"), guild_address); +// world.grant_writer(selector_from_tag!("pixelaw-AllowedApp"), allowed_app_address); +// core_actions.init(); + +// println!("grants done"); + +// (world, core_actions, p_war_actions, propose, voting, guild, guild_address) +// } \ No newline at end of file diff --git a/contracts/src/tests_old/test_add_color.cairo b/contracts/src/tests_old/test_add_color.cairo new file mode 100644 index 0000000..6559385 --- /dev/null +++ b/contracts/src/tests_old/test_add_color.cairo @@ -0,0 +1,108 @@ +use p_war::{ + models::{ + game::{Game, game}, board::{Board, GameId, Position, board, game_id}, proposal::{Proposal}, + allowed_app::AllowedApp, allowed_color::{AllowedColor, PaletteColors}, + }, + systems::{ + actions::{p_war_actions, IActionsDispatcher, IActionsDispatcherTrait}, + propose::{propose_actions, IProposeDispatcher, IProposeDispatcherTrait}, + voting::{voting_actions, IVotingDispatcher, IVotingDispatcherTrait} + }, + constants::{PROPOSAL_DURATION} +}; + +use pixelaw::core::{ + models::{ + permissions::permissions, pixel::{pixel, Pixel, PixelUpdate}, queue::queue_item, + registry::{app, app_user, app_name, core_actions_address, instruction} + }, + actions::{ + actions as core_actions, IActionsDispatcher as ICoreActionsDispatcher, + IActionsDispatcherTrait as ICoreActionsDispatcherTrait + }, + utils::{DefaultParameters, Position as PixelawPosition} +}; +use starknet::{ + class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp}, +}; + +const COLOR: u32 = 0xAAAAAAFF; + +#[test] +#[available_gas(999_999_999)] +fn test_add_color() { + // caller + let caller = starknet::contract_address_const::<0x0>(); + let (world, _, p_war_actions, propose_system, voting_system, _) = p_war::tests::utils::setup(); + + let default_params = DefaultParameters { + for_player: caller, + for_system: caller, + position: PixelawPosition { x: 0, y: 0 }, + color: COLOR + }; + + // create a game + p_war_actions.interact(default_params); + + let id = p_war_actions + .get_game_id(Position { x: default_params.position.x, y: default_params.position.y }); + println!("id = {}", id); + + let NEW_COLOR: u32 = 0xAABBCCFF; + + // let args = Args{ + // address: starknet::contract_address_const::<0x0>(), + // arg1: NEW_COLOR.into(), + // arg2: 0, + // }; + + let index = propose_system + .create_proposal( + game_id: id, proposal_type: 1, target_args_1: NEW_COLOR, target_args_2: 0, + ); + + // let game = get!( + // world, + // (id), + // (Game) + // ); + + let oldest_color_pallette: PaletteColors = world.read_model(id, 0); + + // let index = propose_system.toggle_allowed_color(id, NEW_COLOR); + let vote_px = 3; + voting_system.vote(id, index, vote_px, true); + + let proposal: Proposal = world.read_model(id, index); + + println!("\n## PROPOSAL INFO ##"); + println!("Proposal end: {}", proposal.end); + + // should add cheat code to spend time + set_block_timestamp( + proposal.end + PROPOSAL_DURATION + ); // NOTE: we need to set block timestamp forcely + propose_system.activate_proposal(id, index, array![default_params.position].into()); + + // call place_pixel + let new_params = DefaultParameters { + for_player: caller, + for_system: caller, + position: PixelawPosition { x: 1, y: 1 }, + color: NEW_COLOR + }; + + p_war_actions.interact(new_params); + + // check if the oldest color is unusable + let oldest_color_allowed: AllowedColor = world.read_model(id, oldest_color_pallette.color); + + println!( + "@@@@@ OLDEST_ALLOWED: {}, {} @@@@", + oldest_color_pallette.color, + oldest_color_allowed.is_allowed + ); + + assert(oldest_color_allowed.is_allowed == false, 'the oldest became unusable'); +} diff --git a/contracts/src/tests/test_create_world.cairo b/contracts/src/tests_old/test_create_world.cairo similarity index 100% rename from contracts/src/tests/test_create_world.cairo rename to contracts/src/tests_old/test_create_world.cairo diff --git a/contracts/src/tests/test_expand_area.cairo b/contracts/src/tests_old/test_expand_area.cairo similarity index 100% rename from contracts/src/tests/test_expand_area.cairo rename to contracts/src/tests_old/test_expand_area.cairo diff --git a/contracts/src/tests/test_extend_game_end.cairo b/contracts/src/tests_old/test_extend_game_end.cairo similarity index 100% rename from contracts/src/tests/test_extend_game_end.cairo rename to contracts/src/tests_old/test_extend_game_end.cairo diff --git a/contracts/src/tests/test_guild.cairo b/contracts/src/tests_old/test_guild.cairo similarity index 100% rename from contracts/src/tests/test_guild.cairo rename to contracts/src/tests_old/test_guild.cairo diff --git a/contracts/src/tests/test_reset_to_white.cairo b/contracts/src/tests_old/test_reset_to_white.cairo similarity index 100% rename from contracts/src/tests/test_reset_to_white.cairo rename to contracts/src/tests_old/test_reset_to_white.cairo From 28793266e8534451b66f98eb7764e35f9b44a31c Mon Sep 17 00:00:00 2001 From: OwnerOfJK Date: Mon, 2 Dec 2024 17:42:41 +0800 Subject: [PATCH 09/18] almost all tests are passing --- contracts/src/lib.cairo | 10 +- contracts/src/systems/actions.cairo | 78 +++++-- contracts/src/systems/app.cairo | 45 ++-- contracts/src/systems/guilds.cairo | 6 +- contracts/src/systems/propose.cairo | 17 +- contracts/src/tests/test_add_color.cairo | 17 +- contracts/src/tests/test_expand_area.cairo | 74 ++++++ .../src/tests/test_extend_game_end.cairo | 76 ++++++ contracts/src/tests/test_game_created.cairo | 56 +++++ contracts/src/tests/test_guild.cairo | 220 ++++++++++++++++++ contracts/src/tests/test_px_count.cairo | 69 ++++++ contracts/src/tests/test_reset_to_white.cairo | 134 +++++++++++ contracts/src/tests/utils.cairo | 36 ++- contracts/src/tests_old/test_add_color.cairo | 108 --------- .../src/tests_old/test_create_world.cairo | 54 ----- .../src/tests_old/test_expand_area.cairo | 61 ----- .../src/tests_old/test_extend_game_end.cairo | 79 ------- contracts/src/tests_old/test_guild.cairo | 209 ----------------- .../src/tests_old/test_reset_to_white.cairo | 143 ------------ 19 files changed, 780 insertions(+), 712 deletions(-) create mode 100644 contracts/src/tests/test_expand_area.cairo create mode 100644 contracts/src/tests/test_extend_game_end.cairo create mode 100644 contracts/src/tests/test_game_created.cairo create mode 100644 contracts/src/tests/test_guild.cairo create mode 100644 contracts/src/tests/test_px_count.cairo create mode 100644 contracts/src/tests/test_reset_to_white.cairo delete mode 100644 contracts/src/tests_old/test_add_color.cairo delete mode 100644 contracts/src/tests_old/test_create_world.cairo delete mode 100644 contracts/src/tests_old/test_expand_area.cairo delete mode 100644 contracts/src/tests_old/test_extend_game_end.cairo delete mode 100644 contracts/src/tests_old/test_guild.cairo delete mode 100644 contracts/src/tests_old/test_reset_to_white.cairo diff --git a/contracts/src/lib.cairo b/contracts/src/lib.cairo index b54f7a2..08cbef5 100644 --- a/contracts/src/lib.cairo +++ b/contracts/src/lib.cairo @@ -20,11 +20,13 @@ mod models { #[cfg(test)] mod tests { - mod test_setup; - mod test_add_color; - // // mod test_create_world; + // mod test_setup; + // mod test_game_created; + // mod test_add_color; + // mod test_px_count; + // mod test_expand_area; // mod test_extend_game_end; - // mod test_guild; + mod test_guild; // mod test_reset_to_white; mod utils; } diff --git a/contracts/src/systems/actions.cairo b/contracts/src/systems/actions.cairo index c15524a..68f4b0d 100644 --- a/contracts/src/systems/actions.cairo +++ b/contracts/src/systems/actions.cairo @@ -12,7 +12,7 @@ pub trait IActions { fn init(ref self: T); fn interact(ref self: T, default_params: DefaultParameters); fn create_game(ref self: T, origin: Position) -> usize; - fn create_game_guilds(ref self: T, game_id: usize, guild_address: ContractAddress) -> Array; + fn create_game_guilds(ref self: T, game_id: usize, guild_dispatcher: IGuildDispatcher) -> Array; fn get_game_id(self: @T, position: Position) -> usize; fn place_pixel( ref self: T, app: ContractAddress, default_params: DefaultParameters @@ -53,26 +53,23 @@ mod p_war_actions { get_callers, get_core_actions, Direction, Position, DefaultParameters }; use p_war::systems::app::{IAllowedApp, IAllowedAppDispatcher, IAllowedAppDispatcherTrait}; + use dojo::world::{IWorldDispatcherTrait}; - #[event] - #[derive(Drop, starknet::Event)] - enum Event { - StartedGame: StartedGame, - EndedGame: EndedGame - } - - #[derive(Drop, Serde, starknet::Event)] - struct StartedGame { + #[derive(Copy, Drop, Serde)] + #[dojo::event] + pub struct StartedGame { + #[key] id: usize, timestamp: u128, creator: ContractAddress } - #[derive(Drop, Serde, starknet::Event)] - struct EndedGame { + #[derive(Copy, Drop, Serde)] + #[dojo::event] + pub struct EndedGame { + #[key] id: usize, timestamp: u128, - // should we emit here the states of the pixel as well? } #[abi(embed_v0)] @@ -85,7 +82,9 @@ mod p_war_actions { fn interact(ref self: ContractState, default_params: DefaultParameters) { let position = Position { x: default_params.position.x, y: default_params.position.y }; + println!("position x{}, y{}.", default_params.position.x, default_params.position.y); let game_id = self.get_game_id(position); + println!("game id: {}", game_id); if game_id == 0 { self.create_game(position); } else if game_id == OUT_OF_BOUNDS_GAME_ID { @@ -99,10 +98,17 @@ mod p_war_actions { fn get_game_id(self: @ContractState, position: Position) -> usize { let mut world = self.world(@"pixelaw"); + let mut id = world.dispatcher.uuid(); + if id == 0 { + return 0; + } + // set id as GAME_ID=1 - // let board = get!(world, (GAME_ID), (Board)); this is the pre-dojo 1.0.0 implementation let board: Board = world.read_model(GAME_ID); + println!("board origin x{}, y{}.", board.origin.x, board.origin.y); + println!("board width{}, height{}.", board.width, board.height); + println!("position x{}, y{}.", position.x, position.y); if position.x < board.origin.x || position.x >= board.origin.x + (board.width.try_into().unwrap()) || position.y < board.origin.y || position.y >= board.origin.y + (board.height.try_into().unwrap()) { @@ -208,9 +214,9 @@ mod p_war_actions { } // initialize guilds for the game - fn create_game_guilds(ref self: ContractState, game_id: usize, guild_address: ContractAddress) -> Array { + fn create_game_guilds(ref self: ContractState, game_id: usize, guild_dispatcher: IGuildDispatcher) -> Array { //let guild_address = get!(world, game_id, GuildContractAddress).address; - let guild_dispatcher = IGuildDispatcher { contract_address: guild_address }; + // let guild_dispatcher = IGuildDispatcher { contract_address: guild_address }; let mut guild_ids = ArrayTrait::new(); guild_ids.append(guild_dispatcher.create_guild(game_id, 'Fire')); guild_ids.append(guild_dispatcher.create_guild(game_id, 'Water')); @@ -224,9 +230,12 @@ mod p_war_actions { ref self: ContractState, app: ContractAddress, default_params: DefaultParameters ) { let mut world = self.world(@"pixelaw"); + let core_actions = get_core_actions(ref world); //new + let system = get_contract_address(); //new let position = Position { x: default_params.position.x, y: default_params.position.y }; let game_id = self.get_game_id(position); assert(game_id != 0, 'this game does not exist'); + println!("color: {}", default_params.color); let allowed_color: AllowedColor = world.read_model((game_id, default_params.color)); assert( @@ -236,13 +245,14 @@ mod p_war_actions { let allowed_app: AllowedApp = world.read_model((game_id, app)); assert(app.is_zero() || allowed_app.is_allowed, 'app is not allowed'); - let contract_address = if app.is_zero() { - get_contract_address() - } else { - app - }; + // let contract_address = if app.is_zero() { + // get_contract_address() + // } else { + // app + // }; - let app = IAllowedAppDispatcher { contract_address }; + //let app = IAllowedAppDispatcher { contract_address }; old + // println!("app: {}", app); let player_address = get_tx_info().unbox().account_contract_address; @@ -262,9 +272,27 @@ mod p_war_actions { assert(player.is_banned == false, 'you are banned'); // check if the game is ongoing - assert(check_game_status(game.status()), 'game is not ongoing'); - - app.set_pixel(default_params); + assert(check_game_status(game.status()), 'game is not ongoing: actions1'); + + println!("set_pixel BEGIN"); + core_actions.update_pixel( //new + player_address, + system, + PixelUpdate { + x: default_params.position.x, + y: default_params.position.y, + color: Option::Some(default_params.color), + timestamp: Option::None, + text: Option::None, + app: Option::None, + owner: Option::None, + action: Option::None + }, + Option::None, + false + ); + // app.set_pixel(default_params); old + println!("set_pixel END"); player.num_owns += 1; player.num_commit += game.base_cost; diff --git a/contracts/src/systems/app.cairo b/contracts/src/systems/app.cairo index bec70ca..8be12cc 100644 --- a/contracts/src/systems/app.cairo +++ b/contracts/src/systems/app.cairo @@ -9,31 +9,46 @@ trait IAllowedApp { fn set_pixel(ref self: TContractState, default_params: DefaultParameters); } +// ... existing code ... + #[dojo::contract(namespace: "pixelaw", nomapping: true)] mod allowed_app_actions { use super::IAllowedApp; use pixelaw::core::utils::DefaultParameters; use pixelaw::core::models::pixel::PixelUpdate; use starknet::{ContractAddress, get_contract_address}; - use super::super::actions::{IActionsDispatcher, IActionsDispatcherTrait}; // Add this import + use pixelaw::core::actions::{ + IActionsDispatcher as ICoreActionsDispatcher, + IActionsDispatcherTrait as ICoreActionsDispatcherTrait + }; + use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; + use pixelaw::core::utils::get_core_actions; #[abi(embed_v0)] impl AllowedAppImpl of IAllowedApp { fn set_pixel(ref self: ContractState, default_params: DefaultParameters) { - let actions = IActionsDispatcher { contract_address: get_contract_address() }; - actions - .update_pixel( - PixelUpdate { - x: default_params.position.x, - y: default_params.position.y, - color: Option::Some(default_params.color), - timestamp: Option::None, - text: Option::None, - app: Option::None, - owner: Option::None, - action: Option::None - } - ); + // Instead of calling back to actions, call core_actions directly + let mut world = self.world(@"pixelaw"); + let core_actions = get_core_actions(ref world); + let player = starknet::get_tx_info().unbox().account_contract_address; + let system = get_contract_address(); + + core_actions.update_pixel( + player, + system, + PixelUpdate { + x: default_params.position.x, + y: default_params.position.y, + color: Option::Some(default_params.color), + timestamp: Option::None, + text: Option::None, + app: Option::None, + owner: Option::None, + action: Option::None + }, + Option::None, + false + ); } } } \ No newline at end of file diff --git a/contracts/src/systems/guilds.cairo b/contracts/src/systems/guilds.cairo index e0316a4..ee1845d 100644 --- a/contracts/src/systems/guilds.cairo +++ b/contracts/src/systems/guilds.cairo @@ -36,7 +36,7 @@ mod guild_actions { #[derive(Copy, Drop, Serde)] #[dojo::event] - struct GuildCreated { + pub struct GuildCreated { #[key] game_id: usize, guild_id: usize, @@ -46,7 +46,7 @@ mod guild_actions { #[derive(Copy, Drop, Serde)] #[dojo::event] - struct MemberAdded { + pub struct MemberAdded { #[key] game_id: usize, guild_id: usize, @@ -55,7 +55,7 @@ mod guild_actions { #[derive(Copy, Drop, Serde)] #[dojo::event] - struct MemberRemoved { + pub struct MemberRemoved { #[key] game_id: usize, guild_id: usize, diff --git a/contracts/src/systems/propose.cairo b/contracts/src/systems/propose.cairo index 0edeac4..bb4e49c 100644 --- a/contracts/src/systems/propose.cairo +++ b/contracts/src/systems/propose.cairo @@ -47,7 +47,7 @@ mod propose_actions { #[derive(Copy, Drop, Serde)] #[dojo::event] - struct ProposalCreated { + pub struct ProposalCreated { #[key] game_id: usize, index: usize, @@ -58,7 +58,7 @@ mod propose_actions { #[derive(Copy, Drop, Serde)] #[dojo::event] - struct ProposalActivated { + pub struct ProposalActivated { #[key] game_id: usize, index: usize, @@ -80,7 +80,8 @@ mod propose_actions { let mut world = self.world(@"pixelaw"); // get models let mut game: Game = world.read_model(game_id); - assert(check_game_status(game.status()), 'game is not ongoing'); + // println!("game status: {}", game.status()); + assert(check_game_status(game.status()), 'game is not ongoing: propose1'); let player_address = get_tx_info().unbox().account_contract_address; // recover px @@ -148,7 +149,7 @@ mod propose_actions { assert(proposal.yes_px >= NEEDED_YES_PX, 'did not reach minimum yes_px'); assert(proposal.yes_px > proposal.no_px, 'yes_px is not more than no_px'); assert(proposal.is_activated == false, 'this is already activated'); - assert(check_game_status(game.status()), 'game is not ongoing'); + assert(check_game_status(game.status()), 'game is not ongoing: propose2'); // activate the proposal. if proposal.proposal_type == 1 { @@ -228,8 +229,9 @@ mod propose_actions { loop { let mut palette_color: PaletteColors = world.read_model((game_id, idx)); + let prev_color: PaletteColors = world.read_model((game_id, idx)); palette_color.idx = idx - 1; - palette_color.color = palette_color.color; + palette_color.color = prev_color.color; world.write_model(@palette_color); idx = idx + 1; @@ -238,6 +240,11 @@ mod propose_actions { }; }; + // Set the new color in the last position + let mut last_palette_color: PaletteColors = world.read_model((game_id, 8)); + last_palette_color.color = new_color; + world.write_model(@last_palette_color); + let mut old_in_pallet: InPalette = world.read_model((game_id, oldest_color.color)); old_in_pallet.value = false; world.write_model(@old_in_pallet); diff --git a/contracts/src/tests/test_add_color.cairo b/contracts/src/tests/test_add_color.cairo index 0184b6d..e903c79 100644 --- a/contracts/src/tests/test_add_color.cairo +++ b/contracts/src/tests/test_add_color.cairo @@ -1,4 +1,4 @@ -use p_war::tests::utils::{deploy_p_war}; +use p_war::tests::utils::{deploy_p_war, print_all_colors}; use dojo::model::{ModelStorage, ModelValueStorage}; use dojo::world::{WorldStorage, WorldStorageTrait}; use dojo::event::EventStorage; @@ -31,11 +31,10 @@ const COLOR: u32 = 0xAAAAAAFF; #[test] #[available_gas(999_999_999)] + fn test_add_color() { let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); let (_world, p_war_actions, propose_action, voting_action, _guild, _allowed_app) = deploy_p_war(ref world); - // caller - let caller = starknet::contract_address_const::<0x0>(); let default_params = DefaultParameters { player_override: Option::None, @@ -108,5 +107,17 @@ fn test_add_color() { oldest_color_allowed.is_allowed ); + let newest_color: PaletteColors = world.read_model((id, 8)); + let newest_color_allowed: AllowedColor = world.read_model((id, newest_color.color)); + + println!( + "@@@@@ NEWEST_ALLOWED: {}, {} @@@@", + newest_color.color, + newest_color_allowed.is_allowed + ); + assert(oldest_color_allowed.is_allowed == false, 'the oldest became unusable'); + //print_all_colors(ref world, id); + assert(newest_color.color == NEW_COLOR, 'newest_color is the new color'); + assert(newest_color_allowed.is_allowed == true, 'the newest is usable'); } diff --git a/contracts/src/tests/test_expand_area.cairo b/contracts/src/tests/test_expand_area.cairo new file mode 100644 index 0000000..bf07819 --- /dev/null +++ b/contracts/src/tests/test_expand_area.cairo @@ -0,0 +1,74 @@ +use p_war::tests::utils::{deploy_p_war}; +use dojo::model::{ModelStorage, ModelValueStorage}; +use dojo::world::{WorldStorage, WorldStorageTrait}; +use dojo::event::EventStorage; +use pixelaw_test_helpers::{setup_core_initialized}; +use starknet::{class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp}, get_tx_info}; +use p_war::{ + models::{ + game::{Game}, board::{Board, GameId, Position}, proposal::{Proposal}, + player::{Player}, + allowed_app::AllowedApp, allowed_color::{AllowedColor, PaletteColors}, + }, + systems::{ + actions::{p_war_actions, IActionsDispatcher, IActionsDispatcherTrait}, + propose::{propose_actions, IProposeDispatcher, IProposeDispatcherTrait}, + voting::{voting_actions, IVotingDispatcher, IVotingDispatcherTrait} + }, + constants::{DEFAULT_AREA, PROPOSAL_DURATION} +}; +use pixelaw::core::{ + models::{ + pixel::{Pixel, PixelUpdate}, + }, + actions::{ + actions as core_actions, IActionsDispatcher as ICoreActionsDispatcher, + IActionsDispatcherTrait as ICoreActionsDispatcherTrait + }, + utils::{DefaultParameters, Position as PixelawPosition} +}; + +const COLOR: u32 = 0x000000ff; + +#[test] +#[available_gas(999_999_999)] +fn test_expand_area() { + let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); + let (_world, p_war_actions, propose_action, voting_action, _guild, _allowed_app) = deploy_p_war(ref world); + + let default_params = DefaultParameters { + player_override: Option::None, + system_override: Option::None, + area_hint: Option::None, + position: PixelawPosition { x: 0, y: 0 }, + color: COLOR + }; + + // create a game + p_war_actions.interact(default_params); + + let id = p_war_actions + .get_game_id(Position { x: default_params.position.x, y: default_params.position.y }); + print!("id = {}", id); + + let index = propose_action + .create_proposal(game_id: id, proposal_type: 4, target_args_1: 20, target_args_2: 30,); + + // let index = propose_system.toggle_allowed_color(id, NEW_COLOR); + let vote_px = 3; + voting_action.vote(id, index, vote_px, true); + + let proposal: Proposal = world.read_model((id, index)); + + print!("\n## PROPOSAL INFO ##\n"); + print!("Proposal end: {}\n", proposal.end); + + // should add cheat code to spend time + set_block_timestamp(proposal.end + PROPOSAL_DURATION); + propose_action.activate_proposal(id, index, array![default_params.position].into()); + + let board: Board = world.read_model(id); + + assert(board.width == DEFAULT_AREA + 20, 'game area extended'); + assert(board.height == DEFAULT_AREA + 30, 'game area extended'); +} diff --git a/contracts/src/tests/test_extend_game_end.cairo b/contracts/src/tests/test_extend_game_end.cairo new file mode 100644 index 0000000..f2e65e8 --- /dev/null +++ b/contracts/src/tests/test_extend_game_end.cairo @@ -0,0 +1,76 @@ +use p_war::tests::utils::{deploy_p_war, print_all_colors}; +use dojo::model::{ModelStorage, ModelValueStorage}; +use dojo::world::{WorldStorage, WorldStorageTrait}; +use dojo::event::EventStorage; +use pixelaw_test_helpers::{setup_core_initialized}; +use starknet::{class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp}}; +use p_war::{ + models::{ + game::{Game}, board::{Board, GameId, Position}, proposal::{Proposal}, + allowed_app::AllowedApp, allowed_color::{AllowedColor, PaletteColors}, + }, + systems::{ + actions::{p_war_actions, IActionsDispatcher, IActionsDispatcherTrait}, + propose::{propose_actions, IProposeDispatcher, IProposeDispatcherTrait}, + voting::{voting_actions, IVotingDispatcher, IVotingDispatcherTrait} + }, + constants::{GAME_DURATION} +}; +use pixelaw::core::{ + models::{ + pixel::{Pixel, PixelUpdate}, + }, + actions::{ + actions as core_actions, IActionsDispatcher as ICoreActionsDispatcher, + IActionsDispatcherTrait as ICoreActionsDispatcherTrait + }, + utils::{DefaultParameters, Position as PixelawPosition} +}; + +const COLOR: u32 = 0xAAAAAAFF; + +#[test] +#[available_gas(999_999_999)] +fn test_extend_game_end() { + let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); + let (_world, p_war_actions, propose_action, voting_action, _guild, _allowed_app) = deploy_p_war(ref world); + + let default_params = DefaultParameters { + player_override: Option::None, + system_override: Option::None, + area_hint: Option::None, + position: PixelawPosition { x: 0, y: 0 }, + color: COLOR + }; + + // create a game + p_war_actions.interact(default_params); + + let id = p_war_actions + .get_game_id(Position { x: default_params.position.x, y: default_params.position.y }); + println!("id = {}", id); + + let index = propose_action + .create_proposal( + game_id: id, + proposal_type: 3, + target_args_1: 60 * 60, // extend the game for 1 hour + target_args_2: 0, + ); + + let vote_px = 3; + voting_action.vote(id, index, vote_px, true); + + let proposal: Proposal = world.read_model((id, index)); + + println!("## PROPOSAL INFO ##"); + println!("Proposal end: {}", proposal.end); + + // should add cheat code to spend time + set_block_timestamp(proposal.end + 1); // NOTE: we need to set block timestamp forcely + propose_action.activate_proposal(id, index, array![default_params.position].into()); + + let game: Game = world.read_model(id); + + assert(game.end > GAME_DURATION + 60 * 60 - 1, 'game end extended'); +} diff --git a/contracts/src/tests/test_game_created.cairo b/contracts/src/tests/test_game_created.cairo new file mode 100644 index 0000000..67ae275 --- /dev/null +++ b/contracts/src/tests/test_game_created.cairo @@ -0,0 +1,56 @@ +use p_war::tests::utils::{deploy_p_war}; +use dojo::model::{ModelStorage, ModelValueStorage}; +use dojo::world::{WorldStorage, WorldStorageTrait}; +use dojo::event::EventStorage; +use pixelaw_test_helpers::{setup_core_initialized}; +use starknet::{class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp}}; +use p_war::{ + models::{ + game::{Game}, board::{Board, GameId, Position}, proposal::{Proposal}, + allowed_app::AllowedApp, allowed_color::{AllowedColor, PaletteColors}, + }, + systems::{ + actions::{p_war_actions, IActionsDispatcher, IActionsDispatcherTrait}, + propose::{propose_actions, IProposeDispatcher, IProposeDispatcherTrait}, + voting::{voting_actions, IVotingDispatcher, IVotingDispatcherTrait} + }, + constants::{PROPOSAL_DURATION} +}; +use pixelaw::core::{ + models::{ + pixel::{Pixel, PixelUpdate}, + }, + actions::{ + actions as core_actions, IActionsDispatcher as ICoreActionsDispatcher, + IActionsDispatcherTrait as ICoreActionsDispatcherTrait + }, + utils::{DefaultParameters, Position as PixelawPosition} +}; + +const COLOR: u32 = 0x000000ff; + +#[test] +#[available_gas(999_999_999)] +fn test_game_created() { + let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); + let (_world, p_war_actions, _propose_action, _voting_action, _guild, _allowed_app) = deploy_p_war(ref world); + // caller + let _caller = starknet::contract_address_const::<0x0>(); + + let default_params = DefaultParameters { + player_override: Option::None, + system_override: Option::None, + area_hint: Option::None, + position: PixelawPosition { x: 0, y: 0 }, + color: COLOR + }; + + // create a game + p_war_actions.interact(default_params); + + let id = p_war_actions + .get_game_id(Position { x: default_params.position.x, y: default_params.position.y }); + println!("id = {}", id); + + assert(id == 1, 'game not created'); +} diff --git a/contracts/src/tests/test_guild.cairo b/contracts/src/tests/test_guild.cairo new file mode 100644 index 0000000..dd7399d --- /dev/null +++ b/contracts/src/tests/test_guild.cairo @@ -0,0 +1,220 @@ +use p_war::tests::utils::{deploy_p_war, print_all_colors}; +use dojo::model::{ModelStorage, ModelValueStorage}; +use dojo::world::{WorldStorage, WorldStorageTrait}; +use dojo::event::EventStorage; +use pixelaw_test_helpers::{setup_core_initialized}; +use starknet::{class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp, set_account_contract_address}, get_block_timestamp}; +use p_war::{ + models::{ + game::{Game}, board::{Board, GameId, Position}, proposal::{Proposal}, + guilds::{Guild}, + allowed_app::AllowedApp, allowed_color::{AllowedColor, PaletteColors}, + }, + systems::{ + actions::{p_war_actions, IActionsDispatcher, IActionsDispatcherTrait}, + propose::{propose_actions, IProposeDispatcher, IProposeDispatcherTrait}, + voting::{voting_actions, IVotingDispatcher, IVotingDispatcherTrait}, + guilds::{guild_actions, IGuildDispatcher, IGuildDispatcherTrait} + }, + constants::{GAME_DURATION, PROPOSAL_DURATION} +}; +use pixelaw::core::{ + models::{ + pixel::{Pixel, PixelUpdate}, + }, + actions::{ + actions as core_actions, IActionsDispatcher as ICoreActionsDispatcher, + IActionsDispatcherTrait as ICoreActionsDispatcherTrait + }, + utils::{DefaultParameters, Position as PixelawPosition, is_pixel_color} +}; + +const WHITE_COLOR: u32 = 0xFFFFFFFF; +const RED_COLOR: u32 = 0xFF000000; +const GAME_ORIGIN_POSITION: Position = Position { x: 0, y: 0 }; +const GAME_PAINT_POSITION: Position = Position { x: 1, y: 1 }; +const GAME_PAINT_POSITION_2: Position = Position { x: 2, y: 2 }; +#[test] +#[available_gas(999_999_999)] +fn test_guild_operations() { + println!("start test"); + + // Initialize the world and the actions + let (mut world, _core_actions, player_1, player_2) = setup_core_initialized(); + let (_world, p_war_actions, _propose_action, _voting_action, guild_actions, _allowed_app) = deploy_p_war(ref world); + + println!("setup"); + + // Setup players + // let PLAYER_1 = contract_address_const::<0x1337>(); + // let PLAYER_2 = contract_address_const::<0x42>(); + // let PLAYER_3 = contract_address_const::<0x43>(); + + println!("setup players"); + + // Impersonate player1 + // set_account_contract_address(PLAYER_1); + + println!("impersonate player1"); + + // Create a game + p_war_actions + .interact( + DefaultParameters { + player_override: Option::None, + system_override: Option::None, + area_hint: Option::None, + position: GAME_ORIGIN_POSITION, + color: WHITE_COLOR + } + ); + + let game_id = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); + println!("game created: game_id = {}", game_id); + + //was not able to import set_call from core::helpers + set_account_contract_address(player_1); + let guild_id = guild_actions.create_guild(game_id, 'Test Guild'); + println!("guild created: guild_id = {}", guild_id); + + // Check if the guild was created + let guild: Guild = world.read_model((game_id, guild_id)); + assert(guild.guild_name == 'Test Guild', 'Guild name mismatch'); + assert(guild.creator == player_1, 'Guild creator mismatch'); + assert(guild.member_count == 1, 'create, should be 1'); + + println!("check guild passed"); + + // Add a member + set_account_contract_address(player_2); + guild_actions.add_member(game_id, guild_id, player_2); + + // Check if the member was added + let updated_guild: Guild = world.read_model((game_id, guild_id)); + assert(updated_guild.member_count == 2, 'Member count should be 2'); + + // Remove a member + guild_actions.remove_member(game_id, guild_id, player_2); + + // Check if the member was removed + let final_guild: Guild = world.read_model((game_id, guild_id)); + assert(final_guild.member_count == 1, 'remove, should be 1'); + + println!("guild operations passed"); +} + +// #[test] +// #[available_gas(999_999_999)] +// #[should_panic(expected: 'Guild points mismatch')] +// fn test_guild_points() { + +// // Initialize the world and the actions +// let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); +// let (_world, p_war_actions, _propose_action, _voting_action, guild_actions, _allowed_app) = deploy_p_war(ref world); +// println!("setup"); + +// // let ZERO_ADDRESS: ContractAddress = contract_address_const::<0>(); +// // let PLAYER_1 = contract_address_const::<0x1337>(); +// // set_account_contract_address(PLAYER_1); +// // set_contract_address(PLAYER_1); +// p_war_actions +// .interact( +// DefaultParameters { +// player_override: Option::None, +// system_override: Option::None, +// area_hint: Option::None, +// position: GAME_ORIGIN_POSITION, +// color: WHITE_COLOR +// } +// ); +// let game_id = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); +// println!("game created: game_id = {}", game_id); + +// //was not able to import set_call from core::helpers +// // set_account_contract_address(PLAYER_1); +// // set_contract_address(PLAYER_1); +// let guild_id = guild_actions.create_guild(game_id, 'Test Guild'); +// println!("guild created: guild_id = {}", guild_id); +// //place a pixel +// p_war_actions +// .interact( +// DefaultParameters { +// player_override: Option::None, +// system_override: Option::None, +// area_hint: Option::None, +// position: GAME_PAINT_POSITION, +// color: WHITE_COLOR +// } +// ); +// p_war_actions +// .interact( +// DefaultParameters { +// player_override: Option::None, +// system_override: Option::None, +// area_hint: Option::None, +// position: GAME_PAINT_POSITION_2, +// color: WHITE_COLOR +// } +// ); +// let guild_points = guild_actions.get_guild_points(game_id, guild_id); +// println!("test: guild_points: {}", guild_points); +// assert(guild_points == 1, 'Guild points mismatch'); +// } + +// #[test] +// #[available_gas(999_999_999)] +// fn test_guild_creation() { +// // Initialize the world and the actions +// let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); +// let (_world, p_war_actions, _propose_action, _voting_action, guild_actions, _allowed_app) = deploy_p_war(ref world); + +// // Setup players +// // let PLAYER_1 = contract_address_const::<0x1337>(); +// // let ZERO_ADDRESS: ContractAddress = contract_address_const::<0>(); + +// // // Impersonate player1 +// // set_account_contract_address(PLAYER_1); + +// // Create a game +// p_war_actions +// .interact( +// DefaultParameters { +// player_override: Option::None, +// system_override: Option::None, +// area_hint: Option::None, +// position: GAME_ORIGIN_POSITION, +// color: WHITE_COLOR +// } +// ); + +// let game_id: u32 = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); + +// //p_war_actions.set_guild_contract_address(game_id, guild_contract_address); + +// // set_account_contract_address(PLAYER_1); +// // set_contract_address(PLAYER_1); +// // Create guilds for the game +// let guild_ids: Array = p_war_actions.create_game_guilds(game_id, guild_actions); + +// // Create a guild +// let guild_id: u32 = *guild_ids.at(0); +// println!("guild_id: {}", guild_id); +// let guild: Guild = world.read_model((game_id, guild_id)); +// assert(guild.guild_name == 'Fire', 'Guild name mismatch'); + +// let guild_id_2 = *guild_ids.at(1); +// println!("guild_id_2: {}", guild_id_2); +// let guild: Guild = world.read_model((game_id, guild_id_2)); +// assert(guild.guild_name == 'Water', 'Guild name mismatch'); + +// let guild_id_3 = *guild_ids.at(2); +// println!("guild_id_3: {}", guild_id_3); +// let guild: Guild = world.read_model((game_id, guild_id_3)); +// assert(guild.guild_name == 'Earth', 'Guild name mismatch'); + +// let guild_id_4 = *guild_ids.at(3); +// println!("guild_id_4: {}", guild_id_4); +// let guild: Guild = world.read_model((game_id, guild_id_4)); +// assert(guild.guild_name == 'Air', 'Guild name mismatch'); +// println!("Guild creation tests passed successfully"); +// } diff --git a/contracts/src/tests/test_px_count.cairo b/contracts/src/tests/test_px_count.cairo new file mode 100644 index 0000000..af44848 --- /dev/null +++ b/contracts/src/tests/test_px_count.cairo @@ -0,0 +1,69 @@ +use p_war::tests::utils::{deploy_p_war}; +use dojo::model::{ModelStorage, ModelValueStorage}; +use dojo::world::{WorldStorage, WorldStorageTrait}; +use dojo::event::EventStorage; +use pixelaw_test_helpers::{setup_core_initialized}; +use starknet::{class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp}, get_tx_info}; +use p_war::{ + models::{ + game::{Game}, board::{Board, GameId, Position}, proposal::{Proposal}, + player::{Player}, + allowed_app::AllowedApp, allowed_color::{AllowedColor, PaletteColors}, + }, + systems::{ + actions::{p_war_actions, IActionsDispatcher, IActionsDispatcherTrait}, + propose::{propose_actions, IProposeDispatcher, IProposeDispatcherTrait}, + voting::{voting_actions, IVotingDispatcher, IVotingDispatcherTrait} + }, + constants::{PROPOSAL_DURATION} +}; +use pixelaw::core::{ + models::{ + pixel::{Pixel, PixelUpdate}, + }, + actions::{ + actions as core_actions, IActionsDispatcher as ICoreActionsDispatcher, + IActionsDispatcherTrait as ICoreActionsDispatcherTrait + }, + utils::{DefaultParameters, Position as PixelawPosition} +}; + +const COLOR: u32 = 0x000000ff; + +#[test] +#[available_gas(999_999_999)] +fn test_game_created() { + let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); + let (_world, p_war_actions, _propose_action, _voting_action, _guild, _allowed_app) = deploy_p_war(ref world); + + let default_params = DefaultParameters { + player_override: Option::None, + system_override: Option::None, + area_hint: Option::None, + position: PixelawPosition { x: 0, y: 0 }, + color: COLOR + }; + + // create a game + p_war_actions.interact(default_params); + + let id = p_war_actions + .get_game_id(Position { x: default_params.position.x, y: default_params.position.y }); + println!("id = {}", id); + + assert(id == 1, 'game not created'); + + let new_params = DefaultParameters { + player_override: Option::None, + system_override: Option::None, + area_hint: Option::None, + position: PixelawPosition { x: 1, y: 1 }, + color: COLOR + }; + p_war_actions.interact(new_params); + + let player_address = get_tx_info().unbox().account_contract_address; + let player: Player = world.read_model(player_address); + + assert(player.current_px == 9, 'current px should be 9'); +} \ No newline at end of file diff --git a/contracts/src/tests/test_reset_to_white.cairo b/contracts/src/tests/test_reset_to_white.cairo new file mode 100644 index 0000000..8af42cd --- /dev/null +++ b/contracts/src/tests/test_reset_to_white.cairo @@ -0,0 +1,134 @@ +use p_war::tests::utils::{deploy_p_war, print_all_colors}; +use dojo::model::{ModelStorage, ModelValueStorage}; +use dojo::world::{WorldStorage, WorldStorageTrait}; +use dojo::event::EventStorage; +use pixelaw_test_helpers::{setup_core_initialized}; +use starknet::{class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp}, get_block_timestamp}; +use p_war::{ + models::{ + game::{Game}, board::{Board, GameId, Position}, proposal::{Proposal}, + allowed_app::AllowedApp, allowed_color::{AllowedColor, PaletteColors}, + }, + systems::{ + actions::{p_war_actions, IActionsDispatcher, IActionsDispatcherTrait}, + propose::{propose_actions, IProposeDispatcher, IProposeDispatcherTrait}, + voting::{voting_actions, IVotingDispatcher, IVotingDispatcherTrait} + }, + constants::{GAME_DURATION, PROPOSAL_DURATION} +}; +use pixelaw::core::{ + models::{ + pixel::{Pixel, PixelUpdate}, + }, + actions::{ + actions as core_actions, IActionsDispatcher as ICoreActionsDispatcher, + IActionsDispatcherTrait as ICoreActionsDispatcherTrait + }, + utils::{DefaultParameters, Position as PixelawPosition, is_pixel_color} +}; + + +const WHITE_COLOR: u32 = 0xFFFFFFFF; +const RED_COLOR: u32 = 0xFF0000FF; + +const GAME_ORIGIN_POSITION: Position = Position { x: 0, y: 0 }; +const GAME_PAINT_POSITION: Position = Position { x: 1, y: 1 }; + + +// Proposal type 2 +const PROPOSAL_TYPE_RESET_TO_WHITE_BY_COLOR: u8 = 2; + +const VOTE_PIXEL_COUNT: u32 = 3; + +#[test] +#[available_gas(999_999_999)] +fn test_reset_to_white() { + let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); + let (_world, p_war_actions, propose_action, voting_action, _guild, _allowed_app) = deploy_p_war(ref world); + + // Create a game. + // This creates a 10x10 grid to the bottom-right of the start_position + p_war_actions + .interact( + DefaultParameters { + player_override: Option::None, + system_override: Option::None, + area_hint: Option::None, + position: GAME_ORIGIN_POSITION, + color: WHITE_COLOR + } + ); + + // paint a color inside of the grid + p_war_actions + .interact( + DefaultParameters { + player_override: Option::None, // Leave this 0 if not processing the Queue + system_override: Option::None, // Leave this 0 if not processing the Queue + area_hint: Option::None, + position: GAME_PAINT_POSITION, + color: RED_COLOR + } + ); + + let game_id = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); + + print!("game_id = {}", game_id); + + let proposal_id = propose_action + .create_proposal( + game_id, + proposal_type: PROPOSAL_TYPE_RESET_TO_WHITE_BY_COLOR, + target_args_1: RED_COLOR, + target_args_2: 0 + ); + + // let index = propose_system.toggle_allowed_color(id, NEW_COLOR); + + voting_action.vote(game_id, proposal_id, VOTE_PIXEL_COUNT, true); + + let proposal: Proposal = world.read_model((game_id, proposal_id)); + + print!("proposal.end: {}\n", proposal.end); + + // Fast-forward blocktime by 60 seconds + set_block_timestamp(get_block_timestamp() + PROPOSAL_DURATION); + + // Activate the proposal + propose_action.activate_proposal(game_id, proposal_id, array![GAME_PAINT_POSITION].into()); + + // Retrieve the pixel that was reset + assert( + is_pixel_color(ref world, GAME_PAINT_POSITION, WHITE_COLOR), 'Pixel should be entirely white' + ); + + // Now try to paint on it again + p_war_actions + .interact( + DefaultParameters { + player_override: Option::None, // Leave this 0 if not processing the Queue + system_override: Option::None, // Leave this 0 if not processing the Queue + area_hint: Option::None, + position: GAME_PAINT_POSITION, + color: RED_COLOR + } + ); + + assert(is_pixel_color(ref world, GAME_PAINT_POSITION, RED_COLOR), 'Pixel should be entirely red'); + + // Now try to paint on it again + p_war_actions + .interact( + DefaultParameters { + player_override: Option::None, // Leave this 0 if not processing the Queue + system_override: Option::None, // Leave this 0 if not processing the Queue + area_hint: Option::None, + position: GAME_PAINT_POSITION, + color: WHITE_COLOR + } + ); + + assert( + is_pixel_color(ref world, GAME_PAINT_POSITION, WHITE_COLOR), 'Pixel should be entirely white' + ); +} diff --git a/contracts/src/tests/utils.cairo b/contracts/src/tests/utils.cairo index aa2ed24..63e1f4d 100644 --- a/contracts/src/tests/utils.cairo +++ b/contracts/src/tests/utils.cairo @@ -12,8 +12,11 @@ use dojo::world::{ // import test utils use p_war::{ models::{ - player::{Player, m_Player}, game::{Game, m_Game}, board::{Board, m_Board, GameId, m_GameId, PWarPixel, m_PWarPixel}, - proposal::{Proposal, m_Proposal}, guilds::{Guild, m_Guild}, + player::{Player, m_Player}, + game::{Game, m_Game}, + board::{Board, m_Board, GameId, m_GameId, PWarPixel, m_PWarPixel}, + proposal::{Proposal, m_Proposal, PixelRecoveryRate, m_PixelRecoveryRate, PlayerVote, m_PlayerVote}, + guilds::{Guild, m_Guild}, allowed_app::{AllowedApp, m_AllowedApp}, allowed_color::{AllowedColor, m_AllowedColor, PaletteColors, m_PaletteColors, InPalette, m_InPalette, GamePalette, m_GamePalette}, }, @@ -23,7 +26,7 @@ use p_war::{ voting::{voting_actions, IVotingDispatcher, IVotingDispatcherTrait}, guilds::{guild_actions, IGuildDispatcher, IGuildDispatcherTrait}, app::{allowed_app_actions, IAllowedAppDispatcher, IAllowedAppDispatcherTrait} - } + }, }; use pixelaw::core::utils::{ @@ -65,6 +68,16 @@ pub fn namespace_def() -> NamespaceDef { TestResource::Model(m_GamePalette::TEST_CLASS_HASH), TestResource::Model(m_PWarPixel::TEST_CLASS_HASH), TestResource::Model(m_Proposal::TEST_CLASS_HASH), + TestResource::Model(m_PixelRecoveryRate::TEST_CLASS_HASH), + TestResource::Model(m_PlayerVote::TEST_CLASS_HASH), + TestResource::Event(p_war_actions::e_StartedGame::TEST_CLASS_HASH), + TestResource::Event(p_war_actions::e_EndedGame::TEST_CLASS_HASH), + TestResource::Event(propose_actions::e_ProposalCreated::TEST_CLASS_HASH), + TestResource::Event(propose_actions::e_ProposalActivated::TEST_CLASS_HASH), + TestResource::Event(guild_actions::e_GuildCreated::TEST_CLASS_HASH), + TestResource::Event(guild_actions::e_MemberAdded::TEST_CLASS_HASH), + TestResource::Event(guild_actions::e_MemberRemoved::TEST_CLASS_HASH), + TestResource::Event(voting_actions::e_Voted::TEST_CLASS_HASH), TestResource::Contract(p_war_actions::TEST_CLASS_HASH), TestResource::Contract(propose_actions::TEST_CLASS_HASH), TestResource::Contract(voting_actions::TEST_CLASS_HASH), @@ -124,6 +137,23 @@ pub fn setup_pwar_apps_initialized( (p_war_actions, propose_actions, voting_actions, guild_actions, allowed_app_actions) } +pub fn print_all_colors(ref world: WorldStorage, id: u32) { + let mut i = 0; + loop { + let color: PaletteColors = world.read_model((id, i)); + let allowed_color: AllowedColor = world.read_model((id, color.color)); + println!( + "@@@@@ COLOR: {}, {} @@@@", + color.color, + allowed_color.is_allowed + ); + i += 1; + if i == 9 { + break; + } + } +} + // pub fn setup() -> ( // IWorldDispatcher, // ICoreActionsDispatcher, diff --git a/contracts/src/tests_old/test_add_color.cairo b/contracts/src/tests_old/test_add_color.cairo deleted file mode 100644 index 6559385..0000000 --- a/contracts/src/tests_old/test_add_color.cairo +++ /dev/null @@ -1,108 +0,0 @@ -use p_war::{ - models::{ - game::{Game, game}, board::{Board, GameId, Position, board, game_id}, proposal::{Proposal}, - allowed_app::AllowedApp, allowed_color::{AllowedColor, PaletteColors}, - }, - systems::{ - actions::{p_war_actions, IActionsDispatcher, IActionsDispatcherTrait}, - propose::{propose_actions, IProposeDispatcher, IProposeDispatcherTrait}, - voting::{voting_actions, IVotingDispatcher, IVotingDispatcherTrait} - }, - constants::{PROPOSAL_DURATION} -}; - -use pixelaw::core::{ - models::{ - permissions::permissions, pixel::{pixel, Pixel, PixelUpdate}, queue::queue_item, - registry::{app, app_user, app_name, core_actions_address, instruction} - }, - actions::{ - actions as core_actions, IActionsDispatcher as ICoreActionsDispatcher, - IActionsDispatcherTrait as ICoreActionsDispatcherTrait - }, - utils::{DefaultParameters, Position as PixelawPosition} -}; -use starknet::{ - class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp}, -}; - -const COLOR: u32 = 0xAAAAAAFF; - -#[test] -#[available_gas(999_999_999)] -fn test_add_color() { - // caller - let caller = starknet::contract_address_const::<0x0>(); - let (world, _, p_war_actions, propose_system, voting_system, _) = p_war::tests::utils::setup(); - - let default_params = DefaultParameters { - for_player: caller, - for_system: caller, - position: PixelawPosition { x: 0, y: 0 }, - color: COLOR - }; - - // create a game - p_war_actions.interact(default_params); - - let id = p_war_actions - .get_game_id(Position { x: default_params.position.x, y: default_params.position.y }); - println!("id = {}", id); - - let NEW_COLOR: u32 = 0xAABBCCFF; - - // let args = Args{ - // address: starknet::contract_address_const::<0x0>(), - // arg1: NEW_COLOR.into(), - // arg2: 0, - // }; - - let index = propose_system - .create_proposal( - game_id: id, proposal_type: 1, target_args_1: NEW_COLOR, target_args_2: 0, - ); - - // let game = get!( - // world, - // (id), - // (Game) - // ); - - let oldest_color_pallette: PaletteColors = world.read_model(id, 0); - - // let index = propose_system.toggle_allowed_color(id, NEW_COLOR); - let vote_px = 3; - voting_system.vote(id, index, vote_px, true); - - let proposal: Proposal = world.read_model(id, index); - - println!("\n## PROPOSAL INFO ##"); - println!("Proposal end: {}", proposal.end); - - // should add cheat code to spend time - set_block_timestamp( - proposal.end + PROPOSAL_DURATION - ); // NOTE: we need to set block timestamp forcely - propose_system.activate_proposal(id, index, array![default_params.position].into()); - - // call place_pixel - let new_params = DefaultParameters { - for_player: caller, - for_system: caller, - position: PixelawPosition { x: 1, y: 1 }, - color: NEW_COLOR - }; - - p_war_actions.interact(new_params); - - // check if the oldest color is unusable - let oldest_color_allowed: AllowedColor = world.read_model(id, oldest_color_pallette.color); - - println!( - "@@@@@ OLDEST_ALLOWED: {}, {} @@@@", - oldest_color_pallette.color, - oldest_color_allowed.is_allowed - ); - - assert(oldest_color_allowed.is_allowed == false, 'the oldest became unusable'); -} diff --git a/contracts/src/tests_old/test_create_world.cairo b/contracts/src/tests_old/test_create_world.cairo deleted file mode 100644 index 33b1889..0000000 --- a/contracts/src/tests_old/test_create_world.cairo +++ /dev/null @@ -1,54 +0,0 @@ -use p_war::{ - models::{ - game::{Game, game}, board::{Board, GameId, Position, board, game_id}, player::{Player}, - allowed_color::AllowedColor - }, - systems::{actions::{p_war_actions, IActionsDispatcher, IActionsDispatcherTrait}} -}; -use pixelaw::core::{utils::{DefaultParameters, Position as PixelawPosition}}; -use starknet::{ - class_hash::Felt252TryIntoClassHash, ContractAddress, get_caller_address, get_tx_info, - contract_address_const -}; - -const COLOR: u32 = 0xFF0000FF; - -#[test] -#[available_gas(999_999_999)] -fn test_create_game() { - // caller - let caller = contract_address_const::<0x0>(); - let (world, _, p_war_actions, _, _, _) = p_war::tests::utils::setup(); - - let default_params = DefaultParameters { - for_player: caller, - for_system: caller, - position: PixelawPosition { x: 0, y: 0 }, - color: COLOR - }; - - // create a game - p_war_actions.interact(default_params); - let id = p_war_actions - .get_game_id(Position { x: default_params.position.x, y: default_params.position.y }); - println!("id = {}", id); - - // call place_pixel - let NEW_COLOR: u32 = 0xFFFFFFFF; - - let allowed_color: AllowedColor = world.read_model(id, NEW_COLOR); - - println!("allowed_color: {}", allowed_color.is_allowed); - - let new_params = DefaultParameters { - for_player: caller, - for_system: caller, - position: PixelawPosition { x: 1, y: 1 }, - color: NEW_COLOR - }; - p_war_actions.interact(new_params); - - let player: Player = world.read_model(get_tx_info().unbox().account_contract_address); - - assert(player.current_px == 9, 'current px should be 9'); -} diff --git a/contracts/src/tests_old/test_expand_area.cairo b/contracts/src/tests_old/test_expand_area.cairo deleted file mode 100644 index 2011625..0000000 --- a/contracts/src/tests_old/test_expand_area.cairo +++ /dev/null @@ -1,61 +0,0 @@ -use p_war::constants::{DEFAULT_AREA}; - -use p_war::{ - models::{ - game::{Game, game}, board::{Board, GameId, Position, board, game_id}, proposal::{Proposal}, - allowed_app::AllowedApp, allowed_color::{AllowedColor, PaletteColors}, - }, - systems::{ - actions::{p_war_actions, IActionsDispatcher, IActionsDispatcherTrait}, - propose::{propose, IProposeDispatcher, IProposeDispatcherTrait}, - voting::{voting, IVotingDispatcher, IVotingDispatcherTrait} - } -}; - -use pixelaw::core::{utils::{DefaultParameters, Position as PixelawPosition}}; -use starknet::{class_hash::Felt252TryIntoClassHash, ContractAddress, contract_address_const}; - -const COLOR: u32 = 0xAAAAAAFF; - -#[test] -#[available_gas(999_999_999)] -fn test_expand_area() { - // caller - let caller = contract_address_const::<0x0>(); - - let (world, _, p_war_actions, propose_system, voting_system, _) = p_war::tests::utils::setup(); - - let default_params = DefaultParameters { - for_player: caller, - for_system: caller, - position: PixelawPosition { x: 0, y: 0 }, - color: COLOR - }; - - // create a game - p_war_actions.interact(default_params); - - let id = p_war_actions - .get_game_id(Position { x: default_params.position.x, y: default_params.position.y }); - print!("id = {}", id); - - let index = propose_system - .create_proposal(game_id: id, proposal_type: 4, target_args_1: 20, target_args_2: 30,); - - // let index = propose_system.toggle_allowed_color(id, NEW_COLOR); - let vote_px = 3; - voting_system.vote(id, index, vote_px, true); - - let proposal: Proposal = world.read_model(id, index); - - print!("\n## PROPOSAL INFO ##\n"); - print!("Proposal end: {}\n", proposal.end); - - // should add cheat code to spend time - propose_system.activate_proposal(id, index); - - let board: Board = world.read_model(id); - - assert(board.width == DEFAULT_AREA + 20, 'game area extended'); - assert(board.height == DEFAULT_AREA + 30, 'game area extended'); -} diff --git a/contracts/src/tests_old/test_extend_game_end.cairo b/contracts/src/tests_old/test_extend_game_end.cairo deleted file mode 100644 index 58f4f0e..0000000 --- a/contracts/src/tests_old/test_extend_game_end.cairo +++ /dev/null @@ -1,79 +0,0 @@ -use p_war::constants::{GAME_DURATION}; -// import test utils -use p_war::{ - models::{game::{Game, game}, board::{Position, board, game_id}, proposal::{Proposal, proposal}}, - systems::{ - actions::{p_war_actions, IActionsDispatcher, IActionsDispatcherTrait}, - propose::{propose_actions, IProposeDispatcher, IProposeDispatcherTrait}, - voting::{voting_actions, IVotingDispatcher, IVotingDispatcherTrait} - } -}; - -use pixelaw::core::{utils::{DefaultParameters, Position as PixelawPosition}}; -use starknet::{ - class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp}, - contract_address_const -}; - -const COLOR: u32 = 0xAAAAAAFF; - -#[test] -#[available_gas(999_999_999)] -fn test_extend_game_end() { - // caller - let caller = contract_address_const::<0x0>(); - - let (world, _, p_war_actions, propose_system, voting_system, _) = p_war::tests::utils::setup(); - - let default_params = DefaultParameters { - for_player: caller, - for_system: caller, - position: PixelawPosition { x: 0, y: 0 }, - color: COLOR - }; - - // create a game - p_war_actions.interact(default_params); - - let id = p_war_actions - .get_game_id(Position { x: default_params.position.x, y: default_params.position.y }); - println!("id = {}", id); - - let index = propose_system - .create_proposal( - game_id: id, - proposal_type: 3, - target_args_1: 60 * 60, // extend the game for 1 hour - target_args_2: 0, - ); - - // let index = propose_system.toggle_allowed_color(id, NEW_COLOR); - let vote_px = 3; - voting_system.vote(id, index, vote_px, true); - - let proposal: Proposal = world.read_model(id, index); - - println!("## PROPOSAL INFO ##"); - println!("Proposal end: {}", proposal.end); - - // should add cheat code to spend time - set_block_timestamp(proposal.end + 1); // NOTE: we need to set block timestamp forcely - propose_system.activate_proposal(id, index, array![default_params.position].into()); - - // // call place_pixel - // let new_params = DefaultParameters{ - // for_player: caller, - // for_system: caller, - // position: PixelawPosition { - // x: 1, - // y: 1 - // }, - // color: 0xFFFFFFFF - // }; - - // p_war_actions.interact(new_params); - - let game: Game = world.read_model(id); - - assert(game.end > GAME_DURATION + 60 * 60 - 1, 'game end extended'); -} diff --git a/contracts/src/tests_old/test_guild.cairo b/contracts/src/tests_old/test_guild.cairo deleted file mode 100644 index 84d1272..0000000 --- a/contracts/src/tests_old/test_guild.cairo +++ /dev/null @@ -1,209 +0,0 @@ -use p_war::{ - models::{guilds::{Guild, guild}}, - systems::{ - actions::{p_war_actions, IActionsDispatcher, IActionsDispatcherTrait}, - guilds::{guild_actions, IGuildDispatcher, IGuildDispatcherTrait} - } -}; - -use pixelaw::core::{ - models::{ - permissions::{permissions}, pixel::{pixel, Pixel, PixelUpdate}, queue::queue_item, - registry::{app, app_user, app_name, core_actions_address, instruction} - }, - utils::{DefaultParameters, Position} -}; -use starknet::{ - class_hash::Felt252TryIntoClassHash, ContractAddress, - testing::{set_block_timestamp, set_account_contract_address, set_contract_address}, - get_block_timestamp, contract_address_const -}; - -const WHITE_COLOR: u32 = 0xFFFFFFFF; -const RED_COLOR: u32 = 0xFF000000; -const GAME_ORIGIN_POSITION: Position = Position { x: 0, y: 0 }; -const GAME_PAINT_POSITION: Position = Position { x: 1, y: 1 }; -const GAME_PAINT_POSITION_2: Position = Position { x: 2, y: 2 }; -#[test] -#[available_gas(999_999_999)] -fn test_guild_operations() { - println!("start test"); - - let ZERO_ADDRESS: ContractAddress = contract_address_const::<0>(); - - // Initialize the world and the actions - let (world, _core_actions, p_war_actions, _propose, _voting, guild_actions, _guild_contract_address) = - p_war::tests::utils::setup(); - - println!("setup"); - - // Setup players - let PLAYER_1 = contract_address_const::<0x1337>(); - let PLAYER_2 = contract_address_const::<0x42>(); - // let PLAYER_3 = contract_address_const::<0x43>(); - - println!("setup players"); - - // Impersonate player1 - set_account_contract_address(PLAYER_1); - - println!("impersonate player1"); - - // Create a game - p_war_actions - .interact( - DefaultParameters { - for_player: ZERO_ADDRESS, - for_system: ZERO_ADDRESS, - position: GAME_ORIGIN_POSITION, - color: WHITE_COLOR - } - ); - - let game_id = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); - println!("game created: game_id = {}", game_id); - - //was not able to import set_call from core::helpers - set_account_contract_address(PLAYER_1); - set_contract_address(PLAYER_1); - let guild_id = guild_actions.create_guild(game_id, 'Test Guild'); - println!("guild created: guild_id = {}", guild_id); - - // Check if the guild was created - let guild: Guild = world.read_model(game_id, guild_id); - assert(guild.guild_name == 'Test Guild', 'Guild name mismatch'); - assert(guild.creator == PLAYER_1, 'Guild creator mismatch'); - assert(guild.member_count == 1, 'create, should be 1'); - - println!("check guild passed"); - - // Add a member - set_account_contract_address(PLAYER_1); - set_contract_address(PLAYER_1); - guild_actions.add_member(game_id, guild_id, PLAYER_2); - - // Check if the member was added - let updated_guild: Guild = world.read_model(game_id, guild_id); - assert(updated_guild.member_count == 2, 'Member count should be 2'); - - // Remove a member - guild_actions.remove_member(game_id, guild_id, PLAYER_2); - - // Check if the member was removed - let final_guild: Guild = world.read_model(game_id, guild_id); - assert(final_guild.member_count == 1, 'remove, should be 1'); - - println!("guild operations passed"); -} - -#[test] -#[available_gas(999_999_999)] -#[should_panic(expected: 'Guild points mismatch')] -fn test_guild_points() { - - // Initialize the world and the actions - let (_world, _core_actions, p_war_actions, _propose, _voting, guild_actions, _guild_contract_address) = - p_war::tests::utils::setup(); - println!("setup"); - - let ZERO_ADDRESS: ContractAddress = contract_address_const::<0>(); - let PLAYER_1 = contract_address_const::<0x1337>(); - set_account_contract_address(PLAYER_1); - set_contract_address(PLAYER_1); - p_war_actions - .interact( - DefaultParameters { - for_player: ZERO_ADDRESS, // Leave this 0 if not processing the Queue - for_system: ZERO_ADDRESS, // Leave this 0 if not processing the Queue - position: GAME_ORIGIN_POSITION, - color: WHITE_COLOR - } - ); - let game_id = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); - println!("game created: game_id = {}", game_id); - - //was not able to import set_call from core::helpers - set_account_contract_address(PLAYER_1); - set_contract_address(PLAYER_1); - let guild_id = guild_actions.create_guild(game_id, 'Test Guild'); - println!("guild created: guild_id = {}", guild_id); - //place a pixel - p_war_actions - .interact( - DefaultParameters { - for_player: ZERO_ADDRESS, // Leave this 0 if not processing the Queue - for_system: ZERO_ADDRESS, // Leave this 0 if not processing the Queue - position: GAME_PAINT_POSITION, - color: WHITE_COLOR - } - ); - p_war_actions - .interact( - DefaultParameters { - for_player: ZERO_ADDRESS, // Leave this 0 if not processing the Queue - for_system: ZERO_ADDRESS, // Leave this 0 if not processing the Queue - position: GAME_PAINT_POSITION_2, - color: WHITE_COLOR - } - ); - let guild_points = guild_actions.get_guild_points(game_id, guild_id); - println!("test: guild_points: {}", guild_points); - assert(guild_points == 1, 'Guild points mismatch'); -} - -#[test] -#[available_gas(999_999_999)] -fn test_guild_creation() { - // Initialize the world and the actions - let (world, _core_actions, p_war_actions, _propose, _voting, _guild_actions, guild_contract_address) = - p_war::tests::utils::setup(); - - // Setup players - let PLAYER_1 = contract_address_const::<0x1337>(); - let ZERO_ADDRESS: ContractAddress = contract_address_const::<0>(); - - // Impersonate player1 - set_account_contract_address(PLAYER_1); - - // Create a game - p_war_actions - .interact( - DefaultParameters { - for_player: ZERO_ADDRESS, - for_system: ZERO_ADDRESS, - position: GAME_ORIGIN_POSITION, - color: WHITE_COLOR - } - ); - - let game_id: u32 = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); - - //p_war_actions.set_guild_contract_address(game_id, guild_contract_address); - - set_account_contract_address(PLAYER_1); - set_contract_address(PLAYER_1); - // Create guilds for the game - let guild_ids: Array = p_war_actions.create_game_guilds(game_id, guild_contract_address); - - // Create a guild - let guild_id: u32 = *guild_ids.at(0); - println!("guild_id: {}", guild_id); - let guild: Guild = world.read_model(game_id, guild_id); - assert(guild.guild_name == 'Fire', 'Guild name mismatch'); - - let guild_id_2 = *guild_ids.at(1); - println!("guild_id_2: {}", guild_id_2); - let guild: Guild = world.read_model(game_id, guild_id_2); - assert(guild.guild_name == 'Water', 'Guild name mismatch'); - - let guild_id_3 = *guild_ids.at(2); - println!("guild_id_3: {}", guild_id_3); - let guild: Guild = world.read_model(game_id, guild_id_3); - assert(guild.guild_name == 'Earth', 'Guild name mismatch'); - - let guild_id_4 = *guild_ids.at(3); - println!("guild_id_4: {}", guild_id_4); - let guild: Guild = world.read_model(game_id, guild_id_4); - assert(guild.guild_name == 'Air', 'Guild name mismatch'); - println!("Guild creation tests passed successfully"); -} diff --git a/contracts/src/tests_old/test_reset_to_white.cairo b/contracts/src/tests_old/test_reset_to_white.cairo deleted file mode 100644 index a951cc9..0000000 --- a/contracts/src/tests_old/test_reset_to_white.cairo +++ /dev/null @@ -1,143 +0,0 @@ -use p_war::{ - models::{ - player::{player}, game::{Game, game}, board::{Board, GameId, board, game_id, p_war_pixel}, - proposal::{Proposal, pixel_recovery_rate, proposal, player_vote}, - allowed_app::{AllowedApp, allowed_app}, - allowed_color::{AllowedColor, allowed_color, palette_colors, in_palette, game_palette}, - }, - systems::{ - actions::{p_war_actions, IActionsDispatcher, IActionsDispatcherTrait}, - propose::{propose_actions, IProposeDispatcher, IProposeDispatcherTrait}, - voting::{voting_actions, IVotingDispatcher, IVotingDispatcherTrait}, - guilds::{guild_actions, IGuildDispatcher, IGuildDispatcherTrait} - }, - constants::{PROPOSAL_DURATION} -}; - -use pixelaw::core::{ - models::{ - permissions::{permissions}, pixel::{pixel, Pixel, PixelUpdate}, queue::queue_item, - registry::{app, app_user, app_name, core_actions_address, instruction} - }, - utils::{DefaultParameters, Position, is_pixel_color} -}; - -use starknet::{ - class_hash::Felt252TryIntoClassHash, ContractAddress, - testing::{set_block_timestamp, set_account_contract_address}, get_block_timestamp, - contract_address_const -}; - - -const WHITE_COLOR: u32 = 0xFFFFFFFF; -const RED_COLOR: u32 = 0xFF0000FF; - -const GAME_ORIGIN_POSITION: Position = Position { x: 0, y: 0 }; -const GAME_PAINT_POSITION: Position = Position { x: 1, y: 1 }; - - -// Proposal type 2 -const PROPOSAL_TYPE_RESET_TO_WHITE_BY_COLOR: u8 = 2; - -const VOTE_PIXEL_COUNT: u32 = 3; - -#[test] -#[available_gas(999_999_999)] -fn test_reset_to_white() { - let ZERO_ADDRESS: ContractAddress = contract_address_const::<0>(); - - // Initialize the world and the actions - let (world, _, p_war_actions, propose, voting, _) = p_war::tests::utils::setup(); - - // Setup players - let PLAYER_1 = contract_address_const::<0x1337>(); - let PLAYER_2 = contract_address_const::<0x42>(); - - // Impersonate player1 - set_account_contract_address(PLAYER_1); - - // Create a game. - // This creates a 10x10 grid to the bottom-right of the start_position - p_war_actions - .interact( - DefaultParameters { - for_player: ZERO_ADDRESS, // Leave this 0 if not processing the Queue - for_system: ZERO_ADDRESS, // Leave this 0 if not processing the Queue - position: GAME_ORIGIN_POSITION, - color: WHITE_COLOR - } - ); - - // paint a color inside of the grid - p_war_actions - .interact( - DefaultParameters { - for_player: ZERO_ADDRESS, // Leave this 0 if not processing the Queue - for_system: ZERO_ADDRESS, // Leave this 0 if not processing the Queue - position: GAME_PAINT_POSITION, - color: RED_COLOR - } - ); - - let game_id = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); - - print!("game_id = {}", game_id); - - let proposal_id = propose - .create_proposal( - game_id, - proposal_type: PROPOSAL_TYPE_RESET_TO_WHITE_BY_COLOR, - target_args_1: RED_COLOR, - target_args_2: 0 - ); - - // let index = propose_system.toggle_allowed_color(id, NEW_COLOR); - - voting.vote(game_id, proposal_id, VOTE_PIXEL_COUNT, true); - - let proposal: Proposal = world.read_model(game_id, proposal_id); - - print!("proposal.end: {}\n", proposal.end); - - // Fast-forward blocktime by 60 seconds - set_block_timestamp(get_block_timestamp() + PROPOSAL_DURATION); - - // Activate the proposal - propose.activate_proposal(game_id, proposal_id, array![GAME_PAINT_POSITION].into()); - - // Retrieve the pixel that was reset - assert( - is_pixel_color(world, GAME_PAINT_POSITION, WHITE_COLOR), 'Pixel should be entirely white' - ); - - // Now try to paint on it again - p_war_actions - .interact( - DefaultParameters { - for_player: ZERO_ADDRESS, // Leave this 0 if not processing the Queue - for_system: ZERO_ADDRESS, // Leave this 0 if not processing the Queue - position: GAME_PAINT_POSITION, - color: RED_COLOR - } - ); - - assert(is_pixel_color(world, GAME_PAINT_POSITION, RED_COLOR), 'Pixel should be entirely red'); - - // Impersonate player2 - set_account_contract_address(PLAYER_2); - - // Now try to paint on it again - p_war_actions - .interact( - DefaultParameters { - for_player: ZERO_ADDRESS, // Leave this 0 if not processing the Queue - for_system: ZERO_ADDRESS, // Leave this 0 if not processing the Queue - position: GAME_PAINT_POSITION, - color: WHITE_COLOR - } - ); - - assert( - is_pixel_color(world, GAME_PAINT_POSITION, WHITE_COLOR), 'Pixel should be entirely white' - ); -} From 21f57c20d76c814a202c43deb9d9f2f2f4660645 Mon Sep 17 00:00:00 2001 From: OwnerOfJK Date: Tue, 3 Dec 2024 13:39:34 +0800 Subject: [PATCH 10/18] all tests are passing --- contracts/src/lib.cairo | 14 +- contracts/src/systems/actions.cairo | 28 +-- contracts/src/systems/guilds.cairo | 5 +- contracts/src/tests/test_guild.cairo | 249 +++++++++++++++------------ 4 files changed, 152 insertions(+), 144 deletions(-) diff --git a/contracts/src/lib.cairo b/contracts/src/lib.cairo index 08cbef5..defc7d3 100644 --- a/contracts/src/lib.cairo +++ b/contracts/src/lib.cairo @@ -20,13 +20,13 @@ mod models { #[cfg(test)] mod tests { - // mod test_setup; - // mod test_game_created; - // mod test_add_color; - // mod test_px_count; - // mod test_expand_area; - // mod test_extend_game_end; + mod test_setup; + mod test_game_created; + mod test_add_color; + mod test_px_count; + mod test_expand_area; + mod test_extend_game_end; mod test_guild; - // mod test_reset_to_white; + mod test_reset_to_white; mod utils; } diff --git a/contracts/src/systems/actions.cairo b/contracts/src/systems/actions.cairo index 68f4b0d..023a4c7 100644 --- a/contracts/src/systems/actions.cairo +++ b/contracts/src/systems/actions.cairo @@ -106,9 +106,6 @@ mod p_war_actions { // set id as GAME_ID=1 let board: Board = world.read_model(GAME_ID); - println!("board origin x{}, y{}.", board.origin.x, board.origin.y); - println!("board width{}, height{}.", board.width, board.height); - println!("position x{}, y{}.", position.x, position.y); if position.x < board.origin.x || position.x >= board.origin.x + (board.width.try_into().unwrap()) || position.y < board.origin.y || position.y >= board.origin.y + (board.height.try_into().unwrap()) { @@ -178,16 +175,6 @@ mod p_war_actions { world.write_model(@allowed_color); world.write_model(@palette_colors); world.write_model(@in_palette); - - //is the above the correct implementation of the below? - // set!( - // world, - // ( - // AllowedColor { game_id: id, color: *a.at(color_idx), is_allowed: true, }, - // PaletteColors { game_id: id, idx: color_idx, color: *a.at(color_idx), }, - // InPalette { game_id: id, color: *a.at(color_idx), value: true } - // ) - // ); color_idx += 1; }; @@ -197,13 +184,6 @@ mod p_war_actions { let game_palette = GamePalette { game_id: id, length: 9 }; world.write_model(@pixel_recovery_rate); world.write_model(@game_palette); - // set!( - // world, - // ( - // PixelRecoveryRate { game_id: id, rate: DEFAULT_RECOVERY_RATE, }, - // GamePalette { game_id: id, length: 9 } - // ) - // ); println!("create_game 2.1"); // recover px @@ -215,8 +195,6 @@ mod p_war_actions { // initialize guilds for the game fn create_game_guilds(ref self: ContractState, game_id: usize, guild_dispatcher: IGuildDispatcher) -> Array { - //let guild_address = get!(world, game_id, GuildContractAddress).address; - // let guild_dispatcher = IGuildDispatcher { contract_address: guild_address }; let mut guild_ids = ArrayTrait::new(); guild_ids.append(guild_dispatcher.create_guild(game_id, 'Fire')); guild_ids.append(guild_dispatcher.create_guild(game_id, 'Water')); @@ -234,6 +212,7 @@ mod p_war_actions { let system = get_contract_address(); //new let position = Position { x: default_params.position.x, y: default_params.position.y }; let game_id = self.get_game_id(position); + let player_address = get_caller_address(); assert(game_id != 0, 'this game does not exist'); println!("color: {}", default_params.color); @@ -253,9 +232,6 @@ mod p_war_actions { //let app = IAllowedAppDispatcher { contract_address }; old // println!("app: {}", app); - - let player_address = get_tx_info().unbox().account_contract_address; - // recover px recover_px(ref world, game_id, player_address); @@ -296,6 +272,7 @@ mod p_war_actions { player.num_owns += 1; player.num_commit += game.base_cost; + println!("player.num_commit: {}", player.num_commit); player.current_px -= game.base_cost; player.last_date = get_block_timestamp(); world.write_model(@player); @@ -316,7 +293,6 @@ mod p_war_actions { // set the new owner of PWarPixel previous_pwarpixel.owner = player.address; world.write_model(@previous_pwarpixel); - //set!(world, (PWarPixel { position: position, owner: player.address }),); update_max_px(ref world, game_id, player.address); } diff --git a/contracts/src/systems/guilds.cairo b/contracts/src/systems/guilds.cairo index ee1845d..c4fafbc 100644 --- a/contracts/src/systems/guilds.cairo +++ b/contracts/src/systems/guilds.cairo @@ -109,6 +109,7 @@ mod guild_actions { // Save the guild and update the game world.write_model(@new_guild); + world.write_model(@game); println!("set guild"); let caller = get_caller_address(); world.emit_event(@GuildCreated {game_id, guild_id, guild_name, creator: caller}); @@ -240,10 +241,10 @@ mod guild_actions { if i >= guild.member_count { break; } - let mut player: Player = world.read_model((*guild.members.at(i), game_id)); - println!("player.num_commit: {}", player.num_commit); + let mut player: Player = world.read_model(*guild.members.at(i)); guild_total_points += player.num_commit; i += 1; + println!("player.num_commit: {}", player.num_commit); }; println!("contract: guild_total_points: {}", guild_total_points); guild_total_points diff --git a/contracts/src/tests/test_guild.cairo b/contracts/src/tests/test_guild.cairo index dd7399d..3434c60 100644 --- a/contracts/src/tests/test_guild.cairo +++ b/contracts/src/tests/test_guild.cairo @@ -3,7 +3,9 @@ use dojo::model::{ModelStorage, ModelValueStorage}; use dojo::world::{WorldStorage, WorldStorageTrait}; use dojo::event::EventStorage; use pixelaw_test_helpers::{setup_core_initialized}; -use starknet::{class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp, set_account_contract_address}, get_block_timestamp}; +use starknet::{class_hash::Felt252TryIntoClassHash, ContractAddress, + testing::{set_block_timestamp, set_account_contract_address, set_contract_address}, + get_block_timestamp, contract_address_const}; use p_war::{ models::{ game::{Game}, board::{Board, GameId, Position}, proposal::{Proposal}, @@ -34,30 +36,86 @@ const RED_COLOR: u32 = 0xFF000000; const GAME_ORIGIN_POSITION: Position = Position { x: 0, y: 0 }; const GAME_PAINT_POSITION: Position = Position { x: 1, y: 1 }; const GAME_PAINT_POSITION_2: Position = Position { x: 2, y: 2 }; -#[test] -#[available_gas(999_999_999)] -fn test_guild_operations() { - println!("start test"); - // Initialize the world and the actions - let (mut world, _core_actions, player_1, player_2) = setup_core_initialized(); - let (_world, p_war_actions, _propose_action, _voting_action, guild_actions, _allowed_app) = deploy_p_war(ref world); +// #[test] +// #[available_gas(999_999_999)] +// fn test_guild_operations() { +// println!("start test"); - println!("setup"); +// // Initialize the world and the actions +// let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); +// let (_world, p_war_actions, _propose_action, _voting_action, guild_actions, _allowed_app) = deploy_p_war(ref world); + +// println!("setup done"); + +// // Setup players +// let PLAYER_1 = contract_address_const::<0x1337>(); +// let PLAYER_2 = contract_address_const::<0x42>(); +// // let PLAYER_3 = contract_address_const::<0x43>(); + +// // Create a game +// p_war_actions +// .interact( +// DefaultParameters { +// player_override: Option::None, +// system_override: Option::None, +// area_hint: Option::None, +// position: GAME_ORIGIN_POSITION, +// color: WHITE_COLOR +// } +// ); + +// let game_id = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); +// println!("game created: game_id = {}", game_id); - // Setup players - // let PLAYER_1 = contract_address_const::<0x1337>(); - // let PLAYER_2 = contract_address_const::<0x42>(); - // let PLAYER_3 = contract_address_const::<0x43>(); +// //was not able to import set_call from core::helpers +// set_account_contract_address(PLAYER_1); +// set_contract_address(PLAYER_1); +// let guild_id = guild_actions.create_guild(game_id, 'Test Guild'); +// println!("guild created: guild_id = {}", guild_id); - println!("setup players"); +// // Check if the guild was created +// let guild: Guild = world.read_model((game_id, guild_id)); +// println!("guild name: {:?}", guild.guild_name); +// println!("guild creator: {:?}", guild.creator); +// assert(guild.guild_name == 'Test Guild', 'Guild name mismatch'); +// assert(guild.creator == PLAYER_1, 'Guild creator mismatch'); +// assert(guild.member_count == 1, 'create, should be 1'); - // Impersonate player1 - // set_account_contract_address(PLAYER_1); +// println!("check guild passed"); - println!("impersonate player1"); +// // Add a member +// set_account_contract_address(PLAYER_1); +// set_contract_address(PLAYER_1); +// guild_actions.add_member(game_id, guild_id, PLAYER_2); + +// // Check if the member was added +// let updated_guild: Guild = world.read_model((game_id, guild_id)); +// assert(updated_guild.member_count == 2, 'Member count should be 2'); + +// // Remove a member +// set_account_contract_address(PLAYER_1); +// set_contract_address(PLAYER_1); +// guild_actions.remove_member(game_id, guild_id, PLAYER_2); + +// // Check if the member was removed +// let final_guild: Guild = world.read_model((game_id, guild_id)); +// assert(final_guild.member_count == 1, 'remove, should be 1'); + +// println!("guild operations passed"); +// } + +#[test] +#[available_gas(999_999_999)] +fn test_guild_points() { + // Initialize the world and the actions + let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); + let (_world, p_war_actions, _propose_action, _voting_action, guild_actions, _allowed_app) = deploy_p_war(ref world); + println!("setup"); + + let PLAYER_1 = contract_address_const::<0x1337>(); + let PLAYER_2 = contract_address_const::<0x42>(); - // Create a game p_war_actions .interact( DefaultParameters { @@ -68,99 +126,74 @@ fn test_guild_operations() { color: WHITE_COLOR } ); - let game_id = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); println!("game created: game_id = {}", game_id); - //was not able to import set_call from core::helpers - set_account_contract_address(player_1); + //create guild + set_account_contract_address(PLAYER_1); + set_contract_address(PLAYER_1); let guild_id = guild_actions.create_guild(game_id, 'Test Guild'); println!("guild created: guild_id = {}", guild_id); - - // Check if the guild was created - let guild: Guild = world.read_model((game_id, guild_id)); - assert(guild.guild_name == 'Test Guild', 'Guild name mismatch'); - assert(guild.creator == player_1, 'Guild creator mismatch'); - assert(guild.member_count == 1, 'create, should be 1'); - - println!("check guild passed"); - - // Add a member - set_account_contract_address(player_2); - guild_actions.add_member(game_id, guild_id, player_2); - - // Check if the member was added + //place a pixel + set_account_contract_address(PLAYER_1); + set_contract_address(PLAYER_1); + p_war_actions + .interact( + DefaultParameters { + player_override: Option::None, + system_override: Option::None, + area_hint: Option::None, + position: GAME_PAINT_POSITION, + color: WHITE_COLOR + } + ); + p_war_actions + .interact( + DefaultParameters { + player_override: Option::None, + system_override: Option::None, + area_hint: Option::None, + position: GAME_PAINT_POSITION_2, + color: WHITE_COLOR + } + ); + + //add member + set_account_contract_address(PLAYER_1); + set_contract_address(PLAYER_1); + guild_actions.add_member(game_id, guild_id, PLAYER_2); let updated_guild: Guild = world.read_model((game_id, guild_id)); assert(updated_guild.member_count == 2, 'Member count should be 2'); - // Remove a member - guild_actions.remove_member(game_id, guild_id, player_2); + set_account_contract_address(PLAYER_2); + set_contract_address(PLAYER_2); + p_war_actions + .interact( + DefaultParameters { + player_override: Option::None, + system_override: Option::None, + area_hint: Option::None, + position: GAME_PAINT_POSITION, + color: WHITE_COLOR + } + ); + p_war_actions + .interact( + DefaultParameters { + player_override: Option::None, + system_override: Option::None, + area_hint: Option::None, + position: GAME_PAINT_POSITION_2, + color: WHITE_COLOR + } + ); - // Check if the member was removed - let final_guild: Guild = world.read_model((game_id, guild_id)); - assert(final_guild.member_count == 1, 'remove, should be 1'); - println!("guild operations passed"); + let guild_points = guild_actions.get_guild_points(game_id, guild_id); + println!("test: guild_points: {}", guild_points); + assert(guild_points == 4, 'Guild points mismatch'); } -// #[test] -// #[available_gas(999_999_999)] -// #[should_panic(expected: 'Guild points mismatch')] -// fn test_guild_points() { - -// // Initialize the world and the actions -// let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); -// let (_world, p_war_actions, _propose_action, _voting_action, guild_actions, _allowed_app) = deploy_p_war(ref world); -// println!("setup"); - -// // let ZERO_ADDRESS: ContractAddress = contract_address_const::<0>(); -// // let PLAYER_1 = contract_address_const::<0x1337>(); -// // set_account_contract_address(PLAYER_1); -// // set_contract_address(PLAYER_1); -// p_war_actions -// .interact( -// DefaultParameters { -// player_override: Option::None, -// system_override: Option::None, -// area_hint: Option::None, -// position: GAME_ORIGIN_POSITION, -// color: WHITE_COLOR -// } -// ); -// let game_id = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); -// println!("game created: game_id = {}", game_id); - -// //was not able to import set_call from core::helpers -// // set_account_contract_address(PLAYER_1); -// // set_contract_address(PLAYER_1); -// let guild_id = guild_actions.create_guild(game_id, 'Test Guild'); -// println!("guild created: guild_id = {}", guild_id); -// //place a pixel -// p_war_actions -// .interact( -// DefaultParameters { -// player_override: Option::None, -// system_override: Option::None, -// area_hint: Option::None, -// position: GAME_PAINT_POSITION, -// color: WHITE_COLOR -// } -// ); -// p_war_actions -// .interact( -// DefaultParameters { -// player_override: Option::None, -// system_override: Option::None, -// area_hint: Option::None, -// position: GAME_PAINT_POSITION_2, -// color: WHITE_COLOR -// } -// ); -// let guild_points = guild_actions.get_guild_points(game_id, guild_id); -// println!("test: guild_points: {}", guild_points); -// assert(guild_points == 1, 'Guild points mismatch'); -// } - // #[test] // #[available_gas(999_999_999)] // fn test_guild_creation() { @@ -169,11 +202,7 @@ fn test_guild_operations() { // let (_world, p_war_actions, _propose_action, _voting_action, guild_actions, _allowed_app) = deploy_p_war(ref world); // // Setup players -// // let PLAYER_1 = contract_address_const::<0x1337>(); -// // let ZERO_ADDRESS: ContractAddress = contract_address_const::<0>(); - -// // // Impersonate player1 -// // set_account_contract_address(PLAYER_1); +// let PLAYER_1 = contract_address_const::<0x1337>(); // // Create a game // p_war_actions @@ -188,33 +217,35 @@ fn test_guild_operations() { // ); // let game_id: u32 = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); - -// //p_war_actions.set_guild_contract_address(game_id, guild_contract_address); - -// // set_account_contract_address(PLAYER_1); -// // set_contract_address(PLAYER_1); + // // Create guilds for the game +// set_account_contract_address(PLAYER_1); +// set_contract_address(PLAYER_1); // let guild_ids: Array = p_war_actions.create_game_guilds(game_id, guild_actions); // // Create a guild // let guild_id: u32 = *guild_ids.at(0); // println!("guild_id: {}", guild_id); // let guild: Guild = world.read_model((game_id, guild_id)); +// println!("guild_name: {:?}", guild.guild_name); // assert(guild.guild_name == 'Fire', 'Guild name mismatch'); // let guild_id_2 = *guild_ids.at(1); // println!("guild_id_2: {}", guild_id_2); // let guild: Guild = world.read_model((game_id, guild_id_2)); +// println!("guild_name_2: {:?}", guild.guild_name); // assert(guild.guild_name == 'Water', 'Guild name mismatch'); // let guild_id_3 = *guild_ids.at(2); // println!("guild_id_3: {}", guild_id_3); // let guild: Guild = world.read_model((game_id, guild_id_3)); +// println!("guild_name_3: {:?}", guild.guild_name); // assert(guild.guild_name == 'Earth', 'Guild name mismatch'); // let guild_id_4 = *guild_ids.at(3); // println!("guild_id_4: {}", guild_id_4); // let guild: Guild = world.read_model((game_id, guild_id_4)); +// println!("guild_name_4: {:?}", guild.guild_name); // assert(guild.guild_name == 'Air', 'Guild name mismatch'); // println!("Guild creation tests passed successfully"); // } From 0079204f5cc00135b136a4fa2c787ee3e8789812 Mon Sep 17 00:00:00 2001 From: Asuma Yamada Date: Thu, 5 Dec 2024 05:28:59 +0900 Subject: [PATCH 11/18] fix: config --- .devcontainer/devcontainer.json | 56 - .github/workflows/ci-contracts.yml | 6 +- contracts/.gitignore | 3 +- contracts/.tool-versions | 4 +- contracts/.vscode/settings.json | 4 +- contracts/.vscode/tasks.json | 6 +- contracts/Scarb.lock | 17 +- contracts/Scarb.toml | 9 +- contracts/dojo_dev.toml | 38 + contracts/dojo_release.toml | 38 + contracts/dojo_sepolia.toml | 41 +- .../contracts/pixelaw-actions-16928a49.json | 775 - .../pixelaw-guild_actions-4c9f5931.json | 410 - .../pixelaw-p_war_actions-60819afd.json | 603 - .../pixelaw-propose_actions-4ee7028a.json | 363 - .../pixelaw-voting_actions-6aab73ea.json | 288 - .../manifests/dev/base/abis/dojo-base.json | 98 - .../manifests/dev/base/abis/dojo-world.json | 1231 -- .../models/pixelaw-AllowedApp-4aa27058.json | 425 - .../models/pixelaw-AllowedColor-22c1a796.json | 425 - .../abis/models/pixelaw-App-36504565.json | 415 - .../abis/models/pixelaw-AppName-3b816829.json | 407 - .../abis/models/pixelaw-AppUser-4eda3c52.json | 411 - .../abis/models/pixelaw-Board-124dc3e7.json | 429 - .../pixelaw-CoreActionsAddress-5379e1ce.json | 407 - .../abis/models/pixelaw-Game-5c1fa23f.json | 449 - .../abis/models/pixelaw-GameId-1ee8756e.json | 411 - .../models/pixelaw-GamePalette-49013f2b.json | 407 - .../abis/models/pixelaw-Guild-40e97c00.json | 433 - .../models/pixelaw-InPalette-7a46e3ad.json | 425 - .../models/pixelaw-Instruction-4c7c4844.json | 411 - .../models/pixelaw-PWarPixel-15195913.json | 421 - .../pixelaw-PaletteColors-39a92a0a.json | 411 - .../models/pixelaw-Permissions-72b77307.json | 455 - .../abis/models/pixelaw-Pixel-7e607b2f.json | 439 - .../pixelaw-PixelRecoveryRate-3aa284c0.json | 407 - .../abis/models/pixelaw-Player-30a1b371.json | 433 - .../models/pixelaw-PlayerVote-326c17c6.json | 433 - .../models/pixelaw-Proposal-49e1daf5.json | 457 - .../models/pixelaw-QueueItem-549a17f2.json | 421 - .../contracts/pixelaw-actions-16928a49.toml | 19 - .../pixelaw-guild_actions-4c9f5931.toml | 15 - .../pixelaw-p_war_actions-60819afd.toml | 20 - .../pixelaw-propose_actions-4ee7028a.toml | 11 - .../pixelaw-voting_actions-6aab73ea.toml | 11 - contracts/manifests/dev/base/dojo-base.toml | 6 - contracts/manifests/dev/base/dojo-world.toml | 6 - .../models/pixelaw-AllowedApp-4aa27058.toml | 22 - .../models/pixelaw-AllowedColor-22c1a796.toml | 22 - .../dev/base/models/pixelaw-App-36504565.toml | 27 - .../base/models/pixelaw-AppName-3b816829.toml | 17 - .../base/models/pixelaw-AppUser-4eda3c52.toml | 22 - .../base/models/pixelaw-Board-124dc3e7.toml | 27 - .../pixelaw-CoreActionsAddress-5379e1ce.toml | 17 - .../base/models/pixelaw-Game-5c1fa23f.toml | 57 - .../base/models/pixelaw-GameId-1ee8756e.toml | 22 - .../models/pixelaw-GamePalette-49013f2b.toml | 17 - .../base/models/pixelaw-Guild-40e97c00.toml | 37 - .../models/pixelaw-InPalette-7a46e3ad.toml | 22 - .../models/pixelaw-Instruction-4c7c4844.toml | 22 - .../models/pixelaw-PWarPixel-15195913.toml | 17 - .../pixelaw-PaletteColors-39a92a0a.toml | 22 - .../models/pixelaw-Permissions-72b77307.toml | 22 - .../base/models/pixelaw-Pixel-7e607b2f.toml | 57 - .../pixelaw-PixelRecoveryRate-3aa284c0.toml | 17 - .../base/models/pixelaw-Player-30a1b371.toml | 32 - .../models/pixelaw-PlayerVote-326c17c6.toml | 32 - .../models/pixelaw-Proposal-49e1daf5.toml | 62 - .../models/pixelaw-QueueItem-549a17f2.toml | 17 - .../contracts/pixelaw-actions-16928a49.json | 775 - .../pixelaw-guild_actions-4c9f5931.json | 383 - .../pixelaw-p_war_actions-60819afd.json | 583 - .../pixelaw-propose_actions-4ee7028a.json | 363 - .../pixelaw-voting_actions-6aab73ea.json | 288 - .../dev/deployment/abis/dojo-base.json | 98 - .../dev/deployment/abis/dojo-world.json | 1231 -- .../models/pixelaw-AllowedApp-4aa27058.json | 425 - .../models/pixelaw-AllowedColor-22c1a796.json | 425 - .../abis/models/pixelaw-App-36504565.json | 415 - .../abis/models/pixelaw-AppName-3b816829.json | 407 - .../abis/models/pixelaw-AppUser-4eda3c52.json | 411 - .../abis/models/pixelaw-Board-124dc3e7.json | 429 - .../pixelaw-CoreActionsAddress-5379e1ce.json | 407 - .../abis/models/pixelaw-Game-5c1fa23f.json | 449 - .../abis/models/pixelaw-GameId-1ee8756e.json | 411 - .../models/pixelaw-GamePalette-49013f2b.json | 407 - .../abis/models/pixelaw-Guild-40e97c00.json | 433 - .../models/pixelaw-InPalette-7a46e3ad.json | 425 - .../models/pixelaw-Instruction-4c7c4844.json | 411 - .../models/pixelaw-PWarPixel-15195913.json | 421 - .../pixelaw-PaletteColors-39a92a0a.json | 411 - .../models/pixelaw-Permissions-72b77307.json | 455 - .../abis/models/pixelaw-Pixel-7e607b2f.json | 439 - .../pixelaw-PixelRecoveryRate-3aa284c0.json | 407 - .../abis/models/pixelaw-Player-30a1b371.json | 433 - .../models/pixelaw-PlayerVote-326c17c6.json | 433 - .../models/pixelaw-Proposal-49e1daf5.json | 457 - .../models/pixelaw-QueueItem-549a17f2.json | 421 - .../manifests/dev/deployment/manifest.json | 13785 ---------------- .../manifests/dev/deployment/manifest.toml | 801 - .../contracts/pixelaw-actions-16928a49.json | 775 - .../pixelaw-guild_actions-4c9f5931.json | 383 - .../pixelaw-p_war_actions-60819afd.json | 583 - .../pixelaw-propose_actions-4ee7028a.json | 363 - .../pixelaw-voting_actions-6aab73ea.json | 288 - .../release/base/abis/dojo-base.json | 98 - .../release/base/abis/dojo-world.json | 1231 -- .../models/pixelaw-AllowedApp-4aa27058.json | 425 - .../models/pixelaw-AllowedColor-22c1a796.json | 425 - .../abis/models/pixelaw-App-36504565.json | 415 - .../abis/models/pixelaw-AppName-3b816829.json | 407 - .../abis/models/pixelaw-AppUser-4eda3c52.json | 411 - .../abis/models/pixelaw-Board-124dc3e7.json | 429 - .../pixelaw-CoreActionsAddress-5379e1ce.json | 407 - .../abis/models/pixelaw-Game-5c1fa23f.json | 449 - .../abis/models/pixelaw-GameId-1ee8756e.json | 411 - .../models/pixelaw-GamePalette-49013f2b.json | 407 - .../abis/models/pixelaw-Guild-40e97c00.json | 433 - .../models/pixelaw-InPalette-7a46e3ad.json | 425 - .../models/pixelaw-Instruction-4c7c4844.json | 411 - .../models/pixelaw-PWarPixel-15195913.json | 421 - .../pixelaw-PaletteColors-39a92a0a.json | 411 - .../models/pixelaw-Permissions-72b77307.json | 455 - .../abis/models/pixelaw-Pixel-7e607b2f.json | 439 - .../pixelaw-PixelRecoveryRate-3aa284c0.json | 407 - .../abis/models/pixelaw-Player-30a1b371.json | 433 - .../models/pixelaw-PlayerVote-326c17c6.json | 433 - .../models/pixelaw-Proposal-49e1daf5.json | 457 - .../models/pixelaw-QueueItem-549a17f2.json | 421 - .../contracts/pixelaw-actions-16928a49.toml | 19 - .../pixelaw-guild_actions-4c9f5931.toml | 14 - .../pixelaw-p_war_actions-60819afd.toml | 20 - .../pixelaw-propose_actions-4ee7028a.toml | 11 - .../pixelaw-voting_actions-6aab73ea.toml | 11 - .../manifests/release/base/dojo-base.toml | 6 - .../manifests/release/base/dojo-world.toml | 6 - .../models/pixelaw-AllowedApp-4aa27058.toml | 22 - .../models/pixelaw-AllowedColor-22c1a796.toml | 22 - .../base/models/pixelaw-App-36504565.toml | 27 - .../base/models/pixelaw-AppName-3b816829.toml | 17 - .../base/models/pixelaw-AppUser-4eda3c52.toml | 22 - .../base/models/pixelaw-Board-124dc3e7.toml | 27 - .../pixelaw-CoreActionsAddress-5379e1ce.toml | 17 - .../base/models/pixelaw-Game-5c1fa23f.toml | 57 - .../base/models/pixelaw-GameId-1ee8756e.toml | 22 - .../models/pixelaw-GamePalette-49013f2b.toml | 17 - .../base/models/pixelaw-Guild-40e97c00.toml | 37 - .../models/pixelaw-InPalette-7a46e3ad.toml | 22 - .../models/pixelaw-Instruction-4c7c4844.toml | 22 - .../models/pixelaw-PWarPixel-15195913.toml | 17 - .../pixelaw-PaletteColors-39a92a0a.toml | 22 - .../models/pixelaw-Permissions-72b77307.toml | 22 - .../base/models/pixelaw-Pixel-7e607b2f.toml | 57 - .../pixelaw-PixelRecoveryRate-3aa284c0.toml | 17 - .../base/models/pixelaw-Player-30a1b371.toml | 32 - .../models/pixelaw-PlayerVote-326c17c6.toml | 32 - .../models/pixelaw-Proposal-49e1daf5.toml | 62 - .../models/pixelaw-QueueItem-549a17f2.toml | 17 - .../contracts/pixelaw-actions-16928a49.json | 775 - .../pixelaw-guild_actions-4c9f5931.json | 383 - .../pixelaw-p_war_actions-60819afd.json | 583 - .../contracts/pixelaw-propose-70d0002d.json | 289 - .../pixelaw-propose_actions-4ee7028a.json | 363 - .../contracts/pixelaw-voting-324fa594.json | 255 - .../pixelaw-voting_actions-6aab73ea.json | 288 - .../release/deployment/abis/dojo-base.json | 98 - .../release/deployment/abis/dojo-world.json | 1231 -- .../models/pixelaw-AllowedApp-4aa27058.json | 425 - .../models/pixelaw-AllowedColor-22c1a796.json | 425 - .../abis/models/pixelaw-App-36504565.json | 415 - .../abis/models/pixelaw-AppName-3b816829.json | 407 - .../abis/models/pixelaw-AppUser-4eda3c52.json | 411 - .../abis/models/pixelaw-Board-124dc3e7.json | 429 - .../pixelaw-CoreActionsAddress-5379e1ce.json | 407 - .../abis/models/pixelaw-Game-5c1fa23f.json | 449 - .../abis/models/pixelaw-GameId-1ee8756e.json | 411 - .../models/pixelaw-GamePalette-49013f2b.json | 407 - .../abis/models/pixelaw-Guild-40e97c00.json | 433 - .../models/pixelaw-InPalette-7a46e3ad.json | 425 - .../models/pixelaw-Instruction-4c7c4844.json | 411 - .../models/pixelaw-PWarPixel-15195913.json | 421 - .../pixelaw-PaletteColors-39a92a0a.json | 411 - .../models/pixelaw-Permissions-72b77307.json | 455 - .../abis/models/pixelaw-Pixel-7e607b2f.json | 439 - .../pixelaw-PixelRecoveryRate-3aa284c0.json | 407 - .../abis/models/pixelaw-Player-30a1b371.json | 433 - .../models/pixelaw-PlayerVote-326c17c6.json | 433 - .../models/pixelaw-Proposal-49e1daf5.json | 457 - .../models/pixelaw-QueueItem-549a17f2.json | 421 - .../abis/models/pixelaw-Snake-62b876d4.json | 471 - .../models/pixelaw-SnakeSegment-302de0d8.json | 431 - .../release/deployment/manifest.json | 13785 ---------------- .../release/deployment/manifest.toml | 801 - contracts/overlays/dev/core_actions.toml | 13 - contracts/overlays/dev/guild_actions.toml | 2 - contracts/overlays/dev/p_war_actions.toml | 14 - contracts/overlays/dev/propose_actions.toml | 11 - contracts/overlays/dev/voting_actions.toml | 2 - contracts/overlays/release/core_actions.toml | 13 - contracts/overlays/release/guild_actions.toml | 2 - contracts/overlays/release/p_war_actions.toml | 14 - .../overlays/release/propose_actions.toml | 11 - .../overlays/release/voting_actions.toml | 2 - 203 files changed, 138 insertions(+), 84438 deletions(-) delete mode 100644 .devcontainer/devcontainer.json delete mode 100644 contracts/manifests/dev/base/abis/contracts/pixelaw-actions-16928a49.json delete mode 100644 contracts/manifests/dev/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json delete mode 100644 contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json delete mode 100644 contracts/manifests/dev/base/abis/contracts/pixelaw-propose_actions-4ee7028a.json delete mode 100644 contracts/manifests/dev/base/abis/contracts/pixelaw-voting_actions-6aab73ea.json delete mode 100644 contracts/manifests/dev/base/abis/dojo-base.json delete mode 100644 contracts/manifests/dev/base/abis/dojo-world.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-AllowedApp-4aa27058.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-AllowedColor-22c1a796.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-App-36504565.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-AppName-3b816829.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-AppUser-4eda3c52.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Board-124dc3e7.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Game-5c1fa23f.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-GameId-1ee8756e.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-GamePalette-49013f2b.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Guild-40e97c00.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-InPalette-7a46e3ad.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Instruction-4c7c4844.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-PWarPixel-15195913.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-PaletteColors-39a92a0a.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Permissions-72b77307.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Pixel-7e607b2f.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Player-30a1b371.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-PlayerVote-326c17c6.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-Proposal-49e1daf5.json delete mode 100644 contracts/manifests/dev/base/abis/models/pixelaw-QueueItem-549a17f2.json delete mode 100644 contracts/manifests/dev/base/contracts/pixelaw-actions-16928a49.toml delete mode 100644 contracts/manifests/dev/base/contracts/pixelaw-guild_actions-4c9f5931.toml delete mode 100644 contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml delete mode 100644 contracts/manifests/dev/base/contracts/pixelaw-propose_actions-4ee7028a.toml delete mode 100644 contracts/manifests/dev/base/contracts/pixelaw-voting_actions-6aab73ea.toml delete mode 100644 contracts/manifests/dev/base/dojo-base.toml delete mode 100644 contracts/manifests/dev/base/dojo-world.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-AllowedApp-4aa27058.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-AllowedColor-22c1a796.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-App-36504565.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-AppName-3b816829.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-AppUser-4eda3c52.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Board-124dc3e7.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Game-5c1fa23f.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-GameId-1ee8756e.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-GamePalette-49013f2b.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Guild-40e97c00.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-InPalette-7a46e3ad.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Instruction-4c7c4844.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-PWarPixel-15195913.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-PaletteColors-39a92a0a.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Permissions-72b77307.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Pixel-7e607b2f.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Player-30a1b371.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-PlayerVote-326c17c6.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-Proposal-49e1daf5.toml delete mode 100644 contracts/manifests/dev/base/models/pixelaw-QueueItem-549a17f2.toml delete mode 100644 contracts/manifests/dev/deployment/abis/contracts/pixelaw-actions-16928a49.json delete mode 100644 contracts/manifests/dev/deployment/abis/contracts/pixelaw-guild_actions-4c9f5931.json delete mode 100644 contracts/manifests/dev/deployment/abis/contracts/pixelaw-p_war_actions-60819afd.json delete mode 100644 contracts/manifests/dev/deployment/abis/contracts/pixelaw-propose_actions-4ee7028a.json delete mode 100644 contracts/manifests/dev/deployment/abis/contracts/pixelaw-voting_actions-6aab73ea.json delete mode 100644 contracts/manifests/dev/deployment/abis/dojo-base.json delete mode 100644 contracts/manifests/dev/deployment/abis/dojo-world.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-AllowedApp-4aa27058.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-AllowedColor-22c1a796.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-App-36504565.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-AppName-3b816829.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-AppUser-4eda3c52.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-Board-124dc3e7.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-Game-5c1fa23f.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-GameId-1ee8756e.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-GamePalette-49013f2b.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-Guild-40e97c00.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-InPalette-7a46e3ad.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-Instruction-4c7c4844.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-PWarPixel-15195913.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-PaletteColors-39a92a0a.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-Permissions-72b77307.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-Pixel-7e607b2f.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-Player-30a1b371.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-PlayerVote-326c17c6.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-Proposal-49e1daf5.json delete mode 100644 contracts/manifests/dev/deployment/abis/models/pixelaw-QueueItem-549a17f2.json delete mode 100644 contracts/manifests/dev/deployment/manifest.json delete mode 100644 contracts/manifests/dev/deployment/manifest.toml delete mode 100644 contracts/manifests/release/base/abis/contracts/pixelaw-actions-16928a49.json delete mode 100644 contracts/manifests/release/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json delete mode 100644 contracts/manifests/release/base/abis/contracts/pixelaw-p_war_actions-60819afd.json delete mode 100644 contracts/manifests/release/base/abis/contracts/pixelaw-propose_actions-4ee7028a.json delete mode 100644 contracts/manifests/release/base/abis/contracts/pixelaw-voting_actions-6aab73ea.json delete mode 100644 contracts/manifests/release/base/abis/dojo-base.json delete mode 100644 contracts/manifests/release/base/abis/dojo-world.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-AllowedApp-4aa27058.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-AllowedColor-22c1a796.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-App-36504565.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-AppName-3b816829.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-AppUser-4eda3c52.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-Board-124dc3e7.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-Game-5c1fa23f.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-GameId-1ee8756e.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-GamePalette-49013f2b.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-Guild-40e97c00.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-InPalette-7a46e3ad.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-Instruction-4c7c4844.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-PWarPixel-15195913.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-PaletteColors-39a92a0a.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-Permissions-72b77307.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-Pixel-7e607b2f.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-Player-30a1b371.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-PlayerVote-326c17c6.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-Proposal-49e1daf5.json delete mode 100644 contracts/manifests/release/base/abis/models/pixelaw-QueueItem-549a17f2.json delete mode 100644 contracts/manifests/release/base/contracts/pixelaw-actions-16928a49.toml delete mode 100644 contracts/manifests/release/base/contracts/pixelaw-guild_actions-4c9f5931.toml delete mode 100644 contracts/manifests/release/base/contracts/pixelaw-p_war_actions-60819afd.toml delete mode 100644 contracts/manifests/release/base/contracts/pixelaw-propose_actions-4ee7028a.toml delete mode 100644 contracts/manifests/release/base/contracts/pixelaw-voting_actions-6aab73ea.toml delete mode 100644 contracts/manifests/release/base/dojo-base.toml delete mode 100644 contracts/manifests/release/base/dojo-world.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-AllowedApp-4aa27058.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-AllowedColor-22c1a796.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-App-36504565.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-AppName-3b816829.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-AppUser-4eda3c52.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-Board-124dc3e7.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-Game-5c1fa23f.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-GameId-1ee8756e.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-GamePalette-49013f2b.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-Guild-40e97c00.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-InPalette-7a46e3ad.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-Instruction-4c7c4844.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-PWarPixel-15195913.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-PaletteColors-39a92a0a.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-Permissions-72b77307.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-Pixel-7e607b2f.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-Player-30a1b371.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-PlayerVote-326c17c6.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-Proposal-49e1daf5.toml delete mode 100644 contracts/manifests/release/base/models/pixelaw-QueueItem-549a17f2.toml delete mode 100644 contracts/manifests/release/deployment/abis/contracts/pixelaw-actions-16928a49.json delete mode 100644 contracts/manifests/release/deployment/abis/contracts/pixelaw-guild_actions-4c9f5931.json delete mode 100644 contracts/manifests/release/deployment/abis/contracts/pixelaw-p_war_actions-60819afd.json delete mode 100644 contracts/manifests/release/deployment/abis/contracts/pixelaw-propose-70d0002d.json delete mode 100644 contracts/manifests/release/deployment/abis/contracts/pixelaw-propose_actions-4ee7028a.json delete mode 100644 contracts/manifests/release/deployment/abis/contracts/pixelaw-voting-324fa594.json delete mode 100644 contracts/manifests/release/deployment/abis/contracts/pixelaw-voting_actions-6aab73ea.json delete mode 100644 contracts/manifests/release/deployment/abis/dojo-base.json delete mode 100644 contracts/manifests/release/deployment/abis/dojo-world.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-AllowedApp-4aa27058.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-AllowedColor-22c1a796.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-App-36504565.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-AppName-3b816829.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-AppUser-4eda3c52.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-Board-124dc3e7.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-Game-5c1fa23f.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-GameId-1ee8756e.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-GamePalette-49013f2b.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-Guild-40e97c00.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-InPalette-7a46e3ad.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-Instruction-4c7c4844.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-PWarPixel-15195913.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-PaletteColors-39a92a0a.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-Permissions-72b77307.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-Pixel-7e607b2f.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-Player-30a1b371.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-PlayerVote-326c17c6.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-Proposal-49e1daf5.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-QueueItem-549a17f2.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-Snake-62b876d4.json delete mode 100644 contracts/manifests/release/deployment/abis/models/pixelaw-SnakeSegment-302de0d8.json delete mode 100644 contracts/manifests/release/deployment/manifest.json delete mode 100644 contracts/manifests/release/deployment/manifest.toml delete mode 100644 contracts/overlays/dev/core_actions.toml delete mode 100644 contracts/overlays/dev/guild_actions.toml delete mode 100644 contracts/overlays/dev/p_war_actions.toml delete mode 100644 contracts/overlays/dev/propose_actions.toml delete mode 100644 contracts/overlays/dev/voting_actions.toml delete mode 100644 contracts/overlays/release/core_actions.toml delete mode 100644 contracts/overlays/release/guild_actions.toml delete mode 100644 contracts/overlays/release/p_war_actions.toml delete mode 100644 contracts/overlays/release/propose_actions.toml delete mode 100644 contracts/overlays/release/voting_actions.toml diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json deleted file mode 100644 index 6e5d786..0000000 --- a/.devcontainer/devcontainer.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "My Project", - "image": "ghcr.io/pixelaw/core:0.5.10", - "workspaceFolder": "/workspaces/pwar", - "workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/pwar,type=bind", - "forwardPorts": [ - 5050, - 8080, - 9090, - 3000 - ], - "containerEnv": { - "RPC_URL": "http://localhost:5050", - "TORII_URL": "http://localhost:8080", - "RELAY_URL": "http://localhost:8080", - "PUBLIC_SERVER_URL": "http://localhost:3000", - "PUBLIC_RPC_URL": "http://localhost:5050", - "PUBLIC_TORII_URL": "http://localhost:8080", - "PUBLIC_RELAY_URL": "http://localhost:8080", - "MASTER_ADDRESS": "0xb3ff441a68610b30fd5e2abbf3a1548eb6ba6f3559f2862bf2dc757e5828ca", - "MASTER_PRIVATE_KEY": "0x2bbf4f9fd0bbb2e60b0316c1fe0b76cf7a4d0198bd493ced9b8df2a3a24d68a", - "WORLD_ADDRESS": "0x6f130c8e150882e39cbe878c650c8f35c86579180dbc77d0c1cbe169449b5f6", - "ACCOUNT_CLASS_HASH": "0x05400e90f7e0ae78bd02c77cd75527280470e2fe19c54970dd79dc37a9d3645c", - "FEETOKEN_ADDRESS": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", - "SERVER_PORT": "3000" - }, - "postStartCommand": [ - "/pixelaw/scripts/startup.sh" - ], - // 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.0.1/bin/dojo-language-server", - "cairo1.enableScarb": true, - "cairo1.scarbPath": "${userHome}/.asdf/installs/scarb/2.7.0/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" - ] - } - } -} \ No newline at end of file diff --git a/.github/workflows/ci-contracts.yml b/.github/workflows/ci-contracts.yml index 08974e8..7a5a75b 100644 --- a/.github/workflows/ci-contracts.yml +++ b/.github/workflows/ci-contracts.yml @@ -25,7 +25,7 @@ jobs: - uses: actions/checkout@v3 - uses: software-mansion/setup-scarb@v1 with: - scarb-version: "2.7.0" + scarb-version: "2.8.4" - run: | scarb fmt --check core-test: @@ -35,6 +35,6 @@ jobs: - uses: asdf-vm/actions/setup@v3 - run: | asdf plugin add dojo https://github.com/dojoengine/asdf-dojo - asdf install dojo 1.0.0-alpha.12 - asdf global dojo 1.0.0-alpha.12 + asdf install dojo 1.0.4 + asdf global dojo 1.0.4 sozo test diff --git a/contracts/.gitignore b/contracts/.gitignore index fa002b3..7904cb3 100644 --- a/contracts/.gitignore +++ b/contracts/.gitignore @@ -2,4 +2,5 @@ db target generated .idea -manifests \ No newline at end of file +manifests +sepolia.deployer.keystore.json \ No newline at end of file diff --git a/contracts/.tool-versions b/contracts/.tool-versions index a62484c..7b2bea4 100644 --- a/contracts/.tool-versions +++ b/contracts/.tool-versions @@ -1,2 +1,2 @@ -dojo 1.0.1 -scarb 2.7.0 \ No newline at end of file +dojo 1.0.4 +scarb 2.8.4 \ No newline at end of file diff --git a/contracts/.vscode/settings.json b/contracts/.vscode/settings.json index 087695b..d681426 100644 --- a/contracts/.vscode/settings.json +++ b/contracts/.vscode/settings.json @@ -1,7 +1,7 @@ { "cairo1.enableLanguageServer": true, - "cairo1.languageServerPath": "${userHome}/.asdf/installs/dojo/1.0.0-alpha.12/bin/dojo-language-server", + "cairo1.languageServerPath": "${userHome}/.asdf/installs/dojo/1.0.4/bin/dojo-language-server", "cairo1.enableScarb": true, - "cairo1.scarbPath": "${userHome}/.asdf/installs/scarb/2.7.0/bin/scarb", + "cairo1.scarbPath": "${userHome}/.asdf/installs/scarb/2.8.4/bin/scarb", "cairo1.preferScarbLanguageServer": false } diff --git a/contracts/.vscode/tasks.json b/contracts/.vscode/tasks.json index 95c4ce6..8f90a24 100644 --- a/contracts/.vscode/tasks.json +++ b/contracts/.vscode/tasks.json @@ -4,7 +4,7 @@ { "label": "Start Katana", "type": "shell", - "command": "katana --disable-fee --allowed-origins '*' --db-dir db/katana", + "command": "katana --http.cors_origins '*' --db-dir db/katana", "isBackground": true, "problemMatcher": [], "presentation": { @@ -16,7 +16,7 @@ { "label": "Start Torii", "type": "shell", - "command": "torii --world 0x263ae44e5414519a5c5a135cccaf3d9d7ee196d37e8de47a178da91f3de9b34 --allowed-origins '*' --database db/torii", + "command": "torii --world 0x6f130c8e150882e39cbe878c650c8f35c86579180dbc77d0c1cbe169449b5f6 --http.cors_origins '*' --db-dir db/torii", "isBackground": true, "problemMatcher": [], "presentation": { @@ -40,4 +40,4 @@ } } ] -} +} \ No newline at end of file diff --git a/contracts/Scarb.lock b/contracts/Scarb.lock index 431883e..03ca59b 100644 --- a/contracts/Scarb.lock +++ b/contracts/Scarb.lock @@ -3,8 +3,8 @@ version = 1 [[package]] name = "dojo" -version = "1.0.1" -source = "git+https://github.com/dojoengine/dojo?tag=v1.0.1#d7335e6f5c76a1dda887ec00c594c2c019b4a05f" +version = "1.0.4" +source = "git+https://github.com/dojoengine/dojo?tag=v1.0.4#e9f286c14f5952604bec915719c14b7f2d7b4233" dependencies = [ "dojo_plugin", ] @@ -12,7 +12,7 @@ dependencies = [ [[package]] name = "dojo_cairo_test" version = "1.0.0-rc.0" -source = "git+https://github.com/dojoengine/dojo?tag=v1.0.1#d7335e6f5c76a1dda887ec00c594c2c019b4a05f" +source = "git+https://github.com/dojoengine/dojo?tag=v1.0.4#e9f286c14f5952604bec915719c14b7f2d7b4233" dependencies = [ "dojo", ] @@ -20,13 +20,12 @@ dependencies = [ [[package]] name = "dojo_plugin" version = "2.8.4" -source = "git+https://github.com/dojoengine/dojo?tag=v1.0.1#d7335e6f5c76a1dda887ec00c594c2c019b4a05f" +source = "git+https://github.com/dojoengine/dojo?tag=v1.0.4#e9f286c14f5952604bec915719c14b7f2d7b4233" [[package]] name = "p_war" version = "0.3.54" dependencies = [ - "dojo", "dojo_cairo_test", "pixelaw", "pixelaw_test_helpers", @@ -34,16 +33,16 @@ dependencies = [ [[package]] name = "pixelaw" -version = "0.5.10" -source = "git+https://github.com/pixelaw/core?tag=v0.5.10#fd8a6981da68fffe4889b48406b69cbbd493cc83" +version = "0.5.15" +source = "git+https://github.com/pixelaw/core?tag=v0.5.15#6f18b9210cd917b6247be8e77e96381c05284443" dependencies = [ "dojo", ] [[package]] name = "pixelaw_test_helpers" -version = "0.5.10" -source = "git+https://github.com/pixelaw/core?tag=v0.5.10#fd8a6981da68fffe4889b48406b69cbbd493cc83" +version = "0.5.15" +source = "git+https://github.com/pixelaw/core?tag=v0.5.15#6f18b9210cd917b6247be8e77e96381c05284443" dependencies = [ "dojo", "dojo_cairo_test", diff --git a/contracts/Scarb.toml b/contracts/Scarb.toml index 7f1daab..1506a92 100644 --- a/contracts/Scarb.toml +++ b/contracts/Scarb.toml @@ -7,14 +7,11 @@ version = "0.3.54" sierra-replace-ids = true [dependencies] -pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.5.10" } -#pixelaw = { path = "../core/contracts" } -dojo = { git = "https://github.com/dojoengine/dojo", tag = "v1.0.1" } +pixelaw = { git = "https://github.com/pixelaw/core", tag = "v0.5.15" } [dev-dependencies] -dojo_cairo_test = { git = "https://github.com/dojoengine/dojo", tag = "v1.0.1" } -pixelaw_test_helpers = { git = "https://github.com/pixelaw/core", tag = "v0.5.10" } -#pixelaw_test_helpers = { path = "../core/test_helpers" } +dojo_cairo_test = { git = "https://github.com/dojoengine/dojo", tag = "v1.0.4" } +pixelaw_test_helpers = { git = "https://github.com/pixelaw/core", tag = "v0.5.15" } [[target.starknet-contract]] allowed-libfuncs-list.name = "experimental" diff --git a/contracts/dojo_dev.toml b/contracts/dojo_dev.toml index 2c9aefc..e5ab75d 100644 --- a/contracts/dojo_dev.toml +++ b/contracts/dojo_dev.toml @@ -12,3 +12,41 @@ rpc_url = "http://localhost:5050/" account_address = "0x127fd5f1fe78a71f8bcd1fec63e3fe2f0486b6ecd5c86a0466c3a21fa5cfcec" private_key = "0xc5b2fcab997346f3ea1c00b002ecf6f382c5f9c9659a3894eb783c5320f912" world_address = "0x6f130c8e150882e39cbe878c650c8f35c86579180dbc77d0c1cbe169449b5f6" + +[writers] +# CORE +"pixelaw-App" = ["pixelaw-actions"] +"pixelaw-AppName" = ["pixelaw-actions"] +"pixelaw-AppUser" = ["pixelaw-actions"] +"pixelaw-CoreActionsAddress" = ["pixelaw-actions"] +"pixelaw-QueueScheduled" = ["pixelaw-actions"] +"pixelaw-QueueProcessed" = ["pixelaw-actions"] +"pixelaw-Alert" = ["pixelaw-actions"] +"pixelaw-Pixel" = [ + "pixelaw-actions", + "pixelaw-paint_actions", + "pixelaw-snake_actions", +] +"pixelaw-QueueItem" = ["pixelaw-actions"] +"pixelaw-Snake" = ["pixelaw-actions", "pixelaw-snake_actions"] +"pixelaw-RTree" = ["pixelaw-actions"] +"pixelaw-Area" = ["pixelaw-actions"] +"pixelaw-SnakeSegment" = ["pixelaw-snake_actions"] +# GUILD +"pixelaw-Guild" = ["pixelaw-guild_actions"] +# P-WAR +"pixelaw-AllowedApp" = ["pixelaw-p_war_actions"] +"pixelaw-Board" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] +"pixelaw-AllowedColor" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] +"pixelaw-PaletteColors" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] +"pixelaw-PWarPixel" = ["pixelaw-p_war_actions"] +"pixelaw-Game" = ["pixelaw-p_war_actions"] +"pixelaw-GameId" = ["pixelaw-p_war_actions"] +"pixelaw-GamePalette" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] +"pixelaw-InPalette" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] +"pixelaw-Player" = ["pixelaw-p_war_actions", "pixelaw-propose_actions", "pixelaw-voting_actions"] +"pixelaw-PixelRecoveryRate" = ["pixelaw-p_war_actions"] +# PROPOSE +"pixelaw-Proposal" = ["pixelaw-propose_actions", "pixelaw-voting_actions"] +# VOTING +"pixelaw-PlayerVote" = ["pixelaw-voting_actions"] diff --git a/contracts/dojo_release.toml b/contracts/dojo_release.toml index 980ecf6..2ff975d 100644 --- a/contracts/dojo_release.toml +++ b/contracts/dojo_release.toml @@ -16,3 +16,41 @@ rpc_url = "https://api.cartridge.gg/x/pwar-dev-2/katana/" account_address = "0x8cecdb74164f073793942ddd1c477a6549d43a5ce57f4640eadefe0a6dd8bf" private_key = "0x422f174dedd139c6cad1c535b1a7d43a6cf224f71cb4a67e1070347a952b9d0" world_address = "0x263ae44e5414519a5c5a135cccaf3d9d7ee196d37e8de47a178da91f3de9b34" + +[writers] +# CORE +"pixelaw-App" = ["pixelaw-actions"] +"pixelaw-AppName" = ["pixelaw-actions"] +"pixelaw-AppUser" = ["pixelaw-actions"] +"pixelaw-CoreActionsAddress" = ["pixelaw-actions"] +"pixelaw-QueueScheduled" = ["pixelaw-actions"] +"pixelaw-QueueProcessed" = ["pixelaw-actions"] +"pixelaw-Alert" = ["pixelaw-actions"] +"pixelaw-Pixel" = [ + "pixelaw-actions", + "pixelaw-paint_actions", + "pixelaw-snake_actions", +] +"pixelaw-QueueItem" = ["pixelaw-actions"] +"pixelaw-Snake" = ["pixelaw-actions", "pixelaw-snake_actions"] +"pixelaw-RTree" = ["pixelaw-actions"] +"pixelaw-Area" = ["pixelaw-actions"] +"pixelaw-SnakeSegment" = ["pixelaw-snake_actions"] +# GUILD +"pixelaw-Guild" = ["pixelaw-guild_actions"] +# P-WAR +"pixelaw-AllowedApp" = ["pixelaw-p_war_actions"] +"pixelaw-Board" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] +"pixelaw-AllowedColor" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] +"pixelaw-PaletteColors" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] +"pixelaw-PWarPixel" = ["pixelaw-p_war_actions"] +"pixelaw-Game" = ["pixelaw-p_war_actions"] +"pixelaw-GameId" = ["pixelaw-p_war_actions"] +"pixelaw-GamePalette" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] +"pixelaw-InPalette" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] +"pixelaw-Player" = ["pixelaw-p_war_actions", "pixelaw-propose_actions", "pixelaw-voting_actions"] +"pixelaw-PixelRecoveryRate" = ["pixelaw-p_war_actions"] +# PROPOSE +"pixelaw-Proposal" = ["pixelaw-propose_actions", "pixelaw-voting_actions"] +# VOTING +"pixelaw-PlayerVote" = ["pixelaw-voting_actions"] diff --git a/contracts/dojo_sepolia.toml b/contracts/dojo_sepolia.toml index e595baf..32fec3d 100644 --- a/contracts/dojo_sepolia.toml +++ b/contracts/dojo_sepolia.toml @@ -9,7 +9,44 @@ mappings = {} [env] rpc_url = "https://starknet-sepolia.public.blastapi.io/rpc/v0_7" -keystore_path = "accounts/sepolia.deployer.keystore.json" +keystore_path = "sepolia.deployer.keystore.json" world_address = "0x6f130c8e150882e39cbe878c650c8f35c86579180dbc77d0c1cbe169449b5f6" +account_address = "YOUR_ACCOUNT" -account_address = "YOUR_ACCOUNT" \ No newline at end of file +[writers] +# CORE +"pixelaw-App" = ["pixelaw-actions"] +"pixelaw-AppName" = ["pixelaw-actions"] +"pixelaw-AppUser" = ["pixelaw-actions"] +"pixelaw-CoreActionsAddress" = ["pixelaw-actions"] +"pixelaw-QueueScheduled" = ["pixelaw-actions"] +"pixelaw-QueueProcessed" = ["pixelaw-actions"] +"pixelaw-Alert" = ["pixelaw-actions"] +"pixelaw-Pixel" = [ + "pixelaw-actions", + "pixelaw-paint_actions", + "pixelaw-snake_actions", +] +"pixelaw-QueueItem" = ["pixelaw-actions"] +"pixelaw-Snake" = ["pixelaw-actions", "pixelaw-snake_actions"] +"pixelaw-RTree" = ["pixelaw-actions"] +"pixelaw-Area" = ["pixelaw-actions"] +"pixelaw-SnakeSegment" = ["pixelaw-snake_actions"] +# GUILD +"pixelaw-Guild" = ["pixelaw-guild_actions"] +# P-WAR +"pixelaw-AllowedApp" = ["pixelaw-p_war_actions"] +"pixelaw-Board" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] +"pixelaw-AllowedColor" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] +"pixelaw-PaletteColors" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] +"pixelaw-PWarPixel" = ["pixelaw-p_war_actions"] +"pixelaw-Game" = ["pixelaw-p_war_actions"] +"pixelaw-GameId" = ["pixelaw-p_war_actions"] +"pixelaw-GamePalette" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] +"pixelaw-InPalette" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] +"pixelaw-Player" = ["pixelaw-p_war_actions", "pixelaw-propose_actions", "pixelaw-voting_actions"] +"pixelaw-PixelRecoveryRate" = ["pixelaw-p_war_actions"] +# PROPOSE +"pixelaw-Proposal" = ["pixelaw-propose_actions", "pixelaw-voting_actions"] +# VOTING +"pixelaw-PlayerVote" = ["pixelaw-voting_actions"] diff --git a/contracts/manifests/dev/base/abis/contracts/pixelaw-actions-16928a49.json b/contracts/manifests/dev/base/abis/contracts/pixelaw-actions-16928a49.json deleted file mode 100644 index e71ba18..0000000 --- a/contracts/manifests/dev/base/abis/contracts/pixelaw-actions-16928a49.json +++ /dev/null @@ -1,775 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsImpl", - "interface_name": "pixelaw::core::actions::IActions" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permission", - "members": [ - { - "name": "app", - "type": "core::bool" - }, - { - "name": "color", - "type": "core::bool" - }, - { - "name": "owner", - "type": "core::bool" - }, - { - "name": "text", - "type": "core::bool" - }, - { - "name": "timestamp", - "type": "core::bool" - }, - { - "name": "action", - "type": "core::bool" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::pixel::Pixel", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "created_at", - "type": "core::integer::u64" - }, - { - "name": "updated_at", - "type": "core::integer::u64" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "text", - "type": "core::felt252" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "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": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "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": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "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": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::actions::IActions", - "items": [ - { - "type": "function", - "name": "init", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_permission", - "inputs": [ - { - "name": "app_key", - "type": "core::felt252" - }, - { - "name": "permission", - "type": "pixelaw::core::models::permissions::Permission" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "has_write_access", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "pixel", - "type": "pixelaw::core::models::pixel::Pixel" - }, - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [ - { - "type": "core::bool" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "process_queue", - "inputs": [ - { - "name": "id", - "type": "core::felt252" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "schedule_queue", - "inputs": [ - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_pixel", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "new_app", - "inputs": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "icon", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "pixelaw::core::models::registry::App" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_system_address", - "inputs": [ - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "get_player_address", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "alert_player", - "inputs": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "message", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_instruction", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "instruction", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "pixelaw::core::actions::actions::IDojoInit" - }, - { - "type": "interface", - "name": "pixelaw::core::actions::actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::QueueScheduled", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "calldata", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::QueueProcessed", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::AppNameUpdated", - "kind": "struct", - "members": [ - { - "name": "app", - "type": "pixelaw::core::models::registry::App", - "kind": "data" - }, - { - "name": "caller", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::Alert", - "kind": "struct", - "members": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position", - "kind": "data" - }, - { - "name": "caller", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "message", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "QueueScheduled", - "type": "pixelaw::core::actions::actions::QueueScheduled", - "kind": "nested" - }, - { - "name": "QueueProcessed", - "type": "pixelaw::core::actions::actions::QueueProcessed", - "kind": "nested" - }, - { - "name": "AppNameUpdated", - "type": "pixelaw::core::actions::actions::AppNameUpdated", - "kind": "nested" - }, - { - "name": "Alert", - "type": "pixelaw::core::actions::actions::Alert", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json b/contracts/manifests/dev/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json deleted file mode 100644 index 1c07f99..0000000 --- a/contracts/manifests/dev/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json +++ /dev/null @@ -1,410 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "GuildImpl", - "interface_name": "p_war::systems::guilds::IGuild" - }, - { - "type": "interface", - "name": "p_war::systems::guilds::IGuild", - "items": [ - { - "type": "function", - "name": "create_guild", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_name", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "add_member", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "new_member", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "join_guild", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "remove_member", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_guild_contract_address", - "inputs": [], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "get_guild_points", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::guilds::guild_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::guilds::guild_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::GuildCreated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_name", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::MemberAdded", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::MemberRemoved", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "GuildCreated", - "type": "p_war::systems::guilds::guild_actions::GuildCreated", - "kind": "nested" - }, - { - "name": "MemberAdded", - "type": "p_war::systems::guilds::guild_actions::MemberAdded", - "kind": "nested" - }, - { - "name": "MemberRemoved", - "type": "p_war::systems::guilds::guild_actions::MemberRemoved", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json b/contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json deleted file mode 100644 index 1cce46a..0000000 --- a/contracts/manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json +++ /dev/null @@ -1,603 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsInteroperability", - "interface_name": "pixelaw::core::traits::IInteroperability" - }, - { - "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": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "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": "interface", - "name": "pixelaw::core::traits::IInteroperability", - "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": [], - "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": "impl", - "name": "AllowedAppImpl", - "interface_name": "p_war::systems::apps::IAllowedApp" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::utils::DefaultParameters", - "members": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "color", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::apps::IAllowedApp", - "items": [ - { - "type": "function", - "name": "set_pixel", - "inputs": [ - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsImpl", - "interface_name": "p_war::systems::actions::IActions" - }, - { - "type": "interface", - "name": "p_war::systems::actions::IActions", - "items": [ - { - "type": "function", - "name": "init", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "interact", - "inputs": [ - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "create_game", - "inputs": [ - { - "name": "origin", - "type": "pixelaw::core::utils::Position" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "create_game_guilds", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [ - { - "type": "core::array::Array::" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_game_id", - "inputs": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "place_pixel", - "inputs": [ - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_pixel", - "inputs": [ - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "end_game", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::actions::p_war_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::actions::p_war_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::StartedGame", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u128", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::EndedGame", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u128", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "StartedGame", - "type": "p_war::systems::actions::p_war_actions::StartedGame", - "kind": "nested" - }, - { - "name": "EndedGame", - "type": "p_war::systems::actions::p_war_actions::EndedGame", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/contracts/pixelaw-propose_actions-4ee7028a.json b/contracts/manifests/dev/base/abis/contracts/pixelaw-propose_actions-4ee7028a.json deleted file mode 100644 index 8aa1e40..0000000 --- a/contracts/manifests/dev/base/abis/contracts/pixelaw-propose_actions-4ee7028a.json +++ /dev/null @@ -1,363 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ProposeImpl", - "interface_name": "p_war::systems::propose::IPropose" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::propose::IPropose", - "items": [ - { - "type": "function", - "name": "create_proposal", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "proposal_type", - "type": "core::integer::u8" - }, - { - "name": "target_args_1", - "type": "core::integer::u32" - }, - { - "name": "target_args_2", - "type": "core::integer::u32" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "activate_proposal", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "clear_data", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::propose::propose_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::propose::propose_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::ProposalCreated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "proposal_type", - "type": "core::integer::u8", - "kind": "data" - }, - { - "name": "target_args_1", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "target_args_2", - "type": "core::integer::u32", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::ProposalActivated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "proposal_type", - "type": "core::integer::u8", - "kind": "data" - }, - { - "name": "target_args_1", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "target_args_2", - "type": "core::integer::u32", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "ProposalCreated", - "type": "p_war::systems::propose::propose_actions::ProposalCreated", - "kind": "nested" - }, - { - "name": "ProposalActivated", - "type": "p_war::systems::propose::propose_actions::ProposalActivated", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/contracts/pixelaw-voting_actions-6aab73ea.json b/contracts/manifests/dev/base/abis/contracts/pixelaw-voting_actions-6aab73ea.json deleted file mode 100644 index 0e5b5fe..0000000 --- a/contracts/manifests/dev/base/abis/contracts/pixelaw-voting_actions-6aab73ea.json +++ /dev/null @@ -1,288 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "VotingImpl", - "interface_name": "p_war::systems::voting::IVoting" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::voting::IVoting", - "items": [ - { - "type": "function", - "name": "vote", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "is_in_favor", - "type": "core::bool" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::voting::voting_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::voting::voting_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::voting::voting_actions::Voted", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - }, - { - "name": "voter", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "is_in_favor", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::voting::voting_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "Voted", - "type": "p_war::systems::voting::voting_actions::Voted", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/dojo-base.json b/contracts/manifests/dev/base/abis/dojo-base.json deleted file mode 100644 index 4800464..0000000 --- a/contracts/manifests/dev/base/abis/dojo-base.json +++ /dev/null @@ -1,98 +0,0 @@ -[ - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::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::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::base_contract::base::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "flat" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/dojo-world.json b/contracts/manifests/dev/base/abis/dojo-world.json deleted file mode 100644 index 8553809..0000000 --- a/contracts/manifests/dev/base/abis/dojo-world.json +++ /dev/null @@ -1,1231 +0,0 @@ -[ - { - "type": "impl", - "name": "World", - "interface_name": "dojo::world::world_contract::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": "struct", - "name": "dojo::model::metadata::ResourceMetadata", - "members": [ - { - "name": "resource_id", - "type": "core::felt252" - }, - { - "name": "metadata_uri", - "type": "core::byte_array::ByteArray" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::model::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::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "enum", - "name": "dojo::world::world_contract::Resource", - "variants": [ - { - "name": "Model", - "type": "(core::starknet::class_hash::ClassHash, core::starknet::contract_address::ContractAddress)" - }, - { - "name": "Contract", - "type": "(core::starknet::class_hash::ClassHash, core::starknet::contract_address::ContractAddress)" - }, - { - "name": "Namespace", - "type": "()" - }, - { - "name": "World", - "type": "()" - }, - { - "name": "Unregistered", - "type": "()" - } - ] - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorld", - "items": [ - { - "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_model", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "upgrade_model", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "deploy_contract", - "inputs": [ - { - "name": "salt", - "type": "core::felt252" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "upgrade_contract", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "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": "uuid", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "emit", - "inputs": [ - { - "name": "keys", - "type": "core::array::Array::" - }, - { - "name": "values", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "function", - "name": "entity", - "inputs": [ - { - "name": "model_selector", - "type": "core::felt252" - }, - { - "name": "index", - "type": "dojo::model::model::ModelIndex" - }, - { - "name": "layout", - "type": "dojo::model::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::model::ModelIndex" - }, - { - "name": "values", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::model::layout::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "delete_entity", - "inputs": [ - { - "name": "model_selector", - "type": "core::felt252" - }, - { - "name": "index", - "type": "dojo::model::model::ModelIndex" - }, - { - "name": "layout", - "type": "dojo::model::layout::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "base", - "inputs": [], - "outputs": [ - { - "type": "core::starknet::class_hash::ClassHash" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "resource", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "dojo::world::world_contract::Resource" - } - ], - "state_mutability": "view" - }, - { - "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": "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::world_contract::IUpgradeableWorld" - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IUpgradeableWorld", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "UpgradeableState", - "interface_name": "dojo::world::update::IUpgradeableState" - }, - { - "type": "struct", - "name": "dojo::world::update::StorageUpdate", - "members": [ - { - "name": "key", - "type": "core::felt252" - }, - { - "name": "value", - "type": "core::felt252" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::world::update::ProgramOutput", - "members": [ - { - "name": "prev_state_root", - "type": "core::felt252" - }, - { - "name": "new_state_root", - "type": "core::felt252" - }, - { - "name": "block_number", - "type": "core::felt252" - }, - { - "name": "block_hash", - "type": "core::felt252" - }, - { - "name": "config_hash", - "type": "core::felt252" - }, - { - "name": "world_da_hash", - "type": "core::felt252" - }, - { - "name": "message_to_starknet_segment", - "type": "core::array::Span::" - }, - { - "name": "message_to_appchain_segment", - "type": "core::array::Span::" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::update::IUpgradeableState", - "items": [ - { - "type": "function", - "name": "upgrade_state", - "inputs": [ - { - "name": "new_state", - "type": "core::array::Span::" - }, - { - "name": "program_output", - "type": "dojo::world::update::ProgramOutput" - }, - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "ConfigImpl", - "interface_name": "dojo::world::config::IConfig" - }, - { - "type": "interface", - "name": "dojo::world::config::IConfig", - "items": [ - { - "type": "function", - "name": "set_differ_program_hash", - "inputs": [ - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_merger_program_hash", - "inputs": [ - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_differ_program_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "get_merger_program_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "set_facts_registry", - "inputs": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_facts_registry", - "inputs": [], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "constructor", - "name": "constructor", - "inputs": [ - { - "name": "contract_base", - "type": "core::starknet::class_hash::ClassHash" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::WorldSpawned", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::ContractDeployed", - "kind": "struct", - "members": [ - { - "name": "salt", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - }, - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "name", - "type": "core::byte_array::ByteArray", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::ContractUpgraded", - "kind": "struct", - "members": [ - { - "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::ContractInitialized", - "kind": "struct", - "members": [ - { - "name": "selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "init_calldata", - "type": "core::array::Span::", - "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::MetadataUpdate", - "kind": "struct", - "members": [ - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "uri", - "type": "core::byte_array::ByteArray", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::NamespaceRegistered", - "kind": "struct", - "members": [ - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "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": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "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::ModelUpgraded", - "kind": "struct", - "members": [ - { - "name": "name", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - }, - { - "name": "prev_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::StoreSetRecord", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "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": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "values", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StoreUpdateMember", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "member_selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "values", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StoreDelRecord", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::WriterUpdated", - "kind": "struct", - "members": [ - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "contract", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "value", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::OwnerUpdated", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "value", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::DifferProgramHashUpdate", - "kind": "struct", - "members": [ - { - "name": "program_hash", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::MergerProgramHashUpdate", - "kind": "struct", - "members": [ - { - "name": "program_hash", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::FactsRegistryUpdate", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::Event", - "kind": "enum", - "variants": [ - { - "name": "DifferProgramHashUpdate", - "type": "dojo::world::config::Config::DifferProgramHashUpdate", - "kind": "nested" - }, - { - "name": "MergerProgramHashUpdate", - "type": "dojo::world::config::Config::MergerProgramHashUpdate", - "kind": "nested" - }, - { - "name": "FactsRegistryUpdate", - "type": "dojo::world::config::Config::FactsRegistryUpdate", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StateUpdated", - "kind": "struct", - "members": [ - { - "name": "da_hash", - "type": "core::felt252", - "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": "ContractDeployed", - "type": "dojo::world::world_contract::world::ContractDeployed", - "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": "WorldUpgraded", - "type": "dojo::world::world_contract::world::WorldUpgraded", - "kind": "nested" - }, - { - "name": "MetadataUpdate", - "type": "dojo::world::world_contract::world::MetadataUpdate", - "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": "ModelUpgraded", - "type": "dojo::world::world_contract::world::ModelUpgraded", - "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" - }, - { - "name": "ConfigEvent", - "type": "dojo::world::config::Config::Event", - "kind": "nested" - }, - { - "name": "StateUpdated", - "type": "dojo::world::world_contract::world::StateUpdated", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-AllowedApp-4aa27058.json b/contracts/manifests/dev/base/abis/models/pixelaw-AllowedApp-4aa27058.json deleted file mode 100644 index 316e91a..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-AllowedApp-4aa27058.json +++ /dev/null @@ -1,425 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "allowed_appImpl", - "interface_name": "p_war::models::allowed_app::Iallowed_app" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_app::AllowedApp", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "contract", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "is_allowed", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_app::Iallowed_app", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_app::AllowedApp" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_app::allowed_app::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-AllowedColor-22c1a796.json b/contracts/manifests/dev/base/abis/models/pixelaw-AllowedColor-22c1a796.json deleted file mode 100644 index 48cc27f..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-AllowedColor-22c1a796.json +++ /dev/null @@ -1,425 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "allowed_colorImpl", - "interface_name": "p_war::models::allowed_color::Iallowed_color" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::AllowedColor", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "is_allowed", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Iallowed_color", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::AllowedColor" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::allowed_color::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-App-36504565.json b/contracts/manifests/dev/base/abis/models/pixelaw-App-36504565.json deleted file mode 100644 index c2e9c0e..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-App-36504565.json +++ /dev/null @@ -1,415 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "appImpl", - "interface_name": "pixelaw::core::models::registry::Iapp" - }, - { - "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": "interface", - "name": "pixelaw::core::models::registry::Iapp", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::App" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-AppName-3b816829.json b/contracts/manifests/dev/base/abis/models/pixelaw-AppName-3b816829.json deleted file mode 100644 index 87a5e61..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-AppName-3b816829.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "app_nameImpl", - "interface_name": "pixelaw::core::models::registry::Iapp_name" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::AppName", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iapp_name", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::AppName" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app_name::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-AppUser-4eda3c52.json b/contracts/manifests/dev/base/abis/models/pixelaw-AppUser-4eda3c52.json deleted file mode 100644 index a578a2c..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-AppUser-4eda3c52.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "app_userImpl", - "interface_name": "pixelaw::core::models::registry::Iapp_user" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::AppUser", - "members": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iapp_user", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::AppUser" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app_user::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Board-124dc3e7.json b/contracts/manifests/dev/base/abis/models/pixelaw-Board-124dc3e7.json deleted file mode 100644 index 6f4d779..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Board-124dc3e7.json +++ /dev/null @@ -1,429 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "boardImpl", - "interface_name": "p_war::models::board::Iboard" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::board::Board", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "origin", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "width", - "type": "core::integer::u32" - }, - { - "name": "height", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Iboard", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::Board" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::board::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json b/contracts/manifests/dev/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json deleted file mode 100644 index 512af25..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "core_actions_addressImpl", - "interface_name": "pixelaw::core::models::registry::Icore_actions_address" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::CoreActionsAddress", - "members": [ - { - "name": "key", - "type": "core::felt252" - }, - { - "name": "value", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Icore_actions_address", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::CoreActionsAddress" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::core_actions_address::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Game-5c1fa23f.json b/contracts/manifests/dev/base/abis/models/pixelaw-Game-5c1fa23f.json deleted file mode 100644 index 9e59f59..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Game-5c1fa23f.json +++ /dev/null @@ -1,449 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "gameImpl", - "interface_name": "p_war::models::game::Igame" - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::game::Game", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "start", - "type": "core::integer::u64" - }, - { - "name": "end", - "type": "core::integer::u64" - }, - { - "name": "proposal_idx", - "type": "core::integer::u32" - }, - { - "name": "coeff_own_pixels", - "type": "core::integer::u32" - }, - { - "name": "coeff_commits", - "type": "core::integer::u32" - }, - { - "name": "winner_config", - "type": "core::integer::u32" - }, - { - "name": "winner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "guild_ids", - "type": "core::array::Span::" - }, - { - "name": "guild_count", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::game::Igame", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::game::Game" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::game::game::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-GameId-1ee8756e.json b/contracts/manifests/dev/base/abis/models/pixelaw-GameId-1ee8756e.json deleted file mode 100644 index 869e2a6..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-GameId-1ee8756e.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "game_idImpl", - "interface_name": "p_war::models::board::Igame_id" - }, - { - "type": "struct", - "name": "p_war::models::board::GameId", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "value", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Igame_id", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::GameId" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::game_id::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-GamePalette-49013f2b.json b/contracts/manifests/dev/base/abis/models/pixelaw-GamePalette-49013f2b.json deleted file mode 100644 index 2ee77e7..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-GamePalette-49013f2b.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "game_paletteImpl", - "interface_name": "p_war::models::allowed_color::Igame_palette" - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::GamePalette", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "length", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Igame_palette", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::GamePalette" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::game_palette::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Guild-40e97c00.json b/contracts/manifests/dev/base/abis/models/pixelaw-Guild-40e97c00.json deleted file mode 100644 index f963145..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Guild-40e97c00.json +++ /dev/null @@ -1,433 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "guildImpl", - "interface_name": "p_war::models::guilds::Iguild" - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::guilds::Guild", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "guild_name", - "type": "core::felt252" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "members", - "type": "core::array::Span::" - }, - { - "name": "member_count", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::guilds::Iguild", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::guilds::Guild" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::guilds::guild::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-InPalette-7a46e3ad.json b/contracts/manifests/dev/base/abis/models/pixelaw-InPalette-7a46e3ad.json deleted file mode 100644 index 4c58dd9..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-InPalette-7a46e3ad.json +++ /dev/null @@ -1,425 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "in_paletteImpl", - "interface_name": "p_war::models::allowed_color::Iin_palette" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::InPalette", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "value", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Iin_palette", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::InPalette" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::in_palette::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Instruction-4c7c4844.json b/contracts/manifests/dev/base/abis/models/pixelaw-Instruction-4c7c4844.json deleted file mode 100644 index a79b066..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Instruction-4c7c4844.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "instructionImpl", - "interface_name": "pixelaw::core::models::registry::Iinstruction" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::Instruction", - "members": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "instruction", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iinstruction", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::Instruction" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::instruction::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-PWarPixel-15195913.json b/contracts/manifests/dev/base/abis/models/pixelaw-PWarPixel-15195913.json deleted file mode 100644 index 4fb9f2a..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-PWarPixel-15195913.json +++ /dev/null @@ -1,421 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "p_war_pixelImpl", - "interface_name": "p_war::models::board::Ip_war_pixel" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::board::PWarPixel", - "members": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Ip_war_pixel", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::PWarPixel" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::p_war_pixel::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-PaletteColors-39a92a0a.json b/contracts/manifests/dev/base/abis/models/pixelaw-PaletteColors-39a92a0a.json deleted file mode 100644 index ac5324c..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-PaletteColors-39a92a0a.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "palette_colorsImpl", - "interface_name": "p_war::models::allowed_color::Ipalette_colors" - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::PaletteColors", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "idx", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Ipalette_colors", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::PaletteColors" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::palette_colors::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Permissions-72b77307.json b/contracts/manifests/dev/base/abis/models/pixelaw-Permissions-72b77307.json deleted file mode 100644 index 2e1a096..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Permissions-72b77307.json +++ /dev/null @@ -1,455 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "permissionsImpl", - "interface_name": "pixelaw::core::models::permissions::Ipermissions" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permission", - "members": [ - { - "name": "app", - "type": "core::bool" - }, - { - "name": "color", - "type": "core::bool" - }, - { - "name": "owner", - "type": "core::bool" - }, - { - "name": "text", - "type": "core::bool" - }, - { - "name": "timestamp", - "type": "core::bool" - }, - { - "name": "action", - "type": "core::bool" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permissions", - "members": [ - { - "name": "allowing_app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "allowed_app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "permission", - "type": "pixelaw::core::models::permissions::Permission" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::permissions::Ipermissions", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::permissions::Permissions" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::permissions::permissions::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Pixel-7e607b2f.json b/contracts/manifests/dev/base/abis/models/pixelaw-Pixel-7e607b2f.json deleted file mode 100644 index 8f6c36a..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Pixel-7e607b2f.json +++ /dev/null @@ -1,439 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "pixelImpl", - "interface_name": "pixelaw::core::models::pixel::Ipixel" - }, - { - "type": "struct", - "name": "pixelaw::core::models::pixel::Pixel", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "created_at", - "type": "core::integer::u64" - }, - { - "name": "updated_at", - "type": "core::integer::u64" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "text", - "type": "core::felt252" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::pixel::Ipixel", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::pixel::Pixel" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::pixel::pixel::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json b/contracts/manifests/dev/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json deleted file mode 100644 index 6458f14..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "pixel_recovery_rateImpl", - "interface_name": "p_war::models::proposal::Ipixel_recovery_rate" - }, - { - "type": "struct", - "name": "p_war::models::proposal::PixelRecoveryRate", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "rate", - "type": "core::integer::u64" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Ipixel_recovery_rate", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::PixelRecoveryRate" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::pixel_recovery_rate::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Player-30a1b371.json b/contracts/manifests/dev/base/abis/models/pixelaw-Player-30a1b371.json deleted file mode 100644 index 2d345b9..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Player-30a1b371.json +++ /dev/null @@ -1,433 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "playerImpl", - "interface_name": "p_war::models::player::Iplayer" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::player::Player", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "num_owns", - "type": "core::integer::u32" - }, - { - "name": "num_commit", - "type": "core::integer::u32" - }, - { - "name": "last_date", - "type": "core::integer::u64" - }, - { - "name": "is_banned", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::player::Iplayer", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::player::Player" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::player::player::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-PlayerVote-326c17c6.json b/contracts/manifests/dev/base/abis/models/pixelaw-PlayerVote-326c17c6.json deleted file mode 100644 index e00fd1f..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-PlayerVote-326c17c6.json +++ /dev/null @@ -1,433 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "player_voteImpl", - "interface_name": "p_war::models::proposal::Iplayer_vote" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::proposal::PlayerVote", - "members": [ - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "is_in_favor", - "type": "core::bool" - }, - { - "name": "voting_power", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Iplayer_vote", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::PlayerVote" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::player_vote::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-Proposal-49e1daf5.json b/contracts/manifests/dev/base/abis/models/pixelaw-Proposal-49e1daf5.json deleted file mode 100644 index faa5465..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-Proposal-49e1daf5.json +++ /dev/null @@ -1,457 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "proposalImpl", - "interface_name": "p_war::models::proposal::Iproposal" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::proposal::Proposal", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "author", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "proposal_type", - "type": "core::integer::u8" - }, - { - "name": "target_args_1", - "type": "core::integer::u32" - }, - { - "name": "target_args_2", - "type": "core::integer::u32" - }, - { - "name": "start", - "type": "core::integer::u64" - }, - { - "name": "end", - "type": "core::integer::u64" - }, - { - "name": "yes_voting_power", - "type": "core::integer::u32" - }, - { - "name": "no_voting_power", - "type": "core::integer::u32" - }, - { - "name": "is_activated", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Iproposal", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::Proposal" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::proposal::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/abis/models/pixelaw-QueueItem-549a17f2.json b/contracts/manifests/dev/base/abis/models/pixelaw-QueueItem-549a17f2.json deleted file mode 100644 index 8496a6c..0000000 --- a/contracts/manifests/dev/base/abis/models/pixelaw-QueueItem-549a17f2.json +++ /dev/null @@ -1,421 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "queue_itemImpl", - "interface_name": "pixelaw::core::models::queue::Iqueue_item" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::queue::QueueItem", - "members": [ - { - "name": "id", - "type": "core::felt252" - }, - { - "name": "valid", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::queue::Iqueue_item", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::queue::QueueItem" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::queue::queue_item::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/base/contracts/pixelaw-actions-16928a49.toml b/contracts/manifests/dev/base/contracts/pixelaw-actions-16928a49.toml deleted file mode 100644 index 5ab4bd2..0000000 --- a/contracts/manifests/dev/base/contracts/pixelaw-actions-16928a49.toml +++ /dev/null @@ -1,19 +0,0 @@ -kind = "DojoContract" -class_hash = "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f" -original_class_hash = "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f" -base_class_hash = "0x0" -abi = "manifests/dev/base/abis/contracts/pixelaw-actions-16928a49.json" -reads = [] -writes = [] -init_calldata = [] -tag = "pixelaw-actions" -systems = [ - "init", - "update_permission", - "schedule_queue", - "process_queue", - "update_pixel", - "alert_player", - "set_instruction", -] -manifest_name = "pixelaw-actions-16928a49" diff --git a/contracts/manifests/dev/base/contracts/pixelaw-guild_actions-4c9f5931.toml b/contracts/manifests/dev/base/contracts/pixelaw-guild_actions-4c9f5931.toml deleted file mode 100644 index 63fc0a4..0000000 --- a/contracts/manifests/dev/base/contracts/pixelaw-guild_actions-4c9f5931.toml +++ /dev/null @@ -1,15 +0,0 @@ -kind = "DojoContract" -class_hash = "0x16dce3a4c8116fa7d866bd8896050201427a10214befa642a93135b327bd250" -original_class_hash = "0x16dce3a4c8116fa7d866bd8896050201427a10214befa642a93135b327bd250" -base_class_hash = "0x0" -abi = "manifests/dev/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json" -reads = [] -writes = [] -init_calldata = [] -tag = "pixelaw-guild_actions" -systems = [ - "add_member", - "join_guild", - "remove_member", -] -manifest_name = "pixelaw-guild_actions-4c9f5931" diff --git a/contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml b/contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml deleted file mode 100644 index 7ddb808..0000000 --- a/contracts/manifests/dev/base/contracts/pixelaw-p_war_actions-60819afd.toml +++ /dev/null @@ -1,20 +0,0 @@ -kind = "DojoContract" -class_hash = "0x69dd41f9af4392ca2812831a77b4295acff9473da298b871a6833907e4084fd" -original_class_hash = "0x69dd41f9af4392ca2812831a77b4295acff9473da298b871a6833907e4084fd" -base_class_hash = "0x0" -abi = "manifests/dev/base/abis/contracts/pixelaw-p_war_actions-60819afd.json" -reads = [] -writes = [] -init_calldata = [] -tag = "pixelaw-p_war_actions" -systems = [ - "on_pre_update", - "on_post_update", - "set_pixel", - "init", - "interact", - "place_pixel", - "update_pixel", - "end_game", -] -manifest_name = "pixelaw-p_war_actions-60819afd" diff --git a/contracts/manifests/dev/base/contracts/pixelaw-propose_actions-4ee7028a.toml b/contracts/manifests/dev/base/contracts/pixelaw-propose_actions-4ee7028a.toml deleted file mode 100644 index 5a2e39f..0000000 --- a/contracts/manifests/dev/base/contracts/pixelaw-propose_actions-4ee7028a.toml +++ /dev/null @@ -1,11 +0,0 @@ -kind = "DojoContract" -class_hash = "0x7cc823538eb9a92fcd8af9cdb8d4293fe2c8b1cc090623670721f32b490c0ff" -original_class_hash = "0x7cc823538eb9a92fcd8af9cdb8d4293fe2c8b1cc090623670721f32b490c0ff" -base_class_hash = "0x0" -abi = "manifests/dev/base/abis/contracts/pixelaw-propose_actions-4ee7028a.json" -reads = [] -writes = [] -init_calldata = [] -tag = "pixelaw-propose_actions" -systems = ["activate_proposal"] -manifest_name = "pixelaw-propose_actions-4ee7028a" diff --git a/contracts/manifests/dev/base/contracts/pixelaw-voting_actions-6aab73ea.toml b/contracts/manifests/dev/base/contracts/pixelaw-voting_actions-6aab73ea.toml deleted file mode 100644 index 9750d0d..0000000 --- a/contracts/manifests/dev/base/contracts/pixelaw-voting_actions-6aab73ea.toml +++ /dev/null @@ -1,11 +0,0 @@ -kind = "DojoContract" -class_hash = "0x5e87a338c9ee6d9d72281883bd04133f0d91e4d5ecebcfbbf281319ce877b2a" -original_class_hash = "0x5e87a338c9ee6d9d72281883bd04133f0d91e4d5ecebcfbbf281319ce877b2a" -base_class_hash = "0x0" -abi = "manifests/dev/base/abis/contracts/pixelaw-voting_actions-6aab73ea.json" -reads = [] -writes = [] -init_calldata = [] -tag = "pixelaw-voting_actions" -systems = ["vote"] -manifest_name = "pixelaw-voting_actions-6aab73ea" diff --git a/contracts/manifests/dev/base/dojo-base.toml b/contracts/manifests/dev/base/dojo-base.toml deleted file mode 100644 index 44b3746..0000000 --- a/contracts/manifests/dev/base/dojo-base.toml +++ /dev/null @@ -1,6 +0,0 @@ -kind = "Class" -class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -original_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -abi = "manifests/dev/base/abis/dojo-base.json" -tag = "dojo-base" -manifest_name = "dojo-base" diff --git a/contracts/manifests/dev/base/dojo-world.toml b/contracts/manifests/dev/base/dojo-world.toml deleted file mode 100644 index ff32465..0000000 --- a/contracts/manifests/dev/base/dojo-world.toml +++ /dev/null @@ -1,6 +0,0 @@ -kind = "Class" -class_hash = "0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e" -original_class_hash = "0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e" -abi = "manifests/dev/base/abis/dojo-world.json" -tag = "dojo-world" -manifest_name = "dojo-world" diff --git a/contracts/manifests/dev/base/models/pixelaw-AllowedApp-4aa27058.toml b/contracts/manifests/dev/base/models/pixelaw-AllowedApp-4aa27058.toml deleted file mode 100644 index 3c18d84..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-AllowedApp-4aa27058.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f" -original_class_hash = "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f" -abi = "manifests/dev/base/abis/models/pixelaw-AllowedApp-4aa27058.json" -tag = "pixelaw-AllowedApp" -qualified_path = "p_war::models::allowed_app::allowed_app" -manifest_name = "pixelaw-AllowedApp-4aa27058" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "contract" -type = "ContractAddress" -key = true - -[[members]] -name = "is_allowed" -type = "bool" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-AllowedColor-22c1a796.toml b/contracts/manifests/dev/base/models/pixelaw-AllowedColor-22c1a796.toml deleted file mode 100644 index fe91aad..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-AllowedColor-22c1a796.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54" -original_class_hash = "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54" -abi = "manifests/dev/base/abis/models/pixelaw-AllowedColor-22c1a796.json" -tag = "pixelaw-AllowedColor" -qualified_path = "p_war::models::allowed_color::allowed_color" -manifest_name = "pixelaw-AllowedColor-22c1a796" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "color" -type = "u32" -key = true - -[[members]] -name = "is_allowed" -type = "bool" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-App-36504565.toml b/contracts/manifests/dev/base/models/pixelaw-App-36504565.toml deleted file mode 100644 index ce308c9..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-App-36504565.toml +++ /dev/null @@ -1,27 +0,0 @@ -kind = "DojoModel" -class_hash = "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c" -original_class_hash = "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c" -abi = "manifests/dev/base/abis/models/pixelaw-App-36504565.json" -tag = "pixelaw-App" -qualified_path = "pixelaw::core::models::registry::app" -manifest_name = "pixelaw-App-36504565" - -[[members]] -name = "system" -type = "ContractAddress" -key = true - -[[members]] -name = "name" -type = "felt252" -key = false - -[[members]] -name = "icon" -type = "felt252" -key = false - -[[members]] -name = "action" -type = "felt252" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-AppName-3b816829.toml b/contracts/manifests/dev/base/models/pixelaw-AppName-3b816829.toml deleted file mode 100644 index d48078e..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-AppName-3b816829.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8" -original_class_hash = "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8" -abi = "manifests/dev/base/abis/models/pixelaw-AppName-3b816829.json" -tag = "pixelaw-AppName" -qualified_path = "pixelaw::core::models::registry::app_name" -manifest_name = "pixelaw-AppName-3b816829" - -[[members]] -name = "name" -type = "felt252" -key = true - -[[members]] -name = "system" -type = "ContractAddress" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-AppUser-4eda3c52.toml b/contracts/manifests/dev/base/models/pixelaw-AppUser-4eda3c52.toml deleted file mode 100644 index 426707a..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-AppUser-4eda3c52.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1" -original_class_hash = "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1" -abi = "manifests/dev/base/abis/models/pixelaw-AppUser-4eda3c52.json" -tag = "pixelaw-AppUser" -qualified_path = "pixelaw::core::models::registry::app_user" -manifest_name = "pixelaw-AppUser-4eda3c52" - -[[members]] -name = "system" -type = "ContractAddress" -key = true - -[[members]] -name = "player" -type = "ContractAddress" -key = true - -[[members]] -name = "action" -type = "felt252" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Board-124dc3e7.toml b/contracts/manifests/dev/base/models/pixelaw-Board-124dc3e7.toml deleted file mode 100644 index 9cc4cfe..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Board-124dc3e7.toml +++ /dev/null @@ -1,27 +0,0 @@ -kind = "DojoModel" -class_hash = "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c" -original_class_hash = "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c" -abi = "manifests/dev/base/abis/models/pixelaw-Board-124dc3e7.json" -tag = "pixelaw-Board" -qualified_path = "p_war::models::board::board" -manifest_name = "pixelaw-Board-124dc3e7" - -[[members]] -name = "id" -type = "usize" -key = true - -[[members]] -name = "origin" -type = "Position" -key = false - -[[members]] -name = "width" -type = "u32" -key = false - -[[members]] -name = "height" -type = "u32" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml b/contracts/manifests/dev/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml deleted file mode 100644 index b6eec60..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2" -original_class_hash = "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2" -abi = "manifests/dev/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json" -tag = "pixelaw-CoreActionsAddress" -qualified_path = "pixelaw::core::models::registry::core_actions_address" -manifest_name = "pixelaw-CoreActionsAddress-5379e1ce" - -[[members]] -name = "key" -type = "felt252" -key = true - -[[members]] -name = "value" -type = "ContractAddress" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Game-5c1fa23f.toml b/contracts/manifests/dev/base/models/pixelaw-Game-5c1fa23f.toml deleted file mode 100644 index 0da28fa..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Game-5c1fa23f.toml +++ /dev/null @@ -1,57 +0,0 @@ -kind = "DojoModel" -class_hash = "0x4eb28e2e4c9f69487e5479cacac150e52666d072315dc8e3547b32f977976e0" -original_class_hash = "0x4eb28e2e4c9f69487e5479cacac150e52666d072315dc8e3547b32f977976e0" -abi = "manifests/dev/base/abis/models/pixelaw-Game-5c1fa23f.json" -tag = "pixelaw-Game" -qualified_path = "p_war::models::game::game" -manifest_name = "pixelaw-Game-5c1fa23f" - -[[members]] -name = "id" -type = "usize" -key = true - -[[members]] -name = "start" -type = "u64" -key = false - -[[members]] -name = "end" -type = "u64" -key = false - -[[members]] -name = "proposal_idx" -type = "usize" -key = false - -[[members]] -name = "coeff_own_pixels" -type = "u32" -key = false - -[[members]] -name = "coeff_commits" -type = "u32" -key = false - -[[members]] -name = "winner_config" -type = "u32" -key = false - -[[members]] -name = "winner" -type = "ContractAddress" -key = false - -[[members]] -name = "guild_ids" -type = "Span" -key = false - -[[members]] -name = "guild_count" -type = "usize" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-GameId-1ee8756e.toml b/contracts/manifests/dev/base/models/pixelaw-GameId-1ee8756e.toml deleted file mode 100644 index c38abc0..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-GameId-1ee8756e.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4" -original_class_hash = "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4" -abi = "manifests/dev/base/abis/models/pixelaw-GameId-1ee8756e.json" -tag = "pixelaw-GameId" -qualified_path = "p_war::models::board::game_id" -manifest_name = "pixelaw-GameId-1ee8756e" - -[[members]] -name = "x" -type = "u32" -key = true - -[[members]] -name = "y" -type = "u32" -key = true - -[[members]] -name = "value" -type = "usize" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-GamePalette-49013f2b.toml b/contracts/manifests/dev/base/models/pixelaw-GamePalette-49013f2b.toml deleted file mode 100644 index 1eaf78e..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-GamePalette-49013f2b.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398" -original_class_hash = "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398" -abi = "manifests/dev/base/abis/models/pixelaw-GamePalette-49013f2b.json" -tag = "pixelaw-GamePalette" -qualified_path = "p_war::models::allowed_color::game_palette" -manifest_name = "pixelaw-GamePalette-49013f2b" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "length" -type = "usize" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Guild-40e97c00.toml b/contracts/manifests/dev/base/models/pixelaw-Guild-40e97c00.toml deleted file mode 100644 index 42941e2..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Guild-40e97c00.toml +++ /dev/null @@ -1,37 +0,0 @@ -kind = "DojoModel" -class_hash = "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95" -original_class_hash = "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95" -abi = "manifests/dev/base/abis/models/pixelaw-Guild-40e97c00.json" -tag = "pixelaw-Guild" -qualified_path = "p_war::models::guilds::guild" -manifest_name = "pixelaw-Guild-40e97c00" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "guild_id" -type = "usize" -key = true - -[[members]] -name = "guild_name" -type = "felt252" -key = false - -[[members]] -name = "creator" -type = "ContractAddress" -key = false - -[[members]] -name = "members" -type = "Span" -key = false - -[[members]] -name = "member_count" -type = "usize" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-InPalette-7a46e3ad.toml b/contracts/manifests/dev/base/models/pixelaw-InPalette-7a46e3ad.toml deleted file mode 100644 index d3d005c..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-InPalette-7a46e3ad.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372" -original_class_hash = "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372" -abi = "manifests/dev/base/abis/models/pixelaw-InPalette-7a46e3ad.json" -tag = "pixelaw-InPalette" -qualified_path = "p_war::models::allowed_color::in_palette" -manifest_name = "pixelaw-InPalette-7a46e3ad" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "color" -type = "u32" -key = true - -[[members]] -name = "value" -type = "bool" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Instruction-4c7c4844.toml b/contracts/manifests/dev/base/models/pixelaw-Instruction-4c7c4844.toml deleted file mode 100644 index c6a8378..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Instruction-4c7c4844.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af" -original_class_hash = "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af" -abi = "manifests/dev/base/abis/models/pixelaw-Instruction-4c7c4844.json" -tag = "pixelaw-Instruction" -qualified_path = "pixelaw::core::models::registry::instruction" -manifest_name = "pixelaw-Instruction-4c7c4844" - -[[members]] -name = "system" -type = "ContractAddress" -key = true - -[[members]] -name = "selector" -type = "felt252" -key = true - -[[members]] -name = "instruction" -type = "felt252" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-PWarPixel-15195913.toml b/contracts/manifests/dev/base/models/pixelaw-PWarPixel-15195913.toml deleted file mode 100644 index 30703ad..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-PWarPixel-15195913.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261" -original_class_hash = "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261" -abi = "manifests/dev/base/abis/models/pixelaw-PWarPixel-15195913.json" -tag = "pixelaw-PWarPixel" -qualified_path = "p_war::models::board::p_war_pixel" -manifest_name = "pixelaw-PWarPixel-15195913" - -[[members]] -name = "position" -type = "Position" -key = true - -[[members]] -name = "owner" -type = "ContractAddress" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-PaletteColors-39a92a0a.toml b/contracts/manifests/dev/base/models/pixelaw-PaletteColors-39a92a0a.toml deleted file mode 100644 index 9e95d01..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-PaletteColors-39a92a0a.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444" -original_class_hash = "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444" -abi = "manifests/dev/base/abis/models/pixelaw-PaletteColors-39a92a0a.json" -tag = "pixelaw-PaletteColors" -qualified_path = "p_war::models::allowed_color::palette_colors" -manifest_name = "pixelaw-PaletteColors-39a92a0a" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "idx" -type = "u32" -key = true - -[[members]] -name = "color" -type = "u32" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Permissions-72b77307.toml b/contracts/manifests/dev/base/models/pixelaw-Permissions-72b77307.toml deleted file mode 100644 index e2dd2e5..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Permissions-72b77307.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302" -original_class_hash = "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302" -abi = "manifests/dev/base/abis/models/pixelaw-Permissions-72b77307.json" -tag = "pixelaw-Permissions" -qualified_path = "pixelaw::core::models::permissions::permissions" -manifest_name = "pixelaw-Permissions-72b77307" - -[[members]] -name = "allowing_app" -type = "ContractAddress" -key = true - -[[members]] -name = "allowed_app" -type = "ContractAddress" -key = true - -[[members]] -name = "permission" -type = "Permission" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Pixel-7e607b2f.toml b/contracts/manifests/dev/base/models/pixelaw-Pixel-7e607b2f.toml deleted file mode 100644 index 31ddb3b..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Pixel-7e607b2f.toml +++ /dev/null @@ -1,57 +0,0 @@ -kind = "DojoModel" -class_hash = "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d" -original_class_hash = "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d" -abi = "manifests/dev/base/abis/models/pixelaw-Pixel-7e607b2f.json" -tag = "pixelaw-Pixel" -qualified_path = "pixelaw::core::models::pixel::pixel" -manifest_name = "pixelaw-Pixel-7e607b2f" - -[[members]] -name = "x" -type = "u32" -key = true - -[[members]] -name = "y" -type = "u32" -key = true - -[[members]] -name = "app" -type = "ContractAddress" -key = false - -[[members]] -name = "color" -type = "u32" -key = false - -[[members]] -name = "created_at" -type = "u64" -key = false - -[[members]] -name = "updated_at" -type = "u64" -key = false - -[[members]] -name = "timestamp" -type = "u64" -key = false - -[[members]] -name = "owner" -type = "ContractAddress" -key = false - -[[members]] -name = "text" -type = "felt252" -key = false - -[[members]] -name = "action" -type = "felt252" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml b/contracts/manifests/dev/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml deleted file mode 100644 index 9167f2e..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067" -original_class_hash = "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067" -abi = "manifests/dev/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json" -tag = "pixelaw-PixelRecoveryRate" -qualified_path = "p_war::models::proposal::pixel_recovery_rate" -manifest_name = "pixelaw-PixelRecoveryRate-3aa284c0" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "rate" -type = "u64" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Player-30a1b371.toml b/contracts/manifests/dev/base/models/pixelaw-Player-30a1b371.toml deleted file mode 100644 index 6a61039..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Player-30a1b371.toml +++ /dev/null @@ -1,32 +0,0 @@ -kind = "DojoModel" -class_hash = "0x71a6f6188f355d1337561c8d68538b18ec4be4c493d01be5eee753759246848" -original_class_hash = "0x71a6f6188f355d1337561c8d68538b18ec4be4c493d01be5eee753759246848" -abi = "manifests/dev/base/abis/models/pixelaw-Player-30a1b371.json" -tag = "pixelaw-Player" -qualified_path = "p_war::models::player::player" -manifest_name = "pixelaw-Player-30a1b371" - -[[members]] -name = "address" -type = "ContractAddress" -key = true - -[[members]] -name = "num_owns" -type = "u32" -key = false - -[[members]] -name = "num_commit" -type = "u32" -key = false - -[[members]] -name = "last_date" -type = "u64" -key = false - -[[members]] -name = "is_banned" -type = "bool" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-PlayerVote-326c17c6.toml b/contracts/manifests/dev/base/models/pixelaw-PlayerVote-326c17c6.toml deleted file mode 100644 index 2d85b18..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-PlayerVote-326c17c6.toml +++ /dev/null @@ -1,32 +0,0 @@ -kind = "DojoModel" -class_hash = "0x4b76f6971c93c77d96a22ac7ba0268c452d13538f05b64138a6382e18babb00" -original_class_hash = "0x4b76f6971c93c77d96a22ac7ba0268c452d13538f05b64138a6382e18babb00" -abi = "manifests/dev/base/abis/models/pixelaw-PlayerVote-326c17c6.json" -tag = "pixelaw-PlayerVote" -qualified_path = "p_war::models::proposal::player_vote" -manifest_name = "pixelaw-PlayerVote-326c17c6" - -[[members]] -name = "player" -type = "ContractAddress" -key = true - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "index" -type = "usize" -key = true - -[[members]] -name = "is_in_favor" -type = "bool" -key = false - -[[members]] -name = "voting_power" -type = "u32" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-Proposal-49e1daf5.toml b/contracts/manifests/dev/base/models/pixelaw-Proposal-49e1daf5.toml deleted file mode 100644 index 38fd5e3..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-Proposal-49e1daf5.toml +++ /dev/null @@ -1,62 +0,0 @@ -kind = "DojoModel" -class_hash = "0x76c0a4827cc62be7367ab6fac605335bb5a2d01a7edc3f2dd89e58accafca02" -original_class_hash = "0x76c0a4827cc62be7367ab6fac605335bb5a2d01a7edc3f2dd89e58accafca02" -abi = "manifests/dev/base/abis/models/pixelaw-Proposal-49e1daf5.json" -tag = "pixelaw-Proposal" -qualified_path = "p_war::models::proposal::proposal" -manifest_name = "pixelaw-Proposal-49e1daf5" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "index" -type = "usize" -key = true - -[[members]] -name = "author" -type = "ContractAddress" -key = false - -[[members]] -name = "proposal_type" -type = "u8" -key = false - -[[members]] -name = "target_args_1" -type = "u32" -key = false - -[[members]] -name = "target_args_2" -type = "u32" -key = false - -[[members]] -name = "start" -type = "u64" -key = false - -[[members]] -name = "end" -type = "u64" -key = false - -[[members]] -name = "yes_voting_power" -type = "u32" -key = false - -[[members]] -name = "no_voting_power" -type = "u32" -key = false - -[[members]] -name = "is_activated" -type = "bool" -key = false diff --git a/contracts/manifests/dev/base/models/pixelaw-QueueItem-549a17f2.toml b/contracts/manifests/dev/base/models/pixelaw-QueueItem-549a17f2.toml deleted file mode 100644 index 8e33ac5..0000000 --- a/contracts/manifests/dev/base/models/pixelaw-QueueItem-549a17f2.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70" -original_class_hash = "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70" -abi = "manifests/dev/base/abis/models/pixelaw-QueueItem-549a17f2.json" -tag = "pixelaw-QueueItem" -qualified_path = "pixelaw::core::models::queue::queue_item" -manifest_name = "pixelaw-QueueItem-549a17f2" - -[[members]] -name = "id" -type = "felt252" -key = true - -[[members]] -name = "valid" -type = "bool" -key = false diff --git a/contracts/manifests/dev/deployment/abis/contracts/pixelaw-actions-16928a49.json b/contracts/manifests/dev/deployment/abis/contracts/pixelaw-actions-16928a49.json deleted file mode 100644 index e71ba18..0000000 --- a/contracts/manifests/dev/deployment/abis/contracts/pixelaw-actions-16928a49.json +++ /dev/null @@ -1,775 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsImpl", - "interface_name": "pixelaw::core::actions::IActions" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permission", - "members": [ - { - "name": "app", - "type": "core::bool" - }, - { - "name": "color", - "type": "core::bool" - }, - { - "name": "owner", - "type": "core::bool" - }, - { - "name": "text", - "type": "core::bool" - }, - { - "name": "timestamp", - "type": "core::bool" - }, - { - "name": "action", - "type": "core::bool" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::pixel::Pixel", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "created_at", - "type": "core::integer::u64" - }, - { - "name": "updated_at", - "type": "core::integer::u64" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "text", - "type": "core::felt252" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "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": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "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": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "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": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::actions::IActions", - "items": [ - { - "type": "function", - "name": "init", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_permission", - "inputs": [ - { - "name": "app_key", - "type": "core::felt252" - }, - { - "name": "permission", - "type": "pixelaw::core::models::permissions::Permission" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "has_write_access", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "pixel", - "type": "pixelaw::core::models::pixel::Pixel" - }, - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [ - { - "type": "core::bool" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "process_queue", - "inputs": [ - { - "name": "id", - "type": "core::felt252" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "schedule_queue", - "inputs": [ - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_pixel", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "new_app", - "inputs": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "icon", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "pixelaw::core::models::registry::App" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_system_address", - "inputs": [ - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "get_player_address", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "alert_player", - "inputs": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "message", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_instruction", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "instruction", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "pixelaw::core::actions::actions::IDojoInit" - }, - { - "type": "interface", - "name": "pixelaw::core::actions::actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::QueueScheduled", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "calldata", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::QueueProcessed", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::AppNameUpdated", - "kind": "struct", - "members": [ - { - "name": "app", - "type": "pixelaw::core::models::registry::App", - "kind": "data" - }, - { - "name": "caller", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::Alert", - "kind": "struct", - "members": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position", - "kind": "data" - }, - { - "name": "caller", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "message", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "QueueScheduled", - "type": "pixelaw::core::actions::actions::QueueScheduled", - "kind": "nested" - }, - { - "name": "QueueProcessed", - "type": "pixelaw::core::actions::actions::QueueProcessed", - "kind": "nested" - }, - { - "name": "AppNameUpdated", - "type": "pixelaw::core::actions::actions::AppNameUpdated", - "kind": "nested" - }, - { - "name": "Alert", - "type": "pixelaw::core::actions::actions::Alert", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/contracts/pixelaw-guild_actions-4c9f5931.json b/contracts/manifests/dev/deployment/abis/contracts/pixelaw-guild_actions-4c9f5931.json deleted file mode 100644 index 3efc0d9..0000000 --- a/contracts/manifests/dev/deployment/abis/contracts/pixelaw-guild_actions-4c9f5931.json +++ /dev/null @@ -1,383 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "GuildImpl", - "interface_name": "p_war::systems::guilds::IGuild" - }, - { - "type": "interface", - "name": "p_war::systems::guilds::IGuild", - "items": [ - { - "type": "function", - "name": "create_guild", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_name", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "add_member", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "new_member", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "remove_member", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_guild_points", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::guilds::guild_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::guilds::guild_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::GuildCreated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_name", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::MemberAdded", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::MemberRemoved", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "GuildCreated", - "type": "p_war::systems::guilds::guild_actions::GuildCreated", - "kind": "nested" - }, - { - "name": "MemberAdded", - "type": "p_war::systems::guilds::guild_actions::MemberAdded", - "kind": "nested" - }, - { - "name": "MemberRemoved", - "type": "p_war::systems::guilds::guild_actions::MemberRemoved", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/contracts/pixelaw-p_war_actions-60819afd.json b/contracts/manifests/dev/deployment/abis/contracts/pixelaw-p_war_actions-60819afd.json deleted file mode 100644 index b9e6307..0000000 --- a/contracts/manifests/dev/deployment/abis/contracts/pixelaw-p_war_actions-60819afd.json +++ /dev/null @@ -1,583 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsInteroperability", - "interface_name": "pixelaw::core::traits::IInteroperability" - }, - { - "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": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "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": "interface", - "name": "pixelaw::core::traits::IInteroperability", - "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": [], - "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": "impl", - "name": "AllowedAppImpl", - "interface_name": "p_war::systems::apps::IAllowedApp" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::utils::DefaultParameters", - "members": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "color", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::apps::IAllowedApp", - "items": [ - { - "type": "function", - "name": "set_pixel", - "inputs": [ - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsImpl", - "interface_name": "p_war::systems::actions::IActions" - }, - { - "type": "interface", - "name": "p_war::systems::actions::IActions", - "items": [ - { - "type": "function", - "name": "init", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "interact", - "inputs": [ - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "create_game", - "inputs": [ - { - "name": "origin", - "type": "pixelaw::core::utils::Position" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_game_id", - "inputs": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "place_pixel", - "inputs": [ - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_pixel", - "inputs": [ - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "end_game", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::actions::p_war_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::actions::p_war_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::StartedGame", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u128", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::EndedGame", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u128", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "StartedGame", - "type": "p_war::systems::actions::p_war_actions::StartedGame", - "kind": "nested" - }, - { - "name": "EndedGame", - "type": "p_war::systems::actions::p_war_actions::EndedGame", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/contracts/pixelaw-propose_actions-4ee7028a.json b/contracts/manifests/dev/deployment/abis/contracts/pixelaw-propose_actions-4ee7028a.json deleted file mode 100644 index 8aa1e40..0000000 --- a/contracts/manifests/dev/deployment/abis/contracts/pixelaw-propose_actions-4ee7028a.json +++ /dev/null @@ -1,363 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ProposeImpl", - "interface_name": "p_war::systems::propose::IPropose" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::propose::IPropose", - "items": [ - { - "type": "function", - "name": "create_proposal", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "proposal_type", - "type": "core::integer::u8" - }, - { - "name": "target_args_1", - "type": "core::integer::u32" - }, - { - "name": "target_args_2", - "type": "core::integer::u32" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "activate_proposal", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "clear_data", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::propose::propose_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::propose::propose_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::ProposalCreated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "proposal_type", - "type": "core::integer::u8", - "kind": "data" - }, - { - "name": "target_args_1", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "target_args_2", - "type": "core::integer::u32", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::ProposalActivated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "proposal_type", - "type": "core::integer::u8", - "kind": "data" - }, - { - "name": "target_args_1", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "target_args_2", - "type": "core::integer::u32", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "ProposalCreated", - "type": "p_war::systems::propose::propose_actions::ProposalCreated", - "kind": "nested" - }, - { - "name": "ProposalActivated", - "type": "p_war::systems::propose::propose_actions::ProposalActivated", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/contracts/pixelaw-voting_actions-6aab73ea.json b/contracts/manifests/dev/deployment/abis/contracts/pixelaw-voting_actions-6aab73ea.json deleted file mode 100644 index 0e5b5fe..0000000 --- a/contracts/manifests/dev/deployment/abis/contracts/pixelaw-voting_actions-6aab73ea.json +++ /dev/null @@ -1,288 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "VotingImpl", - "interface_name": "p_war::systems::voting::IVoting" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::voting::IVoting", - "items": [ - { - "type": "function", - "name": "vote", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "is_in_favor", - "type": "core::bool" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::voting::voting_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::voting::voting_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::voting::voting_actions::Voted", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - }, - { - "name": "voter", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "is_in_favor", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::voting::voting_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "Voted", - "type": "p_war::systems::voting::voting_actions::Voted", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/dojo-base.json b/contracts/manifests/dev/deployment/abis/dojo-base.json deleted file mode 100644 index 4800464..0000000 --- a/contracts/manifests/dev/deployment/abis/dojo-base.json +++ /dev/null @@ -1,98 +0,0 @@ -[ - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::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::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::base_contract::base::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "flat" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/dojo-world.json b/contracts/manifests/dev/deployment/abis/dojo-world.json deleted file mode 100644 index 8553809..0000000 --- a/contracts/manifests/dev/deployment/abis/dojo-world.json +++ /dev/null @@ -1,1231 +0,0 @@ -[ - { - "type": "impl", - "name": "World", - "interface_name": "dojo::world::world_contract::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": "struct", - "name": "dojo::model::metadata::ResourceMetadata", - "members": [ - { - "name": "resource_id", - "type": "core::felt252" - }, - { - "name": "metadata_uri", - "type": "core::byte_array::ByteArray" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::model::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::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "enum", - "name": "dojo::world::world_contract::Resource", - "variants": [ - { - "name": "Model", - "type": "(core::starknet::class_hash::ClassHash, core::starknet::contract_address::ContractAddress)" - }, - { - "name": "Contract", - "type": "(core::starknet::class_hash::ClassHash, core::starknet::contract_address::ContractAddress)" - }, - { - "name": "Namespace", - "type": "()" - }, - { - "name": "World", - "type": "()" - }, - { - "name": "Unregistered", - "type": "()" - } - ] - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorld", - "items": [ - { - "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_model", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "upgrade_model", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "deploy_contract", - "inputs": [ - { - "name": "salt", - "type": "core::felt252" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "upgrade_contract", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "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": "uuid", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "emit", - "inputs": [ - { - "name": "keys", - "type": "core::array::Array::" - }, - { - "name": "values", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "function", - "name": "entity", - "inputs": [ - { - "name": "model_selector", - "type": "core::felt252" - }, - { - "name": "index", - "type": "dojo::model::model::ModelIndex" - }, - { - "name": "layout", - "type": "dojo::model::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::model::ModelIndex" - }, - { - "name": "values", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::model::layout::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "delete_entity", - "inputs": [ - { - "name": "model_selector", - "type": "core::felt252" - }, - { - "name": "index", - "type": "dojo::model::model::ModelIndex" - }, - { - "name": "layout", - "type": "dojo::model::layout::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "base", - "inputs": [], - "outputs": [ - { - "type": "core::starknet::class_hash::ClassHash" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "resource", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "dojo::world::world_contract::Resource" - } - ], - "state_mutability": "view" - }, - { - "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": "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::world_contract::IUpgradeableWorld" - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IUpgradeableWorld", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "UpgradeableState", - "interface_name": "dojo::world::update::IUpgradeableState" - }, - { - "type": "struct", - "name": "dojo::world::update::StorageUpdate", - "members": [ - { - "name": "key", - "type": "core::felt252" - }, - { - "name": "value", - "type": "core::felt252" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::world::update::ProgramOutput", - "members": [ - { - "name": "prev_state_root", - "type": "core::felt252" - }, - { - "name": "new_state_root", - "type": "core::felt252" - }, - { - "name": "block_number", - "type": "core::felt252" - }, - { - "name": "block_hash", - "type": "core::felt252" - }, - { - "name": "config_hash", - "type": "core::felt252" - }, - { - "name": "world_da_hash", - "type": "core::felt252" - }, - { - "name": "message_to_starknet_segment", - "type": "core::array::Span::" - }, - { - "name": "message_to_appchain_segment", - "type": "core::array::Span::" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::update::IUpgradeableState", - "items": [ - { - "type": "function", - "name": "upgrade_state", - "inputs": [ - { - "name": "new_state", - "type": "core::array::Span::" - }, - { - "name": "program_output", - "type": "dojo::world::update::ProgramOutput" - }, - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "ConfigImpl", - "interface_name": "dojo::world::config::IConfig" - }, - { - "type": "interface", - "name": "dojo::world::config::IConfig", - "items": [ - { - "type": "function", - "name": "set_differ_program_hash", - "inputs": [ - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_merger_program_hash", - "inputs": [ - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_differ_program_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "get_merger_program_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "set_facts_registry", - "inputs": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_facts_registry", - "inputs": [], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "constructor", - "name": "constructor", - "inputs": [ - { - "name": "contract_base", - "type": "core::starknet::class_hash::ClassHash" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::WorldSpawned", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::ContractDeployed", - "kind": "struct", - "members": [ - { - "name": "salt", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - }, - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "name", - "type": "core::byte_array::ByteArray", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::ContractUpgraded", - "kind": "struct", - "members": [ - { - "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::ContractInitialized", - "kind": "struct", - "members": [ - { - "name": "selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "init_calldata", - "type": "core::array::Span::", - "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::MetadataUpdate", - "kind": "struct", - "members": [ - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "uri", - "type": "core::byte_array::ByteArray", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::NamespaceRegistered", - "kind": "struct", - "members": [ - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "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": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "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::ModelUpgraded", - "kind": "struct", - "members": [ - { - "name": "name", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - }, - { - "name": "prev_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::StoreSetRecord", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "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": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "values", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StoreUpdateMember", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "member_selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "values", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StoreDelRecord", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::WriterUpdated", - "kind": "struct", - "members": [ - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "contract", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "value", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::OwnerUpdated", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "value", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::DifferProgramHashUpdate", - "kind": "struct", - "members": [ - { - "name": "program_hash", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::MergerProgramHashUpdate", - "kind": "struct", - "members": [ - { - "name": "program_hash", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::FactsRegistryUpdate", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::Event", - "kind": "enum", - "variants": [ - { - "name": "DifferProgramHashUpdate", - "type": "dojo::world::config::Config::DifferProgramHashUpdate", - "kind": "nested" - }, - { - "name": "MergerProgramHashUpdate", - "type": "dojo::world::config::Config::MergerProgramHashUpdate", - "kind": "nested" - }, - { - "name": "FactsRegistryUpdate", - "type": "dojo::world::config::Config::FactsRegistryUpdate", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StateUpdated", - "kind": "struct", - "members": [ - { - "name": "da_hash", - "type": "core::felt252", - "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": "ContractDeployed", - "type": "dojo::world::world_contract::world::ContractDeployed", - "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": "WorldUpgraded", - "type": "dojo::world::world_contract::world::WorldUpgraded", - "kind": "nested" - }, - { - "name": "MetadataUpdate", - "type": "dojo::world::world_contract::world::MetadataUpdate", - "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": "ModelUpgraded", - "type": "dojo::world::world_contract::world::ModelUpgraded", - "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" - }, - { - "name": "ConfigEvent", - "type": "dojo::world::config::Config::Event", - "kind": "nested" - }, - { - "name": "StateUpdated", - "type": "dojo::world::world_contract::world::StateUpdated", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-AllowedApp-4aa27058.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-AllowedApp-4aa27058.json deleted file mode 100644 index 316e91a..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-AllowedApp-4aa27058.json +++ /dev/null @@ -1,425 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "allowed_appImpl", - "interface_name": "p_war::models::allowed_app::Iallowed_app" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_app::AllowedApp", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "contract", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "is_allowed", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_app::Iallowed_app", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_app::AllowedApp" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_app::allowed_app::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-AllowedColor-22c1a796.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-AllowedColor-22c1a796.json deleted file mode 100644 index 48cc27f..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-AllowedColor-22c1a796.json +++ /dev/null @@ -1,425 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "allowed_colorImpl", - "interface_name": "p_war::models::allowed_color::Iallowed_color" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::AllowedColor", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "is_allowed", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Iallowed_color", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::AllowedColor" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::allowed_color::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-App-36504565.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-App-36504565.json deleted file mode 100644 index c2e9c0e..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-App-36504565.json +++ /dev/null @@ -1,415 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "appImpl", - "interface_name": "pixelaw::core::models::registry::Iapp" - }, - { - "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": "interface", - "name": "pixelaw::core::models::registry::Iapp", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::App" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-AppName-3b816829.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-AppName-3b816829.json deleted file mode 100644 index 87a5e61..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-AppName-3b816829.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "app_nameImpl", - "interface_name": "pixelaw::core::models::registry::Iapp_name" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::AppName", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iapp_name", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::AppName" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app_name::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-AppUser-4eda3c52.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-AppUser-4eda3c52.json deleted file mode 100644 index a578a2c..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-AppUser-4eda3c52.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "app_userImpl", - "interface_name": "pixelaw::core::models::registry::Iapp_user" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::AppUser", - "members": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iapp_user", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::AppUser" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app_user::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-Board-124dc3e7.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-Board-124dc3e7.json deleted file mode 100644 index 6f4d779..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-Board-124dc3e7.json +++ /dev/null @@ -1,429 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "boardImpl", - "interface_name": "p_war::models::board::Iboard" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::board::Board", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "origin", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "width", - "type": "core::integer::u32" - }, - { - "name": "height", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Iboard", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::Board" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::board::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json deleted file mode 100644 index 512af25..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "core_actions_addressImpl", - "interface_name": "pixelaw::core::models::registry::Icore_actions_address" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::CoreActionsAddress", - "members": [ - { - "name": "key", - "type": "core::felt252" - }, - { - "name": "value", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Icore_actions_address", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::CoreActionsAddress" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::core_actions_address::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-Game-5c1fa23f.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-Game-5c1fa23f.json deleted file mode 100644 index 9e59f59..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-Game-5c1fa23f.json +++ /dev/null @@ -1,449 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "gameImpl", - "interface_name": "p_war::models::game::Igame" - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::game::Game", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "start", - "type": "core::integer::u64" - }, - { - "name": "end", - "type": "core::integer::u64" - }, - { - "name": "proposal_idx", - "type": "core::integer::u32" - }, - { - "name": "coeff_own_pixels", - "type": "core::integer::u32" - }, - { - "name": "coeff_commits", - "type": "core::integer::u32" - }, - { - "name": "winner_config", - "type": "core::integer::u32" - }, - { - "name": "winner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "guild_ids", - "type": "core::array::Span::" - }, - { - "name": "guild_count", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::game::Igame", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::game::Game" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::game::game::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-GameId-1ee8756e.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-GameId-1ee8756e.json deleted file mode 100644 index 869e2a6..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-GameId-1ee8756e.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "game_idImpl", - "interface_name": "p_war::models::board::Igame_id" - }, - { - "type": "struct", - "name": "p_war::models::board::GameId", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "value", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Igame_id", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::GameId" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::game_id::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-GamePalette-49013f2b.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-GamePalette-49013f2b.json deleted file mode 100644 index 2ee77e7..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-GamePalette-49013f2b.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "game_paletteImpl", - "interface_name": "p_war::models::allowed_color::Igame_palette" - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::GamePalette", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "length", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Igame_palette", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::GamePalette" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::game_palette::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-Guild-40e97c00.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-Guild-40e97c00.json deleted file mode 100644 index f963145..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-Guild-40e97c00.json +++ /dev/null @@ -1,433 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "guildImpl", - "interface_name": "p_war::models::guilds::Iguild" - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::guilds::Guild", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "guild_name", - "type": "core::felt252" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "members", - "type": "core::array::Span::" - }, - { - "name": "member_count", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::guilds::Iguild", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::guilds::Guild" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::guilds::guild::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-InPalette-7a46e3ad.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-InPalette-7a46e3ad.json deleted file mode 100644 index 4c58dd9..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-InPalette-7a46e3ad.json +++ /dev/null @@ -1,425 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "in_paletteImpl", - "interface_name": "p_war::models::allowed_color::Iin_palette" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::InPalette", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "value", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Iin_palette", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::InPalette" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::in_palette::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-Instruction-4c7c4844.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-Instruction-4c7c4844.json deleted file mode 100644 index a79b066..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-Instruction-4c7c4844.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "instructionImpl", - "interface_name": "pixelaw::core::models::registry::Iinstruction" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::Instruction", - "members": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "instruction", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iinstruction", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::Instruction" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::instruction::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-PWarPixel-15195913.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-PWarPixel-15195913.json deleted file mode 100644 index 4fb9f2a..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-PWarPixel-15195913.json +++ /dev/null @@ -1,421 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "p_war_pixelImpl", - "interface_name": "p_war::models::board::Ip_war_pixel" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::board::PWarPixel", - "members": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Ip_war_pixel", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::PWarPixel" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::p_war_pixel::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-PaletteColors-39a92a0a.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-PaletteColors-39a92a0a.json deleted file mode 100644 index ac5324c..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-PaletteColors-39a92a0a.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "palette_colorsImpl", - "interface_name": "p_war::models::allowed_color::Ipalette_colors" - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::PaletteColors", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "idx", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Ipalette_colors", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::PaletteColors" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::palette_colors::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-Permissions-72b77307.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-Permissions-72b77307.json deleted file mode 100644 index 2e1a096..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-Permissions-72b77307.json +++ /dev/null @@ -1,455 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "permissionsImpl", - "interface_name": "pixelaw::core::models::permissions::Ipermissions" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permission", - "members": [ - { - "name": "app", - "type": "core::bool" - }, - { - "name": "color", - "type": "core::bool" - }, - { - "name": "owner", - "type": "core::bool" - }, - { - "name": "text", - "type": "core::bool" - }, - { - "name": "timestamp", - "type": "core::bool" - }, - { - "name": "action", - "type": "core::bool" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permissions", - "members": [ - { - "name": "allowing_app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "allowed_app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "permission", - "type": "pixelaw::core::models::permissions::Permission" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::permissions::Ipermissions", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::permissions::Permissions" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::permissions::permissions::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-Pixel-7e607b2f.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-Pixel-7e607b2f.json deleted file mode 100644 index 8f6c36a..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-Pixel-7e607b2f.json +++ /dev/null @@ -1,439 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "pixelImpl", - "interface_name": "pixelaw::core::models::pixel::Ipixel" - }, - { - "type": "struct", - "name": "pixelaw::core::models::pixel::Pixel", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "created_at", - "type": "core::integer::u64" - }, - { - "name": "updated_at", - "type": "core::integer::u64" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "text", - "type": "core::felt252" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::pixel::Ipixel", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::pixel::Pixel" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::pixel::pixel::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json deleted file mode 100644 index 6458f14..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "pixel_recovery_rateImpl", - "interface_name": "p_war::models::proposal::Ipixel_recovery_rate" - }, - { - "type": "struct", - "name": "p_war::models::proposal::PixelRecoveryRate", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "rate", - "type": "core::integer::u64" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Ipixel_recovery_rate", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::PixelRecoveryRate" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::pixel_recovery_rate::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-Player-30a1b371.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-Player-30a1b371.json deleted file mode 100644 index 2d345b9..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-Player-30a1b371.json +++ /dev/null @@ -1,433 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "playerImpl", - "interface_name": "p_war::models::player::Iplayer" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::player::Player", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "num_owns", - "type": "core::integer::u32" - }, - { - "name": "num_commit", - "type": "core::integer::u32" - }, - { - "name": "last_date", - "type": "core::integer::u64" - }, - { - "name": "is_banned", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::player::Iplayer", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::player::Player" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::player::player::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-PlayerVote-326c17c6.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-PlayerVote-326c17c6.json deleted file mode 100644 index e00fd1f..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-PlayerVote-326c17c6.json +++ /dev/null @@ -1,433 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "player_voteImpl", - "interface_name": "p_war::models::proposal::Iplayer_vote" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::proposal::PlayerVote", - "members": [ - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "is_in_favor", - "type": "core::bool" - }, - { - "name": "voting_power", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Iplayer_vote", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::PlayerVote" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::player_vote::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-Proposal-49e1daf5.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-Proposal-49e1daf5.json deleted file mode 100644 index faa5465..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-Proposal-49e1daf5.json +++ /dev/null @@ -1,457 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "proposalImpl", - "interface_name": "p_war::models::proposal::Iproposal" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::proposal::Proposal", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "author", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "proposal_type", - "type": "core::integer::u8" - }, - { - "name": "target_args_1", - "type": "core::integer::u32" - }, - { - "name": "target_args_2", - "type": "core::integer::u32" - }, - { - "name": "start", - "type": "core::integer::u64" - }, - { - "name": "end", - "type": "core::integer::u64" - }, - { - "name": "yes_voting_power", - "type": "core::integer::u32" - }, - { - "name": "no_voting_power", - "type": "core::integer::u32" - }, - { - "name": "is_activated", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Iproposal", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::Proposal" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::proposal::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/abis/models/pixelaw-QueueItem-549a17f2.json b/contracts/manifests/dev/deployment/abis/models/pixelaw-QueueItem-549a17f2.json deleted file mode 100644 index 8496a6c..0000000 --- a/contracts/manifests/dev/deployment/abis/models/pixelaw-QueueItem-549a17f2.json +++ /dev/null @@ -1,421 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "queue_itemImpl", - "interface_name": "pixelaw::core::models::queue::Iqueue_item" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::queue::QueueItem", - "members": [ - { - "name": "id", - "type": "core::felt252" - }, - { - "name": "valid", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::queue::Iqueue_item", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::queue::QueueItem" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::queue::queue_item::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/manifest.json b/contracts/manifests/dev/deployment/manifest.json deleted file mode 100644 index 89fdece..0000000 --- a/contracts/manifests/dev/deployment/manifest.json +++ /dev/null @@ -1,13785 +0,0 @@ -{ - "world": { - "kind": "WorldContract", - "class_hash": "0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e", - "original_class_hash": "0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e", - "abi": [ - { - "type": "impl", - "name": "World", - "interface_name": "dojo::world::world_contract::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": "struct", - "name": "dojo::model::metadata::ResourceMetadata", - "members": [ - { - "name": "resource_id", - "type": "core::felt252" - }, - { - "name": "metadata_uri", - "type": "core::byte_array::ByteArray" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::model::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::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "enum", - "name": "dojo::world::world_contract::Resource", - "variants": [ - { - "name": "Model", - "type": "(core::starknet::class_hash::ClassHash, core::starknet::contract_address::ContractAddress)" - }, - { - "name": "Contract", - "type": "(core::starknet::class_hash::ClassHash, core::starknet::contract_address::ContractAddress)" - }, - { - "name": "Namespace", - "type": "()" - }, - { - "name": "World", - "type": "()" - }, - { - "name": "Unregistered", - "type": "()" - } - ] - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorld", - "items": [ - { - "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_model", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "upgrade_model", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "deploy_contract", - "inputs": [ - { - "name": "salt", - "type": "core::felt252" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "upgrade_contract", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "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": "uuid", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "emit", - "inputs": [ - { - "name": "keys", - "type": "core::array::Array::" - }, - { - "name": "values", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "function", - "name": "entity", - "inputs": [ - { - "name": "model_selector", - "type": "core::felt252" - }, - { - "name": "index", - "type": "dojo::model::model::ModelIndex" - }, - { - "name": "layout", - "type": "dojo::model::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::model::ModelIndex" - }, - { - "name": "values", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::model::layout::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "delete_entity", - "inputs": [ - { - "name": "model_selector", - "type": "core::felt252" - }, - { - "name": "index", - "type": "dojo::model::model::ModelIndex" - }, - { - "name": "layout", - "type": "dojo::model::layout::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "base", - "inputs": [], - "outputs": [ - { - "type": "core::starknet::class_hash::ClassHash" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "resource", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "dojo::world::world_contract::Resource" - } - ], - "state_mutability": "view" - }, - { - "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": "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::world_contract::IUpgradeableWorld" - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IUpgradeableWorld", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "UpgradeableState", - "interface_name": "dojo::world::update::IUpgradeableState" - }, - { - "type": "struct", - "name": "dojo::world::update::StorageUpdate", - "members": [ - { - "name": "key", - "type": "core::felt252" - }, - { - "name": "value", - "type": "core::felt252" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::world::update::ProgramOutput", - "members": [ - { - "name": "prev_state_root", - "type": "core::felt252" - }, - { - "name": "new_state_root", - "type": "core::felt252" - }, - { - "name": "block_number", - "type": "core::felt252" - }, - { - "name": "block_hash", - "type": "core::felt252" - }, - { - "name": "config_hash", - "type": "core::felt252" - }, - { - "name": "world_da_hash", - "type": "core::felt252" - }, - { - "name": "message_to_starknet_segment", - "type": "core::array::Span::" - }, - { - "name": "message_to_appchain_segment", - "type": "core::array::Span::" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::update::IUpgradeableState", - "items": [ - { - "type": "function", - "name": "upgrade_state", - "inputs": [ - { - "name": "new_state", - "type": "core::array::Span::" - }, - { - "name": "program_output", - "type": "dojo::world::update::ProgramOutput" - }, - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "ConfigImpl", - "interface_name": "dojo::world::config::IConfig" - }, - { - "type": "interface", - "name": "dojo::world::config::IConfig", - "items": [ - { - "type": "function", - "name": "set_differ_program_hash", - "inputs": [ - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_merger_program_hash", - "inputs": [ - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_differ_program_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "get_merger_program_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "set_facts_registry", - "inputs": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_facts_registry", - "inputs": [], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "constructor", - "name": "constructor", - "inputs": [ - { - "name": "contract_base", - "type": "core::starknet::class_hash::ClassHash" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::WorldSpawned", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::ContractDeployed", - "kind": "struct", - "members": [ - { - "name": "salt", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - }, - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "name", - "type": "core::byte_array::ByteArray", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::ContractUpgraded", - "kind": "struct", - "members": [ - { - "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::ContractInitialized", - "kind": "struct", - "members": [ - { - "name": "selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "init_calldata", - "type": "core::array::Span::", - "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::MetadataUpdate", - "kind": "struct", - "members": [ - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "uri", - "type": "core::byte_array::ByteArray", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::NamespaceRegistered", - "kind": "struct", - "members": [ - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "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": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "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::ModelUpgraded", - "kind": "struct", - "members": [ - { - "name": "name", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - }, - { - "name": "prev_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::StoreSetRecord", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "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": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "values", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StoreUpdateMember", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "member_selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "values", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StoreDelRecord", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::WriterUpdated", - "kind": "struct", - "members": [ - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "contract", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "value", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::OwnerUpdated", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "value", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::DifferProgramHashUpdate", - "kind": "struct", - "members": [ - { - "name": "program_hash", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::MergerProgramHashUpdate", - "kind": "struct", - "members": [ - { - "name": "program_hash", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::FactsRegistryUpdate", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::Event", - "kind": "enum", - "variants": [ - { - "name": "DifferProgramHashUpdate", - "type": "dojo::world::config::Config::DifferProgramHashUpdate", - "kind": "nested" - }, - { - "name": "MergerProgramHashUpdate", - "type": "dojo::world::config::Config::MergerProgramHashUpdate", - "kind": "nested" - }, - { - "name": "FactsRegistryUpdate", - "type": "dojo::world::config::Config::FactsRegistryUpdate", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StateUpdated", - "kind": "struct", - "members": [ - { - "name": "da_hash", - "type": "core::felt252", - "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": "ContractDeployed", - "type": "dojo::world::world_contract::world::ContractDeployed", - "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": "WorldUpgraded", - "type": "dojo::world::world_contract::world::WorldUpgraded", - "kind": "nested" - }, - { - "name": "MetadataUpdate", - "type": "dojo::world::world_contract::world::MetadataUpdate", - "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": "ModelUpgraded", - "type": "dojo::world::world_contract::world::ModelUpgraded", - "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" - }, - { - "name": "ConfigEvent", - "type": "dojo::world::config::Config::Event", - "kind": "nested" - }, - { - "name": "StateUpdated", - "type": "dojo::world::world_contract::world::StateUpdated", - "kind": "nested" - } - ] - } - ], - "address": "0x263ae44e5414519a5c5a135cccaf3d9d7ee196d37e8de47a178da91f3de9b34", - "transaction_hash": "0x3f0a3ef84b6c8c32b8b2169f3d9cba4206e0704e8f780d0e3e35747123c56fc", - "block_number": 3, - "seed": "pixelaw", - "metadata": { - "profile_name": "dev", - "rpc_url": "http://localhost:5050/" - }, - "manifest_name": "dojo-world" - }, - "base": { - "kind": "Class", - "class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", - "original_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", - "abi": "manifests/dev/deployment/abis/dojo-base.json", - "tag": "dojo-base", - "manifest_name": "dojo-base" - }, - "contracts": [ - { - "kind": "DojoContract", - "address": "0x6c2ffdd97cb5a1bca13de416adb23a1d0e24ae3c805114b2100f6af95a7f60e", - "class_hash": "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f", - "original_class_hash": "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f", - "base_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", - "abi": [ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsImpl", - "interface_name": "pixelaw::core::actions::IActions" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permission", - "members": [ - { - "name": "app", - "type": "core::bool" - }, - { - "name": "color", - "type": "core::bool" - }, - { - "name": "owner", - "type": "core::bool" - }, - { - "name": "text", - "type": "core::bool" - }, - { - "name": "timestamp", - "type": "core::bool" - }, - { - "name": "action", - "type": "core::bool" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::pixel::Pixel", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "created_at", - "type": "core::integer::u64" - }, - { - "name": "updated_at", - "type": "core::integer::u64" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "text", - "type": "core::felt252" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "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": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "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": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "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": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::actions::IActions", - "items": [ - { - "type": "function", - "name": "init", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_permission", - "inputs": [ - { - "name": "app_key", - "type": "core::felt252" - }, - { - "name": "permission", - "type": "pixelaw::core::models::permissions::Permission" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "has_write_access", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "pixel", - "type": "pixelaw::core::models::pixel::Pixel" - }, - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [ - { - "type": "core::bool" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "process_queue", - "inputs": [ - { - "name": "id", - "type": "core::felt252" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "schedule_queue", - "inputs": [ - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_pixel", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "new_app", - "inputs": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "icon", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "pixelaw::core::models::registry::App" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_system_address", - "inputs": [ - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "get_player_address", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "alert_player", - "inputs": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "message", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_instruction", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "instruction", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "pixelaw::core::actions::actions::IDojoInit" - }, - { - "type": "interface", - "name": "pixelaw::core::actions::actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::QueueScheduled", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "calldata", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::QueueProcessed", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::AppNameUpdated", - "kind": "struct", - "members": [ - { - "name": "app", - "type": "pixelaw::core::models::registry::App", - "kind": "data" - }, - { - "name": "caller", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::Alert", - "kind": "struct", - "members": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position", - "kind": "data" - }, - { - "name": "caller", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "message", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "QueueScheduled", - "type": "pixelaw::core::actions::actions::QueueScheduled", - "kind": "nested" - }, - { - "name": "QueueProcessed", - "type": "pixelaw::core::actions::actions::QueueProcessed", - "kind": "nested" - }, - { - "name": "AppNameUpdated", - "type": "pixelaw::core::actions::actions::AppNameUpdated", - "kind": "nested" - }, - { - "name": "Alert", - "type": "pixelaw::core::actions::actions::Alert", - "kind": "nested" - } - ] - } - ], - "reads": [], - "writes": [ - "pixelaw-App", - "pixelaw-AppName", - "pixelaw-CoreActionsAddress", - "pixelaw-Pixel", - "pixelaw-Permissions", - "pixelaw-QueueItem", - "pixelaw-Instruction", - "pixelaw-PWarPixel", - "pixelaw-AllowedColor", - "pixelaw-PaletteColors" - ], - "init_calldata": [], - "tag": "pixelaw-actions", - "systems": [ - "init", - "update_permission", - "schedule_queue", - "process_queue", - "update_pixel", - "alert_player", - "set_instruction" - ], - "manifest_name": "pixelaw-actions-16928a49" - }, - { - "kind": "DojoContract", - "address": "0x138243b2aeb794df3c6a1b9fb9f834591b3e99c0d73cb59441a6e7cac15c7a", - "class_hash": "0x63080ea2cfae99d4b773b06c7d1cb893c197ba5e431afeba8909eac874d038e", - "original_class_hash": "0x63080ea2cfae99d4b773b06c7d1cb893c197ba5e431afeba8909eac874d038e", - "base_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", - "abi": [ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "GuildImpl", - "interface_name": "p_war::systems::guilds::IGuild" - }, - { - "type": "interface", - "name": "p_war::systems::guilds::IGuild", - "items": [ - { - "type": "function", - "name": "create_guild", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_name", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "add_member", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "new_member", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "remove_member", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_guild_points", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::guilds::guild_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::guilds::guild_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::GuildCreated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_name", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::MemberAdded", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::MemberRemoved", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "GuildCreated", - "type": "p_war::systems::guilds::guild_actions::GuildCreated", - "kind": "nested" - }, - { - "name": "MemberAdded", - "type": "p_war::systems::guilds::guild_actions::MemberAdded", - "kind": "nested" - }, - { - "name": "MemberRemoved", - "type": "p_war::systems::guilds::guild_actions::MemberRemoved", - "kind": "nested" - } - ] - } - ], - "reads": [], - "writes": [ - "pixelaw-Guild" - ], - "init_calldata": [], - "tag": "pixelaw-guild_actions", - "systems": [ - "add_member", - "remove_member" - ], - "manifest_name": "pixelaw-guild_actions-4c9f5931" - }, - { - "kind": "DojoContract", - "address": "0x2045bbeab298c52664537ae151262ca5f2a4e41b07f221c4860879551c65cb5", - "class_hash": "0x633981494952c9b7d079a8440b1c1ca8a689ff77f5d4ab2723bf5828d00a357", - "original_class_hash": "0x633981494952c9b7d079a8440b1c1ca8a689ff77f5d4ab2723bf5828d00a357", - "base_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", - "abi": [ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsInteroperability", - "interface_name": "pixelaw::core::traits::IInteroperability" - }, - { - "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": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "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": "interface", - "name": "pixelaw::core::traits::IInteroperability", - "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": [], - "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": "impl", - "name": "AllowedAppImpl", - "interface_name": "p_war::systems::apps::IAllowedApp" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::utils::DefaultParameters", - "members": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "color", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::apps::IAllowedApp", - "items": [ - { - "type": "function", - "name": "set_pixel", - "inputs": [ - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsImpl", - "interface_name": "p_war::systems::actions::IActions" - }, - { - "type": "interface", - "name": "p_war::systems::actions::IActions", - "items": [ - { - "type": "function", - "name": "init", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "interact", - "inputs": [ - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "create_game", - "inputs": [ - { - "name": "origin", - "type": "pixelaw::core::utils::Position" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_game_id", - "inputs": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "place_pixel", - "inputs": [ - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_pixel", - "inputs": [ - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "end_game", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::actions::p_war_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::actions::p_war_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::StartedGame", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u128", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::EndedGame", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u128", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "StartedGame", - "type": "p_war::systems::actions::p_war_actions::StartedGame", - "kind": "nested" - }, - { - "name": "EndedGame", - "type": "p_war::systems::actions::p_war_actions::EndedGame", - "kind": "nested" - } - ] - } - ], - "reads": [], - "writes": [ - "pixelaw-AllowedApp", - "pixelaw-Board", - "pixelaw-AllowedColor", - "pixelaw-PaletteColors", - "pixelaw-PWarPixel", - "pixelaw-Game", - "pixelaw-GameId", - "pixelaw-GamePalette", - "pixelaw-InPalette", - "pixelaw-Player", - "pixelaw-PixelRecoveryRate" - ], - "init_calldata": [], - "tag": "pixelaw-p_war_actions", - "systems": [ - "on_pre_update", - "on_post_update", - "set_pixel", - "init", - "interact", - "place_pixel", - "update_pixel", - "end_game" - ], - "manifest_name": "pixelaw-p_war_actions-60819afd" - }, - { - "kind": "DojoContract", - "address": "0x11c9f67cb73eece3bcf998a0b351e3cb936e0e41a94bebe352d1c1e0b4e09ce", - "class_hash": "0x7cc823538eb9a92fcd8af9cdb8d4293fe2c8b1cc090623670721f32b490c0ff", - "original_class_hash": "0x7cc823538eb9a92fcd8af9cdb8d4293fe2c8b1cc090623670721f32b490c0ff", - "base_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", - "abi": [ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ProposeImpl", - "interface_name": "p_war::systems::propose::IPropose" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::propose::IPropose", - "items": [ - { - "type": "function", - "name": "create_proposal", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "proposal_type", - "type": "core::integer::u8" - }, - { - "name": "target_args_1", - "type": "core::integer::u32" - }, - { - "name": "target_args_2", - "type": "core::integer::u32" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "activate_proposal", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "clear_data", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::propose::propose_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::propose::propose_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::ProposalCreated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "proposal_type", - "type": "core::integer::u8", - "kind": "data" - }, - { - "name": "target_args_1", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "target_args_2", - "type": "core::integer::u32", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::ProposalActivated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "proposal_type", - "type": "core::integer::u8", - "kind": "data" - }, - { - "name": "target_args_1", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "target_args_2", - "type": "core::integer::u32", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "ProposalCreated", - "type": "p_war::systems::propose::propose_actions::ProposalCreated", - "kind": "nested" - }, - { - "name": "ProposalActivated", - "type": "p_war::systems::propose::propose_actions::ProposalActivated", - "kind": "nested" - } - ] - } - ], - "reads": [], - "writes": [ - "pixelaw-AllowedColor", - "pixelaw-GamePalette", - "pixelaw-InPalette", - "pixelaw-PaletteColors", - "pixelaw-Proposal", - "pixelaw-Player", - "pixelaw-Game", - "pixelaw-Board" - ], - "init_calldata": [], - "tag": "pixelaw-propose_actions", - "systems": [ - "activate_proposal" - ], - "manifest_name": "pixelaw-propose_actions-4ee7028a" - }, - { - "kind": "DojoContract", - "address": "0x5e3d35ee4c47433f2550b295d68ec519124e027aeac31e9bbc2b8cf4a769c81", - "class_hash": "0x5e87a338c9ee6d9d72281883bd04133f0d91e4d5ecebcfbbf281319ce877b2a", - "original_class_hash": "0x5e87a338c9ee6d9d72281883bd04133f0d91e4d5ecebcfbbf281319ce877b2a", - "base_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", - "abi": [ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "VotingImpl", - "interface_name": "p_war::systems::voting::IVoting" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::voting::IVoting", - "items": [ - { - "type": "function", - "name": "vote", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "is_in_favor", - "type": "core::bool" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::voting::voting_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::voting::voting_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::voting::voting_actions::Voted", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - }, - { - "name": "voter", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "is_in_favor", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::voting::voting_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "Voted", - "type": "p_war::systems::voting::voting_actions::Voted", - "kind": "nested" - } - ] - } - ], - "reads": [], - "writes": [ - "pixelaw-PlayerVote", - "pixelaw-Proposal", - "pixelaw-Player" - ], - "init_calldata": [], - "tag": "pixelaw-voting_actions", - "systems": [ - "vote" - ], - "manifest_name": "pixelaw-voting_actions-6aab73ea" - } - ], - "models": [ - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "contract", - "type": "ContractAddress", - "key": true - }, - { - "name": "is_allowed", - "type": "bool", - "key": false - } - ], - "class_hash": "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f", - "original_class_hash": "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "allowed_appImpl", - "interface_name": "p_war::models::allowed_app::Iallowed_app" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_app::AllowedApp", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "contract", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "is_allowed", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_app::Iallowed_app", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_app::AllowedApp" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_app::allowed_app::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-AllowedApp", - "qualified_path": "p_war::models::allowed_app::allowed_app", - "manifest_name": "pixelaw-AllowedApp-4aa27058" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "color", - "type": "u32", - "key": true - }, - { - "name": "is_allowed", - "type": "bool", - "key": false - } - ], - "class_hash": "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54", - "original_class_hash": "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "allowed_colorImpl", - "interface_name": "p_war::models::allowed_color::Iallowed_color" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::AllowedColor", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "is_allowed", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Iallowed_color", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::AllowedColor" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::allowed_color::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-AllowedColor", - "qualified_path": "p_war::models::allowed_color::allowed_color", - "manifest_name": "pixelaw-AllowedColor-22c1a796" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "system", - "type": "ContractAddress", - "key": true - }, - { - "name": "name", - "type": "felt252", - "key": false - }, - { - "name": "icon", - "type": "felt252", - "key": false - }, - { - "name": "action", - "type": "felt252", - "key": false - } - ], - "class_hash": "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c", - "original_class_hash": "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "appImpl", - "interface_name": "pixelaw::core::models::registry::Iapp" - }, - { - "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": "interface", - "name": "pixelaw::core::models::registry::Iapp", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::App" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-App", - "qualified_path": "pixelaw::core::models::registry::app", - "manifest_name": "pixelaw-App-36504565" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "name", - "type": "felt252", - "key": true - }, - { - "name": "system", - "type": "ContractAddress", - "key": false - } - ], - "class_hash": "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8", - "original_class_hash": "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "app_nameImpl", - "interface_name": "pixelaw::core::models::registry::Iapp_name" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::AppName", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iapp_name", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::AppName" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app_name::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-AppName", - "qualified_path": "pixelaw::core::models::registry::app_name", - "manifest_name": "pixelaw-AppName-3b816829" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "system", - "type": "ContractAddress", - "key": true - }, - { - "name": "player", - "type": "ContractAddress", - "key": true - }, - { - "name": "action", - "type": "felt252", - "key": false - } - ], - "class_hash": "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1", - "original_class_hash": "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "app_userImpl", - "interface_name": "pixelaw::core::models::registry::Iapp_user" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::AppUser", - "members": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iapp_user", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::AppUser" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app_user::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-AppUser", - "qualified_path": "pixelaw::core::models::registry::app_user", - "manifest_name": "pixelaw-AppUser-4eda3c52" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "id", - "type": "usize", - "key": true - }, - { - "name": "origin", - "type": "Position", - "key": false - }, - { - "name": "width", - "type": "u32", - "key": false - }, - { - "name": "height", - "type": "u32", - "key": false - } - ], - "class_hash": "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c", - "original_class_hash": "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "boardImpl", - "interface_name": "p_war::models::board::Iboard" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::board::Board", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "origin", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "width", - "type": "core::integer::u32" - }, - { - "name": "height", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Iboard", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::Board" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::board::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Board", - "qualified_path": "p_war::models::board::board", - "manifest_name": "pixelaw-Board-124dc3e7" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "key", - "type": "felt252", - "key": true - }, - { - "name": "value", - "type": "ContractAddress", - "key": false - } - ], - "class_hash": "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2", - "original_class_hash": "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "core_actions_addressImpl", - "interface_name": "pixelaw::core::models::registry::Icore_actions_address" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::CoreActionsAddress", - "members": [ - { - "name": "key", - "type": "core::felt252" - }, - { - "name": "value", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Icore_actions_address", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::CoreActionsAddress" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::core_actions_address::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-CoreActionsAddress", - "qualified_path": "pixelaw::core::models::registry::core_actions_address", - "manifest_name": "pixelaw-CoreActionsAddress-5379e1ce" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "id", - "type": "usize", - "key": true - }, - { - "name": "start", - "type": "u64", - "key": false - }, - { - "name": "end", - "type": "u64", - "key": false - }, - { - "name": "proposal_idx", - "type": "usize", - "key": false - }, - { - "name": "coeff_own_pixels", - "type": "u32", - "key": false - }, - { - "name": "coeff_commits", - "type": "u32", - "key": false - }, - { - "name": "winner_config", - "type": "u32", - "key": false - }, - { - "name": "winner", - "type": "ContractAddress", - "key": false - }, - { - "name": "guild_ids", - "type": "Span", - "key": false - }, - { - "name": "guild_count", - "type": "usize", - "key": false - } - ], - "class_hash": "0x4eb28e2e4c9f69487e5479cacac150e52666d072315dc8e3547b32f977976e0", - "original_class_hash": "0x4eb28e2e4c9f69487e5479cacac150e52666d072315dc8e3547b32f977976e0", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "gameImpl", - "interface_name": "p_war::models::game::Igame" - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::game::Game", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "start", - "type": "core::integer::u64" - }, - { - "name": "end", - "type": "core::integer::u64" - }, - { - "name": "proposal_idx", - "type": "core::integer::u32" - }, - { - "name": "coeff_own_pixels", - "type": "core::integer::u32" - }, - { - "name": "coeff_commits", - "type": "core::integer::u32" - }, - { - "name": "winner_config", - "type": "core::integer::u32" - }, - { - "name": "winner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "guild_ids", - "type": "core::array::Span::" - }, - { - "name": "guild_count", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::game::Igame", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::game::Game" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::game::game::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Game", - "qualified_path": "p_war::models::game::game", - "manifest_name": "pixelaw-Game-5c1fa23f" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "x", - "type": "u32", - "key": true - }, - { - "name": "y", - "type": "u32", - "key": true - }, - { - "name": "value", - "type": "usize", - "key": false - } - ], - "class_hash": "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4", - "original_class_hash": "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "game_idImpl", - "interface_name": "p_war::models::board::Igame_id" - }, - { - "type": "struct", - "name": "p_war::models::board::GameId", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "value", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Igame_id", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::GameId" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::game_id::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-GameId", - "qualified_path": "p_war::models::board::game_id", - "manifest_name": "pixelaw-GameId-1ee8756e" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "length", - "type": "usize", - "key": false - } - ], - "class_hash": "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398", - "original_class_hash": "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "game_paletteImpl", - "interface_name": "p_war::models::allowed_color::Igame_palette" - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::GamePalette", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "length", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Igame_palette", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::GamePalette" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::game_palette::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-GamePalette", - "qualified_path": "p_war::models::allowed_color::game_palette", - "manifest_name": "pixelaw-GamePalette-49013f2b" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "guild_id", - "type": "usize", - "key": true - }, - { - "name": "guild_name", - "type": "felt252", - "key": false - }, - { - "name": "creator", - "type": "ContractAddress", - "key": false - }, - { - "name": "members", - "type": "Span", - "key": false - }, - { - "name": "member_count", - "type": "usize", - "key": false - } - ], - "class_hash": "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95", - "original_class_hash": "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "guildImpl", - "interface_name": "p_war::models::guilds::Iguild" - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::guilds::Guild", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "guild_name", - "type": "core::felt252" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "members", - "type": "core::array::Span::" - }, - { - "name": "member_count", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::guilds::Iguild", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::guilds::Guild" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::guilds::guild::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Guild", - "qualified_path": "p_war::models::guilds::guild", - "manifest_name": "pixelaw-Guild-40e97c00" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "color", - "type": "u32", - "key": true - }, - { - "name": "value", - "type": "bool", - "key": false - } - ], - "class_hash": "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372", - "original_class_hash": "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "in_paletteImpl", - "interface_name": "p_war::models::allowed_color::Iin_palette" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::InPalette", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "value", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Iin_palette", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::InPalette" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::in_palette::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-InPalette", - "qualified_path": "p_war::models::allowed_color::in_palette", - "manifest_name": "pixelaw-InPalette-7a46e3ad" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "system", - "type": "ContractAddress", - "key": true - }, - { - "name": "selector", - "type": "felt252", - "key": true - }, - { - "name": "instruction", - "type": "felt252", - "key": false - } - ], - "class_hash": "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af", - "original_class_hash": "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "instructionImpl", - "interface_name": "pixelaw::core::models::registry::Iinstruction" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::Instruction", - "members": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "instruction", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iinstruction", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::Instruction" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::instruction::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Instruction", - "qualified_path": "pixelaw::core::models::registry::instruction", - "manifest_name": "pixelaw-Instruction-4c7c4844" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "position", - "type": "Position", - "key": true - }, - { - "name": "owner", - "type": "ContractAddress", - "key": false - } - ], - "class_hash": "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261", - "original_class_hash": "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "p_war_pixelImpl", - "interface_name": "p_war::models::board::Ip_war_pixel" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::board::PWarPixel", - "members": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Ip_war_pixel", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::PWarPixel" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::p_war_pixel::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-PWarPixel", - "qualified_path": "p_war::models::board::p_war_pixel", - "manifest_name": "pixelaw-PWarPixel-15195913" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "idx", - "type": "u32", - "key": true - }, - { - "name": "color", - "type": "u32", - "key": false - } - ], - "class_hash": "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444", - "original_class_hash": "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "palette_colorsImpl", - "interface_name": "p_war::models::allowed_color::Ipalette_colors" - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::PaletteColors", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "idx", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Ipalette_colors", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::PaletteColors" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::palette_colors::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-PaletteColors", - "qualified_path": "p_war::models::allowed_color::palette_colors", - "manifest_name": "pixelaw-PaletteColors-39a92a0a" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "allowing_app", - "type": "ContractAddress", - "key": true - }, - { - "name": "allowed_app", - "type": "ContractAddress", - "key": true - }, - { - "name": "permission", - "type": "Permission", - "key": false - } - ], - "class_hash": "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302", - "original_class_hash": "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "permissionsImpl", - "interface_name": "pixelaw::core::models::permissions::Ipermissions" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permission", - "members": [ - { - "name": "app", - "type": "core::bool" - }, - { - "name": "color", - "type": "core::bool" - }, - { - "name": "owner", - "type": "core::bool" - }, - { - "name": "text", - "type": "core::bool" - }, - { - "name": "timestamp", - "type": "core::bool" - }, - { - "name": "action", - "type": "core::bool" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permissions", - "members": [ - { - "name": "allowing_app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "allowed_app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "permission", - "type": "pixelaw::core::models::permissions::Permission" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::permissions::Ipermissions", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::permissions::Permissions" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::permissions::permissions::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Permissions", - "qualified_path": "pixelaw::core::models::permissions::permissions", - "manifest_name": "pixelaw-Permissions-72b77307" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "x", - "type": "u32", - "key": true - }, - { - "name": "y", - "type": "u32", - "key": true - }, - { - "name": "app", - "type": "ContractAddress", - "key": false - }, - { - "name": "color", - "type": "u32", - "key": false - }, - { - "name": "created_at", - "type": "u64", - "key": false - }, - { - "name": "updated_at", - "type": "u64", - "key": false - }, - { - "name": "timestamp", - "type": "u64", - "key": false - }, - { - "name": "owner", - "type": "ContractAddress", - "key": false - }, - { - "name": "text", - "type": "felt252", - "key": false - }, - { - "name": "action", - "type": "felt252", - "key": false - } - ], - "class_hash": "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d", - "original_class_hash": "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "pixelImpl", - "interface_name": "pixelaw::core::models::pixel::Ipixel" - }, - { - "type": "struct", - "name": "pixelaw::core::models::pixel::Pixel", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "created_at", - "type": "core::integer::u64" - }, - { - "name": "updated_at", - "type": "core::integer::u64" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "text", - "type": "core::felt252" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::pixel::Ipixel", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::pixel::Pixel" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::pixel::pixel::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Pixel", - "qualified_path": "pixelaw::core::models::pixel::pixel", - "manifest_name": "pixelaw-Pixel-7e607b2f" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "rate", - "type": "u64", - "key": false - } - ], - "class_hash": "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067", - "original_class_hash": "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "pixel_recovery_rateImpl", - "interface_name": "p_war::models::proposal::Ipixel_recovery_rate" - }, - { - "type": "struct", - "name": "p_war::models::proposal::PixelRecoveryRate", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "rate", - "type": "core::integer::u64" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Ipixel_recovery_rate", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::PixelRecoveryRate" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::pixel_recovery_rate::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-PixelRecoveryRate", - "qualified_path": "p_war::models::proposal::pixel_recovery_rate", - "manifest_name": "pixelaw-PixelRecoveryRate-3aa284c0" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "address", - "type": "ContractAddress", - "key": true - }, - { - "name": "num_owns", - "type": "u32", - "key": false - }, - { - "name": "num_commit", - "type": "u32", - "key": false - }, - { - "name": "last_date", - "type": "u64", - "key": false - }, - { - "name": "is_banned", - "type": "bool", - "key": false - } - ], - "class_hash": "0x71a6f6188f355d1337561c8d68538b18ec4be4c493d01be5eee753759246848", - "original_class_hash": "0x71a6f6188f355d1337561c8d68538b18ec4be4c493d01be5eee753759246848", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "playerImpl", - "interface_name": "p_war::models::player::Iplayer" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::player::Player", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "num_owns", - "type": "core::integer::u32" - }, - { - "name": "num_commit", - "type": "core::integer::u32" - }, - { - "name": "last_date", - "type": "core::integer::u64" - }, - { - "name": "is_banned", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::player::Iplayer", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::player::Player" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::player::player::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Player", - "qualified_path": "p_war::models::player::player", - "manifest_name": "pixelaw-Player-30a1b371" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "player", - "type": "ContractAddress", - "key": true - }, - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "index", - "type": "usize", - "key": true - }, - { - "name": "is_in_favor", - "type": "bool", - "key": false - }, - { - "name": "voting_power", - "type": "u32", - "key": false - } - ], - "class_hash": "0x4b76f6971c93c77d96a22ac7ba0268c452d13538f05b64138a6382e18babb00", - "original_class_hash": "0x4b76f6971c93c77d96a22ac7ba0268c452d13538f05b64138a6382e18babb00", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "player_voteImpl", - "interface_name": "p_war::models::proposal::Iplayer_vote" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::proposal::PlayerVote", - "members": [ - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "is_in_favor", - "type": "core::bool" - }, - { - "name": "voting_power", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Iplayer_vote", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::PlayerVote" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::player_vote::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-PlayerVote", - "qualified_path": "p_war::models::proposal::player_vote", - "manifest_name": "pixelaw-PlayerVote-326c17c6" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "index", - "type": "usize", - "key": true - }, - { - "name": "author", - "type": "ContractAddress", - "key": false - }, - { - "name": "proposal_type", - "type": "u8", - "key": false - }, - { - "name": "target_args_1", - "type": "u32", - "key": false - }, - { - "name": "target_args_2", - "type": "u32", - "key": false - }, - { - "name": "start", - "type": "u64", - "key": false - }, - { - "name": "end", - "type": "u64", - "key": false - }, - { - "name": "yes_voting_power", - "type": "u32", - "key": false - }, - { - "name": "no_voting_power", - "type": "u32", - "key": false - }, - { - "name": "is_activated", - "type": "bool", - "key": false - } - ], - "class_hash": "0x76c0a4827cc62be7367ab6fac605335bb5a2d01a7edc3f2dd89e58accafca02", - "original_class_hash": "0x76c0a4827cc62be7367ab6fac605335bb5a2d01a7edc3f2dd89e58accafca02", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "proposalImpl", - "interface_name": "p_war::models::proposal::Iproposal" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::proposal::Proposal", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "author", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "proposal_type", - "type": "core::integer::u8" - }, - { - "name": "target_args_1", - "type": "core::integer::u32" - }, - { - "name": "target_args_2", - "type": "core::integer::u32" - }, - { - "name": "start", - "type": "core::integer::u64" - }, - { - "name": "end", - "type": "core::integer::u64" - }, - { - "name": "yes_voting_power", - "type": "core::integer::u32" - }, - { - "name": "no_voting_power", - "type": "core::integer::u32" - }, - { - "name": "is_activated", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Iproposal", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::Proposal" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::proposal::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Proposal", - "qualified_path": "p_war::models::proposal::proposal", - "manifest_name": "pixelaw-Proposal-49e1daf5" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "id", - "type": "felt252", - "key": true - }, - { - "name": "valid", - "type": "bool", - "key": false - } - ], - "class_hash": "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70", - "original_class_hash": "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "queue_itemImpl", - "interface_name": "pixelaw::core::models::queue::Iqueue_item" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::queue::QueueItem", - "members": [ - { - "name": "id", - "type": "core::felt252" - }, - { - "name": "valid", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::queue::Iqueue_item", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::queue::QueueItem" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::queue::queue_item::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-QueueItem", - "qualified_path": "pixelaw::core::models::queue::queue_item", - "manifest_name": "pixelaw-QueueItem-549a17f2" - } - ] -} \ No newline at end of file diff --git a/contracts/manifests/dev/deployment/manifest.toml b/contracts/manifests/dev/deployment/manifest.toml deleted file mode 100644 index 9b6d027..0000000 --- a/contracts/manifests/dev/deployment/manifest.toml +++ /dev/null @@ -1,801 +0,0 @@ -[world] -kind = "WorldContract" -class_hash = "0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e" -original_class_hash = "0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e" -abi = "manifests/dev/deployment/abis/dojo-world.json" -address = "0x263ae44e5414519a5c5a135cccaf3d9d7ee196d37e8de47a178da91f3de9b34" -transaction_hash = "0x3f0a3ef84b6c8c32b8b2169f3d9cba4206e0704e8f780d0e3e35747123c56fc" -block_number = 3 -seed = "pixelaw" -manifest_name = "dojo-world" - -[world.metadata] -profile_name = "dev" -rpc_url = "http://localhost:5050/" - -[base] -kind = "Class" -class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -original_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -abi = "manifests/dev/deployment/abis/dojo-base.json" -tag = "dojo-base" -manifest_name = "dojo-base" - -[[contracts]] -kind = "DojoContract" -address = "0x6c2ffdd97cb5a1bca13de416adb23a1d0e24ae3c805114b2100f6af95a7f60e" -class_hash = "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f" -original_class_hash = "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f" -base_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -abi = "manifests/dev/deployment/abis/contracts/pixelaw-actions-16928a49.json" -reads = [] -writes = [ - "pixelaw-App", - "pixelaw-AppName", - "pixelaw-CoreActionsAddress", - "pixelaw-Pixel", - "pixelaw-Permissions", - "pixelaw-QueueItem", - "pixelaw-Instruction", - "pixelaw-PWarPixel", - "pixelaw-AllowedColor", - "pixelaw-PaletteColors", -] -init_calldata = [] -tag = "pixelaw-actions" -systems = [ - "init", - "update_permission", - "schedule_queue", - "process_queue", - "update_pixel", - "alert_player", - "set_instruction", -] -manifest_name = "pixelaw-actions-16928a49" - -[[contracts]] -kind = "DojoContract" -address = "0x138243b2aeb794df3c6a1b9fb9f834591b3e99c0d73cb59441a6e7cac15c7a" -class_hash = "0x63080ea2cfae99d4b773b06c7d1cb893c197ba5e431afeba8909eac874d038e" -original_class_hash = "0x63080ea2cfae99d4b773b06c7d1cb893c197ba5e431afeba8909eac874d038e" -base_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -abi = "manifests/dev/deployment/abis/contracts/pixelaw-guild_actions-4c9f5931.json" -reads = [] -writes = ["pixelaw-Guild"] -init_calldata = [] -tag = "pixelaw-guild_actions" -systems = [ - "add_member", - "remove_member", -] -manifest_name = "pixelaw-guild_actions-4c9f5931" - -[[contracts]] -kind = "DojoContract" -address = "0x2045bbeab298c52664537ae151262ca5f2a4e41b07f221c4860879551c65cb5" -class_hash = "0x633981494952c9b7d079a8440b1c1ca8a689ff77f5d4ab2723bf5828d00a357" -original_class_hash = "0x633981494952c9b7d079a8440b1c1ca8a689ff77f5d4ab2723bf5828d00a357" -base_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -abi = "manifests/dev/deployment/abis/contracts/pixelaw-p_war_actions-60819afd.json" -reads = [] -writes = [ - "pixelaw-AllowedApp", - "pixelaw-Board", - "pixelaw-AllowedColor", - "pixelaw-PaletteColors", - "pixelaw-PWarPixel", - "pixelaw-Game", - "pixelaw-GameId", - "pixelaw-GamePalette", - "pixelaw-InPalette", - "pixelaw-Player", - "pixelaw-PixelRecoveryRate", -] -init_calldata = [] -tag = "pixelaw-p_war_actions" -systems = [ - "on_pre_update", - "on_post_update", - "set_pixel", - "init", - "interact", - "place_pixel", - "update_pixel", - "end_game", -] -manifest_name = "pixelaw-p_war_actions-60819afd" - -[[contracts]] -kind = "DojoContract" -address = "0x11c9f67cb73eece3bcf998a0b351e3cb936e0e41a94bebe352d1c1e0b4e09ce" -class_hash = "0x7cc823538eb9a92fcd8af9cdb8d4293fe2c8b1cc090623670721f32b490c0ff" -original_class_hash = "0x7cc823538eb9a92fcd8af9cdb8d4293fe2c8b1cc090623670721f32b490c0ff" -base_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -abi = "manifests/dev/deployment/abis/contracts/pixelaw-propose_actions-4ee7028a.json" -reads = [] -writes = [ - "pixelaw-AllowedColor", - "pixelaw-GamePalette", - "pixelaw-InPalette", - "pixelaw-PaletteColors", - "pixelaw-Proposal", - "pixelaw-Player", - "pixelaw-Game", - "pixelaw-Board", -] -init_calldata = [] -tag = "pixelaw-propose_actions" -systems = ["activate_proposal"] -manifest_name = "pixelaw-propose_actions-4ee7028a" - -[[contracts]] -kind = "DojoContract" -address = "0x5e3d35ee4c47433f2550b295d68ec519124e027aeac31e9bbc2b8cf4a769c81" -class_hash = "0x5e87a338c9ee6d9d72281883bd04133f0d91e4d5ecebcfbbf281319ce877b2a" -original_class_hash = "0x5e87a338c9ee6d9d72281883bd04133f0d91e4d5ecebcfbbf281319ce877b2a" -base_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -abi = "manifests/dev/deployment/abis/contracts/pixelaw-voting_actions-6aab73ea.json" -reads = [] -writes = [ - "pixelaw-PlayerVote", - "pixelaw-Proposal", - "pixelaw-Player", -] -init_calldata = [] -tag = "pixelaw-voting_actions" -systems = ["vote"] -manifest_name = "pixelaw-voting_actions-6aab73ea" - -[[models]] -kind = "DojoModel" -class_hash = "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f" -original_class_hash = "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f" -abi = "manifests/dev/deployment/abis/models/pixelaw-AllowedApp-4aa27058.json" -tag = "pixelaw-AllowedApp" -qualified_path = "p_war::models::allowed_app::allowed_app" -manifest_name = "pixelaw-AllowedApp-4aa27058" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "contract" -type = "ContractAddress" -key = true - -[[models.members]] -name = "is_allowed" -type = "bool" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54" -original_class_hash = "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54" -abi = "manifests/dev/deployment/abis/models/pixelaw-AllowedColor-22c1a796.json" -tag = "pixelaw-AllowedColor" -qualified_path = "p_war::models::allowed_color::allowed_color" -manifest_name = "pixelaw-AllowedColor-22c1a796" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "color" -type = "u32" -key = true - -[[models.members]] -name = "is_allowed" -type = "bool" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c" -original_class_hash = "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c" -abi = "manifests/dev/deployment/abis/models/pixelaw-App-36504565.json" -tag = "pixelaw-App" -qualified_path = "pixelaw::core::models::registry::app" -manifest_name = "pixelaw-App-36504565" - -[[models.members]] -name = "system" -type = "ContractAddress" -key = true - -[[models.members]] -name = "name" -type = "felt252" -key = false - -[[models.members]] -name = "icon" -type = "felt252" -key = false - -[[models.members]] -name = "action" -type = "felt252" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8" -original_class_hash = "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8" -abi = "manifests/dev/deployment/abis/models/pixelaw-AppName-3b816829.json" -tag = "pixelaw-AppName" -qualified_path = "pixelaw::core::models::registry::app_name" -manifest_name = "pixelaw-AppName-3b816829" - -[[models.members]] -name = "name" -type = "felt252" -key = true - -[[models.members]] -name = "system" -type = "ContractAddress" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1" -original_class_hash = "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1" -abi = "manifests/dev/deployment/abis/models/pixelaw-AppUser-4eda3c52.json" -tag = "pixelaw-AppUser" -qualified_path = "pixelaw::core::models::registry::app_user" -manifest_name = "pixelaw-AppUser-4eda3c52" - -[[models.members]] -name = "system" -type = "ContractAddress" -key = true - -[[models.members]] -name = "player" -type = "ContractAddress" -key = true - -[[models.members]] -name = "action" -type = "felt252" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c" -original_class_hash = "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c" -abi = "manifests/dev/deployment/abis/models/pixelaw-Board-124dc3e7.json" -tag = "pixelaw-Board" -qualified_path = "p_war::models::board::board" -manifest_name = "pixelaw-Board-124dc3e7" - -[[models.members]] -name = "id" -type = "usize" -key = true - -[[models.members]] -name = "origin" -type = "Position" -key = false - -[[models.members]] -name = "width" -type = "u32" -key = false - -[[models.members]] -name = "height" -type = "u32" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2" -original_class_hash = "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2" -abi = "manifests/dev/deployment/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json" -tag = "pixelaw-CoreActionsAddress" -qualified_path = "pixelaw::core::models::registry::core_actions_address" -manifest_name = "pixelaw-CoreActionsAddress-5379e1ce" - -[[models.members]] -name = "key" -type = "felt252" -key = true - -[[models.members]] -name = "value" -type = "ContractAddress" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x4eb28e2e4c9f69487e5479cacac150e52666d072315dc8e3547b32f977976e0" -original_class_hash = "0x4eb28e2e4c9f69487e5479cacac150e52666d072315dc8e3547b32f977976e0" -abi = "manifests/dev/deployment/abis/models/pixelaw-Game-5c1fa23f.json" -tag = "pixelaw-Game" -qualified_path = "p_war::models::game::game" -manifest_name = "pixelaw-Game-5c1fa23f" - -[[models.members]] -name = "id" -type = "usize" -key = true - -[[models.members]] -name = "start" -type = "u64" -key = false - -[[models.members]] -name = "end" -type = "u64" -key = false - -[[models.members]] -name = "proposal_idx" -type = "usize" -key = false - -[[models.members]] -name = "coeff_own_pixels" -type = "u32" -key = false - -[[models.members]] -name = "coeff_commits" -type = "u32" -key = false - -[[models.members]] -name = "winner_config" -type = "u32" -key = false - -[[models.members]] -name = "winner" -type = "ContractAddress" -key = false - -[[models.members]] -name = "guild_ids" -type = "Span" -key = false - -[[models.members]] -name = "guild_count" -type = "usize" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4" -original_class_hash = "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4" -abi = "manifests/dev/deployment/abis/models/pixelaw-GameId-1ee8756e.json" -tag = "pixelaw-GameId" -qualified_path = "p_war::models::board::game_id" -manifest_name = "pixelaw-GameId-1ee8756e" - -[[models.members]] -name = "x" -type = "u32" -key = true - -[[models.members]] -name = "y" -type = "u32" -key = true - -[[models.members]] -name = "value" -type = "usize" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398" -original_class_hash = "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398" -abi = "manifests/dev/deployment/abis/models/pixelaw-GamePalette-49013f2b.json" -tag = "pixelaw-GamePalette" -qualified_path = "p_war::models::allowed_color::game_palette" -manifest_name = "pixelaw-GamePalette-49013f2b" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "length" -type = "usize" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95" -original_class_hash = "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95" -abi = "manifests/dev/deployment/abis/models/pixelaw-Guild-40e97c00.json" -tag = "pixelaw-Guild" -qualified_path = "p_war::models::guilds::guild" -manifest_name = "pixelaw-Guild-40e97c00" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "guild_id" -type = "usize" -key = true - -[[models.members]] -name = "guild_name" -type = "felt252" -key = false - -[[models.members]] -name = "creator" -type = "ContractAddress" -key = false - -[[models.members]] -name = "members" -type = "Span" -key = false - -[[models.members]] -name = "member_count" -type = "usize" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372" -original_class_hash = "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372" -abi = "manifests/dev/deployment/abis/models/pixelaw-InPalette-7a46e3ad.json" -tag = "pixelaw-InPalette" -qualified_path = "p_war::models::allowed_color::in_palette" -manifest_name = "pixelaw-InPalette-7a46e3ad" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "color" -type = "u32" -key = true - -[[models.members]] -name = "value" -type = "bool" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af" -original_class_hash = "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af" -abi = "manifests/dev/deployment/abis/models/pixelaw-Instruction-4c7c4844.json" -tag = "pixelaw-Instruction" -qualified_path = "pixelaw::core::models::registry::instruction" -manifest_name = "pixelaw-Instruction-4c7c4844" - -[[models.members]] -name = "system" -type = "ContractAddress" -key = true - -[[models.members]] -name = "selector" -type = "felt252" -key = true - -[[models.members]] -name = "instruction" -type = "felt252" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261" -original_class_hash = "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261" -abi = "manifests/dev/deployment/abis/models/pixelaw-PWarPixel-15195913.json" -tag = "pixelaw-PWarPixel" -qualified_path = "p_war::models::board::p_war_pixel" -manifest_name = "pixelaw-PWarPixel-15195913" - -[[models.members]] -name = "position" -type = "Position" -key = true - -[[models.members]] -name = "owner" -type = "ContractAddress" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444" -original_class_hash = "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444" -abi = "manifests/dev/deployment/abis/models/pixelaw-PaletteColors-39a92a0a.json" -tag = "pixelaw-PaletteColors" -qualified_path = "p_war::models::allowed_color::palette_colors" -manifest_name = "pixelaw-PaletteColors-39a92a0a" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "idx" -type = "u32" -key = true - -[[models.members]] -name = "color" -type = "u32" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302" -original_class_hash = "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302" -abi = "manifests/dev/deployment/abis/models/pixelaw-Permissions-72b77307.json" -tag = "pixelaw-Permissions" -qualified_path = "pixelaw::core::models::permissions::permissions" -manifest_name = "pixelaw-Permissions-72b77307" - -[[models.members]] -name = "allowing_app" -type = "ContractAddress" -key = true - -[[models.members]] -name = "allowed_app" -type = "ContractAddress" -key = true - -[[models.members]] -name = "permission" -type = "Permission" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d" -original_class_hash = "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d" -abi = "manifests/dev/deployment/abis/models/pixelaw-Pixel-7e607b2f.json" -tag = "pixelaw-Pixel" -qualified_path = "pixelaw::core::models::pixel::pixel" -manifest_name = "pixelaw-Pixel-7e607b2f" - -[[models.members]] -name = "x" -type = "u32" -key = true - -[[models.members]] -name = "y" -type = "u32" -key = true - -[[models.members]] -name = "app" -type = "ContractAddress" -key = false - -[[models.members]] -name = "color" -type = "u32" -key = false - -[[models.members]] -name = "created_at" -type = "u64" -key = false - -[[models.members]] -name = "updated_at" -type = "u64" -key = false - -[[models.members]] -name = "timestamp" -type = "u64" -key = false - -[[models.members]] -name = "owner" -type = "ContractAddress" -key = false - -[[models.members]] -name = "text" -type = "felt252" -key = false - -[[models.members]] -name = "action" -type = "felt252" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067" -original_class_hash = "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067" -abi = "manifests/dev/deployment/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json" -tag = "pixelaw-PixelRecoveryRate" -qualified_path = "p_war::models::proposal::pixel_recovery_rate" -manifest_name = "pixelaw-PixelRecoveryRate-3aa284c0" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "rate" -type = "u64" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x71a6f6188f355d1337561c8d68538b18ec4be4c493d01be5eee753759246848" -original_class_hash = "0x71a6f6188f355d1337561c8d68538b18ec4be4c493d01be5eee753759246848" -abi = "manifests/dev/deployment/abis/models/pixelaw-Player-30a1b371.json" -tag = "pixelaw-Player" -qualified_path = "p_war::models::player::player" -manifest_name = "pixelaw-Player-30a1b371" - -[[models.members]] -name = "address" -type = "ContractAddress" -key = true - -[[models.members]] -name = "num_owns" -type = "u32" -key = false - -[[models.members]] -name = "num_commit" -type = "u32" -key = false - -[[models.members]] -name = "last_date" -type = "u64" -key = false - -[[models.members]] -name = "is_banned" -type = "bool" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x4b76f6971c93c77d96a22ac7ba0268c452d13538f05b64138a6382e18babb00" -original_class_hash = "0x4b76f6971c93c77d96a22ac7ba0268c452d13538f05b64138a6382e18babb00" -abi = "manifests/dev/deployment/abis/models/pixelaw-PlayerVote-326c17c6.json" -tag = "pixelaw-PlayerVote" -qualified_path = "p_war::models::proposal::player_vote" -manifest_name = "pixelaw-PlayerVote-326c17c6" - -[[models.members]] -name = "player" -type = "ContractAddress" -key = true - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "index" -type = "usize" -key = true - -[[models.members]] -name = "is_in_favor" -type = "bool" -key = false - -[[models.members]] -name = "voting_power" -type = "u32" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x76c0a4827cc62be7367ab6fac605335bb5a2d01a7edc3f2dd89e58accafca02" -original_class_hash = "0x76c0a4827cc62be7367ab6fac605335bb5a2d01a7edc3f2dd89e58accafca02" -abi = "manifests/dev/deployment/abis/models/pixelaw-Proposal-49e1daf5.json" -tag = "pixelaw-Proposal" -qualified_path = "p_war::models::proposal::proposal" -manifest_name = "pixelaw-Proposal-49e1daf5" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "index" -type = "usize" -key = true - -[[models.members]] -name = "author" -type = "ContractAddress" -key = false - -[[models.members]] -name = "proposal_type" -type = "u8" -key = false - -[[models.members]] -name = "target_args_1" -type = "u32" -key = false - -[[models.members]] -name = "target_args_2" -type = "u32" -key = false - -[[models.members]] -name = "start" -type = "u64" -key = false - -[[models.members]] -name = "end" -type = "u64" -key = false - -[[models.members]] -name = "yes_voting_power" -type = "u32" -key = false - -[[models.members]] -name = "no_voting_power" -type = "u32" -key = false - -[[models.members]] -name = "is_activated" -type = "bool" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70" -original_class_hash = "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70" -abi = "manifests/dev/deployment/abis/models/pixelaw-QueueItem-549a17f2.json" -tag = "pixelaw-QueueItem" -qualified_path = "pixelaw::core::models::queue::queue_item" -manifest_name = "pixelaw-QueueItem-549a17f2" - -[[models.members]] -name = "id" -type = "felt252" -key = true - -[[models.members]] -name = "valid" -type = "bool" -key = false diff --git a/contracts/manifests/release/base/abis/contracts/pixelaw-actions-16928a49.json b/contracts/manifests/release/base/abis/contracts/pixelaw-actions-16928a49.json deleted file mode 100644 index e71ba18..0000000 --- a/contracts/manifests/release/base/abis/contracts/pixelaw-actions-16928a49.json +++ /dev/null @@ -1,775 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsImpl", - "interface_name": "pixelaw::core::actions::IActions" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permission", - "members": [ - { - "name": "app", - "type": "core::bool" - }, - { - "name": "color", - "type": "core::bool" - }, - { - "name": "owner", - "type": "core::bool" - }, - { - "name": "text", - "type": "core::bool" - }, - { - "name": "timestamp", - "type": "core::bool" - }, - { - "name": "action", - "type": "core::bool" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::pixel::Pixel", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "created_at", - "type": "core::integer::u64" - }, - { - "name": "updated_at", - "type": "core::integer::u64" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "text", - "type": "core::felt252" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "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": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "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": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "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": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::actions::IActions", - "items": [ - { - "type": "function", - "name": "init", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_permission", - "inputs": [ - { - "name": "app_key", - "type": "core::felt252" - }, - { - "name": "permission", - "type": "pixelaw::core::models::permissions::Permission" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "has_write_access", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "pixel", - "type": "pixelaw::core::models::pixel::Pixel" - }, - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [ - { - "type": "core::bool" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "process_queue", - "inputs": [ - { - "name": "id", - "type": "core::felt252" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "schedule_queue", - "inputs": [ - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_pixel", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "new_app", - "inputs": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "icon", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "pixelaw::core::models::registry::App" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_system_address", - "inputs": [ - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "get_player_address", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "alert_player", - "inputs": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "message", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_instruction", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "instruction", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "pixelaw::core::actions::actions::IDojoInit" - }, - { - "type": "interface", - "name": "pixelaw::core::actions::actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::QueueScheduled", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "calldata", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::QueueProcessed", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::AppNameUpdated", - "kind": "struct", - "members": [ - { - "name": "app", - "type": "pixelaw::core::models::registry::App", - "kind": "data" - }, - { - "name": "caller", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::Alert", - "kind": "struct", - "members": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position", - "kind": "data" - }, - { - "name": "caller", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "message", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "QueueScheduled", - "type": "pixelaw::core::actions::actions::QueueScheduled", - "kind": "nested" - }, - { - "name": "QueueProcessed", - "type": "pixelaw::core::actions::actions::QueueProcessed", - "kind": "nested" - }, - { - "name": "AppNameUpdated", - "type": "pixelaw::core::actions::actions::AppNameUpdated", - "kind": "nested" - }, - { - "name": "Alert", - "type": "pixelaw::core::actions::actions::Alert", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json b/contracts/manifests/release/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json deleted file mode 100644 index 3efc0d9..0000000 --- a/contracts/manifests/release/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json +++ /dev/null @@ -1,383 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "GuildImpl", - "interface_name": "p_war::systems::guilds::IGuild" - }, - { - "type": "interface", - "name": "p_war::systems::guilds::IGuild", - "items": [ - { - "type": "function", - "name": "create_guild", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_name", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "add_member", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "new_member", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "remove_member", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_guild_points", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::guilds::guild_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::guilds::guild_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::GuildCreated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_name", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::MemberAdded", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::MemberRemoved", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "GuildCreated", - "type": "p_war::systems::guilds::guild_actions::GuildCreated", - "kind": "nested" - }, - { - "name": "MemberAdded", - "type": "p_war::systems::guilds::guild_actions::MemberAdded", - "kind": "nested" - }, - { - "name": "MemberRemoved", - "type": "p_war::systems::guilds::guild_actions::MemberRemoved", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/contracts/pixelaw-p_war_actions-60819afd.json b/contracts/manifests/release/base/abis/contracts/pixelaw-p_war_actions-60819afd.json deleted file mode 100644 index b9e6307..0000000 --- a/contracts/manifests/release/base/abis/contracts/pixelaw-p_war_actions-60819afd.json +++ /dev/null @@ -1,583 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsInteroperability", - "interface_name": "pixelaw::core::traits::IInteroperability" - }, - { - "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": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "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": "interface", - "name": "pixelaw::core::traits::IInteroperability", - "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": [], - "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": "impl", - "name": "AllowedAppImpl", - "interface_name": "p_war::systems::apps::IAllowedApp" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::utils::DefaultParameters", - "members": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "color", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::apps::IAllowedApp", - "items": [ - { - "type": "function", - "name": "set_pixel", - "inputs": [ - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsImpl", - "interface_name": "p_war::systems::actions::IActions" - }, - { - "type": "interface", - "name": "p_war::systems::actions::IActions", - "items": [ - { - "type": "function", - "name": "init", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "interact", - "inputs": [ - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "create_game", - "inputs": [ - { - "name": "origin", - "type": "pixelaw::core::utils::Position" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_game_id", - "inputs": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "place_pixel", - "inputs": [ - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_pixel", - "inputs": [ - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "end_game", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::actions::p_war_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::actions::p_war_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::StartedGame", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u128", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::EndedGame", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u128", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "StartedGame", - "type": "p_war::systems::actions::p_war_actions::StartedGame", - "kind": "nested" - }, - { - "name": "EndedGame", - "type": "p_war::systems::actions::p_war_actions::EndedGame", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/contracts/pixelaw-propose_actions-4ee7028a.json b/contracts/manifests/release/base/abis/contracts/pixelaw-propose_actions-4ee7028a.json deleted file mode 100644 index 8aa1e40..0000000 --- a/contracts/manifests/release/base/abis/contracts/pixelaw-propose_actions-4ee7028a.json +++ /dev/null @@ -1,363 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ProposeImpl", - "interface_name": "p_war::systems::propose::IPropose" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::propose::IPropose", - "items": [ - { - "type": "function", - "name": "create_proposal", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "proposal_type", - "type": "core::integer::u8" - }, - { - "name": "target_args_1", - "type": "core::integer::u32" - }, - { - "name": "target_args_2", - "type": "core::integer::u32" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "activate_proposal", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "clear_data", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::propose::propose_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::propose::propose_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::ProposalCreated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "proposal_type", - "type": "core::integer::u8", - "kind": "data" - }, - { - "name": "target_args_1", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "target_args_2", - "type": "core::integer::u32", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::ProposalActivated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "proposal_type", - "type": "core::integer::u8", - "kind": "data" - }, - { - "name": "target_args_1", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "target_args_2", - "type": "core::integer::u32", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "ProposalCreated", - "type": "p_war::systems::propose::propose_actions::ProposalCreated", - "kind": "nested" - }, - { - "name": "ProposalActivated", - "type": "p_war::systems::propose::propose_actions::ProposalActivated", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/contracts/pixelaw-voting_actions-6aab73ea.json b/contracts/manifests/release/base/abis/contracts/pixelaw-voting_actions-6aab73ea.json deleted file mode 100644 index 0e5b5fe..0000000 --- a/contracts/manifests/release/base/abis/contracts/pixelaw-voting_actions-6aab73ea.json +++ /dev/null @@ -1,288 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "VotingImpl", - "interface_name": "p_war::systems::voting::IVoting" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::voting::IVoting", - "items": [ - { - "type": "function", - "name": "vote", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "is_in_favor", - "type": "core::bool" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::voting::voting_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::voting::voting_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::voting::voting_actions::Voted", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - }, - { - "name": "voter", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "is_in_favor", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::voting::voting_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "Voted", - "type": "p_war::systems::voting::voting_actions::Voted", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/dojo-base.json b/contracts/manifests/release/base/abis/dojo-base.json deleted file mode 100644 index 4800464..0000000 --- a/contracts/manifests/release/base/abis/dojo-base.json +++ /dev/null @@ -1,98 +0,0 @@ -[ - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::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::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::base_contract::base::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "flat" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/dojo-world.json b/contracts/manifests/release/base/abis/dojo-world.json deleted file mode 100644 index 8553809..0000000 --- a/contracts/manifests/release/base/abis/dojo-world.json +++ /dev/null @@ -1,1231 +0,0 @@ -[ - { - "type": "impl", - "name": "World", - "interface_name": "dojo::world::world_contract::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": "struct", - "name": "dojo::model::metadata::ResourceMetadata", - "members": [ - { - "name": "resource_id", - "type": "core::felt252" - }, - { - "name": "metadata_uri", - "type": "core::byte_array::ByteArray" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::model::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::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "enum", - "name": "dojo::world::world_contract::Resource", - "variants": [ - { - "name": "Model", - "type": "(core::starknet::class_hash::ClassHash, core::starknet::contract_address::ContractAddress)" - }, - { - "name": "Contract", - "type": "(core::starknet::class_hash::ClassHash, core::starknet::contract_address::ContractAddress)" - }, - { - "name": "Namespace", - "type": "()" - }, - { - "name": "World", - "type": "()" - }, - { - "name": "Unregistered", - "type": "()" - } - ] - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorld", - "items": [ - { - "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_model", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "upgrade_model", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "deploy_contract", - "inputs": [ - { - "name": "salt", - "type": "core::felt252" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "upgrade_contract", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "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": "uuid", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "emit", - "inputs": [ - { - "name": "keys", - "type": "core::array::Array::" - }, - { - "name": "values", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "function", - "name": "entity", - "inputs": [ - { - "name": "model_selector", - "type": "core::felt252" - }, - { - "name": "index", - "type": "dojo::model::model::ModelIndex" - }, - { - "name": "layout", - "type": "dojo::model::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::model::ModelIndex" - }, - { - "name": "values", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::model::layout::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "delete_entity", - "inputs": [ - { - "name": "model_selector", - "type": "core::felt252" - }, - { - "name": "index", - "type": "dojo::model::model::ModelIndex" - }, - { - "name": "layout", - "type": "dojo::model::layout::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "base", - "inputs": [], - "outputs": [ - { - "type": "core::starknet::class_hash::ClassHash" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "resource", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "dojo::world::world_contract::Resource" - } - ], - "state_mutability": "view" - }, - { - "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": "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::world_contract::IUpgradeableWorld" - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IUpgradeableWorld", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "UpgradeableState", - "interface_name": "dojo::world::update::IUpgradeableState" - }, - { - "type": "struct", - "name": "dojo::world::update::StorageUpdate", - "members": [ - { - "name": "key", - "type": "core::felt252" - }, - { - "name": "value", - "type": "core::felt252" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::world::update::ProgramOutput", - "members": [ - { - "name": "prev_state_root", - "type": "core::felt252" - }, - { - "name": "new_state_root", - "type": "core::felt252" - }, - { - "name": "block_number", - "type": "core::felt252" - }, - { - "name": "block_hash", - "type": "core::felt252" - }, - { - "name": "config_hash", - "type": "core::felt252" - }, - { - "name": "world_da_hash", - "type": "core::felt252" - }, - { - "name": "message_to_starknet_segment", - "type": "core::array::Span::" - }, - { - "name": "message_to_appchain_segment", - "type": "core::array::Span::" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::update::IUpgradeableState", - "items": [ - { - "type": "function", - "name": "upgrade_state", - "inputs": [ - { - "name": "new_state", - "type": "core::array::Span::" - }, - { - "name": "program_output", - "type": "dojo::world::update::ProgramOutput" - }, - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "ConfigImpl", - "interface_name": "dojo::world::config::IConfig" - }, - { - "type": "interface", - "name": "dojo::world::config::IConfig", - "items": [ - { - "type": "function", - "name": "set_differ_program_hash", - "inputs": [ - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_merger_program_hash", - "inputs": [ - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_differ_program_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "get_merger_program_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "set_facts_registry", - "inputs": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_facts_registry", - "inputs": [], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "constructor", - "name": "constructor", - "inputs": [ - { - "name": "contract_base", - "type": "core::starknet::class_hash::ClassHash" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::WorldSpawned", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::ContractDeployed", - "kind": "struct", - "members": [ - { - "name": "salt", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - }, - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "name", - "type": "core::byte_array::ByteArray", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::ContractUpgraded", - "kind": "struct", - "members": [ - { - "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::ContractInitialized", - "kind": "struct", - "members": [ - { - "name": "selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "init_calldata", - "type": "core::array::Span::", - "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::MetadataUpdate", - "kind": "struct", - "members": [ - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "uri", - "type": "core::byte_array::ByteArray", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::NamespaceRegistered", - "kind": "struct", - "members": [ - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "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": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "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::ModelUpgraded", - "kind": "struct", - "members": [ - { - "name": "name", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - }, - { - "name": "prev_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::StoreSetRecord", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "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": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "values", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StoreUpdateMember", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "member_selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "values", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StoreDelRecord", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::WriterUpdated", - "kind": "struct", - "members": [ - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "contract", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "value", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::OwnerUpdated", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "value", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::DifferProgramHashUpdate", - "kind": "struct", - "members": [ - { - "name": "program_hash", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::MergerProgramHashUpdate", - "kind": "struct", - "members": [ - { - "name": "program_hash", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::FactsRegistryUpdate", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::Event", - "kind": "enum", - "variants": [ - { - "name": "DifferProgramHashUpdate", - "type": "dojo::world::config::Config::DifferProgramHashUpdate", - "kind": "nested" - }, - { - "name": "MergerProgramHashUpdate", - "type": "dojo::world::config::Config::MergerProgramHashUpdate", - "kind": "nested" - }, - { - "name": "FactsRegistryUpdate", - "type": "dojo::world::config::Config::FactsRegistryUpdate", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StateUpdated", - "kind": "struct", - "members": [ - { - "name": "da_hash", - "type": "core::felt252", - "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": "ContractDeployed", - "type": "dojo::world::world_contract::world::ContractDeployed", - "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": "WorldUpgraded", - "type": "dojo::world::world_contract::world::WorldUpgraded", - "kind": "nested" - }, - { - "name": "MetadataUpdate", - "type": "dojo::world::world_contract::world::MetadataUpdate", - "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": "ModelUpgraded", - "type": "dojo::world::world_contract::world::ModelUpgraded", - "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" - }, - { - "name": "ConfigEvent", - "type": "dojo::world::config::Config::Event", - "kind": "nested" - }, - { - "name": "StateUpdated", - "type": "dojo::world::world_contract::world::StateUpdated", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-AllowedApp-4aa27058.json b/contracts/manifests/release/base/abis/models/pixelaw-AllowedApp-4aa27058.json deleted file mode 100644 index 316e91a..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-AllowedApp-4aa27058.json +++ /dev/null @@ -1,425 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "allowed_appImpl", - "interface_name": "p_war::models::allowed_app::Iallowed_app" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_app::AllowedApp", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "contract", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "is_allowed", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_app::Iallowed_app", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_app::AllowedApp" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_app::allowed_app::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-AllowedColor-22c1a796.json b/contracts/manifests/release/base/abis/models/pixelaw-AllowedColor-22c1a796.json deleted file mode 100644 index 48cc27f..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-AllowedColor-22c1a796.json +++ /dev/null @@ -1,425 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "allowed_colorImpl", - "interface_name": "p_war::models::allowed_color::Iallowed_color" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::AllowedColor", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "is_allowed", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Iallowed_color", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::AllowedColor" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::allowed_color::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-App-36504565.json b/contracts/manifests/release/base/abis/models/pixelaw-App-36504565.json deleted file mode 100644 index c2e9c0e..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-App-36504565.json +++ /dev/null @@ -1,415 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "appImpl", - "interface_name": "pixelaw::core::models::registry::Iapp" - }, - { - "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": "interface", - "name": "pixelaw::core::models::registry::Iapp", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::App" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-AppName-3b816829.json b/contracts/manifests/release/base/abis/models/pixelaw-AppName-3b816829.json deleted file mode 100644 index 87a5e61..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-AppName-3b816829.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "app_nameImpl", - "interface_name": "pixelaw::core::models::registry::Iapp_name" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::AppName", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iapp_name", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::AppName" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app_name::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-AppUser-4eda3c52.json b/contracts/manifests/release/base/abis/models/pixelaw-AppUser-4eda3c52.json deleted file mode 100644 index a578a2c..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-AppUser-4eda3c52.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "app_userImpl", - "interface_name": "pixelaw::core::models::registry::Iapp_user" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::AppUser", - "members": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iapp_user", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::AppUser" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app_user::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-Board-124dc3e7.json b/contracts/manifests/release/base/abis/models/pixelaw-Board-124dc3e7.json deleted file mode 100644 index 6f4d779..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-Board-124dc3e7.json +++ /dev/null @@ -1,429 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "boardImpl", - "interface_name": "p_war::models::board::Iboard" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::board::Board", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "origin", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "width", - "type": "core::integer::u32" - }, - { - "name": "height", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Iboard", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::Board" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::board::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json b/contracts/manifests/release/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json deleted file mode 100644 index 512af25..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "core_actions_addressImpl", - "interface_name": "pixelaw::core::models::registry::Icore_actions_address" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::CoreActionsAddress", - "members": [ - { - "name": "key", - "type": "core::felt252" - }, - { - "name": "value", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Icore_actions_address", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::CoreActionsAddress" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::core_actions_address::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-Game-5c1fa23f.json b/contracts/manifests/release/base/abis/models/pixelaw-Game-5c1fa23f.json deleted file mode 100644 index 9e59f59..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-Game-5c1fa23f.json +++ /dev/null @@ -1,449 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "gameImpl", - "interface_name": "p_war::models::game::Igame" - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::game::Game", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "start", - "type": "core::integer::u64" - }, - { - "name": "end", - "type": "core::integer::u64" - }, - { - "name": "proposal_idx", - "type": "core::integer::u32" - }, - { - "name": "coeff_own_pixels", - "type": "core::integer::u32" - }, - { - "name": "coeff_commits", - "type": "core::integer::u32" - }, - { - "name": "winner_config", - "type": "core::integer::u32" - }, - { - "name": "winner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "guild_ids", - "type": "core::array::Span::" - }, - { - "name": "guild_count", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::game::Igame", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::game::Game" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::game::game::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-GameId-1ee8756e.json b/contracts/manifests/release/base/abis/models/pixelaw-GameId-1ee8756e.json deleted file mode 100644 index 869e2a6..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-GameId-1ee8756e.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "game_idImpl", - "interface_name": "p_war::models::board::Igame_id" - }, - { - "type": "struct", - "name": "p_war::models::board::GameId", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "value", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Igame_id", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::GameId" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::game_id::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-GamePalette-49013f2b.json b/contracts/manifests/release/base/abis/models/pixelaw-GamePalette-49013f2b.json deleted file mode 100644 index 2ee77e7..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-GamePalette-49013f2b.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "game_paletteImpl", - "interface_name": "p_war::models::allowed_color::Igame_palette" - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::GamePalette", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "length", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Igame_palette", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::GamePalette" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::game_palette::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-Guild-40e97c00.json b/contracts/manifests/release/base/abis/models/pixelaw-Guild-40e97c00.json deleted file mode 100644 index f963145..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-Guild-40e97c00.json +++ /dev/null @@ -1,433 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "guildImpl", - "interface_name": "p_war::models::guilds::Iguild" - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::guilds::Guild", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "guild_name", - "type": "core::felt252" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "members", - "type": "core::array::Span::" - }, - { - "name": "member_count", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::guilds::Iguild", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::guilds::Guild" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::guilds::guild::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-InPalette-7a46e3ad.json b/contracts/manifests/release/base/abis/models/pixelaw-InPalette-7a46e3ad.json deleted file mode 100644 index 4c58dd9..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-InPalette-7a46e3ad.json +++ /dev/null @@ -1,425 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "in_paletteImpl", - "interface_name": "p_war::models::allowed_color::Iin_palette" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::InPalette", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "value", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Iin_palette", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::InPalette" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::in_palette::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-Instruction-4c7c4844.json b/contracts/manifests/release/base/abis/models/pixelaw-Instruction-4c7c4844.json deleted file mode 100644 index a79b066..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-Instruction-4c7c4844.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "instructionImpl", - "interface_name": "pixelaw::core::models::registry::Iinstruction" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::Instruction", - "members": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "instruction", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iinstruction", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::Instruction" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::instruction::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-PWarPixel-15195913.json b/contracts/manifests/release/base/abis/models/pixelaw-PWarPixel-15195913.json deleted file mode 100644 index 4fb9f2a..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-PWarPixel-15195913.json +++ /dev/null @@ -1,421 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "p_war_pixelImpl", - "interface_name": "p_war::models::board::Ip_war_pixel" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::board::PWarPixel", - "members": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Ip_war_pixel", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::PWarPixel" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::p_war_pixel::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-PaletteColors-39a92a0a.json b/contracts/manifests/release/base/abis/models/pixelaw-PaletteColors-39a92a0a.json deleted file mode 100644 index ac5324c..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-PaletteColors-39a92a0a.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "palette_colorsImpl", - "interface_name": "p_war::models::allowed_color::Ipalette_colors" - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::PaletteColors", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "idx", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Ipalette_colors", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::PaletteColors" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::palette_colors::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-Permissions-72b77307.json b/contracts/manifests/release/base/abis/models/pixelaw-Permissions-72b77307.json deleted file mode 100644 index 2e1a096..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-Permissions-72b77307.json +++ /dev/null @@ -1,455 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "permissionsImpl", - "interface_name": "pixelaw::core::models::permissions::Ipermissions" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permission", - "members": [ - { - "name": "app", - "type": "core::bool" - }, - { - "name": "color", - "type": "core::bool" - }, - { - "name": "owner", - "type": "core::bool" - }, - { - "name": "text", - "type": "core::bool" - }, - { - "name": "timestamp", - "type": "core::bool" - }, - { - "name": "action", - "type": "core::bool" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permissions", - "members": [ - { - "name": "allowing_app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "allowed_app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "permission", - "type": "pixelaw::core::models::permissions::Permission" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::permissions::Ipermissions", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::permissions::Permissions" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::permissions::permissions::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-Pixel-7e607b2f.json b/contracts/manifests/release/base/abis/models/pixelaw-Pixel-7e607b2f.json deleted file mode 100644 index 8f6c36a..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-Pixel-7e607b2f.json +++ /dev/null @@ -1,439 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "pixelImpl", - "interface_name": "pixelaw::core::models::pixel::Ipixel" - }, - { - "type": "struct", - "name": "pixelaw::core::models::pixel::Pixel", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "created_at", - "type": "core::integer::u64" - }, - { - "name": "updated_at", - "type": "core::integer::u64" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "text", - "type": "core::felt252" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::pixel::Ipixel", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::pixel::Pixel" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::pixel::pixel::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json b/contracts/manifests/release/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json deleted file mode 100644 index 6458f14..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "pixel_recovery_rateImpl", - "interface_name": "p_war::models::proposal::Ipixel_recovery_rate" - }, - { - "type": "struct", - "name": "p_war::models::proposal::PixelRecoveryRate", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "rate", - "type": "core::integer::u64" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Ipixel_recovery_rate", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::PixelRecoveryRate" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::pixel_recovery_rate::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-Player-30a1b371.json b/contracts/manifests/release/base/abis/models/pixelaw-Player-30a1b371.json deleted file mode 100644 index 2d345b9..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-Player-30a1b371.json +++ /dev/null @@ -1,433 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "playerImpl", - "interface_name": "p_war::models::player::Iplayer" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::player::Player", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "num_owns", - "type": "core::integer::u32" - }, - { - "name": "num_commit", - "type": "core::integer::u32" - }, - { - "name": "last_date", - "type": "core::integer::u64" - }, - { - "name": "is_banned", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::player::Iplayer", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::player::Player" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::player::player::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-PlayerVote-326c17c6.json b/contracts/manifests/release/base/abis/models/pixelaw-PlayerVote-326c17c6.json deleted file mode 100644 index e00fd1f..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-PlayerVote-326c17c6.json +++ /dev/null @@ -1,433 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "player_voteImpl", - "interface_name": "p_war::models::proposal::Iplayer_vote" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::proposal::PlayerVote", - "members": [ - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "is_in_favor", - "type": "core::bool" - }, - { - "name": "voting_power", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Iplayer_vote", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::PlayerVote" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::player_vote::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-Proposal-49e1daf5.json b/contracts/manifests/release/base/abis/models/pixelaw-Proposal-49e1daf5.json deleted file mode 100644 index faa5465..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-Proposal-49e1daf5.json +++ /dev/null @@ -1,457 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "proposalImpl", - "interface_name": "p_war::models::proposal::Iproposal" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::proposal::Proposal", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "author", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "proposal_type", - "type": "core::integer::u8" - }, - { - "name": "target_args_1", - "type": "core::integer::u32" - }, - { - "name": "target_args_2", - "type": "core::integer::u32" - }, - { - "name": "start", - "type": "core::integer::u64" - }, - { - "name": "end", - "type": "core::integer::u64" - }, - { - "name": "yes_voting_power", - "type": "core::integer::u32" - }, - { - "name": "no_voting_power", - "type": "core::integer::u32" - }, - { - "name": "is_activated", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Iproposal", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::Proposal" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::proposal::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/abis/models/pixelaw-QueueItem-549a17f2.json b/contracts/manifests/release/base/abis/models/pixelaw-QueueItem-549a17f2.json deleted file mode 100644 index 8496a6c..0000000 --- a/contracts/manifests/release/base/abis/models/pixelaw-QueueItem-549a17f2.json +++ /dev/null @@ -1,421 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "queue_itemImpl", - "interface_name": "pixelaw::core::models::queue::Iqueue_item" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::queue::QueueItem", - "members": [ - { - "name": "id", - "type": "core::felt252" - }, - { - "name": "valid", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::queue::Iqueue_item", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::queue::QueueItem" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::queue::queue_item::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/base/contracts/pixelaw-actions-16928a49.toml b/contracts/manifests/release/base/contracts/pixelaw-actions-16928a49.toml deleted file mode 100644 index ff088d7..0000000 --- a/contracts/manifests/release/base/contracts/pixelaw-actions-16928a49.toml +++ /dev/null @@ -1,19 +0,0 @@ -kind = "DojoContract" -class_hash = "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f" -original_class_hash = "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f" -base_class_hash = "0x0" -abi = "manifests/release/base/abis/contracts/pixelaw-actions-16928a49.json" -reads = [] -writes = [] -init_calldata = [] -tag = "pixelaw-actions" -systems = [ - "init", - "update_permission", - "schedule_queue", - "process_queue", - "update_pixel", - "alert_player", - "set_instruction", -] -manifest_name = "pixelaw-actions-16928a49" diff --git a/contracts/manifests/release/base/contracts/pixelaw-guild_actions-4c9f5931.toml b/contracts/manifests/release/base/contracts/pixelaw-guild_actions-4c9f5931.toml deleted file mode 100644 index 6ac7683..0000000 --- a/contracts/manifests/release/base/contracts/pixelaw-guild_actions-4c9f5931.toml +++ /dev/null @@ -1,14 +0,0 @@ -kind = "DojoContract" -class_hash = "0x63080ea2cfae99d4b773b06c7d1cb893c197ba5e431afeba8909eac874d038e" -original_class_hash = "0x63080ea2cfae99d4b773b06c7d1cb893c197ba5e431afeba8909eac874d038e" -base_class_hash = "0x0" -abi = "manifests/release/base/abis/contracts/pixelaw-guild_actions-4c9f5931.json" -reads = [] -writes = [] -init_calldata = [] -tag = "pixelaw-guild_actions" -systems = [ - "add_member", - "remove_member", -] -manifest_name = "pixelaw-guild_actions-4c9f5931" diff --git a/contracts/manifests/release/base/contracts/pixelaw-p_war_actions-60819afd.toml b/contracts/manifests/release/base/contracts/pixelaw-p_war_actions-60819afd.toml deleted file mode 100644 index b9cc63f..0000000 --- a/contracts/manifests/release/base/contracts/pixelaw-p_war_actions-60819afd.toml +++ /dev/null @@ -1,20 +0,0 @@ -kind = "DojoContract" -class_hash = "0x121b6dbe4e601a2d06856e92fc198299dd8bb540481c741898ce68cf9c9c57" -original_class_hash = "0x121b6dbe4e601a2d06856e92fc198299dd8bb540481c741898ce68cf9c9c57" -base_class_hash = "0x0" -abi = "manifests/release/base/abis/contracts/pixelaw-p_war_actions-60819afd.json" -reads = [] -writes = [] -init_calldata = [] -tag = "pixelaw-p_war_actions" -systems = [ - "on_pre_update", - "on_post_update", - "set_pixel", - "init", - "interact", - "place_pixel", - "update_pixel", - "end_game", -] -manifest_name = "pixelaw-p_war_actions-60819afd" diff --git a/contracts/manifests/release/base/contracts/pixelaw-propose_actions-4ee7028a.toml b/contracts/manifests/release/base/contracts/pixelaw-propose_actions-4ee7028a.toml deleted file mode 100644 index 7ff47a8..0000000 --- a/contracts/manifests/release/base/contracts/pixelaw-propose_actions-4ee7028a.toml +++ /dev/null @@ -1,11 +0,0 @@ -kind = "DojoContract" -class_hash = "0x76a41721719a58f3dd43429eecfff5ed72ff993d653f417bdb337418ec8e589" -original_class_hash = "0x76a41721719a58f3dd43429eecfff5ed72ff993d653f417bdb337418ec8e589" -base_class_hash = "0x0" -abi = "manifests/release/base/abis/contracts/pixelaw-propose_actions-4ee7028a.json" -reads = [] -writes = [] -init_calldata = [] -tag = "pixelaw-propose_actions" -systems = ["activate_proposal"] -manifest_name = "pixelaw-propose_actions-4ee7028a" diff --git a/contracts/manifests/release/base/contracts/pixelaw-voting_actions-6aab73ea.toml b/contracts/manifests/release/base/contracts/pixelaw-voting_actions-6aab73ea.toml deleted file mode 100644 index 81c2d1c..0000000 --- a/contracts/manifests/release/base/contracts/pixelaw-voting_actions-6aab73ea.toml +++ /dev/null @@ -1,11 +0,0 @@ -kind = "DojoContract" -class_hash = "0x5e87a338c9ee6d9d72281883bd04133f0d91e4d5ecebcfbbf281319ce877b2a" -original_class_hash = "0x5e87a338c9ee6d9d72281883bd04133f0d91e4d5ecebcfbbf281319ce877b2a" -base_class_hash = "0x0" -abi = "manifests/release/base/abis/contracts/pixelaw-voting_actions-6aab73ea.json" -reads = [] -writes = [] -init_calldata = [] -tag = "pixelaw-voting_actions" -systems = ["vote"] -manifest_name = "pixelaw-voting_actions-6aab73ea" diff --git a/contracts/manifests/release/base/dojo-base.toml b/contracts/manifests/release/base/dojo-base.toml deleted file mode 100644 index a2ae530..0000000 --- a/contracts/manifests/release/base/dojo-base.toml +++ /dev/null @@ -1,6 +0,0 @@ -kind = "Class" -class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -original_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -abi = "manifests/release/base/abis/dojo-base.json" -tag = "dojo-base" -manifest_name = "dojo-base" diff --git a/contracts/manifests/release/base/dojo-world.toml b/contracts/manifests/release/base/dojo-world.toml deleted file mode 100644 index 796442c..0000000 --- a/contracts/manifests/release/base/dojo-world.toml +++ /dev/null @@ -1,6 +0,0 @@ -kind = "Class" -class_hash = "0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e" -original_class_hash = "0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e" -abi = "manifests/release/base/abis/dojo-world.json" -tag = "dojo-world" -manifest_name = "dojo-world" diff --git a/contracts/manifests/release/base/models/pixelaw-AllowedApp-4aa27058.toml b/contracts/manifests/release/base/models/pixelaw-AllowedApp-4aa27058.toml deleted file mode 100644 index 9c68e36..0000000 --- a/contracts/manifests/release/base/models/pixelaw-AllowedApp-4aa27058.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f" -original_class_hash = "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f" -abi = "manifests/release/base/abis/models/pixelaw-AllowedApp-4aa27058.json" -tag = "pixelaw-AllowedApp" -qualified_path = "p_war::models::allowed_app::allowed_app" -manifest_name = "pixelaw-AllowedApp-4aa27058" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "contract" -type = "ContractAddress" -key = true - -[[members]] -name = "is_allowed" -type = "bool" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-AllowedColor-22c1a796.toml b/contracts/manifests/release/base/models/pixelaw-AllowedColor-22c1a796.toml deleted file mode 100644 index 8c2c88c..0000000 --- a/contracts/manifests/release/base/models/pixelaw-AllowedColor-22c1a796.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54" -original_class_hash = "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54" -abi = "manifests/release/base/abis/models/pixelaw-AllowedColor-22c1a796.json" -tag = "pixelaw-AllowedColor" -qualified_path = "p_war::models::allowed_color::allowed_color" -manifest_name = "pixelaw-AllowedColor-22c1a796" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "color" -type = "u32" -key = true - -[[members]] -name = "is_allowed" -type = "bool" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-App-36504565.toml b/contracts/manifests/release/base/models/pixelaw-App-36504565.toml deleted file mode 100644 index 31b101e..0000000 --- a/contracts/manifests/release/base/models/pixelaw-App-36504565.toml +++ /dev/null @@ -1,27 +0,0 @@ -kind = "DojoModel" -class_hash = "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c" -original_class_hash = "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c" -abi = "manifests/release/base/abis/models/pixelaw-App-36504565.json" -tag = "pixelaw-App" -qualified_path = "pixelaw::core::models::registry::app" -manifest_name = "pixelaw-App-36504565" - -[[members]] -name = "system" -type = "ContractAddress" -key = true - -[[members]] -name = "name" -type = "felt252" -key = false - -[[members]] -name = "icon" -type = "felt252" -key = false - -[[members]] -name = "action" -type = "felt252" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-AppName-3b816829.toml b/contracts/manifests/release/base/models/pixelaw-AppName-3b816829.toml deleted file mode 100644 index 8b92ef1..0000000 --- a/contracts/manifests/release/base/models/pixelaw-AppName-3b816829.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8" -original_class_hash = "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8" -abi = "manifests/release/base/abis/models/pixelaw-AppName-3b816829.json" -tag = "pixelaw-AppName" -qualified_path = "pixelaw::core::models::registry::app_name" -manifest_name = "pixelaw-AppName-3b816829" - -[[members]] -name = "name" -type = "felt252" -key = true - -[[members]] -name = "system" -type = "ContractAddress" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-AppUser-4eda3c52.toml b/contracts/manifests/release/base/models/pixelaw-AppUser-4eda3c52.toml deleted file mode 100644 index 498dbaa..0000000 --- a/contracts/manifests/release/base/models/pixelaw-AppUser-4eda3c52.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1" -original_class_hash = "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1" -abi = "manifests/release/base/abis/models/pixelaw-AppUser-4eda3c52.json" -tag = "pixelaw-AppUser" -qualified_path = "pixelaw::core::models::registry::app_user" -manifest_name = "pixelaw-AppUser-4eda3c52" - -[[members]] -name = "system" -type = "ContractAddress" -key = true - -[[members]] -name = "player" -type = "ContractAddress" -key = true - -[[members]] -name = "action" -type = "felt252" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-Board-124dc3e7.toml b/contracts/manifests/release/base/models/pixelaw-Board-124dc3e7.toml deleted file mode 100644 index e8681a9..0000000 --- a/contracts/manifests/release/base/models/pixelaw-Board-124dc3e7.toml +++ /dev/null @@ -1,27 +0,0 @@ -kind = "DojoModel" -class_hash = "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c" -original_class_hash = "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c" -abi = "manifests/release/base/abis/models/pixelaw-Board-124dc3e7.json" -tag = "pixelaw-Board" -qualified_path = "p_war::models::board::board" -manifest_name = "pixelaw-Board-124dc3e7" - -[[members]] -name = "id" -type = "usize" -key = true - -[[members]] -name = "origin" -type = "Position" -key = false - -[[members]] -name = "width" -type = "u32" -key = false - -[[members]] -name = "height" -type = "u32" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml b/contracts/manifests/release/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml deleted file mode 100644 index 1d5fab5..0000000 --- a/contracts/manifests/release/base/models/pixelaw-CoreActionsAddress-5379e1ce.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2" -original_class_hash = "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2" -abi = "manifests/release/base/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json" -tag = "pixelaw-CoreActionsAddress" -qualified_path = "pixelaw::core::models::registry::core_actions_address" -manifest_name = "pixelaw-CoreActionsAddress-5379e1ce" - -[[members]] -name = "key" -type = "felt252" -key = true - -[[members]] -name = "value" -type = "ContractAddress" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-Game-5c1fa23f.toml b/contracts/manifests/release/base/models/pixelaw-Game-5c1fa23f.toml deleted file mode 100644 index 5565b9a..0000000 --- a/contracts/manifests/release/base/models/pixelaw-Game-5c1fa23f.toml +++ /dev/null @@ -1,57 +0,0 @@ -kind = "DojoModel" -class_hash = "0x4eb28e2e4c9f69487e5479cacac150e52666d072315dc8e3547b32f977976e0" -original_class_hash = "0x4eb28e2e4c9f69487e5479cacac150e52666d072315dc8e3547b32f977976e0" -abi = "manifests/release/base/abis/models/pixelaw-Game-5c1fa23f.json" -tag = "pixelaw-Game" -qualified_path = "p_war::models::game::game" -manifest_name = "pixelaw-Game-5c1fa23f" - -[[members]] -name = "id" -type = "usize" -key = true - -[[members]] -name = "start" -type = "u64" -key = false - -[[members]] -name = "end" -type = "u64" -key = false - -[[members]] -name = "proposal_idx" -type = "usize" -key = false - -[[members]] -name = "coeff_own_pixels" -type = "u32" -key = false - -[[members]] -name = "coeff_commits" -type = "u32" -key = false - -[[members]] -name = "winner_config" -type = "u32" -key = false - -[[members]] -name = "winner" -type = "ContractAddress" -key = false - -[[members]] -name = "guild_ids" -type = "Span" -key = false - -[[members]] -name = "guild_count" -type = "usize" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-GameId-1ee8756e.toml b/contracts/manifests/release/base/models/pixelaw-GameId-1ee8756e.toml deleted file mode 100644 index 88ba80a..0000000 --- a/contracts/manifests/release/base/models/pixelaw-GameId-1ee8756e.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4" -original_class_hash = "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4" -abi = "manifests/release/base/abis/models/pixelaw-GameId-1ee8756e.json" -tag = "pixelaw-GameId" -qualified_path = "p_war::models::board::game_id" -manifest_name = "pixelaw-GameId-1ee8756e" - -[[members]] -name = "x" -type = "u32" -key = true - -[[members]] -name = "y" -type = "u32" -key = true - -[[members]] -name = "value" -type = "usize" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-GamePalette-49013f2b.toml b/contracts/manifests/release/base/models/pixelaw-GamePalette-49013f2b.toml deleted file mode 100644 index 68dca20..0000000 --- a/contracts/manifests/release/base/models/pixelaw-GamePalette-49013f2b.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398" -original_class_hash = "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398" -abi = "manifests/release/base/abis/models/pixelaw-GamePalette-49013f2b.json" -tag = "pixelaw-GamePalette" -qualified_path = "p_war::models::allowed_color::game_palette" -manifest_name = "pixelaw-GamePalette-49013f2b" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "length" -type = "usize" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-Guild-40e97c00.toml b/contracts/manifests/release/base/models/pixelaw-Guild-40e97c00.toml deleted file mode 100644 index c4ca367..0000000 --- a/contracts/manifests/release/base/models/pixelaw-Guild-40e97c00.toml +++ /dev/null @@ -1,37 +0,0 @@ -kind = "DojoModel" -class_hash = "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95" -original_class_hash = "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95" -abi = "manifests/release/base/abis/models/pixelaw-Guild-40e97c00.json" -tag = "pixelaw-Guild" -qualified_path = "p_war::models::guilds::guild" -manifest_name = "pixelaw-Guild-40e97c00" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "guild_id" -type = "usize" -key = true - -[[members]] -name = "guild_name" -type = "felt252" -key = false - -[[members]] -name = "creator" -type = "ContractAddress" -key = false - -[[members]] -name = "members" -type = "Span" -key = false - -[[members]] -name = "member_count" -type = "usize" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-InPalette-7a46e3ad.toml b/contracts/manifests/release/base/models/pixelaw-InPalette-7a46e3ad.toml deleted file mode 100644 index 5d46580..0000000 --- a/contracts/manifests/release/base/models/pixelaw-InPalette-7a46e3ad.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372" -original_class_hash = "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372" -abi = "manifests/release/base/abis/models/pixelaw-InPalette-7a46e3ad.json" -tag = "pixelaw-InPalette" -qualified_path = "p_war::models::allowed_color::in_palette" -manifest_name = "pixelaw-InPalette-7a46e3ad" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "color" -type = "u32" -key = true - -[[members]] -name = "value" -type = "bool" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-Instruction-4c7c4844.toml b/contracts/manifests/release/base/models/pixelaw-Instruction-4c7c4844.toml deleted file mode 100644 index 2365e98..0000000 --- a/contracts/manifests/release/base/models/pixelaw-Instruction-4c7c4844.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af" -original_class_hash = "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af" -abi = "manifests/release/base/abis/models/pixelaw-Instruction-4c7c4844.json" -tag = "pixelaw-Instruction" -qualified_path = "pixelaw::core::models::registry::instruction" -manifest_name = "pixelaw-Instruction-4c7c4844" - -[[members]] -name = "system" -type = "ContractAddress" -key = true - -[[members]] -name = "selector" -type = "felt252" -key = true - -[[members]] -name = "instruction" -type = "felt252" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-PWarPixel-15195913.toml b/contracts/manifests/release/base/models/pixelaw-PWarPixel-15195913.toml deleted file mode 100644 index 5e86182..0000000 --- a/contracts/manifests/release/base/models/pixelaw-PWarPixel-15195913.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261" -original_class_hash = "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261" -abi = "manifests/release/base/abis/models/pixelaw-PWarPixel-15195913.json" -tag = "pixelaw-PWarPixel" -qualified_path = "p_war::models::board::p_war_pixel" -manifest_name = "pixelaw-PWarPixel-15195913" - -[[members]] -name = "position" -type = "Position" -key = true - -[[members]] -name = "owner" -type = "ContractAddress" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-PaletteColors-39a92a0a.toml b/contracts/manifests/release/base/models/pixelaw-PaletteColors-39a92a0a.toml deleted file mode 100644 index 1140bf8..0000000 --- a/contracts/manifests/release/base/models/pixelaw-PaletteColors-39a92a0a.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444" -original_class_hash = "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444" -abi = "manifests/release/base/abis/models/pixelaw-PaletteColors-39a92a0a.json" -tag = "pixelaw-PaletteColors" -qualified_path = "p_war::models::allowed_color::palette_colors" -manifest_name = "pixelaw-PaletteColors-39a92a0a" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "idx" -type = "u32" -key = true - -[[members]] -name = "color" -type = "u32" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-Permissions-72b77307.toml b/contracts/manifests/release/base/models/pixelaw-Permissions-72b77307.toml deleted file mode 100644 index 2a7f528..0000000 --- a/contracts/manifests/release/base/models/pixelaw-Permissions-72b77307.toml +++ /dev/null @@ -1,22 +0,0 @@ -kind = "DojoModel" -class_hash = "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302" -original_class_hash = "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302" -abi = "manifests/release/base/abis/models/pixelaw-Permissions-72b77307.json" -tag = "pixelaw-Permissions" -qualified_path = "pixelaw::core::models::permissions::permissions" -manifest_name = "pixelaw-Permissions-72b77307" - -[[members]] -name = "allowing_app" -type = "ContractAddress" -key = true - -[[members]] -name = "allowed_app" -type = "ContractAddress" -key = true - -[[members]] -name = "permission" -type = "Permission" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-Pixel-7e607b2f.toml b/contracts/manifests/release/base/models/pixelaw-Pixel-7e607b2f.toml deleted file mode 100644 index d56ccc8..0000000 --- a/contracts/manifests/release/base/models/pixelaw-Pixel-7e607b2f.toml +++ /dev/null @@ -1,57 +0,0 @@ -kind = "DojoModel" -class_hash = "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d" -original_class_hash = "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d" -abi = "manifests/release/base/abis/models/pixelaw-Pixel-7e607b2f.json" -tag = "pixelaw-Pixel" -qualified_path = "pixelaw::core::models::pixel::pixel" -manifest_name = "pixelaw-Pixel-7e607b2f" - -[[members]] -name = "x" -type = "u32" -key = true - -[[members]] -name = "y" -type = "u32" -key = true - -[[members]] -name = "app" -type = "ContractAddress" -key = false - -[[members]] -name = "color" -type = "u32" -key = false - -[[members]] -name = "created_at" -type = "u64" -key = false - -[[members]] -name = "updated_at" -type = "u64" -key = false - -[[members]] -name = "timestamp" -type = "u64" -key = false - -[[members]] -name = "owner" -type = "ContractAddress" -key = false - -[[members]] -name = "text" -type = "felt252" -key = false - -[[members]] -name = "action" -type = "felt252" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml b/contracts/manifests/release/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml deleted file mode 100644 index bcb212c..0000000 --- a/contracts/manifests/release/base/models/pixelaw-PixelRecoveryRate-3aa284c0.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067" -original_class_hash = "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067" -abi = "manifests/release/base/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json" -tag = "pixelaw-PixelRecoveryRate" -qualified_path = "p_war::models::proposal::pixel_recovery_rate" -manifest_name = "pixelaw-PixelRecoveryRate-3aa284c0" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "rate" -type = "u64" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-Player-30a1b371.toml b/contracts/manifests/release/base/models/pixelaw-Player-30a1b371.toml deleted file mode 100644 index 2136f9f..0000000 --- a/contracts/manifests/release/base/models/pixelaw-Player-30a1b371.toml +++ /dev/null @@ -1,32 +0,0 @@ -kind = "DojoModel" -class_hash = "0x71a6f6188f355d1337561c8d68538b18ec4be4c493d01be5eee753759246848" -original_class_hash = "0x71a6f6188f355d1337561c8d68538b18ec4be4c493d01be5eee753759246848" -abi = "manifests/release/base/abis/models/pixelaw-Player-30a1b371.json" -tag = "pixelaw-Player" -qualified_path = "p_war::models::player::player" -manifest_name = "pixelaw-Player-30a1b371" - -[[members]] -name = "address" -type = "ContractAddress" -key = true - -[[members]] -name = "num_owns" -type = "u32" -key = false - -[[members]] -name = "num_commit" -type = "u32" -key = false - -[[members]] -name = "last_date" -type = "u64" -key = false - -[[members]] -name = "is_banned" -type = "bool" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-PlayerVote-326c17c6.toml b/contracts/manifests/release/base/models/pixelaw-PlayerVote-326c17c6.toml deleted file mode 100644 index c95f9f6..0000000 --- a/contracts/manifests/release/base/models/pixelaw-PlayerVote-326c17c6.toml +++ /dev/null @@ -1,32 +0,0 @@ -kind = "DojoModel" -class_hash = "0x4b76f6971c93c77d96a22ac7ba0268c452d13538f05b64138a6382e18babb00" -original_class_hash = "0x4b76f6971c93c77d96a22ac7ba0268c452d13538f05b64138a6382e18babb00" -abi = "manifests/release/base/abis/models/pixelaw-PlayerVote-326c17c6.json" -tag = "pixelaw-PlayerVote" -qualified_path = "p_war::models::proposal::player_vote" -manifest_name = "pixelaw-PlayerVote-326c17c6" - -[[members]] -name = "player" -type = "ContractAddress" -key = true - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "index" -type = "usize" -key = true - -[[members]] -name = "is_in_favor" -type = "bool" -key = false - -[[members]] -name = "voting_power" -type = "u32" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-Proposal-49e1daf5.toml b/contracts/manifests/release/base/models/pixelaw-Proposal-49e1daf5.toml deleted file mode 100644 index 06be490..0000000 --- a/contracts/manifests/release/base/models/pixelaw-Proposal-49e1daf5.toml +++ /dev/null @@ -1,62 +0,0 @@ -kind = "DojoModel" -class_hash = "0x76c0a4827cc62be7367ab6fac605335bb5a2d01a7edc3f2dd89e58accafca02" -original_class_hash = "0x76c0a4827cc62be7367ab6fac605335bb5a2d01a7edc3f2dd89e58accafca02" -abi = "manifests/release/base/abis/models/pixelaw-Proposal-49e1daf5.json" -tag = "pixelaw-Proposal" -qualified_path = "p_war::models::proposal::proposal" -manifest_name = "pixelaw-Proposal-49e1daf5" - -[[members]] -name = "game_id" -type = "usize" -key = true - -[[members]] -name = "index" -type = "usize" -key = true - -[[members]] -name = "author" -type = "ContractAddress" -key = false - -[[members]] -name = "proposal_type" -type = "u8" -key = false - -[[members]] -name = "target_args_1" -type = "u32" -key = false - -[[members]] -name = "target_args_2" -type = "u32" -key = false - -[[members]] -name = "start" -type = "u64" -key = false - -[[members]] -name = "end" -type = "u64" -key = false - -[[members]] -name = "yes_voting_power" -type = "u32" -key = false - -[[members]] -name = "no_voting_power" -type = "u32" -key = false - -[[members]] -name = "is_activated" -type = "bool" -key = false diff --git a/contracts/manifests/release/base/models/pixelaw-QueueItem-549a17f2.toml b/contracts/manifests/release/base/models/pixelaw-QueueItem-549a17f2.toml deleted file mode 100644 index d08e371..0000000 --- a/contracts/manifests/release/base/models/pixelaw-QueueItem-549a17f2.toml +++ /dev/null @@ -1,17 +0,0 @@ -kind = "DojoModel" -class_hash = "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70" -original_class_hash = "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70" -abi = "manifests/release/base/abis/models/pixelaw-QueueItem-549a17f2.json" -tag = "pixelaw-QueueItem" -qualified_path = "pixelaw::core::models::queue::queue_item" -manifest_name = "pixelaw-QueueItem-549a17f2" - -[[members]] -name = "id" -type = "felt252" -key = true - -[[members]] -name = "valid" -type = "bool" -key = false diff --git a/contracts/manifests/release/deployment/abis/contracts/pixelaw-actions-16928a49.json b/contracts/manifests/release/deployment/abis/contracts/pixelaw-actions-16928a49.json deleted file mode 100644 index e71ba18..0000000 --- a/contracts/manifests/release/deployment/abis/contracts/pixelaw-actions-16928a49.json +++ /dev/null @@ -1,775 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsImpl", - "interface_name": "pixelaw::core::actions::IActions" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permission", - "members": [ - { - "name": "app", - "type": "core::bool" - }, - { - "name": "color", - "type": "core::bool" - }, - { - "name": "owner", - "type": "core::bool" - }, - { - "name": "text", - "type": "core::bool" - }, - { - "name": "timestamp", - "type": "core::bool" - }, - { - "name": "action", - "type": "core::bool" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::pixel::Pixel", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "created_at", - "type": "core::integer::u64" - }, - { - "name": "updated_at", - "type": "core::integer::u64" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "text", - "type": "core::felt252" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "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": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "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": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "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": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::actions::IActions", - "items": [ - { - "type": "function", - "name": "init", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_permission", - "inputs": [ - { - "name": "app_key", - "type": "core::felt252" - }, - { - "name": "permission", - "type": "pixelaw::core::models::permissions::Permission" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "has_write_access", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "pixel", - "type": "pixelaw::core::models::pixel::Pixel" - }, - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [ - { - "type": "core::bool" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "process_queue", - "inputs": [ - { - "name": "id", - "type": "core::felt252" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "schedule_queue", - "inputs": [ - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_pixel", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "new_app", - "inputs": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "icon", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "pixelaw::core::models::registry::App" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_system_address", - "inputs": [ - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "get_player_address", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "alert_player", - "inputs": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "message", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_instruction", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "instruction", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "pixelaw::core::actions::actions::IDojoInit" - }, - { - "type": "interface", - "name": "pixelaw::core::actions::actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::QueueScheduled", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "calldata", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::QueueProcessed", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::AppNameUpdated", - "kind": "struct", - "members": [ - { - "name": "app", - "type": "pixelaw::core::models::registry::App", - "kind": "data" - }, - { - "name": "caller", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::Alert", - "kind": "struct", - "members": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position", - "kind": "data" - }, - { - "name": "caller", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "message", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "QueueScheduled", - "type": "pixelaw::core::actions::actions::QueueScheduled", - "kind": "nested" - }, - { - "name": "QueueProcessed", - "type": "pixelaw::core::actions::actions::QueueProcessed", - "kind": "nested" - }, - { - "name": "AppNameUpdated", - "type": "pixelaw::core::actions::actions::AppNameUpdated", - "kind": "nested" - }, - { - "name": "Alert", - "type": "pixelaw::core::actions::actions::Alert", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/contracts/pixelaw-guild_actions-4c9f5931.json b/contracts/manifests/release/deployment/abis/contracts/pixelaw-guild_actions-4c9f5931.json deleted file mode 100644 index 3efc0d9..0000000 --- a/contracts/manifests/release/deployment/abis/contracts/pixelaw-guild_actions-4c9f5931.json +++ /dev/null @@ -1,383 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "GuildImpl", - "interface_name": "p_war::systems::guilds::IGuild" - }, - { - "type": "interface", - "name": "p_war::systems::guilds::IGuild", - "items": [ - { - "type": "function", - "name": "create_guild", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_name", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "add_member", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "new_member", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "remove_member", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_guild_points", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::guilds::guild_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::guilds::guild_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::GuildCreated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_name", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::MemberAdded", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::MemberRemoved", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "GuildCreated", - "type": "p_war::systems::guilds::guild_actions::GuildCreated", - "kind": "nested" - }, - { - "name": "MemberAdded", - "type": "p_war::systems::guilds::guild_actions::MemberAdded", - "kind": "nested" - }, - { - "name": "MemberRemoved", - "type": "p_war::systems::guilds::guild_actions::MemberRemoved", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/contracts/pixelaw-p_war_actions-60819afd.json b/contracts/manifests/release/deployment/abis/contracts/pixelaw-p_war_actions-60819afd.json deleted file mode 100644 index b9e6307..0000000 --- a/contracts/manifests/release/deployment/abis/contracts/pixelaw-p_war_actions-60819afd.json +++ /dev/null @@ -1,583 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsInteroperability", - "interface_name": "pixelaw::core::traits::IInteroperability" - }, - { - "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": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "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": "interface", - "name": "pixelaw::core::traits::IInteroperability", - "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": [], - "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": "impl", - "name": "AllowedAppImpl", - "interface_name": "p_war::systems::apps::IAllowedApp" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::utils::DefaultParameters", - "members": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "color", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::apps::IAllowedApp", - "items": [ - { - "type": "function", - "name": "set_pixel", - "inputs": [ - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsImpl", - "interface_name": "p_war::systems::actions::IActions" - }, - { - "type": "interface", - "name": "p_war::systems::actions::IActions", - "items": [ - { - "type": "function", - "name": "init", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "interact", - "inputs": [ - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "create_game", - "inputs": [ - { - "name": "origin", - "type": "pixelaw::core::utils::Position" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_game_id", - "inputs": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "place_pixel", - "inputs": [ - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_pixel", - "inputs": [ - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "end_game", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::actions::p_war_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::actions::p_war_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::StartedGame", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u128", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::EndedGame", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u128", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "StartedGame", - "type": "p_war::systems::actions::p_war_actions::StartedGame", - "kind": "nested" - }, - { - "name": "EndedGame", - "type": "p_war::systems::actions::p_war_actions::EndedGame", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/contracts/pixelaw-propose-70d0002d.json b/contracts/manifests/release/deployment/abis/contracts/pixelaw-propose-70d0002d.json deleted file mode 100644 index 3836f73..0000000 --- a/contracts/manifests/release/deployment/abis/contracts/pixelaw-propose-70d0002d.json +++ /dev/null @@ -1,289 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ProposeImpl", - "interface_name": "p_war::systems::propose::IPropose" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::propose::IPropose", - "items": [ - { - "type": "function", - "name": "create_proposal", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "proposal_type", - "type": "core::integer::u8" - }, - { - "name": "target_args_1", - "type": "core::integer::u32" - }, - { - "name": "target_args_2", - "type": "core::integer::u32" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "activate_proposal", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "clear_data", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::propose::propose::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::propose::propose::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/contracts/pixelaw-propose_actions-4ee7028a.json b/contracts/manifests/release/deployment/abis/contracts/pixelaw-propose_actions-4ee7028a.json deleted file mode 100644 index 8aa1e40..0000000 --- a/contracts/manifests/release/deployment/abis/contracts/pixelaw-propose_actions-4ee7028a.json +++ /dev/null @@ -1,363 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ProposeImpl", - "interface_name": "p_war::systems::propose::IPropose" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::propose::IPropose", - "items": [ - { - "type": "function", - "name": "create_proposal", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "proposal_type", - "type": "core::integer::u8" - }, - { - "name": "target_args_1", - "type": "core::integer::u32" - }, - { - "name": "target_args_2", - "type": "core::integer::u32" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "activate_proposal", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "clear_data", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::propose::propose_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::propose::propose_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::ProposalCreated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "proposal_type", - "type": "core::integer::u8", - "kind": "data" - }, - { - "name": "target_args_1", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "target_args_2", - "type": "core::integer::u32", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::ProposalActivated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "proposal_type", - "type": "core::integer::u8", - "kind": "data" - }, - { - "name": "target_args_1", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "target_args_2", - "type": "core::integer::u32", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "ProposalCreated", - "type": "p_war::systems::propose::propose_actions::ProposalCreated", - "kind": "nested" - }, - { - "name": "ProposalActivated", - "type": "p_war::systems::propose::propose_actions::ProposalActivated", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/contracts/pixelaw-voting-324fa594.json b/contracts/manifests/release/deployment/abis/contracts/pixelaw-voting-324fa594.json deleted file mode 100644 index 3f3d3f4..0000000 --- a/contracts/manifests/release/deployment/abis/contracts/pixelaw-voting-324fa594.json +++ /dev/null @@ -1,255 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "VotingImpl", - "interface_name": "p_war::systems::voting::IVoting" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::voting::IVoting", - "items": [ - { - "type": "function", - "name": "vote", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "use_px", - "type": "core::integer::u32" - }, - { - "name": "is_in_favor", - "type": "core::bool" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::voting::voting::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::voting::voting::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::voting::voting::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/contracts/pixelaw-voting_actions-6aab73ea.json b/contracts/manifests/release/deployment/abis/contracts/pixelaw-voting_actions-6aab73ea.json deleted file mode 100644 index 0e5b5fe..0000000 --- a/contracts/manifests/release/deployment/abis/contracts/pixelaw-voting_actions-6aab73ea.json +++ /dev/null @@ -1,288 +0,0 @@ -[ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "VotingImpl", - "interface_name": "p_war::systems::voting::IVoting" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::voting::IVoting", - "items": [ - { - "type": "function", - "name": "vote", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "is_in_favor", - "type": "core::bool" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::voting::voting_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::voting::voting_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::voting::voting_actions::Voted", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - }, - { - "name": "voter", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "is_in_favor", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::voting::voting_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "Voted", - "type": "p_war::systems::voting::voting_actions::Voted", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/dojo-base.json b/contracts/manifests/release/deployment/abis/dojo-base.json deleted file mode 100644 index 4800464..0000000 --- a/contracts/manifests/release/deployment/abis/dojo-base.json +++ /dev/null @@ -1,98 +0,0 @@ -[ - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::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::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::base_contract::base::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "flat" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/dojo-world.json b/contracts/manifests/release/deployment/abis/dojo-world.json deleted file mode 100644 index 8553809..0000000 --- a/contracts/manifests/release/deployment/abis/dojo-world.json +++ /dev/null @@ -1,1231 +0,0 @@ -[ - { - "type": "impl", - "name": "World", - "interface_name": "dojo::world::world_contract::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": "struct", - "name": "dojo::model::metadata::ResourceMetadata", - "members": [ - { - "name": "resource_id", - "type": "core::felt252" - }, - { - "name": "metadata_uri", - "type": "core::byte_array::ByteArray" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::model::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::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "enum", - "name": "dojo::world::world_contract::Resource", - "variants": [ - { - "name": "Model", - "type": "(core::starknet::class_hash::ClassHash, core::starknet::contract_address::ContractAddress)" - }, - { - "name": "Contract", - "type": "(core::starknet::class_hash::ClassHash, core::starknet::contract_address::ContractAddress)" - }, - { - "name": "Namespace", - "type": "()" - }, - { - "name": "World", - "type": "()" - }, - { - "name": "Unregistered", - "type": "()" - } - ] - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorld", - "items": [ - { - "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_model", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "upgrade_model", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "deploy_contract", - "inputs": [ - { - "name": "salt", - "type": "core::felt252" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "upgrade_contract", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "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": "uuid", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "emit", - "inputs": [ - { - "name": "keys", - "type": "core::array::Array::" - }, - { - "name": "values", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "function", - "name": "entity", - "inputs": [ - { - "name": "model_selector", - "type": "core::felt252" - }, - { - "name": "index", - "type": "dojo::model::model::ModelIndex" - }, - { - "name": "layout", - "type": "dojo::model::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::model::ModelIndex" - }, - { - "name": "values", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::model::layout::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "delete_entity", - "inputs": [ - { - "name": "model_selector", - "type": "core::felt252" - }, - { - "name": "index", - "type": "dojo::model::model::ModelIndex" - }, - { - "name": "layout", - "type": "dojo::model::layout::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "base", - "inputs": [], - "outputs": [ - { - "type": "core::starknet::class_hash::ClassHash" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "resource", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "dojo::world::world_contract::Resource" - } - ], - "state_mutability": "view" - }, - { - "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": "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::world_contract::IUpgradeableWorld" - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IUpgradeableWorld", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "UpgradeableState", - "interface_name": "dojo::world::update::IUpgradeableState" - }, - { - "type": "struct", - "name": "dojo::world::update::StorageUpdate", - "members": [ - { - "name": "key", - "type": "core::felt252" - }, - { - "name": "value", - "type": "core::felt252" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::world::update::ProgramOutput", - "members": [ - { - "name": "prev_state_root", - "type": "core::felt252" - }, - { - "name": "new_state_root", - "type": "core::felt252" - }, - { - "name": "block_number", - "type": "core::felt252" - }, - { - "name": "block_hash", - "type": "core::felt252" - }, - { - "name": "config_hash", - "type": "core::felt252" - }, - { - "name": "world_da_hash", - "type": "core::felt252" - }, - { - "name": "message_to_starknet_segment", - "type": "core::array::Span::" - }, - { - "name": "message_to_appchain_segment", - "type": "core::array::Span::" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::update::IUpgradeableState", - "items": [ - { - "type": "function", - "name": "upgrade_state", - "inputs": [ - { - "name": "new_state", - "type": "core::array::Span::" - }, - { - "name": "program_output", - "type": "dojo::world::update::ProgramOutput" - }, - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "ConfigImpl", - "interface_name": "dojo::world::config::IConfig" - }, - { - "type": "interface", - "name": "dojo::world::config::IConfig", - "items": [ - { - "type": "function", - "name": "set_differ_program_hash", - "inputs": [ - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_merger_program_hash", - "inputs": [ - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_differ_program_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "get_merger_program_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "set_facts_registry", - "inputs": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_facts_registry", - "inputs": [], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "constructor", - "name": "constructor", - "inputs": [ - { - "name": "contract_base", - "type": "core::starknet::class_hash::ClassHash" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::WorldSpawned", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::ContractDeployed", - "kind": "struct", - "members": [ - { - "name": "salt", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - }, - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "name", - "type": "core::byte_array::ByteArray", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::ContractUpgraded", - "kind": "struct", - "members": [ - { - "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::ContractInitialized", - "kind": "struct", - "members": [ - { - "name": "selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "init_calldata", - "type": "core::array::Span::", - "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::MetadataUpdate", - "kind": "struct", - "members": [ - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "uri", - "type": "core::byte_array::ByteArray", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::NamespaceRegistered", - "kind": "struct", - "members": [ - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "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": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "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::ModelUpgraded", - "kind": "struct", - "members": [ - { - "name": "name", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - }, - { - "name": "prev_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::StoreSetRecord", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "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": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "values", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StoreUpdateMember", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "member_selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "values", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StoreDelRecord", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::WriterUpdated", - "kind": "struct", - "members": [ - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "contract", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "value", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::OwnerUpdated", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "value", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::DifferProgramHashUpdate", - "kind": "struct", - "members": [ - { - "name": "program_hash", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::MergerProgramHashUpdate", - "kind": "struct", - "members": [ - { - "name": "program_hash", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::FactsRegistryUpdate", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::Event", - "kind": "enum", - "variants": [ - { - "name": "DifferProgramHashUpdate", - "type": "dojo::world::config::Config::DifferProgramHashUpdate", - "kind": "nested" - }, - { - "name": "MergerProgramHashUpdate", - "type": "dojo::world::config::Config::MergerProgramHashUpdate", - "kind": "nested" - }, - { - "name": "FactsRegistryUpdate", - "type": "dojo::world::config::Config::FactsRegistryUpdate", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StateUpdated", - "kind": "struct", - "members": [ - { - "name": "da_hash", - "type": "core::felt252", - "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": "ContractDeployed", - "type": "dojo::world::world_contract::world::ContractDeployed", - "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": "WorldUpgraded", - "type": "dojo::world::world_contract::world::WorldUpgraded", - "kind": "nested" - }, - { - "name": "MetadataUpdate", - "type": "dojo::world::world_contract::world::MetadataUpdate", - "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": "ModelUpgraded", - "type": "dojo::world::world_contract::world::ModelUpgraded", - "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" - }, - { - "name": "ConfigEvent", - "type": "dojo::world::config::Config::Event", - "kind": "nested" - }, - { - "name": "StateUpdated", - "type": "dojo::world::world_contract::world::StateUpdated", - "kind": "nested" - } - ] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-AllowedApp-4aa27058.json b/contracts/manifests/release/deployment/abis/models/pixelaw-AllowedApp-4aa27058.json deleted file mode 100644 index 316e91a..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-AllowedApp-4aa27058.json +++ /dev/null @@ -1,425 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "allowed_appImpl", - "interface_name": "p_war::models::allowed_app::Iallowed_app" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_app::AllowedApp", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "contract", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "is_allowed", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_app::Iallowed_app", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_app::AllowedApp" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_app::allowed_app::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-AllowedColor-22c1a796.json b/contracts/manifests/release/deployment/abis/models/pixelaw-AllowedColor-22c1a796.json deleted file mode 100644 index 48cc27f..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-AllowedColor-22c1a796.json +++ /dev/null @@ -1,425 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "allowed_colorImpl", - "interface_name": "p_war::models::allowed_color::Iallowed_color" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::AllowedColor", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "is_allowed", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Iallowed_color", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::AllowedColor" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::allowed_color::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-App-36504565.json b/contracts/manifests/release/deployment/abis/models/pixelaw-App-36504565.json deleted file mode 100644 index c2e9c0e..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-App-36504565.json +++ /dev/null @@ -1,415 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "appImpl", - "interface_name": "pixelaw::core::models::registry::Iapp" - }, - { - "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": "interface", - "name": "pixelaw::core::models::registry::Iapp", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::App" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-AppName-3b816829.json b/contracts/manifests/release/deployment/abis/models/pixelaw-AppName-3b816829.json deleted file mode 100644 index 87a5e61..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-AppName-3b816829.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "app_nameImpl", - "interface_name": "pixelaw::core::models::registry::Iapp_name" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::AppName", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iapp_name", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::AppName" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app_name::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-AppUser-4eda3c52.json b/contracts/manifests/release/deployment/abis/models/pixelaw-AppUser-4eda3c52.json deleted file mode 100644 index a578a2c..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-AppUser-4eda3c52.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "app_userImpl", - "interface_name": "pixelaw::core::models::registry::Iapp_user" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::AppUser", - "members": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iapp_user", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::AppUser" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app_user::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-Board-124dc3e7.json b/contracts/manifests/release/deployment/abis/models/pixelaw-Board-124dc3e7.json deleted file mode 100644 index 6f4d779..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-Board-124dc3e7.json +++ /dev/null @@ -1,429 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "boardImpl", - "interface_name": "p_war::models::board::Iboard" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::board::Board", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "origin", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "width", - "type": "core::integer::u32" - }, - { - "name": "height", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Iboard", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::Board" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::board::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json b/contracts/manifests/release/deployment/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json deleted file mode 100644 index 512af25..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "core_actions_addressImpl", - "interface_name": "pixelaw::core::models::registry::Icore_actions_address" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::CoreActionsAddress", - "members": [ - { - "name": "key", - "type": "core::felt252" - }, - { - "name": "value", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Icore_actions_address", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::CoreActionsAddress" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::core_actions_address::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-Game-5c1fa23f.json b/contracts/manifests/release/deployment/abis/models/pixelaw-Game-5c1fa23f.json deleted file mode 100644 index 9e59f59..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-Game-5c1fa23f.json +++ /dev/null @@ -1,449 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "gameImpl", - "interface_name": "p_war::models::game::Igame" - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::game::Game", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "start", - "type": "core::integer::u64" - }, - { - "name": "end", - "type": "core::integer::u64" - }, - { - "name": "proposal_idx", - "type": "core::integer::u32" - }, - { - "name": "coeff_own_pixels", - "type": "core::integer::u32" - }, - { - "name": "coeff_commits", - "type": "core::integer::u32" - }, - { - "name": "winner_config", - "type": "core::integer::u32" - }, - { - "name": "winner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "guild_ids", - "type": "core::array::Span::" - }, - { - "name": "guild_count", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::game::Igame", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::game::Game" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::game::game::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-GameId-1ee8756e.json b/contracts/manifests/release/deployment/abis/models/pixelaw-GameId-1ee8756e.json deleted file mode 100644 index 869e2a6..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-GameId-1ee8756e.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "game_idImpl", - "interface_name": "p_war::models::board::Igame_id" - }, - { - "type": "struct", - "name": "p_war::models::board::GameId", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "value", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Igame_id", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::GameId" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::game_id::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-GamePalette-49013f2b.json b/contracts/manifests/release/deployment/abis/models/pixelaw-GamePalette-49013f2b.json deleted file mode 100644 index 2ee77e7..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-GamePalette-49013f2b.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "game_paletteImpl", - "interface_name": "p_war::models::allowed_color::Igame_palette" - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::GamePalette", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "length", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Igame_palette", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::GamePalette" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::game_palette::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-Guild-40e97c00.json b/contracts/manifests/release/deployment/abis/models/pixelaw-Guild-40e97c00.json deleted file mode 100644 index f963145..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-Guild-40e97c00.json +++ /dev/null @@ -1,433 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "guildImpl", - "interface_name": "p_war::models::guilds::Iguild" - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::guilds::Guild", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "guild_name", - "type": "core::felt252" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "members", - "type": "core::array::Span::" - }, - { - "name": "member_count", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::guilds::Iguild", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::guilds::Guild" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::guilds::guild::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-InPalette-7a46e3ad.json b/contracts/manifests/release/deployment/abis/models/pixelaw-InPalette-7a46e3ad.json deleted file mode 100644 index 4c58dd9..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-InPalette-7a46e3ad.json +++ /dev/null @@ -1,425 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "in_paletteImpl", - "interface_name": "p_war::models::allowed_color::Iin_palette" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::InPalette", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "value", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Iin_palette", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::InPalette" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::in_palette::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-Instruction-4c7c4844.json b/contracts/manifests/release/deployment/abis/models/pixelaw-Instruction-4c7c4844.json deleted file mode 100644 index a79b066..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-Instruction-4c7c4844.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "instructionImpl", - "interface_name": "pixelaw::core::models::registry::Iinstruction" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::Instruction", - "members": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "instruction", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iinstruction", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::Instruction" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::instruction::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-PWarPixel-15195913.json b/contracts/manifests/release/deployment/abis/models/pixelaw-PWarPixel-15195913.json deleted file mode 100644 index 4fb9f2a..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-PWarPixel-15195913.json +++ /dev/null @@ -1,421 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "p_war_pixelImpl", - "interface_name": "p_war::models::board::Ip_war_pixel" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::board::PWarPixel", - "members": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Ip_war_pixel", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::PWarPixel" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::p_war_pixel::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-PaletteColors-39a92a0a.json b/contracts/manifests/release/deployment/abis/models/pixelaw-PaletteColors-39a92a0a.json deleted file mode 100644 index ac5324c..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-PaletteColors-39a92a0a.json +++ /dev/null @@ -1,411 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "palette_colorsImpl", - "interface_name": "p_war::models::allowed_color::Ipalette_colors" - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::PaletteColors", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "idx", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Ipalette_colors", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::PaletteColors" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::palette_colors::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-Permissions-72b77307.json b/contracts/manifests/release/deployment/abis/models/pixelaw-Permissions-72b77307.json deleted file mode 100644 index 2e1a096..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-Permissions-72b77307.json +++ /dev/null @@ -1,455 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "permissionsImpl", - "interface_name": "pixelaw::core::models::permissions::Ipermissions" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permission", - "members": [ - { - "name": "app", - "type": "core::bool" - }, - { - "name": "color", - "type": "core::bool" - }, - { - "name": "owner", - "type": "core::bool" - }, - { - "name": "text", - "type": "core::bool" - }, - { - "name": "timestamp", - "type": "core::bool" - }, - { - "name": "action", - "type": "core::bool" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permissions", - "members": [ - { - "name": "allowing_app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "allowed_app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "permission", - "type": "pixelaw::core::models::permissions::Permission" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::permissions::Ipermissions", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::permissions::Permissions" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::permissions::permissions::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-Pixel-7e607b2f.json b/contracts/manifests/release/deployment/abis/models/pixelaw-Pixel-7e607b2f.json deleted file mode 100644 index 8f6c36a..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-Pixel-7e607b2f.json +++ /dev/null @@ -1,439 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "pixelImpl", - "interface_name": "pixelaw::core::models::pixel::Ipixel" - }, - { - "type": "struct", - "name": "pixelaw::core::models::pixel::Pixel", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "created_at", - "type": "core::integer::u64" - }, - { - "name": "updated_at", - "type": "core::integer::u64" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "text", - "type": "core::felt252" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::pixel::Ipixel", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::pixel::Pixel" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::pixel::pixel::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json b/contracts/manifests/release/deployment/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json deleted file mode 100644 index 6458f14..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json +++ /dev/null @@ -1,407 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "pixel_recovery_rateImpl", - "interface_name": "p_war::models::proposal::Ipixel_recovery_rate" - }, - { - "type": "struct", - "name": "p_war::models::proposal::PixelRecoveryRate", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "rate", - "type": "core::integer::u64" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Ipixel_recovery_rate", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::PixelRecoveryRate" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::pixel_recovery_rate::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-Player-30a1b371.json b/contracts/manifests/release/deployment/abis/models/pixelaw-Player-30a1b371.json deleted file mode 100644 index 2d345b9..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-Player-30a1b371.json +++ /dev/null @@ -1,433 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "playerImpl", - "interface_name": "p_war::models::player::Iplayer" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::player::Player", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "num_owns", - "type": "core::integer::u32" - }, - { - "name": "num_commit", - "type": "core::integer::u32" - }, - { - "name": "last_date", - "type": "core::integer::u64" - }, - { - "name": "is_banned", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::player::Iplayer", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::player::Player" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::player::player::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-PlayerVote-326c17c6.json b/contracts/manifests/release/deployment/abis/models/pixelaw-PlayerVote-326c17c6.json deleted file mode 100644 index e00fd1f..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-PlayerVote-326c17c6.json +++ /dev/null @@ -1,433 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "player_voteImpl", - "interface_name": "p_war::models::proposal::Iplayer_vote" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::proposal::PlayerVote", - "members": [ - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "is_in_favor", - "type": "core::bool" - }, - { - "name": "voting_power", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Iplayer_vote", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::PlayerVote" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::player_vote::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-Proposal-49e1daf5.json b/contracts/manifests/release/deployment/abis/models/pixelaw-Proposal-49e1daf5.json deleted file mode 100644 index faa5465..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-Proposal-49e1daf5.json +++ /dev/null @@ -1,457 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "proposalImpl", - "interface_name": "p_war::models::proposal::Iproposal" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::proposal::Proposal", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "author", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "proposal_type", - "type": "core::integer::u8" - }, - { - "name": "target_args_1", - "type": "core::integer::u32" - }, - { - "name": "target_args_2", - "type": "core::integer::u32" - }, - { - "name": "start", - "type": "core::integer::u64" - }, - { - "name": "end", - "type": "core::integer::u64" - }, - { - "name": "yes_voting_power", - "type": "core::integer::u32" - }, - { - "name": "no_voting_power", - "type": "core::integer::u32" - }, - { - "name": "is_activated", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Iproposal", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::Proposal" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::proposal::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-QueueItem-549a17f2.json b/contracts/manifests/release/deployment/abis/models/pixelaw-QueueItem-549a17f2.json deleted file mode 100644 index 8496a6c..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-QueueItem-549a17f2.json +++ /dev/null @@ -1,421 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "queue_itemImpl", - "interface_name": "pixelaw::core::models::queue::Iqueue_item" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::queue::QueueItem", - "members": [ - { - "name": "id", - "type": "core::felt252" - }, - { - "name": "valid", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::queue::Iqueue_item", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::queue::QueueItem" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::queue::queue_item::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-Snake-62b876d4.json b/contracts/manifests/release/deployment/abis/models/pixelaw-Snake-62b876d4.json deleted file mode 100644 index 427033f..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-Snake-62b876d4.json +++ /dev/null @@ -1,471 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "snakeImpl", - "interface_name": "pixelaw::apps::snake::app::Isnake" - }, - { - "type": "enum", - "name": "pixelaw::core::utils::Direction", - "variants": [ - { - "name": "None", - "type": "()" - }, - { - "name": "Left", - "type": "()" - }, - { - "name": "Right", - "type": "()" - }, - { - "name": "Up", - "type": "()" - }, - { - "name": "Down", - "type": "()" - } - ] - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::apps::snake::app::Snake", - "members": [ - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "length", - "type": "core::integer::u8" - }, - { - "name": "first_segment_id", - "type": "core::integer::u32" - }, - { - "name": "last_segment_id", - "type": "core::integer::u32" - }, - { - "name": "direction", - "type": "pixelaw::core::utils::Direction" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "text", - "type": "core::felt252" - }, - { - "name": "is_dying", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::apps::snake::app::Isnake", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::apps::snake::app::Snake" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::apps::snake::app::snake::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/abis/models/pixelaw-SnakeSegment-302de0d8.json b/contracts/manifests/release/deployment/abis/models/pixelaw-SnakeSegment-302de0d8.json deleted file mode 100644 index 7baeb86..0000000 --- a/contracts/manifests/release/deployment/abis/models/pixelaw-SnakeSegment-302de0d8.json +++ /dev/null @@ -1,431 +0,0 @@ -[ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "snake_segmentImpl", - "interface_name": "pixelaw::apps::snake::app::Isnake_segment" - }, - { - "type": "struct", - "name": "pixelaw::apps::snake::app::SnakeSegment", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "previous_id", - "type": "core::integer::u32" - }, - { - "name": "next_id", - "type": "core::integer::u32" - }, - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "pixel_original_color", - "type": "core::integer::u32" - }, - { - "name": "pixel_original_text", - "type": "core::felt252" - }, - { - "name": "pixel_original_app", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::apps::snake::app::Isnake_segment", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::apps::snake::app::SnakeSegment" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::apps::snake::app::snake_segment::Event", - "kind": "enum", - "variants": [] - } -] \ No newline at end of file diff --git a/contracts/manifests/release/deployment/manifest.json b/contracts/manifests/release/deployment/manifest.json deleted file mode 100644 index f53c9aa..0000000 --- a/contracts/manifests/release/deployment/manifest.json +++ /dev/null @@ -1,13785 +0,0 @@ -{ - "world": { - "kind": "WorldContract", - "class_hash": "0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e", - "original_class_hash": "0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e", - "abi": [ - { - "type": "impl", - "name": "World", - "interface_name": "dojo::world::world_contract::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": "struct", - "name": "dojo::model::metadata::ResourceMetadata", - "members": [ - { - "name": "resource_id", - "type": "core::felt252" - }, - { - "name": "metadata_uri", - "type": "core::byte_array::ByteArray" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::model::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::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "enum", - "name": "dojo::world::world_contract::Resource", - "variants": [ - { - "name": "Model", - "type": "(core::starknet::class_hash::ClassHash, core::starknet::contract_address::ContractAddress)" - }, - { - "name": "Contract", - "type": "(core::starknet::class_hash::ClassHash, core::starknet::contract_address::ContractAddress)" - }, - { - "name": "Namespace", - "type": "()" - }, - { - "name": "World", - "type": "()" - }, - { - "name": "Unregistered", - "type": "()" - } - ] - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorld", - "items": [ - { - "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_model", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "upgrade_model", - "inputs": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "deploy_contract", - "inputs": [ - { - "name": "salt", - "type": "core::felt252" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "upgrade_contract", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "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": "uuid", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "emit", - "inputs": [ - { - "name": "keys", - "type": "core::array::Array::" - }, - { - "name": "values", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "view" - }, - { - "type": "function", - "name": "entity", - "inputs": [ - { - "name": "model_selector", - "type": "core::felt252" - }, - { - "name": "index", - "type": "dojo::model::model::ModelIndex" - }, - { - "name": "layout", - "type": "dojo::model::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::model::ModelIndex" - }, - { - "name": "values", - "type": "core::array::Span::" - }, - { - "name": "layout", - "type": "dojo::model::layout::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "delete_entity", - "inputs": [ - { - "name": "model_selector", - "type": "core::felt252" - }, - { - "name": "index", - "type": "dojo::model::model::ModelIndex" - }, - { - "name": "layout", - "type": "dojo::model::layout::Layout" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "base", - "inputs": [], - "outputs": [ - { - "type": "core::starknet::class_hash::ClassHash" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "resource", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "dojo::world::world_contract::Resource" - } - ], - "state_mutability": "view" - }, - { - "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": "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::world_contract::IUpgradeableWorld" - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IUpgradeableWorld", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "UpgradeableState", - "interface_name": "dojo::world::update::IUpgradeableState" - }, - { - "type": "struct", - "name": "dojo::world::update::StorageUpdate", - "members": [ - { - "name": "key", - "type": "core::felt252" - }, - { - "name": "value", - "type": "core::felt252" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::world::update::ProgramOutput", - "members": [ - { - "name": "prev_state_root", - "type": "core::felt252" - }, - { - "name": "new_state_root", - "type": "core::felt252" - }, - { - "name": "block_number", - "type": "core::felt252" - }, - { - "name": "block_hash", - "type": "core::felt252" - }, - { - "name": "config_hash", - "type": "core::felt252" - }, - { - "name": "world_da_hash", - "type": "core::felt252" - }, - { - "name": "message_to_starknet_segment", - "type": "core::array::Span::" - }, - { - "name": "message_to_appchain_segment", - "type": "core::array::Span::" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::update::IUpgradeableState", - "items": [ - { - "type": "function", - "name": "upgrade_state", - "inputs": [ - { - "name": "new_state", - "type": "core::array::Span::" - }, - { - "name": "program_output", - "type": "dojo::world::update::ProgramOutput" - }, - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "ConfigImpl", - "interface_name": "dojo::world::config::IConfig" - }, - { - "type": "interface", - "name": "dojo::world::config::IConfig", - "items": [ - { - "type": "function", - "name": "set_differ_program_hash", - "inputs": [ - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_merger_program_hash", - "inputs": [ - { - "name": "program_hash", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_differ_program_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "get_merger_program_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "set_facts_registry", - "inputs": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_facts_registry", - "inputs": [], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "constructor", - "name": "constructor", - "inputs": [ - { - "name": "contract_base", - "type": "core::starknet::class_hash::ClassHash" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::WorldSpawned", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::ContractDeployed", - "kind": "struct", - "members": [ - { - "name": "salt", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - }, - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "name", - "type": "core::byte_array::ByteArray", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::ContractUpgraded", - "kind": "struct", - "members": [ - { - "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::ContractInitialized", - "kind": "struct", - "members": [ - { - "name": "selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "init_calldata", - "type": "core::array::Span::", - "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::MetadataUpdate", - "kind": "struct", - "members": [ - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "uri", - "type": "core::byte_array::ByteArray", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::NamespaceRegistered", - "kind": "struct", - "members": [ - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "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": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "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::ModelUpgraded", - "kind": "struct", - "members": [ - { - "name": "name", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "namespace", - "type": "core::byte_array::ByteArray", - "kind": "data" - }, - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - }, - { - "name": "prev_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::StoreSetRecord", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "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": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "values", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StoreUpdateMember", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "member_selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "values", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StoreDelRecord", - "kind": "struct", - "members": [ - { - "name": "table", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "entity_id", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::WriterUpdated", - "kind": "struct", - "members": [ - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "contract", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "value", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::OwnerUpdated", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "resource", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "value", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::DifferProgramHashUpdate", - "kind": "struct", - "members": [ - { - "name": "program_hash", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::MergerProgramHashUpdate", - "kind": "struct", - "members": [ - { - "name": "program_hash", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::FactsRegistryUpdate", - "kind": "struct", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::world::config::Config::Event", - "kind": "enum", - "variants": [ - { - "name": "DifferProgramHashUpdate", - "type": "dojo::world::config::Config::DifferProgramHashUpdate", - "kind": "nested" - }, - { - "name": "MergerProgramHashUpdate", - "type": "dojo::world::config::Config::MergerProgramHashUpdate", - "kind": "nested" - }, - { - "name": "FactsRegistryUpdate", - "type": "dojo::world::config::Config::FactsRegistryUpdate", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "dojo::world::world_contract::world::StateUpdated", - "kind": "struct", - "members": [ - { - "name": "da_hash", - "type": "core::felt252", - "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": "ContractDeployed", - "type": "dojo::world::world_contract::world::ContractDeployed", - "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": "WorldUpgraded", - "type": "dojo::world::world_contract::world::WorldUpgraded", - "kind": "nested" - }, - { - "name": "MetadataUpdate", - "type": "dojo::world::world_contract::world::MetadataUpdate", - "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": "ModelUpgraded", - "type": "dojo::world::world_contract::world::ModelUpgraded", - "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" - }, - { - "name": "ConfigEvent", - "type": "dojo::world::config::Config::Event", - "kind": "nested" - }, - { - "name": "StateUpdated", - "type": "dojo::world::world_contract::world::StateUpdated", - "kind": "nested" - } - ] - } - ], - "address": "0x263ae44e5414519a5c5a135cccaf3d9d7ee196d37e8de47a178da91f3de9b34", - "transaction_hash": "0x2686985b1f75cb1d4e21fc4b33c2db298c31fbfac2b113a14a11591e82a3e2d", - "block_number": 3, - "seed": "pixelaw", - "metadata": { - "profile_name": "release", - "rpc_url": "https://api.cartridge.gg/x/pwar-dev-2/katana/" - }, - "manifest_name": "dojo-world" - }, - "base": { - "kind": "Class", - "class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", - "original_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", - "abi": "manifests/release/deployment/abis/dojo-base.json", - "tag": "dojo-base", - "manifest_name": "dojo-base" - }, - "contracts": [ - { - "kind": "DojoContract", - "address": "0x6c2ffdd97cb5a1bca13de416adb23a1d0e24ae3c805114b2100f6af95a7f60e", - "class_hash": "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f", - "original_class_hash": "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f", - "base_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", - "abi": [ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsImpl", - "interface_name": "pixelaw::core::actions::IActions" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permission", - "members": [ - { - "name": "app", - "type": "core::bool" - }, - { - "name": "color", - "type": "core::bool" - }, - { - "name": "owner", - "type": "core::bool" - }, - { - "name": "text", - "type": "core::bool" - }, - { - "name": "timestamp", - "type": "core::bool" - }, - { - "name": "action", - "type": "core::bool" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::pixel::Pixel", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "created_at", - "type": "core::integer::u64" - }, - { - "name": "updated_at", - "type": "core::integer::u64" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "text", - "type": "core::felt252" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "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": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "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": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "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": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::actions::IActions", - "items": [ - { - "type": "function", - "name": "init", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_permission", - "inputs": [ - { - "name": "app_key", - "type": "core::felt252" - }, - { - "name": "permission", - "type": "pixelaw::core::models::permissions::Permission" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "has_write_access", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "pixel", - "type": "pixelaw::core::models::pixel::Pixel" - }, - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [ - { - "type": "core::bool" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "process_queue", - "inputs": [ - { - "name": "id", - "type": "core::felt252" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "schedule_queue", - "inputs": [ - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "calldata", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_pixel", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "new_app", - "inputs": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "icon", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "pixelaw::core::models::registry::App" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_system_address", - "inputs": [ - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "get_player_address", - "inputs": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [ - { - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "alert_player", - "inputs": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "message", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "set_instruction", - "inputs": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "instruction", - "type": "core::felt252" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "pixelaw::core::actions::actions::IDojoInit" - }, - { - "type": "interface", - "name": "pixelaw::core::actions::actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::QueueScheduled", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - }, - { - "name": "called_system", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "selector", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "calldata", - "type": "core::array::Span::", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::QueueProcessed", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::AppNameUpdated", - "kind": "struct", - "members": [ - { - "name": "app", - "type": "pixelaw::core::models::registry::App", - "kind": "data" - }, - { - "name": "caller", - "type": "core::felt252", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::Alert", - "kind": "struct", - "members": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position", - "kind": "data" - }, - { - "name": "caller", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "message", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::actions::actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "QueueScheduled", - "type": "pixelaw::core::actions::actions::QueueScheduled", - "kind": "nested" - }, - { - "name": "QueueProcessed", - "type": "pixelaw::core::actions::actions::QueueProcessed", - "kind": "nested" - }, - { - "name": "AppNameUpdated", - "type": "pixelaw::core::actions::actions::AppNameUpdated", - "kind": "nested" - }, - { - "name": "Alert", - "type": "pixelaw::core::actions::actions::Alert", - "kind": "nested" - } - ] - } - ], - "reads": [], - "writes": [ - "pixelaw-App", - "pixelaw-AppName", - "pixelaw-CoreActionsAddress", - "pixelaw-Pixel", - "pixelaw-Permissions", - "pixelaw-QueueItem", - "pixelaw-Instruction", - "pixelaw-PWarPixel", - "pixelaw-AllowedColor", - "pixelaw-PaletteColors" - ], - "init_calldata": [], - "tag": "pixelaw-actions", - "systems": [ - "init", - "update_permission", - "schedule_queue", - "process_queue", - "update_pixel", - "alert_player", - "set_instruction" - ], - "manifest_name": "pixelaw-actions-16928a49" - }, - { - "kind": "DojoContract", - "address": "0x138243b2aeb794df3c6a1b9fb9f834591b3e99c0d73cb59441a6e7cac15c7a", - "class_hash": "0x63080ea2cfae99d4b773b06c7d1cb893c197ba5e431afeba8909eac874d038e", - "original_class_hash": "0x63080ea2cfae99d4b773b06c7d1cb893c197ba5e431afeba8909eac874d038e", - "base_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", - "abi": [ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "GuildImpl", - "interface_name": "p_war::systems::guilds::IGuild" - }, - { - "type": "interface", - "name": "p_war::systems::guilds::IGuild", - "items": [ - { - "type": "function", - "name": "create_guild", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_name", - "type": "core::felt252" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "add_member", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "new_member", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "remove_member", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_guild_points", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::guilds::guild_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::guilds::guild_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::GuildCreated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_name", - "type": "core::felt252", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::MemberAdded", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::MemberRemoved", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "guild_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "member", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::guilds::guild_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "GuildCreated", - "type": "p_war::systems::guilds::guild_actions::GuildCreated", - "kind": "nested" - }, - { - "name": "MemberAdded", - "type": "p_war::systems::guilds::guild_actions::MemberAdded", - "kind": "nested" - }, - { - "name": "MemberRemoved", - "type": "p_war::systems::guilds::guild_actions::MemberRemoved", - "kind": "nested" - } - ] - } - ], - "reads": [], - "writes": [ - "pixelaw-Guild" - ], - "init_calldata": [], - "tag": "pixelaw-guild_actions", - "systems": [ - "add_member", - "remove_member" - ], - "manifest_name": "pixelaw-guild_actions-4c9f5931" - }, - { - "kind": "DojoContract", - "address": "0x2045bbeab298c52664537ae151262ca5f2a4e41b07f221c4860879551c65cb5", - "class_hash": "0x121b6dbe4e601a2d06856e92fc198299dd8bb540481c741898ce68cf9c9c57", - "original_class_hash": "0x121b6dbe4e601a2d06856e92fc198299dd8bb540481c741898ce68cf9c9c57", - "base_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", - "abi": [ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsInteroperability", - "interface_name": "pixelaw::core::traits::IInteroperability" - }, - { - "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": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "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": "interface", - "name": "pixelaw::core::traits::IInteroperability", - "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": [], - "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": "impl", - "name": "AllowedAppImpl", - "interface_name": "p_war::systems::apps::IAllowedApp" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::utils::DefaultParameters", - "members": [ - { - "name": "for_player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "for_system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "color", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::apps::IAllowedApp", - "items": [ - { - "type": "function", - "name": "set_pixel", - "inputs": [ - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ActionsImpl", - "interface_name": "p_war::systems::actions::IActions" - }, - { - "type": "interface", - "name": "p_war::systems::actions::IActions", - "items": [ - { - "type": "function", - "name": "init", - "inputs": [], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "interact", - "inputs": [ - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "create_game", - "inputs": [ - { - "name": "origin", - "type": "pixelaw::core::utils::Position" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "get_game_id", - "inputs": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "place_pixel", - "inputs": [ - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "default_params", - "type": "pixelaw::core::utils::DefaultParameters" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "update_pixel", - "inputs": [ - { - "name": "pixel_update", - "type": "pixelaw::core::models::pixel::PixelUpdate" - } - ], - "outputs": [], - "state_mutability": "external" - }, - { - "type": "function", - "name": "end_game", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::actions::p_war_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::actions::p_war_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::StartedGame", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u128", - "kind": "data" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::EndedGame", - "kind": "struct", - "members": [ - { - "name": "id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u128", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::actions::p_war_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "StartedGame", - "type": "p_war::systems::actions::p_war_actions::StartedGame", - "kind": "nested" - }, - { - "name": "EndedGame", - "type": "p_war::systems::actions::p_war_actions::EndedGame", - "kind": "nested" - } - ] - } - ], - "reads": [], - "writes": [ - "pixelaw-AllowedApp", - "pixelaw-Board", - "pixelaw-AllowedColor", - "pixelaw-PaletteColors", - "pixelaw-PWarPixel", - "pixelaw-Game", - "pixelaw-GameId", - "pixelaw-GamePalette", - "pixelaw-InPalette", - "pixelaw-Player", - "pixelaw-PixelRecoveryRate" - ], - "init_calldata": [], - "tag": "pixelaw-p_war_actions", - "systems": [ - "on_pre_update", - "on_post_update", - "set_pixel", - "init", - "interact", - "place_pixel", - "update_pixel", - "end_game" - ], - "manifest_name": "pixelaw-p_war_actions-60819afd" - }, - { - "kind": "DojoContract", - "address": "0x11c9f67cb73eece3bcf998a0b351e3cb936e0e41a94bebe352d1c1e0b4e09ce", - "class_hash": "0x76a41721719a58f3dd43429eecfff5ed72ff993d653f417bdb337418ec8e589", - "original_class_hash": "0x76a41721719a58f3dd43429eecfff5ed72ff993d653f417bdb337418ec8e589", - "base_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", - "abi": [ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "ProposeImpl", - "interface_name": "p_war::systems::propose::IPropose" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::propose::IPropose", - "items": [ - { - "type": "function", - "name": "create_proposal", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "proposal_type", - "type": "core::integer::u8" - }, - { - "name": "target_args_1", - "type": "core::integer::u32" - }, - { - "name": "target_args_2", - "type": "core::integer::u32" - } - ], - "outputs": [ - { - "type": "core::integer::u32" - } - ], - "state_mutability": "external" - }, - { - "type": "function", - "name": "activate_proposal", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "clear_data", - "type": "core::array::Span::" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::propose::propose_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::propose::propose_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::ProposalCreated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "proposal_type", - "type": "core::integer::u8", - "kind": "data" - }, - { - "name": "target_args_1", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "target_args_2", - "type": "core::integer::u32", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::ProposalActivated", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "proposal_type", - "type": "core::integer::u8", - "kind": "data" - }, - { - "name": "target_args_1", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "target_args_2", - "type": "core::integer::u32", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::propose::propose_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "ProposalCreated", - "type": "p_war::systems::propose::propose_actions::ProposalCreated", - "kind": "nested" - }, - { - "name": "ProposalActivated", - "type": "p_war::systems::propose::propose_actions::ProposalActivated", - "kind": "nested" - } - ] - } - ], - "reads": [], - "writes": [ - "pixelaw-AllowedColor", - "pixelaw-GamePalette", - "pixelaw-InPalette", - "pixelaw-PaletteColors", - "pixelaw-Proposal", - "pixelaw-Player", - "pixelaw-Game", - "pixelaw-Board" - ], - "init_calldata": [], - "tag": "pixelaw-propose_actions", - "systems": [ - "activate_proposal" - ], - "manifest_name": "pixelaw-propose_actions-4ee7028a" - }, - { - "kind": "DojoContract", - "address": "0x5e3d35ee4c47433f2550b295d68ec519124e027aeac31e9bbc2b8cf4a769c81", - "class_hash": "0x5e87a338c9ee6d9d72281883bd04133f0d91e4d5ecebcfbbf281319ce877b2a", - "original_class_hash": "0x5e87a338c9ee6d9d72281883bd04133f0d91e4d5ecebcfbbf281319ce877b2a", - "base_class_hash": "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2", - "abi": [ - { - "type": "impl", - "name": "ContractImpl", - "interface_name": "dojo::contract::contract::IContract" - }, - { - "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::contract::contract::IContract", - "items": [ - { - "type": "function", - "name": "contract_name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "WorldProviderImpl", - "interface_name": "dojo::world::world_contract::IWorldProvider" - }, - { - "type": "struct", - "name": "dojo::world::world_contract::IWorldDispatcher", - "members": [ - { - "name": "contract_address", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "dojo::world::world_contract::IWorldProvider", - "items": [ - { - "type": "function", - "name": "world", - "inputs": [], - "outputs": [ - { - "type": "dojo::world::world_contract::IWorldDispatcher" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "VotingImpl", - "interface_name": "p_war::systems::voting::IVoting" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "p_war::systems::voting::IVoting", - "items": [ - { - "type": "function", - "name": "vote", - "inputs": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "is_in_favor", - "type": "core::bool" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "impl", - "name": "IDojoInitImpl", - "interface_name": "p_war::systems::voting::voting_actions::IDojoInit" - }, - { - "type": "interface", - "name": "p_war::systems::voting::voting_actions::IDojoInit", - "items": [ - { - "type": "function", - "name": "dojo_init", - "inputs": [], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "UpgradableImpl", - "interface_name": "dojo::contract::upgradeable::IUpgradeable" - }, - { - "type": "interface", - "name": "dojo::contract::upgradeable::IUpgradeable", - "items": [ - { - "type": "function", - "name": "upgrade", - "inputs": [ - { - "name": "new_class_hash", - "type": "core::starknet::class_hash::ClassHash" - } - ], - "outputs": [], - "state_mutability": "external" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "struct", - "members": [ - { - "name": "class_hash", - "type": "core::starknet::class_hash::ClassHash", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "enum", - "variants": [ - { - "name": "Upgraded", - "type": "dojo::contract::upgradeable::upgradeable::Upgraded", - "kind": "nested" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::voting::voting_actions::Voted", - "kind": "struct", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "index", - "type": "core::integer::u32", - "kind": "data" - }, - { - "name": "timestamp", - "type": "core::integer::u64", - "kind": "data" - }, - { - "name": "voter", - "type": "core::starknet::contract_address::ContractAddress", - "kind": "data" - }, - { - "name": "is_in_favor", - "type": "core::bool", - "kind": "data" - } - ] - }, - { - "type": "event", - "name": "p_war::systems::voting::voting_actions::Event", - "kind": "enum", - "variants": [ - { - "name": "UpgradeableEvent", - "type": "dojo::contract::upgradeable::upgradeable::Event", - "kind": "nested" - }, - { - "name": "Voted", - "type": "p_war::systems::voting::voting_actions::Voted", - "kind": "nested" - } - ] - } - ], - "reads": [], - "writes": [ - "pixelaw-PlayerVote", - "pixelaw-Proposal", - "pixelaw-Player" - ], - "init_calldata": [], - "tag": "pixelaw-voting_actions", - "systems": [ - "vote" - ], - "manifest_name": "pixelaw-voting_actions-6aab73ea" - } - ], - "models": [ - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "contract", - "type": "ContractAddress", - "key": true - }, - { - "name": "is_allowed", - "type": "bool", - "key": false - } - ], - "class_hash": "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f", - "original_class_hash": "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "allowed_appImpl", - "interface_name": "p_war::models::allowed_app::Iallowed_app" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_app::AllowedApp", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "contract", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "is_allowed", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_app::Iallowed_app", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_app::AllowedApp" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_app::allowed_app::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-AllowedApp", - "qualified_path": "p_war::models::allowed_app::allowed_app", - "manifest_name": "pixelaw-AllowedApp-4aa27058" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "color", - "type": "u32", - "key": true - }, - { - "name": "is_allowed", - "type": "bool", - "key": false - } - ], - "class_hash": "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54", - "original_class_hash": "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "allowed_colorImpl", - "interface_name": "p_war::models::allowed_color::Iallowed_color" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::AllowedColor", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "is_allowed", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Iallowed_color", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::AllowedColor" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::allowed_color::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-AllowedColor", - "qualified_path": "p_war::models::allowed_color::allowed_color", - "manifest_name": "pixelaw-AllowedColor-22c1a796" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "system", - "type": "ContractAddress", - "key": true - }, - { - "name": "name", - "type": "felt252", - "key": false - }, - { - "name": "icon", - "type": "felt252", - "key": false - }, - { - "name": "action", - "type": "felt252", - "key": false - } - ], - "class_hash": "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c", - "original_class_hash": "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "appImpl", - "interface_name": "pixelaw::core::models::registry::Iapp" - }, - { - "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": "interface", - "name": "pixelaw::core::models::registry::Iapp", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::App" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-App", - "qualified_path": "pixelaw::core::models::registry::app", - "manifest_name": "pixelaw-App-36504565" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "name", - "type": "felt252", - "key": true - }, - { - "name": "system", - "type": "ContractAddress", - "key": false - } - ], - "class_hash": "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8", - "original_class_hash": "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "app_nameImpl", - "interface_name": "pixelaw::core::models::registry::Iapp_name" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::AppName", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iapp_name", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::AppName" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app_name::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-AppName", - "qualified_path": "pixelaw::core::models::registry::app_name", - "manifest_name": "pixelaw-AppName-3b816829" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "system", - "type": "ContractAddress", - "key": true - }, - { - "name": "player", - "type": "ContractAddress", - "key": true - }, - { - "name": "action", - "type": "felt252", - "key": false - } - ], - "class_hash": "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1", - "original_class_hash": "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "app_userImpl", - "interface_name": "pixelaw::core::models::registry::Iapp_user" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::AppUser", - "members": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iapp_user", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::AppUser" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::app_user::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-AppUser", - "qualified_path": "pixelaw::core::models::registry::app_user", - "manifest_name": "pixelaw-AppUser-4eda3c52" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "id", - "type": "usize", - "key": true - }, - { - "name": "origin", - "type": "Position", - "key": false - }, - { - "name": "width", - "type": "u32", - "key": false - }, - { - "name": "height", - "type": "u32", - "key": false - } - ], - "class_hash": "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c", - "original_class_hash": "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "boardImpl", - "interface_name": "p_war::models::board::Iboard" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::board::Board", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "origin", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "width", - "type": "core::integer::u32" - }, - { - "name": "height", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Iboard", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::Board" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::board::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Board", - "qualified_path": "p_war::models::board::board", - "manifest_name": "pixelaw-Board-124dc3e7" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "key", - "type": "felt252", - "key": true - }, - { - "name": "value", - "type": "ContractAddress", - "key": false - } - ], - "class_hash": "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2", - "original_class_hash": "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "core_actions_addressImpl", - "interface_name": "pixelaw::core::models::registry::Icore_actions_address" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::CoreActionsAddress", - "members": [ - { - "name": "key", - "type": "core::felt252" - }, - { - "name": "value", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Icore_actions_address", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::CoreActionsAddress" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::core_actions_address::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-CoreActionsAddress", - "qualified_path": "pixelaw::core::models::registry::core_actions_address", - "manifest_name": "pixelaw-CoreActionsAddress-5379e1ce" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "id", - "type": "usize", - "key": true - }, - { - "name": "start", - "type": "u64", - "key": false - }, - { - "name": "end", - "type": "u64", - "key": false - }, - { - "name": "proposal_idx", - "type": "usize", - "key": false - }, - { - "name": "coeff_own_pixels", - "type": "u32", - "key": false - }, - { - "name": "coeff_commits", - "type": "u32", - "key": false - }, - { - "name": "winner_config", - "type": "u32", - "key": false - }, - { - "name": "winner", - "type": "ContractAddress", - "key": false - }, - { - "name": "guild_ids", - "type": "Span", - "key": false - }, - { - "name": "guild_count", - "type": "usize", - "key": false - } - ], - "class_hash": "0x4eb28e2e4c9f69487e5479cacac150e52666d072315dc8e3547b32f977976e0", - "original_class_hash": "0x4eb28e2e4c9f69487e5479cacac150e52666d072315dc8e3547b32f977976e0", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "gameImpl", - "interface_name": "p_war::models::game::Igame" - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::game::Game", - "members": [ - { - "name": "id", - "type": "core::integer::u32" - }, - { - "name": "start", - "type": "core::integer::u64" - }, - { - "name": "end", - "type": "core::integer::u64" - }, - { - "name": "proposal_idx", - "type": "core::integer::u32" - }, - { - "name": "coeff_own_pixels", - "type": "core::integer::u32" - }, - { - "name": "coeff_commits", - "type": "core::integer::u32" - }, - { - "name": "winner_config", - "type": "core::integer::u32" - }, - { - "name": "winner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "guild_ids", - "type": "core::array::Span::" - }, - { - "name": "guild_count", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::game::Igame", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::game::Game" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::game::game::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Game", - "qualified_path": "p_war::models::game::game", - "manifest_name": "pixelaw-Game-5c1fa23f" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "x", - "type": "u32", - "key": true - }, - { - "name": "y", - "type": "u32", - "key": true - }, - { - "name": "value", - "type": "usize", - "key": false - } - ], - "class_hash": "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4", - "original_class_hash": "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "game_idImpl", - "interface_name": "p_war::models::board::Igame_id" - }, - { - "type": "struct", - "name": "p_war::models::board::GameId", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "value", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Igame_id", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::GameId" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::game_id::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-GameId", - "qualified_path": "p_war::models::board::game_id", - "manifest_name": "pixelaw-GameId-1ee8756e" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "length", - "type": "usize", - "key": false - } - ], - "class_hash": "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398", - "original_class_hash": "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "game_paletteImpl", - "interface_name": "p_war::models::allowed_color::Igame_palette" - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::GamePalette", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "length", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Igame_palette", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::GamePalette" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::game_palette::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-GamePalette", - "qualified_path": "p_war::models::allowed_color::game_palette", - "manifest_name": "pixelaw-GamePalette-49013f2b" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "guild_id", - "type": "usize", - "key": true - }, - { - "name": "guild_name", - "type": "felt252", - "key": false - }, - { - "name": "creator", - "type": "ContractAddress", - "key": false - }, - { - "name": "members", - "type": "Span", - "key": false - }, - { - "name": "member_count", - "type": "usize", - "key": false - } - ], - "class_hash": "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95", - "original_class_hash": "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "guildImpl", - "interface_name": "p_war::models::guilds::Iguild" - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::guilds::Guild", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "guild_id", - "type": "core::integer::u32" - }, - { - "name": "guild_name", - "type": "core::felt252" - }, - { - "name": "creator", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "members", - "type": "core::array::Span::" - }, - { - "name": "member_count", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::guilds::Iguild", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::guilds::Guild" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::guilds::guild::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Guild", - "qualified_path": "p_war::models::guilds::guild", - "manifest_name": "pixelaw-Guild-40e97c00" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "color", - "type": "u32", - "key": true - }, - { - "name": "value", - "type": "bool", - "key": false - } - ], - "class_hash": "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372", - "original_class_hash": "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "in_paletteImpl", - "interface_name": "p_war::models::allowed_color::Iin_palette" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::InPalette", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "value", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Iin_palette", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::InPalette" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::in_palette::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-InPalette", - "qualified_path": "p_war::models::allowed_color::in_palette", - "manifest_name": "pixelaw-InPalette-7a46e3ad" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "system", - "type": "ContractAddress", - "key": true - }, - { - "name": "selector", - "type": "felt252", - "key": true - }, - { - "name": "instruction", - "type": "felt252", - "key": false - } - ], - "class_hash": "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af", - "original_class_hash": "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "instructionImpl", - "interface_name": "pixelaw::core::models::registry::Iinstruction" - }, - { - "type": "struct", - "name": "pixelaw::core::models::registry::Instruction", - "members": [ - { - "name": "system", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "instruction", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::registry::Iinstruction", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::registry::Instruction" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::registry::instruction::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Instruction", - "qualified_path": "pixelaw::core::models::registry::instruction", - "manifest_name": "pixelaw-Instruction-4c7c4844" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "position", - "type": "Position", - "key": true - }, - { - "name": "owner", - "type": "ContractAddress", - "key": false - } - ], - "class_hash": "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261", - "original_class_hash": "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "p_war_pixelImpl", - "interface_name": "p_war::models::board::Ip_war_pixel" - }, - { - "type": "struct", - "name": "pixelaw::core::utils::Position", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::board::PWarPixel", - "members": [ - { - "name": "position", - "type": "pixelaw::core::utils::Position" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::board::Ip_war_pixel", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::board::PWarPixel" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::board::p_war_pixel::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-PWarPixel", - "qualified_path": "p_war::models::board::p_war_pixel", - "manifest_name": "pixelaw-PWarPixel-15195913" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "idx", - "type": "u32", - "key": true - }, - { - "name": "color", - "type": "u32", - "key": false - } - ], - "class_hash": "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444", - "original_class_hash": "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "palette_colorsImpl", - "interface_name": "p_war::models::allowed_color::Ipalette_colors" - }, - { - "type": "struct", - "name": "p_war::models::allowed_color::PaletteColors", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "idx", - "type": "core::integer::u32" - }, - { - "name": "color", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::allowed_color::Ipalette_colors", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::allowed_color::PaletteColors" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::allowed_color::palette_colors::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-PaletteColors", - "qualified_path": "p_war::models::allowed_color::palette_colors", - "manifest_name": "pixelaw-PaletteColors-39a92a0a" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "allowing_app", - "type": "ContractAddress", - "key": true - }, - { - "name": "allowed_app", - "type": "ContractAddress", - "key": true - }, - { - "name": "permission", - "type": "Permission", - "key": false - } - ], - "class_hash": "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302", - "original_class_hash": "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "permissionsImpl", - "interface_name": "pixelaw::core::models::permissions::Ipermissions" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permission", - "members": [ - { - "name": "app", - "type": "core::bool" - }, - { - "name": "color", - "type": "core::bool" - }, - { - "name": "owner", - "type": "core::bool" - }, - { - "name": "text", - "type": "core::bool" - }, - { - "name": "timestamp", - "type": "core::bool" - }, - { - "name": "action", - "type": "core::bool" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::permissions::Permissions", - "members": [ - { - "name": "allowing_app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "allowed_app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "permission", - "type": "pixelaw::core::models::permissions::Permission" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::permissions::Ipermissions", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::permissions::Permissions" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::permissions::permissions::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Permissions", - "qualified_path": "pixelaw::core::models::permissions::permissions", - "manifest_name": "pixelaw-Permissions-72b77307" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "x", - "type": "u32", - "key": true - }, - { - "name": "y", - "type": "u32", - "key": true - }, - { - "name": "app", - "type": "ContractAddress", - "key": false - }, - { - "name": "color", - "type": "u32", - "key": false - }, - { - "name": "created_at", - "type": "u64", - "key": false - }, - { - "name": "updated_at", - "type": "u64", - "key": false - }, - { - "name": "timestamp", - "type": "u64", - "key": false - }, - { - "name": "owner", - "type": "ContractAddress", - "key": false - }, - { - "name": "text", - "type": "felt252", - "key": false - }, - { - "name": "action", - "type": "felt252", - "key": false - } - ], - "class_hash": "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d", - "original_class_hash": "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "pixelImpl", - "interface_name": "pixelaw::core::models::pixel::Ipixel" - }, - { - "type": "struct", - "name": "pixelaw::core::models::pixel::Pixel", - "members": [ - { - "name": "x", - "type": "core::integer::u32" - }, - { - "name": "y", - "type": "core::integer::u32" - }, - { - "name": "app", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "color", - "type": "core::integer::u32" - }, - { - "name": "created_at", - "type": "core::integer::u64" - }, - { - "name": "updated_at", - "type": "core::integer::u64" - }, - { - "name": "timestamp", - "type": "core::integer::u64" - }, - { - "name": "owner", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "text", - "type": "core::felt252" - }, - { - "name": "action", - "type": "core::felt252" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::pixel::Ipixel", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::pixel::Pixel" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::pixel::pixel::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Pixel", - "qualified_path": "pixelaw::core::models::pixel::pixel", - "manifest_name": "pixelaw-Pixel-7e607b2f" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "rate", - "type": "u64", - "key": false - } - ], - "class_hash": "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067", - "original_class_hash": "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "pixel_recovery_rateImpl", - "interface_name": "p_war::models::proposal::Ipixel_recovery_rate" - }, - { - "type": "struct", - "name": "p_war::models::proposal::PixelRecoveryRate", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "rate", - "type": "core::integer::u64" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Ipixel_recovery_rate", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::PixelRecoveryRate" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::pixel_recovery_rate::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-PixelRecoveryRate", - "qualified_path": "p_war::models::proposal::pixel_recovery_rate", - "manifest_name": "pixelaw-PixelRecoveryRate-3aa284c0" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "address", - "type": "ContractAddress", - "key": true - }, - { - "name": "num_owns", - "type": "u32", - "key": false - }, - { - "name": "num_commit", - "type": "u32", - "key": false - }, - { - "name": "last_date", - "type": "u64", - "key": false - }, - { - "name": "is_banned", - "type": "bool", - "key": false - } - ], - "class_hash": "0x71a6f6188f355d1337561c8d68538b18ec4be4c493d01be5eee753759246848", - "original_class_hash": "0x71a6f6188f355d1337561c8d68538b18ec4be4c493d01be5eee753759246848", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "playerImpl", - "interface_name": "p_war::models::player::Iplayer" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::player::Player", - "members": [ - { - "name": "address", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "num_owns", - "type": "core::integer::u32" - }, - { - "name": "num_commit", - "type": "core::integer::u32" - }, - { - "name": "last_date", - "type": "core::integer::u64" - }, - { - "name": "is_banned", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::player::Iplayer", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::player::Player" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::player::player::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Player", - "qualified_path": "p_war::models::player::player", - "manifest_name": "pixelaw-Player-30a1b371" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "player", - "type": "ContractAddress", - "key": true - }, - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "index", - "type": "usize", - "key": true - }, - { - "name": "is_in_favor", - "type": "bool", - "key": false - }, - { - "name": "voting_power", - "type": "u32", - "key": false - } - ], - "class_hash": "0x4b76f6971c93c77d96a22ac7ba0268c452d13538f05b64138a6382e18babb00", - "original_class_hash": "0x4b76f6971c93c77d96a22ac7ba0268c452d13538f05b64138a6382e18babb00", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "player_voteImpl", - "interface_name": "p_war::models::proposal::Iplayer_vote" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::proposal::PlayerVote", - "members": [ - { - "name": "player", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "is_in_favor", - "type": "core::bool" - }, - { - "name": "voting_power", - "type": "core::integer::u32" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Iplayer_vote", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::PlayerVote" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::player_vote::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-PlayerVote", - "qualified_path": "p_war::models::proposal::player_vote", - "manifest_name": "pixelaw-PlayerVote-326c17c6" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "game_id", - "type": "usize", - "key": true - }, - { - "name": "index", - "type": "usize", - "key": true - }, - { - "name": "author", - "type": "ContractAddress", - "key": false - }, - { - "name": "proposal_type", - "type": "u8", - "key": false - }, - { - "name": "target_args_1", - "type": "u32", - "key": false - }, - { - "name": "target_args_2", - "type": "u32", - "key": false - }, - { - "name": "start", - "type": "u64", - "key": false - }, - { - "name": "end", - "type": "u64", - "key": false - }, - { - "name": "yes_voting_power", - "type": "u32", - "key": false - }, - { - "name": "no_voting_power", - "type": "u32", - "key": false - }, - { - "name": "is_activated", - "type": "bool", - "key": false - } - ], - "class_hash": "0x76c0a4827cc62be7367ab6fac605335bb5a2d01a7edc3f2dd89e58accafca02", - "original_class_hash": "0x76c0a4827cc62be7367ab6fac605335bb5a2d01a7edc3f2dd89e58accafca02", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "proposalImpl", - "interface_name": "p_war::models::proposal::Iproposal" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "p_war::models::proposal::Proposal", - "members": [ - { - "name": "game_id", - "type": "core::integer::u32" - }, - { - "name": "index", - "type": "core::integer::u32" - }, - { - "name": "author", - "type": "core::starknet::contract_address::ContractAddress" - }, - { - "name": "proposal_type", - "type": "core::integer::u8" - }, - { - "name": "target_args_1", - "type": "core::integer::u32" - }, - { - "name": "target_args_2", - "type": "core::integer::u32" - }, - { - "name": "start", - "type": "core::integer::u64" - }, - { - "name": "end", - "type": "core::integer::u64" - }, - { - "name": "yes_voting_power", - "type": "core::integer::u32" - }, - { - "name": "no_voting_power", - "type": "core::integer::u32" - }, - { - "name": "is_activated", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "p_war::models::proposal::Iproposal", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "p_war::models::proposal::Proposal" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "p_war::models::proposal::proposal::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-Proposal", - "qualified_path": "p_war::models::proposal::proposal", - "manifest_name": "pixelaw-Proposal-49e1daf5" - }, - { - "kind": "DojoModel", - "members": [ - { - "name": "id", - "type": "felt252", - "key": true - }, - { - "name": "valid", - "type": "bool", - "key": false - } - ], - "class_hash": "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70", - "original_class_hash": "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70", - "abi": [ - { - "type": "impl", - "name": "DojoModelImpl", - "interface_name": "dojo::model::model::IModel" - }, - { - "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": "core::option::Option::", - "variants": [ - { - "name": "Some", - "type": "core::integer::u32" - }, - { - "name": "None", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::layout::FieldLayout", - "members": [ - { - "name": "selector", - "type": "core::felt252" - }, - { - "name": "layout", - "type": "dojo::model::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::model::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": "struct", - "name": "dojo::model::introspect::Member", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "ty", - "type": "dojo::model::introspect::Ty" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Struct", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "dojo::model::introspect::Enum", - "members": [ - { - "name": "name", - "type": "core::felt252" - }, - { - "name": "attrs", - "type": "core::array::Span::" - }, - { - "name": "children", - "type": "core::array::Span::<(core::felt252, dojo::model::introspect::Ty)>" - } - ] - }, - { - "type": "struct", - "name": "core::array::Span::", - "members": [ - { - "name": "snapshot", - "type": "@core::array::Array::" - } - ] - }, - { - "type": "enum", - "name": "dojo::model::introspect::Ty", - "variants": [ - { - "name": "Primitive", - "type": "core::felt252" - }, - { - "name": "Struct", - "type": "dojo::model::introspect::Struct" - }, - { - "name": "Enum", - "type": "dojo::model::introspect::Enum" - }, - { - "name": "Tuple", - "type": "core::array::Span::" - }, - { - "name": "Array", - "type": "core::array::Span::" - }, - { - "name": "ByteArray", - "type": "()" - } - ] - }, - { - "type": "interface", - "name": "dojo::model::model::IModel", - "items": [ - { - "type": "function", - "name": "name", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "tag", - "inputs": [], - "outputs": [ - { - "type": "core::byte_array::ByteArray" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "version", - "inputs": [], - "outputs": [ - { - "type": "core::integer::u8" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "selector", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "name_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "namespace_hash", - "inputs": [], - "outputs": [ - { - "type": "core::felt252" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "unpacked_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "packed_size", - "inputs": [], - "outputs": [ - { - "type": "core::option::Option::" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "layout", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::layout::Layout" - } - ], - "state_mutability": "view" - }, - { - "type": "function", - "name": "schema", - "inputs": [], - "outputs": [ - { - "type": "dojo::model::introspect::Ty" - } - ], - "state_mutability": "view" - } - ] - }, - { - "type": "impl", - "name": "queue_itemImpl", - "interface_name": "pixelaw::core::models::queue::Iqueue_item" - }, - { - "type": "enum", - "name": "core::bool", - "variants": [ - { - "name": "False", - "type": "()" - }, - { - "name": "True", - "type": "()" - } - ] - }, - { - "type": "struct", - "name": "pixelaw::core::models::queue::QueueItem", - "members": [ - { - "name": "id", - "type": "core::felt252" - }, - { - "name": "valid", - "type": "core::bool" - } - ] - }, - { - "type": "interface", - "name": "pixelaw::core::models::queue::Iqueue_item", - "items": [ - { - "type": "function", - "name": "ensure_abi", - "inputs": [ - { - "name": "model", - "type": "pixelaw::core::models::queue::QueueItem" - } - ], - "outputs": [], - "state_mutability": "view" - } - ] - }, - { - "type": "event", - "name": "pixelaw::core::models::queue::queue_item::Event", - "kind": "enum", - "variants": [] - } - ], - "tag": "pixelaw-QueueItem", - "qualified_path": "pixelaw::core::models::queue::queue_item", - "manifest_name": "pixelaw-QueueItem-549a17f2" - } - ] -} \ No newline at end of file diff --git a/contracts/manifests/release/deployment/manifest.toml b/contracts/manifests/release/deployment/manifest.toml deleted file mode 100644 index 0ff272a..0000000 --- a/contracts/manifests/release/deployment/manifest.toml +++ /dev/null @@ -1,801 +0,0 @@ -[world] -kind = "WorldContract" -class_hash = "0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e" -original_class_hash = "0x6f4515274ee23404789c3351a77107d0ec07508530119822046600ca6948d6e" -abi = "manifests/release/deployment/abis/dojo-world.json" -address = "0x263ae44e5414519a5c5a135cccaf3d9d7ee196d37e8de47a178da91f3de9b34" -transaction_hash = "0x2686985b1f75cb1d4e21fc4b33c2db298c31fbfac2b113a14a11591e82a3e2d" -block_number = 3 -seed = "pixelaw" -manifest_name = "dojo-world" - -[world.metadata] -profile_name = "release" -rpc_url = "https://api.cartridge.gg/x/pwar-dev-2/katana/" - -[base] -kind = "Class" -class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -original_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -abi = "manifests/release/deployment/abis/dojo-base.json" -tag = "dojo-base" -manifest_name = "dojo-base" - -[[contracts]] -kind = "DojoContract" -address = "0x6c2ffdd97cb5a1bca13de416adb23a1d0e24ae3c805114b2100f6af95a7f60e" -class_hash = "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f" -original_class_hash = "0x17d390af6c3b449b52da5a0969a00006a3b7935ffc08192dc8cefdeb563488f" -base_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -abi = "manifests/release/deployment/abis/contracts/pixelaw-actions-16928a49.json" -reads = [] -writes = [ - "pixelaw-App", - "pixelaw-AppName", - "pixelaw-CoreActionsAddress", - "pixelaw-Pixel", - "pixelaw-Permissions", - "pixelaw-QueueItem", - "pixelaw-Instruction", - "pixelaw-PWarPixel", - "pixelaw-AllowedColor", - "pixelaw-PaletteColors", -] -init_calldata = [] -tag = "pixelaw-actions" -systems = [ - "init", - "update_permission", - "schedule_queue", - "process_queue", - "update_pixel", - "alert_player", - "set_instruction", -] -manifest_name = "pixelaw-actions-16928a49" - -[[contracts]] -kind = "DojoContract" -address = "0x138243b2aeb794df3c6a1b9fb9f834591b3e99c0d73cb59441a6e7cac15c7a" -class_hash = "0x63080ea2cfae99d4b773b06c7d1cb893c197ba5e431afeba8909eac874d038e" -original_class_hash = "0x63080ea2cfae99d4b773b06c7d1cb893c197ba5e431afeba8909eac874d038e" -base_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -abi = "manifests/release/deployment/abis/contracts/pixelaw-guild_actions-4c9f5931.json" -reads = [] -writes = ["pixelaw-Guild"] -init_calldata = [] -tag = "pixelaw-guild_actions" -systems = [ - "add_member", - "remove_member", -] -manifest_name = "pixelaw-guild_actions-4c9f5931" - -[[contracts]] -kind = "DojoContract" -address = "0x2045bbeab298c52664537ae151262ca5f2a4e41b07f221c4860879551c65cb5" -class_hash = "0x121b6dbe4e601a2d06856e92fc198299dd8bb540481c741898ce68cf9c9c57" -original_class_hash = "0x121b6dbe4e601a2d06856e92fc198299dd8bb540481c741898ce68cf9c9c57" -base_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -abi = "manifests/release/deployment/abis/contracts/pixelaw-p_war_actions-60819afd.json" -reads = [] -writes = [ - "pixelaw-AllowedApp", - "pixelaw-Board", - "pixelaw-AllowedColor", - "pixelaw-PaletteColors", - "pixelaw-PWarPixel", - "pixelaw-Game", - "pixelaw-GameId", - "pixelaw-GamePalette", - "pixelaw-InPalette", - "pixelaw-Player", - "pixelaw-PixelRecoveryRate", -] -init_calldata = [] -tag = "pixelaw-p_war_actions" -systems = [ - "on_pre_update", - "on_post_update", - "set_pixel", - "init", - "interact", - "place_pixel", - "update_pixel", - "end_game", -] -manifest_name = "pixelaw-p_war_actions-60819afd" - -[[contracts]] -kind = "DojoContract" -address = "0x11c9f67cb73eece3bcf998a0b351e3cb936e0e41a94bebe352d1c1e0b4e09ce" -class_hash = "0x76a41721719a58f3dd43429eecfff5ed72ff993d653f417bdb337418ec8e589" -original_class_hash = "0x76a41721719a58f3dd43429eecfff5ed72ff993d653f417bdb337418ec8e589" -base_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -abi = "manifests/release/deployment/abis/contracts/pixelaw-propose_actions-4ee7028a.json" -reads = [] -writes = [ - "pixelaw-AllowedColor", - "pixelaw-GamePalette", - "pixelaw-InPalette", - "pixelaw-PaletteColors", - "pixelaw-Proposal", - "pixelaw-Player", - "pixelaw-Game", - "pixelaw-Board", -] -init_calldata = [] -tag = "pixelaw-propose_actions" -systems = ["activate_proposal"] -manifest_name = "pixelaw-propose_actions-4ee7028a" - -[[contracts]] -kind = "DojoContract" -address = "0x5e3d35ee4c47433f2550b295d68ec519124e027aeac31e9bbc2b8cf4a769c81" -class_hash = "0x5e87a338c9ee6d9d72281883bd04133f0d91e4d5ecebcfbbf281319ce877b2a" -original_class_hash = "0x5e87a338c9ee6d9d72281883bd04133f0d91e4d5ecebcfbbf281319ce877b2a" -base_class_hash = "0x2427dd10a58850ac9a5ca6ce04b7771b05330fd18f2e481831ad903b969e6b2" -abi = "manifests/release/deployment/abis/contracts/pixelaw-voting_actions-6aab73ea.json" -reads = [] -writes = [ - "pixelaw-PlayerVote", - "pixelaw-Proposal", - "pixelaw-Player", -] -init_calldata = [] -tag = "pixelaw-voting_actions" -systems = ["vote"] -manifest_name = "pixelaw-voting_actions-6aab73ea" - -[[models]] -kind = "DojoModel" -class_hash = "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f" -original_class_hash = "0x2e21c14e524e53add7e001d5ff402bbb8573d8bfabfee7025eaa755aa6e729f" -abi = "manifests/release/deployment/abis/models/pixelaw-AllowedApp-4aa27058.json" -tag = "pixelaw-AllowedApp" -qualified_path = "p_war::models::allowed_app::allowed_app" -manifest_name = "pixelaw-AllowedApp-4aa27058" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "contract" -type = "ContractAddress" -key = true - -[[models.members]] -name = "is_allowed" -type = "bool" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54" -original_class_hash = "0x661de232e8fd024ceef7e099030347690f4e8280bc50840982c6cab3298da54" -abi = "manifests/release/deployment/abis/models/pixelaw-AllowedColor-22c1a796.json" -tag = "pixelaw-AllowedColor" -qualified_path = "p_war::models::allowed_color::allowed_color" -manifest_name = "pixelaw-AllowedColor-22c1a796" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "color" -type = "u32" -key = true - -[[models.members]] -name = "is_allowed" -type = "bool" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c" -original_class_hash = "0x4107d94a66470b68d2e06102c87937c03cca51fafa84a3a4fc45c95a4d2403c" -abi = "manifests/release/deployment/abis/models/pixelaw-App-36504565.json" -tag = "pixelaw-App" -qualified_path = "pixelaw::core::models::registry::app" -manifest_name = "pixelaw-App-36504565" - -[[models.members]] -name = "system" -type = "ContractAddress" -key = true - -[[models.members]] -name = "name" -type = "felt252" -key = false - -[[models.members]] -name = "icon" -type = "felt252" -key = false - -[[models.members]] -name = "action" -type = "felt252" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8" -original_class_hash = "0x7d54c34e9b4215ceaada6950e0b521ef3892de01fbaea2c8323e8c2cf3329c8" -abi = "manifests/release/deployment/abis/models/pixelaw-AppName-3b816829.json" -tag = "pixelaw-AppName" -qualified_path = "pixelaw::core::models::registry::app_name" -manifest_name = "pixelaw-AppName-3b816829" - -[[models.members]] -name = "name" -type = "felt252" -key = true - -[[models.members]] -name = "system" -type = "ContractAddress" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1" -original_class_hash = "0x3d55e23acf8df5ef0c25b76d5a6b7765c241c494af075c7ce3858568bec45f1" -abi = "manifests/release/deployment/abis/models/pixelaw-AppUser-4eda3c52.json" -tag = "pixelaw-AppUser" -qualified_path = "pixelaw::core::models::registry::app_user" -manifest_name = "pixelaw-AppUser-4eda3c52" - -[[models.members]] -name = "system" -type = "ContractAddress" -key = true - -[[models.members]] -name = "player" -type = "ContractAddress" -key = true - -[[models.members]] -name = "action" -type = "felt252" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c" -original_class_hash = "0x38dd4eb04738175abe3d1d4b2541dbf6c318004fe9a76d5181001bfe72ae66c" -abi = "manifests/release/deployment/abis/models/pixelaw-Board-124dc3e7.json" -tag = "pixelaw-Board" -qualified_path = "p_war::models::board::board" -manifest_name = "pixelaw-Board-124dc3e7" - -[[models.members]] -name = "id" -type = "usize" -key = true - -[[models.members]] -name = "origin" -type = "Position" -key = false - -[[models.members]] -name = "width" -type = "u32" -key = false - -[[models.members]] -name = "height" -type = "u32" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2" -original_class_hash = "0x296cfe5fb82a8b03b4aa78e35955bc70971babeb414d70a6a8acc52a4eacab2" -abi = "manifests/release/deployment/abis/models/pixelaw-CoreActionsAddress-5379e1ce.json" -tag = "pixelaw-CoreActionsAddress" -qualified_path = "pixelaw::core::models::registry::core_actions_address" -manifest_name = "pixelaw-CoreActionsAddress-5379e1ce" - -[[models.members]] -name = "key" -type = "felt252" -key = true - -[[models.members]] -name = "value" -type = "ContractAddress" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x4eb28e2e4c9f69487e5479cacac150e52666d072315dc8e3547b32f977976e0" -original_class_hash = "0x4eb28e2e4c9f69487e5479cacac150e52666d072315dc8e3547b32f977976e0" -abi = "manifests/release/deployment/abis/models/pixelaw-Game-5c1fa23f.json" -tag = "pixelaw-Game" -qualified_path = "p_war::models::game::game" -manifest_name = "pixelaw-Game-5c1fa23f" - -[[models.members]] -name = "id" -type = "usize" -key = true - -[[models.members]] -name = "start" -type = "u64" -key = false - -[[models.members]] -name = "end" -type = "u64" -key = false - -[[models.members]] -name = "proposal_idx" -type = "usize" -key = false - -[[models.members]] -name = "coeff_own_pixels" -type = "u32" -key = false - -[[models.members]] -name = "coeff_commits" -type = "u32" -key = false - -[[models.members]] -name = "winner_config" -type = "u32" -key = false - -[[models.members]] -name = "winner" -type = "ContractAddress" -key = false - -[[models.members]] -name = "guild_ids" -type = "Span" -key = false - -[[models.members]] -name = "guild_count" -type = "usize" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4" -original_class_hash = "0x22a02c0555eedefbbf217bf90fa1796bd4e113b4ee5f79007ea3d271181c2f4" -abi = "manifests/release/deployment/abis/models/pixelaw-GameId-1ee8756e.json" -tag = "pixelaw-GameId" -qualified_path = "p_war::models::board::game_id" -manifest_name = "pixelaw-GameId-1ee8756e" - -[[models.members]] -name = "x" -type = "u32" -key = true - -[[models.members]] -name = "y" -type = "u32" -key = true - -[[models.members]] -name = "value" -type = "usize" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398" -original_class_hash = "0x71970d089bfc265a629cb22eb01266723e8db49ae13a35bc1a53867a38d7398" -abi = "manifests/release/deployment/abis/models/pixelaw-GamePalette-49013f2b.json" -tag = "pixelaw-GamePalette" -qualified_path = "p_war::models::allowed_color::game_palette" -manifest_name = "pixelaw-GamePalette-49013f2b" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "length" -type = "usize" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95" -original_class_hash = "0x54ea4b52cb546ddc0cd309cd998980b20b333d9cec4dd148a8da1a2500cff95" -abi = "manifests/release/deployment/abis/models/pixelaw-Guild-40e97c00.json" -tag = "pixelaw-Guild" -qualified_path = "p_war::models::guilds::guild" -manifest_name = "pixelaw-Guild-40e97c00" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "guild_id" -type = "usize" -key = true - -[[models.members]] -name = "guild_name" -type = "felt252" -key = false - -[[models.members]] -name = "creator" -type = "ContractAddress" -key = false - -[[models.members]] -name = "members" -type = "Span" -key = false - -[[models.members]] -name = "member_count" -type = "usize" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372" -original_class_hash = "0x42e6b8f760d9ae43dfdac6767b2c7e12ea881dfbe10ccac7c30d2ed025ac372" -abi = "manifests/release/deployment/abis/models/pixelaw-InPalette-7a46e3ad.json" -tag = "pixelaw-InPalette" -qualified_path = "p_war::models::allowed_color::in_palette" -manifest_name = "pixelaw-InPalette-7a46e3ad" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "color" -type = "u32" -key = true - -[[models.members]] -name = "value" -type = "bool" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af" -original_class_hash = "0x710dc73b9f03542890421c368ca53fe61416010f69709337bc7b40b9c3115af" -abi = "manifests/release/deployment/abis/models/pixelaw-Instruction-4c7c4844.json" -tag = "pixelaw-Instruction" -qualified_path = "pixelaw::core::models::registry::instruction" -manifest_name = "pixelaw-Instruction-4c7c4844" - -[[models.members]] -name = "system" -type = "ContractAddress" -key = true - -[[models.members]] -name = "selector" -type = "felt252" -key = true - -[[models.members]] -name = "instruction" -type = "felt252" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261" -original_class_hash = "0x3f15ee957414f1442830161943dfac7ca65fb77b5a9a2ed2e53099d8493c261" -abi = "manifests/release/deployment/abis/models/pixelaw-PWarPixel-15195913.json" -tag = "pixelaw-PWarPixel" -qualified_path = "p_war::models::board::p_war_pixel" -manifest_name = "pixelaw-PWarPixel-15195913" - -[[models.members]] -name = "position" -type = "Position" -key = true - -[[models.members]] -name = "owner" -type = "ContractAddress" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444" -original_class_hash = "0x37fca9c9d7ab57dda36b03416d16bfc625e9b0e6187c8f7f73030225c9b5444" -abi = "manifests/release/deployment/abis/models/pixelaw-PaletteColors-39a92a0a.json" -tag = "pixelaw-PaletteColors" -qualified_path = "p_war::models::allowed_color::palette_colors" -manifest_name = "pixelaw-PaletteColors-39a92a0a" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "idx" -type = "u32" -key = true - -[[models.members]] -name = "color" -type = "u32" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302" -original_class_hash = "0x7083f333ceabd1e174c4f5b129b7d5cfeaccd7b4fcc5ea2e5a264cce7dc302" -abi = "manifests/release/deployment/abis/models/pixelaw-Permissions-72b77307.json" -tag = "pixelaw-Permissions" -qualified_path = "pixelaw::core::models::permissions::permissions" -manifest_name = "pixelaw-Permissions-72b77307" - -[[models.members]] -name = "allowing_app" -type = "ContractAddress" -key = true - -[[models.members]] -name = "allowed_app" -type = "ContractAddress" -key = true - -[[models.members]] -name = "permission" -type = "Permission" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d" -original_class_hash = "0x71570f33b7f66331952b84691bb5794ee6b19f43ad729cc654c3930f47c5f0d" -abi = "manifests/release/deployment/abis/models/pixelaw-Pixel-7e607b2f.json" -tag = "pixelaw-Pixel" -qualified_path = "pixelaw::core::models::pixel::pixel" -manifest_name = "pixelaw-Pixel-7e607b2f" - -[[models.members]] -name = "x" -type = "u32" -key = true - -[[models.members]] -name = "y" -type = "u32" -key = true - -[[models.members]] -name = "app" -type = "ContractAddress" -key = false - -[[models.members]] -name = "color" -type = "u32" -key = false - -[[models.members]] -name = "created_at" -type = "u64" -key = false - -[[models.members]] -name = "updated_at" -type = "u64" -key = false - -[[models.members]] -name = "timestamp" -type = "u64" -key = false - -[[models.members]] -name = "owner" -type = "ContractAddress" -key = false - -[[models.members]] -name = "text" -type = "felt252" -key = false - -[[models.members]] -name = "action" -type = "felt252" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067" -original_class_hash = "0x432d5d7bf204934886fa3dc72b24ad292b14caf4bea83531cef5004d7cb5067" -abi = "manifests/release/deployment/abis/models/pixelaw-PixelRecoveryRate-3aa284c0.json" -tag = "pixelaw-PixelRecoveryRate" -qualified_path = "p_war::models::proposal::pixel_recovery_rate" -manifest_name = "pixelaw-PixelRecoveryRate-3aa284c0" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "rate" -type = "u64" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x71a6f6188f355d1337561c8d68538b18ec4be4c493d01be5eee753759246848" -original_class_hash = "0x71a6f6188f355d1337561c8d68538b18ec4be4c493d01be5eee753759246848" -abi = "manifests/release/deployment/abis/models/pixelaw-Player-30a1b371.json" -tag = "pixelaw-Player" -qualified_path = "p_war::models::player::player" -manifest_name = "pixelaw-Player-30a1b371" - -[[models.members]] -name = "address" -type = "ContractAddress" -key = true - -[[models.members]] -name = "num_owns" -type = "u32" -key = false - -[[models.members]] -name = "num_commit" -type = "u32" -key = false - -[[models.members]] -name = "last_date" -type = "u64" -key = false - -[[models.members]] -name = "is_banned" -type = "bool" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x4b76f6971c93c77d96a22ac7ba0268c452d13538f05b64138a6382e18babb00" -original_class_hash = "0x4b76f6971c93c77d96a22ac7ba0268c452d13538f05b64138a6382e18babb00" -abi = "manifests/release/deployment/abis/models/pixelaw-PlayerVote-326c17c6.json" -tag = "pixelaw-PlayerVote" -qualified_path = "p_war::models::proposal::player_vote" -manifest_name = "pixelaw-PlayerVote-326c17c6" - -[[models.members]] -name = "player" -type = "ContractAddress" -key = true - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "index" -type = "usize" -key = true - -[[models.members]] -name = "is_in_favor" -type = "bool" -key = false - -[[models.members]] -name = "voting_power" -type = "u32" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x76c0a4827cc62be7367ab6fac605335bb5a2d01a7edc3f2dd89e58accafca02" -original_class_hash = "0x76c0a4827cc62be7367ab6fac605335bb5a2d01a7edc3f2dd89e58accafca02" -abi = "manifests/release/deployment/abis/models/pixelaw-Proposal-49e1daf5.json" -tag = "pixelaw-Proposal" -qualified_path = "p_war::models::proposal::proposal" -manifest_name = "pixelaw-Proposal-49e1daf5" - -[[models.members]] -name = "game_id" -type = "usize" -key = true - -[[models.members]] -name = "index" -type = "usize" -key = true - -[[models.members]] -name = "author" -type = "ContractAddress" -key = false - -[[models.members]] -name = "proposal_type" -type = "u8" -key = false - -[[models.members]] -name = "target_args_1" -type = "u32" -key = false - -[[models.members]] -name = "target_args_2" -type = "u32" -key = false - -[[models.members]] -name = "start" -type = "u64" -key = false - -[[models.members]] -name = "end" -type = "u64" -key = false - -[[models.members]] -name = "yes_voting_power" -type = "u32" -key = false - -[[models.members]] -name = "no_voting_power" -type = "u32" -key = false - -[[models.members]] -name = "is_activated" -type = "bool" -key = false - -[[models]] -kind = "DojoModel" -class_hash = "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70" -original_class_hash = "0x672114a91934388e6a4950f164dc151894579281f4eab56fe439108fd4fca70" -abi = "manifests/release/deployment/abis/models/pixelaw-QueueItem-549a17f2.json" -tag = "pixelaw-QueueItem" -qualified_path = "pixelaw::core::models::queue::queue_item" -manifest_name = "pixelaw-QueueItem-549a17f2" - -[[models.members]] -name = "id" -type = "felt252" -key = true - -[[models.members]] -name = "valid" -type = "bool" -key = false diff --git a/contracts/overlays/dev/core_actions.toml b/contracts/overlays/dev/core_actions.toml deleted file mode 100644 index f70ae4b..0000000 --- a/contracts/overlays/dev/core_actions.toml +++ /dev/null @@ -1,13 +0,0 @@ -tag = "pixelaw-actions" -writes = [ - "pixelaw-App", - "pixelaw-AppName", - "pixelaw-CoreActionsAddress", - "pixelaw-Pixel", - "pixelaw-Permissions", - "pixelaw-QueueItem", - "pixelaw-Instruction", - "pixelaw-PWarPixel", - "pixelaw-AllowedColor", - "pixelaw-PaletteColors", -] diff --git a/contracts/overlays/dev/guild_actions.toml b/contracts/overlays/dev/guild_actions.toml deleted file mode 100644 index 8ebc66a..0000000 --- a/contracts/overlays/dev/guild_actions.toml +++ /dev/null @@ -1,2 +0,0 @@ -tag = "pixelaw-guild_actions" -writes = ["pixelaw-Guild"] diff --git a/contracts/overlays/dev/p_war_actions.toml b/contracts/overlays/dev/p_war_actions.toml deleted file mode 100644 index 37f2ea6..0000000 --- a/contracts/overlays/dev/p_war_actions.toml +++ /dev/null @@ -1,14 +0,0 @@ -tag = "pixelaw-p_war_actions" -writes = [ - "pixelaw-AllowedApp", - "pixelaw-Board", - "pixelaw-AllowedColor", - "pixelaw-PaletteColors", - "pixelaw-PWarPixel", - "pixelaw-Game", - "pixelaw-GameId", - "pixelaw-GamePalette", - "pixelaw-InPalette", - "pixelaw-Player", - "pixelaw-PixelRecoveryRate", -] diff --git a/contracts/overlays/dev/propose_actions.toml b/contracts/overlays/dev/propose_actions.toml deleted file mode 100644 index 761738a..0000000 --- a/contracts/overlays/dev/propose_actions.toml +++ /dev/null @@ -1,11 +0,0 @@ -tag = "pixelaw-propose_actions" -writes = [ - "pixelaw-AllowedColor", - "pixelaw-GamePalette", - "pixelaw-InPalette", - "pixelaw-PaletteColors", - "pixelaw-Proposal", - "pixelaw-Player", - "pixelaw-Game", - "pixelaw-Board", -] diff --git a/contracts/overlays/dev/voting_actions.toml b/contracts/overlays/dev/voting_actions.toml deleted file mode 100644 index 4fc81a9..0000000 --- a/contracts/overlays/dev/voting_actions.toml +++ /dev/null @@ -1,2 +0,0 @@ -tag = "pixelaw-voting_actions" -writes = ["pixelaw-PlayerVote", "pixelaw-Proposal", "pixelaw-Player"] diff --git a/contracts/overlays/release/core_actions.toml b/contracts/overlays/release/core_actions.toml deleted file mode 100644 index f70ae4b..0000000 --- a/contracts/overlays/release/core_actions.toml +++ /dev/null @@ -1,13 +0,0 @@ -tag = "pixelaw-actions" -writes = [ - "pixelaw-App", - "pixelaw-AppName", - "pixelaw-CoreActionsAddress", - "pixelaw-Pixel", - "pixelaw-Permissions", - "pixelaw-QueueItem", - "pixelaw-Instruction", - "pixelaw-PWarPixel", - "pixelaw-AllowedColor", - "pixelaw-PaletteColors", -] diff --git a/contracts/overlays/release/guild_actions.toml b/contracts/overlays/release/guild_actions.toml deleted file mode 100644 index 8ebc66a..0000000 --- a/contracts/overlays/release/guild_actions.toml +++ /dev/null @@ -1,2 +0,0 @@ -tag = "pixelaw-guild_actions" -writes = ["pixelaw-Guild"] diff --git a/contracts/overlays/release/p_war_actions.toml b/contracts/overlays/release/p_war_actions.toml deleted file mode 100644 index 37f2ea6..0000000 --- a/contracts/overlays/release/p_war_actions.toml +++ /dev/null @@ -1,14 +0,0 @@ -tag = "pixelaw-p_war_actions" -writes = [ - "pixelaw-AllowedApp", - "pixelaw-Board", - "pixelaw-AllowedColor", - "pixelaw-PaletteColors", - "pixelaw-PWarPixel", - "pixelaw-Game", - "pixelaw-GameId", - "pixelaw-GamePalette", - "pixelaw-InPalette", - "pixelaw-Player", - "pixelaw-PixelRecoveryRate", -] diff --git a/contracts/overlays/release/propose_actions.toml b/contracts/overlays/release/propose_actions.toml deleted file mode 100644 index 761738a..0000000 --- a/contracts/overlays/release/propose_actions.toml +++ /dev/null @@ -1,11 +0,0 @@ -tag = "pixelaw-propose_actions" -writes = [ - "pixelaw-AllowedColor", - "pixelaw-GamePalette", - "pixelaw-InPalette", - "pixelaw-PaletteColors", - "pixelaw-Proposal", - "pixelaw-Player", - "pixelaw-Game", - "pixelaw-Board", -] diff --git a/contracts/overlays/release/voting_actions.toml b/contracts/overlays/release/voting_actions.toml deleted file mode 100644 index 4fc81a9..0000000 --- a/contracts/overlays/release/voting_actions.toml +++ /dev/null @@ -1,2 +0,0 @@ -tag = "pixelaw-voting_actions" -writes = ["pixelaw-PlayerVote", "pixelaw-Proposal", "pixelaw-Player"] From 6c0e1d89ab5236c6a5cb5939c72cfcca2bc5a16e Mon Sep 17 00:00:00 2001 From: Asuma Yamada Date: Thu, 5 Dec 2024 05:39:52 +0900 Subject: [PATCH 12/18] fix: ci error --- client/bun.lockb | Bin 314740 -> 330820 bytes client/dojoConfig.ts | 6 +- client/src/libs/dojo/helper.ts | 1 + client/src/libs/dojo/setup.ts | 4 +- client/src/vite-env.d.ts | 8 +- contracts/dojo_dev.toml | 2 +- contracts/dojo_release.toml | 56 - contracts/dojo_sepolia.toml | 8 +- contracts/manifest_dev.json | 3835 ++++++++++++++++++++++++++++++++ 9 files changed, 3850 insertions(+), 70 deletions(-) delete mode 100644 contracts/dojo_release.toml create mode 100644 contracts/manifest_dev.json diff --git a/client/bun.lockb b/client/bun.lockb index 4602a163403877b76e04f5dfe94a85669f161a4e..7fd6be1d8ed1d293c9d0a37cdd3c52ef904ac5d2 100755 GIT binary patch delta 71998 zcmeFad0dS9|NlQTHOz&OwGgsq2_e%u2_a;sa)dS-+7~J^g@|K47hd*#Df@Czkt1s% z`%?C-WzSwmd>_y2x~BKM-=Fh&e}2Eu_xt($b>?PzydL-0zFyZgbLxCrRr~acI*U8B z`R(|&6{e?dI^Tb`^Los0^Nt+-p5qi;dFjwGmWP`;Ryla-_o_-6y}B;(Y|`UtTO+~9 zWd6b0z|d%!Yyki#lO;w5`ufAljErTnYVc#B#Dl`71P4aSWHXVj3jC6NR=UZRWwJU5 zhifB!qXVO4A@O3NBUCb3Rq*Jbz)69R?e-P4XqXJ_Cp`#I5LnhNDc0>!Qz;NH_AnQqiaph&tYq#489; zg+`K|Mz^Sd+O@1V&B>>@1V%dAp|K+>iH-ijF}3$iSE=YU68g>fmlman4Jjw00Uw z=>vjQlaX8|>sg7vW7L@I*j#K_2`@LUuj_)^uqF~mV!KfHqoREyCxr$^w{0cPS5ZrG z3tWIwx~8qgTIxZm)oGHxgJLZuMn`t-MwJ~ydTPZ|C=Kr%N%ugho;csg2^g(fvIlL% z3NAw_!zn(^xV7oJc49RXqryVRYl8!MzRMk}Z5sK}Zc+5rA?NHjwfv)1# zSOrgWtgksf3>y!xy$W&fX7!ZzI+VJ!8l1M&jUHmx7&w+&;xRX2h;)hL0kGc_Q+kVI zH5i^6;2`O@KH?BOf>OF1N#CPDI)x6xQv=sRDc=!yaq-saCoWPWD9y7K%Buyf45c~g z)n6uSM#p6~3aSl|jFwUXZwH7iy(Z}qC{5B@C{5ZdDD^A?O8L4Ck`9ZgV67iUVhuda zSt}^*B2y?e@X=s#u5L?OHc&b)eNhl490{e#4Mjt!XG5U0x~>luhtPVM*f2+_p>3hm zGrQqph5Bu$-zg!u08NZSgGPwuEre3T5+(h0q;y!*#53lEe{)&_=9x;>+?TWHAjE!Ov7 z(vO$I1MIe6`3XTaCR_1AH-*;*%u}2n-Cj4vYw< z22J*D5iENkwxr_5XCFMxjIV!KWGD*S?!z~$(n@y&rCI=|L+Kn@E%_NxTCxGq#?bE2 z7SN{9rci~%AL53lIeZqh8FU@A2~;PkFO>54kbEmB)l(IUEuu>djPi@o1_#JaMu;=M z3rZ8bT+&2ICrUa3S{L!IP&y^7B{i2+DQQW#7=K^VTuBc}x(QlaHd>arNC?Ohr%9@n z)Dud(-%Zjkl3GeyLsEZVOdVe9Fu)wrFO&3rEWfF0x6bS1#TEA(lorBlDD52mydVd7@YSO&$2+%moXNVPlP7(_^1y2PYfSN+LKxySiJBtnQ z_X~@(#-46DOH4mCSzI`tlG;G&G&hla5z@7U&xW>!ZiF^P4T<^-*K1Tv<9auVuVT_l z_uD+te*aZmxR0R?5S=6GUMO{ZxunyfbP*UY=^!W#q&<|@SxYGO#~e!YQUgl!Fb(xk zd@qax1|)IyVqqS2iTWMwhzM#I9W6Bfkzv8XF<2A-x}&=OCN}W@&CbHr=U=y$87iPH z^`C69ilaw=IoDs_^*c|$(8V3`kDaAo`1&1|wGtzOzNd& ziz7IeJj}P{Zjt&fv1xCe0YlEYp5ix<0ak8A9Vurw|@W?<^yblG{M*5z+#GY+| zrv`V}E&9dqvIwtr|6snb-(Crad^DZc5h>6r%)1`cxRKOT0 zo%aKvbb9teVYHo`;Hf8d_lpgg7-cOyYT-UV+&3~RkOQX%xf~F+Gn9_YJSa^CJq!7w zgE}jzqQwWr^JzQghW2|Esbc+{>(l8QpdW!Po5b_zKJw9pYCb%j5A)%v0Zrv%gQEgN zCesH6-@%)LpMYA(WR8jVH;5T#0#M8J8S2W#DbYX3No!B0@A0Y({=8``o&FhK|7?#t zkdPQ0@WFxN14E@_V*S1$0fAU9f#pZVYV?oNA(QBCou2P7)3~Kk92W=lW0tr^pGx`; zoM!MAJZV%^P&j6`s?6+!*wGp%`1o3l70G|_t7^5GjW63*l+rXGt2O4GFXk@RLo2r&05biVO9hq>YXgJ?~Q6T~{eb zTr+>36U%xDPuor#8Wb3*jgIP`D|SU2g~t}(IGMh!_mGad7!VdB?1F3XR5v~o!s?UB zR%M7jDkv~G7>o5+cq%srN^R+WQP9qbT@j$p=;x-L7?C(IPi)xuDC@x3=t$p4ZAhf= zc$tjn?dvo#H@Yn5(l>K_R5WfALl7HL$J5W@npn9Flqw4i3&)8hlll7jMFwJ1=|4Qu zuM1&d5U)m^G@yEq+l-*Vfbmhf8zR@YHR1-}wr&Sq&3y5)b{I<8&fFD`M9X_(U!CrV zd_q`w09F6CK%Cbu;MA;j@TB8$^~OhMLH<&DcZv6VATG0p;KFtRuZ8qG!Ep}g61xD< z*2zANKccy0G_Vf zlO+w1;`>1x&_mgFG=M7HiV>g!FH1e>j0DtT3n(?DI+W7k1D43Z34yWYNJr`QtLg+nKPpj5#@DD`NY#OJ*id;Atk7mW^5{7fkM$0cIE?jOXF+VKJ7PX)Ps6kE0(N)@h^ z6hj>qh*b~8X9+S{CvfVKIkY}h1*Itn2=kAQ#F;k<6;X$VLn+=#@~dTHh59r8A6GYw ze{CexKiudqZ~9MO1HOta)?cMO;b{aWm5TbGU9I{f9ZjYFVxqs;EJ8zw@A^}mVjtfT z;;P*MKoN5!E&49D_%4(xJO`!4GzA4v5A`>XVL!xz&O>SS<1EJVS7$Xn{oW|w#%;)=)WlD?5mK|tG!+fX>%c{ zbXuaZ%b`B)Zf=geI_bdZE(42pd$nq>nQ&sBPeYfEna!FobBks}f8|w;z4)NUK`MQM zgI5}xDO9ib4`^uB#Aya!)YPly*L2tUMtf@Iu~qwP416)F+rc2qrbab$@(+%#SF735 zgS{HJPQ9kP!>6?9-t@LZ+xF8hYF2bR`A4I>mCI)A&KmnB!EOCky+4@KqOa0yeapo5 z?UDoi`hCj{R=(RjJhqYcN@2>F4+m?uU0g}Gt-jmDddE^azt|JE#Pe~)*MhH$0x~x| zEm^&?#c>aQ`=`OvgOAE|-7j8GN-jaoj8FYW9ipUc~Kagl%G&k%0j!6d3&{s@(5UGK1=N=FXl7UE}Ro~Mh_u7 z6*e8tPH;)KYWZP4&dx<)X2NIMX{cLvF7jV_dwUo84L;7^g|ou>)C-B_e71+33Wi1r zeXvu@Px1B+E}Rl4Eio1Ein4PhSDD6MzE4Fg2N@JBqv|Y$2q!iAHYV6B_e%a zoJG_Zm5_V3|yo-ighx3vq$A~g> zMR54=lh%Yrt+21hJ9O7@+i}&xO$m*WTCFsxkCyPxT^!}^d}((VVgX3C^y!Vy;|A5p)}Ck420akYY1cd z3{I?r8fDq2qJ&d+Dwx4S0cat&5sqe2Z2dzx>X_)7Tj;BD?V{#_;HXgw+7sL+II-8* zVca7rWo2F-Y^Q2079uPiZVDV_6BpTj$)S*LYWWx5zORe2H6Ad!@d-AL+ysQ2getJu zxy^9YG^~p^cD%j2i^8!fAMdW=!kUT^;u6`-m%6*ifAaSIToj!x`S^Ysc@Uq`&xOmd z6ju^v5FJ%Dt5^(RyaDGMW?bB9rnXSJ2Er|GTzl) z&Bep@fD^aMF*rxQ+{RJPhoN>-EAz?m<<5=@vyOb(NDUX- zQNM#}aQDIW5?Vkj>k}NcSlAef_MP}LPmOXE#=9TQi+l?o=jFoPg{MS9Te#Xb`c5YG zQ*-^{XnKToq?`(eBgn;3xfdZvJ_{}W$d`J%m~_A(0wv0EyEBxxv1!M5`pBsOX_ttn z!!YbgI;TXJ1~;n08QJ2?^a?i?ZcK&Cf*V)iEHJ!&6;22Dk9>FG{*ljKEnfM=`WC?b zqxL6oLn}(LMen^T+yc1a6|NAD#uJxC%x_EV1DZq}g~QZb3>@_jhd9>mK{%RH;YjB` z!_nD-lLm1e5kx`K5KpLZ+57BNFmxqA1@>yInpp4DFkET==~aeQ^}rR^lD-tz&g{vL zvoW(;gT(#*zb1Yzl}yE&8FIGm$^bUKL_*D5G%wBYC{ z7!NmCXw+eZXx7lxgLWzyT3bTDxuLk!O%w|lZl{77qmNQLAj?2LYrK;&0^|6s04G%+ zu{#(?EU#e|jy7+lzGCylV!Oi))R)99tZ;Hv0wXpVjpVG{#j{w<77m9}F?y&#an7BO z57a1H_2V-kf&KWhKn=GE<4J=eW_SuWuELG)FK#z6E(Z>Ml~Ptioir8VVOPb&a1h4* zlRFGYTS_dY3c5jSTy&%12J4+-*FZiqNW+a8q~BRMq!s4|@eW#zvJ|iv?;PZ$LV9!= z1<+BN3@7g8B#l~G42OHL&W_6FLxj*yC;1RQbE1Yj2#+NuRa;Wwk~(95q5yFOX&R=& z(Ml9M_5zNkT6FHi^xc%Z*{NV?1jN}Zh7&7r#X;N~9j39uO2kEd9-Me7!y&CaLr%Dq zRT&|Z;e1Q1Mt8!BgCqE|5Dmv+F;P|=$hcAS7|F+nY82~6@|mF;?hWF^-9U3~?I}78 z?*91XI^|+ zxJFUen|FxND0+MI@sL%JaE-FSTPEwzCxoNCQR2o%-MHolj^Z66HHy=t`1nW-SMwKr zcWH+DS2$YMv*BLfwV*GZE^E6c%*&aM$5*mchAd z)e6gTeEbv*=Z9TE(<|H>DL25`(*;mbFphVK)o=}c^-af;ReHcVQOU}=2ssFKJV1zU zgN0JL=6>R?!;s?w5eesrI4o)0mF$M2VZc=NRCBMTl<3P9JC(owIK`-QVQ}J-!@MbX z!-K7h~crr|mSRuqYL1;g118F25x zZGoe+TwL#W;CcwHq@~zsyg0_3@T@Tsjusp4t8h%O9?zF0Xq0y;iO{OL6T}YUmS&=w z>jT$bD9AP2P6b0v#4wLkD{f8T9dsIHiB=~2g?H9DDhEuI$-H^znNG$Ch)6a`CL1P1 z4nxRC2<<~i%O~iZjDzt>t$^YY5+iRTG(ljR5Sc7c2yI4atPoO!>O;N=Q4S~L3SLi$LQxf=KPp01qx7+!2;oKyIW{8HR|pkX zglwYqEUqGyT@m79^sz%KLMtmmg$VT)+cH@n3aJPktO%7N)JsU`JVhT$stBE_2ywAe ztimIfkDsgIrUB575--Y!C5QcmWmPIU@!_URoH(Cwp=!<_t^@MH;kj)ITsJuJYJDz_ zclcGq{gfa!2DYMYytqI_M43r( z!iBpGA!%V^qjj4mc0(*L9FCfU`+JnP4X&aD?g5;*({O|+oD=x?g&Hn4LCj#x%Olj> z8Mu+iEbNf$O#-Hr$uvgViz!~$TJy^I*anq zoYNI?=$_IzQ8<2Z(m5lf7E;j$kA`y;oE*pc-U>&zR4>U1+s`vetW_u(Cj(!$SfezX zLF=-7u_G6NPfZvw4@N1`%iK0=E!6L6>*E;f-0O(is*1phj~8(rxD`l zST&lfpM)d~s56`k;_%e&s8&vc>n-&6Btmpa!4(r%zsB=;hvgbBb)NV{gNHy&c)>hA zbGb&@az1Y7_^joQ%9#jx38A|cp)L!s00cI-BJ>cU;R5TjP#>Cu&`^ODAcPxAl-Fhv zjXpwL3_>)8G8%owzD0cIN)1;;(P9&E1sk@QHa|TI=OEM@T)3ZBR$qb*A$&yi3qrI% zu`)3^%iub}2_IuAo-EBq? zS72Ka5@U-in9XWo`6FEdLRc6GokB=VS9y&-?;wP*O%S`ff;~ZKpulX_>SGfSl1f2H ztheeqeR+cr5*b5CEbj?IVvaWJg-y1_$ru4K*-?bVWR*AQ*&u|3=5ahi{V>7!@DvAd zhmDxU3g@;-d;$>S6gM~VWd~hUTlB{c-8XLG<5M-zxXr-1+jy(EWN+&5f;ryOAkyT@i%?A5Gi|*G+JA zcz=~riXTteriuB)gFOn44tDGrq}&Nd`EW90rxZ#lQ3G6)9paFPpCd=W(IAMQlkA40 zJ%t^HD_IeoMks|E-D+n=nZ4~)lEFD^qgMV#PB?_GAwE)4=sjE}oGTnI3aIu^I9hPxlnve|RwRz$QaD@0 zaePvwoeGB9E)KTUe*M)PJ6Aai4kOdeQJIO5o$!g<2ZY4*R89W_`gKC1@+(}Aib`+6 ziOY;8uI54UqF7xxy!#yF;}2`Nt$_WI0lmZOc?ahXhg)F>HD~v`_z;QN!~)+6M}6gl zj~oi%C?)!ePsExXGK?DuM-zn(*{PLV;C%S>FicM zL&%9Q@9fBRI3ku=S-1=EgBwwi`3T&g3RfvzUlcaFvOk;y?J`AjIv*dcG0g^`E1Z!` zCNsvnCO(R5&4=5lI9W!;_~4q}6OLAfI7M6Fs1tCA`v6Dl5;q3})tp17*fe2DC_*#& zvZETswoKmPn1*|ZI9fwEBk;6V|0th%OrscjlrKZv{G;L)!2N)io%|>tpQTaMJjQ2c zX*iE#Vm5KL@NhJ7ICh4qm3icZXS2##sF*L;I4T^o__E^~uI_QMmEvbN{%~~RL%YV? zsU(9Y<72sUxL!gBl9t=4{?Hp*_4nYqh*5{tT#FOpdJ=Dg0#5K{Cp6r8K(SM_X>P-H zLI!jZ3$Svw*eT(Dm2-yE2!+vdoC;?zx=^*^_iR4?q(=D^5S0u7>Xd$UQ{fXOha;<>T6q`_&v|%&{Xm>AKkCSJJuQ}n zImGE54M$~RtkCNNQXGcZ#ZCo7(~D~G30a3TeAyX|V$vDj;jBiv=?sm2!T?9^9zxP6 zU_aD3E6x%6jlu`QRg92g_E|puoQC@YkhTo&q0ruPI2tw_`p9m5PWo_|ca2ah#+>8h zb2Qw%f572t?i?ItM-!K;IkO!7sACQkeRKHuTn)DrkoqLvrIqIJWq<>7#kSyZ?T3qh zE+2nh!(9aIhLmV7rciNSKgx7R*aNN?;;=5^X2VfeuoQFE+;KP>8u9omgX$I7b~2DoeG9#88d?#Pf1az1FrlZ2_4mn zae2JMB@K5pPd~mil^@~6k)czo^(Fn9qfeCr;l!Dsj&6e!8=QU8PJW5cysS~wxXhPb z)^LL^>-&k>QOvo_$6wKK#{q@If=>!ZQ{bpu!cZujuka36HOh!9$j6tvJ1R1-@R?UN ziVs)#GVr!nXMgyDqLJtO6{X(Qx9h4I6 zZ^>j4fJ&K6CdXU<`VXI~v48X_daAJwsfof&V z2gpWWF>^i$4HSxV#ewk$oR{dZnd?8qt*7A7UZp=A9$B0ml?M?TF66d+RPiY}(kH<6 zuE_laZm8ZVg9@p}gno|7O+pBDEAJtMrx~=O#bfabjUM7Nv`{!9EtiUr*lIdlp2Lal zp&QlCPsA%C^1w}j8!6T{*-lkqXnQn&T9FNfgu#s#6XKF_0Zwc(y2zP6(>H@o&tKrg z%4z+rgp-B_`AXo#&L!Q%RrR^P6wHEhE}WgPN3s#>C)9;*aaCW48x2PtoGaXLu^j`| z%58A{gakE=Evs1zJMU-&Q z$sL62E+nLJ_y|XR#j3`&#Qr5+L1^&jAS9;3uqw~N;mg~8j-1geeZe&No^av-(}}qo zj>dK<_1U8B(`A*oH$Z6!cQt3waE63*jkhVmjE|LEE8+_E}S^th*NZV z%a^^-a0}mxM*{BWapQ6FEgxT`QT%+%XBKHVr+4C3s7V(aZZaGV999P!m<}g43HJ#K zP8>^y~& z);ad1!)IDHbVD!;AspBPoQx5`=M$*9&X?M;zVfB}%=X{JRiqLIJQ$Al4sL9_ zs!evl(Q2uT9Ju{(ZO6Y~%&7of0deJYSDVuPYKj3Ikg^$4$zm)UwCHU&5oX;%L zaPP{+r6qo_>GDH7&2fu{tJL%#eEbKE@+KfYkNx1tng0||39PmLYLh{5_9(Ucw?=}W(*gltW)I z%RKR>`N0kpUWRG};)^$>_mk8gO0U0CYL`}s6_uJYN%$=@F(9J?L-D2p!|mLyH>FR+n_h`{6Q7AUy$qGo&7v$6 zNTyi4NGU@K-o)qPO)pa7^U2`#@08Ll5>kmu4PGL7L#1>}>Awu7*HTdgrHYr~E$213poai^raB;5_A*Iy~6-y_6|N`5ciO1yuUI4SW%G^NzyBN9l5(u)Ts;D+2{GdKphMGdn2>!E*i|#KX{x#u$ z+f&0DNEQD_Mg0`lP)a~b!AAH&85>L7P>DB{(pgIJq}0=vP&#!TB~D5sqLKW6P&&IQ z&P7TfFaF$g)1e#M&j$B^diMSooqdRQURNw9CWAT_dw}I zY7V8}pQVCxCA|QpjdTr4BX&pP_ay!VN>lOzN-smD`d)%7>CkzH0Ht{^B_yScpCnI8 z!O!?n8>&JpszPf+X|CHq>73{Wtp)81rJj30@lQ4gKPdlTGLlk9y~)%17Xp$}!ckJf z|Bh16e5CxORNffLlTye0pp-5UDqNH&Ab@`|Eq+kTBFX%VQbAEtx)>-G5DO(9C-JG0 zp9ZBDDOH#VZ2(;brKmOZLsY(bxv7rI+5|>rZI7AGZsO5&#! zSOe7%aT$QtPoWg?zovEmqQd%YZGCxtwyVBe^}qW=Sde9C5lwD6lqOeB=D$!{xK*Td zhDvi#RpS3nDP1)q;XYUh2&Y^FDI+O0q%o8dHj%iY5^pNSTT1by)UdWtI;1*7jh2PT z>(jX}>n5clrJy~2(30yeaZ;+am*oGQQh9Dt{sB_@f1`Bn;Ob$JkP7gS{9h?W4aN^j zHv~!z8zH49r6bT!^8dAp_5c6KAXe;;3a9}AP+GO)q12FxQpJW^13V7A4s?MOU!lU8 z^H&l7n(%+f>nd7;3aF07QbnX@@TrpjA5z`_bOl2B)Q6q;L6^(JP`aTw25nA{r4K0< zFH(wlCV5ht+ZRxp>mrH&JEe5Rl#hip!m%~25ss~Y{vn(zZ=|9~Da%_)-%0vjiYKM` z5-2t0qvStH@qeY1{<9QMO2KcEhl)?1r2tgmpHRy1T}nVo{D;JUN}QC|H~rB(dKoI^ zHGNaf5!DQ}`9G7vxLDmhGwHdMOV(n_3^R#mj*|4ONv$x^(b5|5R* zfi@5-PCx_=z;r1Ashn9?!jVk}2`^zorQ}N`PD=e}P#X9RP>SCu#gkI~np;Cr&iIY;gpOVU{TX_AI(qUT}@swW$rF>PS^g4aOP$?n(kx$ZUPlqz}xr6-qnPhybOm@p_I`M zN)2*=((A93%5_9MsgtD6l4_t-e$Pr6e=4vK0RGA7Z+lXPfzamA2q^W0{-`Lu43!!% zS&EO7;tiGJr%IfZ%AF>8Qo39u>m-m2rHWD{Pf9&sB>BHmYB(?DTP~$DRBFHqa2mNS zP-?(dNw-Pqttmhe+a*9so?i6z1HGxBzrTW@tx6-4h&R0w@un%8i8s9rmD0_kPkShk zOtE;83Udr4J{NC#krJOz2CsjolMtD~P|pf{^|F6~y0PLC{wZ z^dhDEqD1K5UqN6H=r;H7uOR;I_ZokH1tI(UD~P}RYJ%?4|NaW%|It?xe}4r*%jxg0 zAZpB$pCx)HBD?4>z$l<|j zx&-!rm^_F63skx6M~xrQ$}FRm+>-^hmYXn(*7E*xj%iy1m{|ej5va<{tpIWeBv=8M zuv`MMZ4k0<15ks-wE?hd3vi!+DQnXfAfLd3wg9zR0fCfu0M6|I>aw}*0PNZWydhAZ z*|!HMBCxhSfH^BBu)-R^!y2F=TWJl@w*x>q0So5d0pJ^f-5mg$uu=l49RYkg0$8%N zjsRYr08BaoG-uwO08};rSp-@#&ITZzK!^=MYnDMEs55{?XMi?L+Zn*D3qT%$cFepB zKn{U~E&$dnmq2V+0PC&*9a&sg04rO7`vh!Q8(V;U0t;*by08KQDct~^y8+m;x!nNp zH-j-A1k?J-{~tyX^s7SSf*2 z2LK-j09Tgg0N~{aVB!eSlX*J=sGI<@2)HrM2_T(7h!a2`mO&uM8Nk9Bz@2HG0n9W2 zc?9}1a}7WafdmbJ2g@Z8>jGfy0x*chxd2#o2e?mQ2y4?FAfLd3?f}DB0f7`(0B2W# z5p1q2fL#xOHv~MHeGmL7BCxgxfHx~9u%ah`M^AuX*vg&&eR~0v6Yyc~y#T%u*xd_Y zEGs3D>IUHB2H?xm+yK0K1DNy%@Mqq=0aSeevIqn+t`9&ufsj4`6Icd;puPYWeF3yg z+ZVvh9UzauBxddokV7EB9Uz3|0?0#|Wj{z5i-RyL+DG^MAv%J!q3-1qSb*V_N3j9| zDFXnU2LQydxdQ;~JOJJhn8NHm0E!5#^#F)t#ROIi1n?LLFqN$w2+(&BKskW~<~|7E z8-d+}0CcRBK0wyx>F%r}XK5{eNudd5(H=D3p`_*sv#8X?^4Lzc3zv!3RXJ#2cedExt z$LNUrIrp#2g4)XVo{~G;U!L>wu7zE=vFDMAJy+Ro?s$I_{g?JQ)K&D~CTurs-NAMb zlh=Icl54!j~?Q)&ZyfHx~jq-I1dso8RFwus$s!9MtqC2J{HoaCU@s?a9q`Y_ ze;L0l{E*$O%jL^^f7N!s=(+Xq0ieEM!oHnQaV`KMD*1gZoZ{@7?zdtG_YtfNEEwVOiR)&`Jp0f6p<0bymFSnjr z@4uSm-_@(@>jl^Op~~M+@AJ4xDjcX(#4xW1_kSXxsA#pIIBe)uZ2_ zk>kIwNkn1vTXOoBaanqseK-1@TqJujWoz2ub3WJSA6oQAapR*++I4R$*QaUrj~>?i z5}fBf=8fm$h7DfK2+8?=cXJc3K=rCsw+_GfJU}SdSSWX&zEG&~k*Z^lcusFwJ3!ZE zdBc^j$A;_jp4gu{Y}a|;$Yoz03s(7!$*WprTb~Q#*3Yf$^Y(nz4ed5qH_c0xb$MEO zoW-mLdGn-^NJL@#4GUgcR+9B@@^)9%bVzPd`EFF8A7`M9?OHdqgu_qAylXKS%N@?^D`)rl8Z zoO2bLC*GhQGH9N$^RyUFqQvxiF!qxG&DuWk+BZ2ub5?50=hkw%lgKbqrK=#;#{ zy0iH~Q=cmnZBAue`(xHm7aOi;L$iH-lT|yq88d5tx!Hg%LGNeh?%F=LYC)Zk*Dp45 z7_#7Fy!G;p4{Cgg8f+IPsnL*^f99WR zb&)LyK(BMUboo+anRaDc<*Yw8JIGsCN=oilusO!WSDx3$r00Ft!IjTfuKeq7Kdw}- z_HJbdo8>EepIH1}f&lIlIK$e|P^J@j<_mC++4unjX#tk`0pzkm z0%j8d-24G9uqFNgIRriv$YZVn0I`z*wgv!PW+eoyf&oSZ0$gPq0|D|0D8~a_XTH>z zln?+P0ykOOcmTUl0Fwy-x0&|@fFc4}1PT}z1h66uAS4LjF3TX$Hypr13vi!lwE*7; zd8!3qcjMFTj8 z02H&iApmAE0B;DqV)mf`IRw^*0=!|x1Y#!xc!UAGV=Kb|tfl~z6DVQs;Q;vrc83Fe zWTgaBVgY<206w#{2mre{0Fy|7ugp6Vpol;gfl|gr0j!7z2#EstlVuR-I~Bkp8laqM zqXE7V$RqHRna2R6P6J4Yk@r`~&-nFQ4HoyP2`OnS_o-m+lj|)~8TQvNjdhdA4uXBB` zRrl-{vhoDE8M}{i6-qg4I|VhRPe)A)rhrtIvpYnBbRf>LAe@}div=-D1bIWGs+>8* zf#eWb8wX+{XD^AwCV_awgVd0-Rq-HJGeF9Tn95ndsUZ0v9<4jMwpkitJvE$tEgRS{ zaCh^iuE`#<=k+J{wn%-RI!jhJNSkQ=^|yg9F5g<(WM^c9K>@oR9&9t(doISUvVE17 z4-7V7Z87Sb*BR~ zWWLh@`pyP8L%@QW>HxkGh|vKwVc7&y=K!=!1h8Zgi2z+xgmkM3JZyGTy==Q={X4f8h9G~-0v+mEhG?Qtm z+Dr65R@Q$E(cEyZ^J>mM(7jpPMY-!ftkYRFfB9)o?_A?gyEpiqnbf^q=dOdpemim9 zX?qj%Nkxkfw(Iii1XG8MxH_{QN85eh)&qZ&^Z5!^o`Umk$(x=(EM7dCaQ<+|ey@L7 z_}iVK6WeTHQ}_4F^}AWaUVCGlZM8SXR&5^I=QMqLc)QQml=zs1Y|g^5@4L2+_3N1z zX3)HrtY8Luojw=C;5-w<(3;Ji2@o_7;0=K`%zhSt*{=X=X92Wh#RPH)cq9W@vz5sJ zvGW1S33O!cvjMCY0PLO(V8coYhVR2w;)|V9UHy0PGe4WD!s^ZZ1F( zfsnZX_ACQH?!ZjvK^&Qu#EE5-I5YEKAsQAz;=*!Cx--l95LXsQ(t}+k>B-tGfb?QX zByOyLq&Kr!2WI%__H=EAOS3iB#;%5jAu40ArshKk|0({qGk50AQRaV zl1Z$XB$&CbhJ>({B%!Q?B#gPQfrPV-BoVBXB$5qT3yETB5SFrqCUPC7DTaBkqlw%~ z6G>nSoKz({2FhyB#2pKms%02=I+S!bSic%O#MS3Shkn zAc@6o0`N)$xKCgvYqJ?ZwF6+mW`JZ?Kp>rf^A>r3?>UAWu{2{~qUE&qZ+aPzu9DWd zQ_=t=LXLn9?^1Y>%ja~KKqwtb!cjA zwB29_rLe*+7>K#74K|W|9!nzmmDz8F%x6nT7O-Lni`|X3cx*%C7O|Dv0Ic@NO$N9G zyl|W9Im{<}?2YliEUGOJsDAp}j7dA6OgdF_&%(AZIus_?Xnt$2?!(e*uVfqU-dJ8M zWu8mF8TFFm28KKJtMqkUHGt!j^mymjt)wb*-OWh)FnNu~cQwf<#X zO*{MdjRXs`|K^*du8ob#jM^-Kh8Jbwz-YXKHg#G zT${yP3Z_o4o@-H~OxObMh~surS7G6 z@8;jlaPdrft=#OZZtYn;Xp+x_HaYDJ7QedW_L^M-V>9KCmF ztesoSQRm`%#AU4PTbz1(rcd=Ebx_35p+!M=`_}c|x5~-<{j~Gh(_Yw?q}g=snX|HO z=Po^+Q<_}cIC4F+-iPM-x>eP=wRlpRXmmNe%;QIHZ_A=Pr~jxo>Y3&@|7k5dmvoCX zeR_ICou-|g%3}_>Ha+qpJ@NU{?K>XauGR32L)uLG0|xpF05fdfmL5MkZQN_=Id$?B z|IdBa$GeCAEZ9Es?#q~3eFuiBN*=}Ut>^A>#INPJb$%^_*Nj@db>auFKO#48+x>BM zdW((i^TbD9@%do|8WZ763I?hK(dS3?1k)R zb4m8FLXy4Aejj8XTSBs*6_XrbuKOVe*-Db%SqaG@=6(Qjm~A9E!b(Zf*^q;f43hI7jxuiu>zjqafP z!*WT^GRt(xITiF3k3R^;Q zl@*g*W3I;_*V#&v8?1!nCUeh%++rI^ZnIJdD>{oReU78b0+x0h{0@`<0lCY(N$#=z zB=;G20`h?Ql00M?B#)SBHl&bgNglIok|)gkB;+ZJAbG}eNuD#yQ;-)dj--fPB`IcY zPD5U@B$8LGfaEo^IRkma=90W+g(UBo{aMI+wuGdF6+>A5Wi;I592)+Stvm;ias{BA zz-Q*317LR*V0R9{S5``(h=5NnKq*Vh1z2$nz~nr@pUnF_K;P>CSp>=%cLCrVfshLT zKUoHW)EfX67jZKvSFni}aYgmI36e*|NWmK9fv9eQB;qLj{x!rG-u}d0IEWOgnWRO zESEq!0qX*Q)-0|7Am}l`eFAM*n>zqzPXHF&0cghx2;>lOz6)T@=H3N}eG2e~Ku2bO z55Vdfz}kBNHmsOHJ^_#W0A1M1`v57=0m=#3GWQ1nb}s;SKLAj(QUXN;d>#VWv$Tf* zD~bS29sxKq??(WAivh9-I5Vyg;2VLELI4+*K_K-dfOQg{yIkqNL6Tm^0~RVSG=5aQ zRs7zCjk7n6Khn>k(m}-NYP-fv&!_8U{L ze+VxP3*Td|W*)C_EB>R@&8kY}r&iYY<{WR4J|xU&7gu?a%xvj{YccWiy}31x+;8$O z%Bb6TpT&JXd|Y^9Otb569?V+ivtvS8XzT8d#g`2(6g`>gV>DOw8qJM)jP|>+Yy#;7 zT0Q~j!y=vl1ib;cNx+?1J_Rs)3y}O2pg+4xAcuhMGXM{k^b8>O9l$dJgP6^80IT-^ z%bo)aVTAo07xkT_)K5~b1ed}`v9=D2*8t-5GW!rq8PxNZ7c>@@ex4z z65tm$Ujd9|`w66e2B`ZQz?b>H2JrdQ8`WB>)kukU%~Gw+{eOY{>_Jlv1U@9B(8KCb^fI|clnEVUCHv)lQ0Ca3Wz_L^YhT|)I67&6v1YUB0GX!Qb z({BJO1whO7HHs1lPDgi9}4zPq3638duRt~_kCFKAql>t5zSjJp`0NAMjw*CNMtb{-j zfe}9eRnHKt2IC6~IBZLL(G)}u&WKQ zl><1!N(dAY7*PcvgKew=u%ZrtvMRt)Hl!**-?{*Y2xKvNHGppf0;>W1!S)kKtp`xo z1R$IFngDp!2RK9E6f><3pfUr9sSa?4WfMpz(6R==ITld^AjllxCV^aLSrfpl0YGw1 zfD7y@fgA$1rT}>?$rK>AA;2>Nmzhm10INm-%W45!WrYOt3Aoh;xXzZ;21v00_)Op? zbFBkl*BD@H9e~@cgg_C25p@9y*v7g5E1Cc(>jB(lL+SzaZ3=LRz%LV{1SVRMWpcVi(2^2HS zh5%+Q0g@X6ykb`gH3Eoj1@Mf(J7!}6VAUF6nFT-zDX9Ay@YZCywHUL|j0DNU71d0fZXbMouHZ}!V(H1~y3GgQyVhPZ<9l#+1GtzpDETS03Y zv3aDXM(iQTqKJ`dM-FrI(SYsygXHT79jq(R4?nfouM_yS>YT5z9AiDfp$IuLUoDT_-*i)io^l zY9&QUR=UM_r%PQYm~<}dZTZk-U%mCaUxv-lU0gIWHf&&-(XZR5=1srsaeijT)K$7~ z??2bxF{AiU%LkXww^%z!vE1P5T+guJVa;B+7kM1nom{WZz6C4$tbEyGYpskgN4nh2 z|51PJo$8gIhSYibPSNP|wEG)(RvYrWhgFxZX;pRKYQaZS&gqlE1nPQ8x|Zn zCi6@9T#v=U9Uok(KetYg&~eXe9?rB1xN^_yzORYQy0-7Nsw2C1Zqg=kUA|2N_o?k( zMMp%oYqGl8g{A3ZTqEf(`strL%?!(RiW@nkBy;)4dk@=Pep7Tf!O zSsVQN!ua{y&n}sp?)SMMs{WEkbC%8tYBF%H&8(cRk6WzSf9-X~P38UE@o!{Np_7tx z^K?DdOo}?#rq7gP1_kT?5*IBC;}sUy&Z#~Ywc${o(TAY5O^TViil?=brX=vEssC187-mbc3 z#b*YD2VB@Qe)isaHM9-YHymboG#ognW#5MPUaV`rHF}G?vtR6=Yqvf4Vf4P{@xs@i zdbXV(e%oe2;4Xs(H!>{P?{T+)=&J8d+gqgfOsQ!*cE)qxnpO^GHZe3cv(zA}Co^q(Ub7yR+)d7bfF4}adAwB2L*{!b6bUm5Z7^7Um;#z!@ucdFWn zw-)_2C8`#y+-A(GJHvne8(H9xg~|NwyPtA$*Sz>py4axLCi;S@+#@D)&UJ0E`^cU@ ztUmu9vSP>H-<#a4v|&L?=Yhr!ryGxb^?b^4o!jq=yXcB)8|@ug|M{K4TfBNso4n+} z>FYVKpT4R+(xBj`h6T?!xOw>XX)dw;t#l8X_BwOBn#JvL_t(pNZf@Op@NfCP1#QBr z99ffoys&KN0HX!x4xN%^ZtWQI`-zTMEt>w}+S$e6LnEDx{%o86W&GOs>L;JZg<X2H(mnEuQ3dV&-rAqXv&$b^W5} zo+qu}jTmas;AV#9=3RZ1KP;!twM8-6w+=TSR%WAAO|H9baQ$97`@uEZ9=L9^|HtmM ziN`G8WS(tl#h)>E@o3&6`0~$74p(BuwYfI9@SQ_O>Z)AsB3_~ zU(;>8cW3LZN|n)_UGK-ZHk&kNP12jRdEH#Ju~|jU2JCoraeZ9wZdH8X8$ZqRP}Lwov{vAV!PN@4e%5 zyyA!d-1l|I9zjINjl^DwEHO&N-my0!BnUyoEGn@|?S0hVRPDB6*DOWVs!f#+t7@y( zc;26DNJ`RvpXd4g{(JKBcCPE3&pGFFK4)C#oa@R7`(6(N?Cmr4;&7@={MzZj%t?Mx z_WgDaFLx+sIeP|IKaR1=tRidJr|N#Y#BVz%zGYHA?Ridnhj9Oj15dMwjGPPZNa_$` zuWNI?TY!j30a5ldMrw(bkPIxzx#}YMqn=va2lz#n5#8|1BWfkh{lMPCE?Q0!k*o&- zNe0a#Ie*+;q#kb#wRdoJl|NCGNs_OlC!cpv%z)_r12{muqfruB9_Qio@LYPSllC^X z&$3CX3nW#a$gX|k`yer+n|_dq{JO2nYGP(2rxW;PeOnr}E7qPNZ~yLw79tnlH#T-) z9H%%=sHz&wRtF8d%KsbPm*b-=Hff2z1>au z2T%(Cj&{dPN1(SP< zcR;1FyUZ4~T+gylQb0$0C%gUeH!7lry}BfwwP*hxdfGb=(|p8E>5Xze=xonmk2)rT zH*{-Wk0il`Cs07`Yj00bv0b-hawev#OqbpT2QYFqa*t#SGKi+P}{f7au)fKumOe!ylv*4RXz^o5(D6 ze02Z5v4f&r^!_C3KG)UtnNJ#Yu|&N+o3hcS+4PDL!yB6XqtS}@V_g$DPbCX6%l&Qk zEnPv6aomb`*Vq`pp8bvAS-bU8^@+8&a@E_5r11I7@fAxLo#X%g|NkuT|CI$~pzWNg zL}}xx_9Q^X*tO7v*Kdp;={BD+5-_0Yr^}_hmjNQXc<{598@ZQMxr4jvSt0~6_te>(ao=K)3z0IYWWXR7pGp?MT*V6Q}j$oD}!g@&o_>p6n`In#< zI@a`*vzMhnQs~~M-ySo;9QgIck6V|$rd&?0+nI9vOg}mFuD$6e2PlZVoCq0Z`W-ao za^u(CI&Slj=_yB7t~IA5-p!PW zIdATcnI%4J`uX4|CooDgJ7>mCD8$WnJjLYaP0zwye`rR&U`8&2-!Rkfk||ddzqTMh zmrcK7TsJl4u9$I)GzxI=ZoJ2)9;q)=ZD`E)9<#N=`E4V!c^1qjw$GmpM0?{)o|DJ zlOA#%%b+`PgXM`S69k^8BeJ%S&E2fJ*w?AP3}x zT;L8Ks-l}#FhQ0aRX|QJ?g{eHl4q1Wllnj$#6y3OlaE_KOK1!7Jd)>62j~b9&>6Zw zSCHpWG<1XR&;#V8j?X|IJsgdm;1bJ4Z;nRE6>&J*x;51?fD} zBV`9wHalgTFM@W|8AiY`kjIQXR^;zsl!ppX5h}q4P}$yr47dn|svvJ%t3wUQ0| z5t3j#?1nw?HSB{hkZ9T0W66ASx3eJFxPc2cj6|{yn&=%T3 zd*}ciAp)cWb%tqF=yaF?V__tW0y(gAD7-<&hGp#_hjzb$LHG}bA#!}FObz5zP&p|y z9^@$TyKoQIqmZ0p{v%w6pWp`k3>lEk2$>)=WPz+u9~weV$OXB<1M+|;L0raQ)x0Fs!T-XLXU?=PXIW1cr;6p(k z+QVTG41j^qT5ZnC+>d&8=?FVv7wmz3un{)F7Ld)FrMN3#AY#52>b4`uUbIXnx3cf0v{*@g`p@EOW?oaPzHRVER=@|P!TG@2T&P8 zp(=zyEvOB3pf1#d`p^IxLL&%=!B7z8SL4bQWCQLgls^M9v8uJ3|MtMwAhRktkUJ4Z z!Dtu*W8q^M2jk%rm{zSm<&^(D?~vzkU5uZf;-9?XZfaF>kl!A?5t3g!kj0(@P7^sdGIH?r z7?2aIk8*z;WKov{+hH*5Ms_oN0V`nqA;5rl*M{k6+P zx&m?r|7kN}Nqi(sfDsT)cqp!{LTW)d5|oujALt9Rn2;&5Oo<(Y$;5vb$XtIXG=}?S zNJJ*^7f9eT?1y;#`aulHwfq5`K?wI({c>x00%Xl6Ydl%g-G)0LOSF6NJIIpj50GV+ ztg0TV-Z`{9t_w(s&mVGYHJW82!B>Q&)bMle7sC?x15x>FBQkOS10KUukh%DCxB=H- z5OOld9_pe-xN9E&_nL*gCe`ck3)}*+`R6c!T*kv#aG`16!SBzisL0RUc8Upku>^Sl zN~H!sS@450Pz2;IWOgSry)cm9eUX{mUXa<{dXRUf@;Be+ zf_x4wZw}=-CeNcHzznaI-dgS4ydlxo@H<=pc_tl$Z{Y~+hkdXYz6NQrG6RvB$VylS zVpGO8CITJZ$b(l?}J+~^OzAr^W;By5?hjj3qTx16~!^6cJw+Q$^0q}s_;0bvkKX^f2$OlgFhJsKC z3PUj{3PDf`0-yx=Lvip0@h>3*OiBI1SUQ*H+7HS?2uK1FInZ>=;RZuxs00<^1Jez| ztqP$~4XQ&es0m^bu~dB!tJQ@@(2)FH%x%m!jky+~=Fk+xgmT{u+CXb)3+<7y5u?)DOf@u9w0RSPY9`Hq3&V zFat(`6hubwAu!lv817IQ4pPVwxF5ktNHj>$|6=SEZYIEJ_yoqoI4A`l!&n$&-b+0e zhsiJrCYs3obeIa$K$Keub6^3?hq<6&9()QiOK@4v#R|}L55wKg^)^U?Rj?JrN?*a3 z@C9sv&9DhJ!Uk9m>)>-(3!lLnSPf!wvE~l2!yeczW|JFHLfpgf4IG36&>wn1M-T-L zfwYUv&>JG514x&ZdY5?N&>32QRACdS4FjM7)PVXRvI$bcqi`0^z-c%M--9SL2#&*d z=Jg5OQy^jY;3C|FJ8&C*glljG&cg+`1n0nN=)1Yz1%xNO=P3~^LCZ3diTKIAKCg>A4F`Q+6sgXw@2|k1e zAZ7al?t|2ZBq+5eibxGv8Sds`Y-NZr0~SoMhv6^`2Ejn61GS(Y^0JRv76PFLxK-l604NE?K-qjW&x8_O z6$eR9#7lu6_(EwY0~JY5!YhCz7XrZ`vO!P|%0opEH6?42lf{n6R)=a3230|1WsQSd zPWPzEO>GzeRv9HjDTl0}J3t+-8{qcARU->)-svRUJ}zpIk5;{2f3D-9AH+dl=mWhW z7J5NXhynTBv^#WzXo!NY&;=q@qz~Hy@|Tnc!%&cGQAQLLSNuPOu`mWkgC|Pmfl*v1 zf>gF_{EUQ;K`OHdNQG*U6DGqXI8MBYxYFuA0lG$lUgP7rnE*zcF#eZ*GX=k?pkM|} z2T9CI$m(0tYX0kqIh%O1U?$7~QS_`#I3)5~Za#y>Aeznt@t6ICMX(SSz$a zgcYzHmcde31ILIf@#k_a)w~Nf!UpqxC+-f|u67sJiU&)HNAK?B0_u+TA2Y2BP+=g558~h5tz|U|KZop4) z9e#vsa22k=Ww-@>EdiyW6qJFo zAaNwT9M^#$=}3BFKr1~-%d(l+O6((Xg1LSs4-(5LV)4!(Mih&S@x+j#u^3QlOlnAs zE+q{DsWqt~sa2_6sYx-s7}!$IQdC~aNam5?1JaTz$b(#(iIhN^OeND5KS@A@q#a5V zl5ojHnwr(5-kq&W_o+hSnZcT^S4TdU`>#OyPB?C7XaNZ=`7gEUy6mBBfQc{xhJoxV z)rUGz8)`vKs0VeSAvA!YAiGe_pb3OSV`vH=!Vnk?gQP zN#lwEQEUNLqxI@L!13IRLZbL5FdoK%SZV}(1jFHD7z<+{0Y<|pxfltFAOV6q2}@-0 zTMtuVGE4$7`4kZUbs+w;VH#NBQgw@A5zK+$ z4+}vO`3zRW3Rn)3*isPrB_N4OrlPncz6|nFkX5)VVGT&SYoQ@XJJ~GtFQwT88^J1p z_z7|^gK8kI?4##|93XE-{ zY~(2yhhaZFfyeL&4#C%O9v;FUa36NV?{E)x!9myqJ3$n=gL@nH!7ca=uEMWy98SY8 z@H1RY;J=%29j?I@xD1!z9Q*)h;S8LDZ(%!F3h(7wl-L2HfG8(QS4WYQN{KR7fh0`i z4nV>;{AWcFPpd>CEcaF<@jn7$rIR3;9fj}V1bhclx?><=qL3i+;z}I3wiFiSutb8M zXlf-g1yYNo`-#$GN=a1eQ>sb)q(D+77a?VsbuINSvU2~m)c;lU#?n?wEhYHT^q0gX z;h(^=)(x&D6Dv`Xw=xtzOEF1H;!3-?i)&OeTka`^gN~htrAFyQ!4WAy_8bSCjNoA0U&Rg3V{!J zgSA#POB`8`_~O31=Cn+TPYqvQ+VQGL?JH0I;#LwR^AnAU9mPykp`UR=K zgSDl3GV$Eo>oMcXoz(?r+HDa5BExfAeOgXy6ree1OY&em-!D;B3oNY*Ai~Upkc@=f zS~DU0xpV2_?6$`ExT%r#wcM&qh?YU^XsYFut9+TxyJBx-gVL!cAzDLwjdW^Jh!)6k z1E)f?yc}e)uc4M#Im&Cn{9b=muD#^bDpBli?}PK({MPgs`39p{Ii_N&cX{HBQkRkA zH`14u*Mj&R^6ZVcTdDq#u#KuCcV7ERBO7V7{k-s_gxoU`@ICo1R9l_53`76S~or0sNSG#REKDqH(j4PIDdFEb`p?%%j zl4u1I#jv{wp%{q)nI7IPRomTRx2?g43236`rot;@tW*>VHsZ#sk(Du4eKlX4cy($z z&Pnw>cOjS2R8(8nH{i?I`&}22V-U6>$AdYH9J}-@QY9>N_6mfUR?C%B6{vz;HR7^- zNenN$e_7t62i%dM$4T5&bSY<8+%SPxeWFUUZf9F?x%TtL(ge&VX$X`%X{LQIs$I*g zmG{;}prT)(n708PNUYcPn~-LA>c6;0h(96Zx={U&dA+t^6$Z4#4LgQ2|1~X zR@E9AUCqP6*buMYe4=@%sqOA40?Ulxj%(r?l7 zvg#Pdkkmw$223`vNyfKgaSo4^*|rCWQ55Yv!- zly5b3>Zs~e(}L_?-fDO?&C_1mTZPTjayx=p>8Oo_a8TV%aqg)+)wM=mUfxFAoESB0 z^R7$Z{%E&JoiduZtXB!uN$-XF6gj7SA}Uq8=;NI=*1XEL%5EEBw(hcpmAwXid4MWc z17jG)NEax|K2!^9kc2rf=^@?A#T7MDI$x<&nGwfB=aLd7^FzU5gvjWyB6pqXReIHn zr)*}^8>f2Lq#|b_AZHivqK!6`sWIdynBEV@`J4J36a&(5otpH<1VU~hkOP5MKVM&0ck|+*cH3n$>Ab~^kP2-bq0x!UXW4Bp2*F5+rHZN0 zS~PNx;zr#}d$w}Pj{KS^5$H!VM~V>9|Nf;Zzivu;y-nAjF2@o~O{~QL`Ue6z5m-^` z+QfnNO4d(NKr{RGyF2~=l- z7}b&p+6& z0xM~?S>(P~Z;&gui1fsOFVEMv*J^QMJaT4FZeG@C_75Kv{d!qY$al#lh*XX0k-{A{ zza9??&7ro|(*ni4Q%@_^*Xm=P7$;;L4GO=tzD=<*()*;_;2Y1#AZ@Dj56k0E_1e(wY z%%nYUz4mJ`b>KHdH0^tZ5P3wEZgl&`h)rj|bHiB-BV+dBh@BEG8&cb@tUhQPVYz#=}bsL zLVm0i9@64rjlRht34}22BpxYpZOyh-M@J-wEF{E-kg_eVRy=jNI*-FZzXU_?Jp@U= zX}jglC!MnI9Ge{JnwinCWee*MX?;yT#7BZc(Jpi$XnBOiI40W-Jg}K`-OBn4*XUSbIX82CdMe0UmtAa zqa&lDV&dZp6;yfi7iu;UDH)jqly@`D-T6x;<4JsndY2Z|?B=Rov$||-Ww&+tKqW>n z#3mT7>!8Za<CK?>zMRKaa zot@Of1p3vys>&~1^K`DRYFNW}<657lmB&}bR??5K&915{EKzI7ad;cUiQo)VN5koe ziDBwB5$(~{lxJh6VjosBM$diKm0NfG&sJ9tn&LjFt`ZyLrmvwQ#J@xh71j;6QVn$i ze`k{##?0^hX9aKW4*vWvyG+Lj8HKCc7 zPc3Pxm9bx`p-#5ZJTqM(Ek>k7V%%$@MOgkBEPu7PEm6WdYPGGPw^0mrYl?s8R$Aa& z|6R3Iw+>pMN^GU&d@s-{!{8xu*Da3j7rFoDLT~I zqu_JH7BW^?Ia$^;Q*`dCW%R{-UwxZy*pa5Ml4BToc{-1fCfn$VyPmIn@!_Sm>yss} z*HQj0vFD$4RQ;C8+P~GxNWm!jTTg`ZwbI_V(>o@AE1y(P6===+N2{-5Ta%f4eYGT| zn`$QSwxRznZOsNMu1zXsNLhVvb!yd6g|)@pkqwP0l9yZaKgVoY&QnR6o|xNeq?RK6 z8mh|CG&yNM|AUrm){=7!8OS(3v}L#S(>vvul$-%2s@#U>Z9^47Q+6gHC_~+tU){WC zr_W(e7PKnHZb2?sddJM`M*PLJM>jYiv|U`Q7Q0b~+m$ zW(YE;N+FF^iwLchy;@^^V9rzxNqJ^0Xsnh+&=}Vm{u17#ljg08b*8hL!j`A=d=q1w zFYxJ=>qBThaf)6E+RANDsc!L-P(P-olvn-`m{K zt3<)d#!4wrrv1Gm2lSA0A;u4w(fnGKs29@7WNsbgQlW(kjA6MvF0}=b-l>cQQANhz z)E7iDFjsA9%rbHWhD=;`_4ahqXF)2{g?cU3i5Sf@q`4{4BxBa>_7N>IA|X>l7QP(` zk(F+py%B0y?$WG6(M$HCTza%r&Ylde1CYpq#L%vH<~y3smAwi{os1J(swPN;OhH1H z5Y?Nl9eFTcrdmkI!ifAA5F*P_IrCwS?)vT8mYzBI&k9#pWY1dAj=%w|s&uOPZW7+Uo*3Qst#I1{Un;stI zA%niY4tL>1%UB*Gv(!W!`-XOERV-6c;}%C&m=4sBQ(1enTuasV`i6=wnwJyo+xKRV zp>+o}t+(bG7}>!n?a6ZPE!tjrlHT1GT194sfi61o+p0~{Hsoa4ChMd?7ghfw z&8gh_XgR$N58f!7XXsQp6+AAWR?eOnhLxnBzq%f-xvLWiY@6=w&$P_1ueQKGyQ4bZ zmzr4A(HN}%oa`~g{oBDG=rzH<1TQ>0&WXb$n-GwV6rWx0zcv1~>JkJhP@62NjQO;E zM@JQoV8|f^rB3H;ZLmB;`Gd@?r-(!6rq-omVI}GIxA_W zU8X^uR9Jr|DwX23e9lyM?WFc7;WwRBTs&5E>uhx7f(z}}gL8iQn{J%I^7LeV%gkLR z#cLJqr#h-f@nm}-(lFTmgz%sG{@<>NcvYTGO9$nsp}`KkKh0hK%JK59zsOd)93^ za(uRPW@MIo)69^%_r6@-;m+zXLZm;wP1e&n9|^Il)+z7fv)R{G(c`9+@Jcle-AtWS zu7TQoV+oa)Kdqz9vR8>v5rZ^u`-bi+ageCmU6mN8MW)v`tD?Io=U_ZD_fSm+)Aow> zFjx3*?mfzs?`Tm6BTk^6cXdK!N#1nc{rh1{PO-o&28MN4@M3N8cn%*khFU5K{M!G1d*`i?6Q` z`1i@$$r53N6d~@6kUj*l`Juzko<(?AKKXV z%kUo(lS8(}s9nT$o;4-L$ImZ*b$q?7$r9P))B{P~C(hVPi`iazO>ny2zdCG;D*-Zo z2bm$i%^C1$Y1L;tlS697sn8FJ+uD=}X?T3=(ivY4O_qouMEaP2^?99=(q-qsDJ#|C zacUBAol{MT@s4#pI_0RumX{^5EKco})W1T)oivW5Z=!17>b*Z%;#)Js^RK@GnjH;^ zP7b*mr?L$t?n6`J^5|~01Lj=Xmn`Ah&q%dY&Jsbki8q%fhve<2IuO_CYf8-g;9lXL zljn_3mZ;WGO_S7HB9R--7J2#aICHyeyJU%;gvdDEEc9e)XZ{?klS2~wscRBa4WPtGJ0Yr!l*Cifa`=fuJ2T6ofAS8g-wDNw(qauCz2Lz;-?`alu!2bHo zwB)`#l-M$cAIosNSpD#$#|e?mY|{OBs5(9z8_hsM#`2YO7Tt68?pzHCbEsQ9bk0ZG zkXF{yNZzN)a`?^ViGQ~loo%D_;4(g9%RxxxD;ZaNj}I-H9Fq2QN1gbH1)=jJl{gJ0 z-rszt`1(d}>5o(#yDh5x2+g0P+-3hsU9ZPpX5t8~fIavlwPXYnf(;+3S$(u23D)}K z>M9_{dF{xw4~ks94fe;QyDY1kjSZn_yh`@SlhpcVbk!X*Bm?jWT;3t_j^ z+!A*$uRnxSeVd?9dQzJmN)%)6k!>XJg@gPmsGq{MT>A9Fd3mJql$-xY&y&x;J(8P} zV@265yf;!sjHDr(HE4f2QmvDF_TR3Lq;m|YV${F_ZNyAx`>h0EGkpMGG0J$-jTrQK zP`ySk*w?q7XIn-ozfr_JfP`4}>c~Yw*F%P#M}qz%wO4eEQ4{_z^L-G!BB7DK|Ey2L zmX1-wiR;{l1g{hlpX?g_xaO^cF|sMD3%J}Gqc%zES;rc~^n!k~KPgyk7{jC`5kLs< zIub`l56tkg*x%QaLt2kjuO;#_u;rQeDo_- zKK+289nUC(bZE*jV}d#{nn`W;iOM;KwwrgN>N6I%=tR|o`;dwgjhMx6ANy`}u0|6a zOlFu3)8QKvA`|6{cgCy2GuC{U9MWx~S|o8tAR&G9VZHEcBL+(=-y0K^HyVb#L_!`?)lUC-U_tv;A0|uW zon#I(t>%1p`s}Dq$x}6>bfq!{Pct6d^QWn0W0|^b;9hb|dv(ZJ#u!O`spbBxmjKo zFR9Kk^pNU3RGIOZ#B+u*3pp3K^UdT(t!>G1nQL@LBK5h3o<^#34LyXp#s-O->RdyY zu=A`hfX=^GE1KbHjhY9O^YxBVFGaId=Nfuk<{JK=kb0_f4P7GDxrQDRJVT8ju5%mt z%T`(T8>a%wygc?YIsdaUYRf0GWiOvnxTn+CZ^qtuNcK2m`f=^r*9$)n++9(B=;@QY zR3HC(NY8#Md;-d*It|bzQhh+{Au(}k0dbv)=EF8?o|?B8Z5VVoIbWs_Cnfb%Cq{Z2 zsZK8R5GFSTCK5N*hrBMapM0e^o?7ab|6qyRjg#|r?Wbai>r8bTpvPr`vP4o(bz-JV zq&lh6Lw0|v?n~TMCpWr8Ewd)}{W5(`t~_;~Cu_#Er}88;TZV*8>N4aAExpY)>v*z6 z>o^sMg#GFg6*d{kr%Q}+qua%*TUz>7_{DCkV7`RQwp8tz#M)-`Qe*0Ju&w{|Op~@w z)yH#Pk4a0F-vZK_yHqWjo}6aLYGTM(^wapu12%^r%|Hy69x^N0ONfjx(~}Myh$$4n zzOt3u)un0*`q*DCRcj_|rJT-X#*^t?{oHK6%hdhJtTQGpQ*KivS0kqLC24z;cAo-| zzy9Guk&4M_uUMucrtl)hN;A`P)#NlWS1(oTNWocRxiO|+^U0etQ4?5 zdAYhi1sgO(A}4A0Z`iA4=NhBN8WQqgj##eT=99*7GmR&g3g=$>*-d#%#9~?`jL#7~ z)zGQDTRN&XPGuWm+H&O-4OT2yuczW}TCS$eVsYv}O$&ef$UU%J&6`GFG{1=Ybs7_@ zGs~5IItpDQJ6TS;PrP)a($-_GbI-vpQcy$%|~+Vqw*> zYlZ3~65k-nd=BLNmRJ3J>LkW7B|=j9 zJV~Y#<#~uuOeyL6pC`Rqr9x+7`k&Sqv*T7xkA+9NeJQ)+OnM~sduvquOdiFop7$bY z@4i-D;@)|6tr4Sl$pT&0&g#Pch8T}0u*;FpRrOhvsm3~^)N^Nr9Xz|OjVEcAGd59- zsw!3FEE4j7^ILC7M(+1HRA+A9r%1}?8M%|zH7eC^x~XkCm@D$f>s6WA=xI#0au-CC zbsLN}d2xKP*P-pl%VwRJjF7z>)P~vG346xPYQ!9xhgrcK^Lw0Id*GHiiqWI$7UPM1 z@6Rq*JLSqC3l0n}YJEqDROsC--gz^RDk?KKDLo<6zEI&RIYmmkK(YBh;mf2WO3P$3 zb5i%_YWe=B?a0$;@z!U3&NH;z%w%3RdxkCrr+;xrFBTuP@TtDp70h<~FD=}fl3K%# z(MhfEemtEA$it010%N~;eDwPs-N{2%R20zcX7&=x)s%Vv+G(em9n>5m?ADNBc6Ynk z%hZC??9X+W&)a0P8VnnjRr}^^<&78K9t8vWR3D3r(ck~v&l*JE8O~%#7%qdW>8~~{ zp!@$*D6e|8fF5h5U=HbaW4L=8Q*=*UNNN9bfXrYGkg7!kUTcTQryYUL;PNikVag=} zR(|hwYoP2DG6t}%t@>8b@@OoT)W{IcBb~lH(ZA#La8PLdb1?Vx`iD-&SDtCU?Pr5L z<&?wxcJqJxmA}3cFkkumZ{+(ec?dRsap0?6jxO`iTDky=og_pa?FTmuuAb9Ylck`1 zw5PIt#-#Jlg<2u|!0pPpNb_``xZT(yyKp{!!}h0TIx%o>RUO zEm=w0^R}zAxFPS4ApU+s{D$z%`unh6D-x3Kh^oAbG)^B;apGP% zqQX|A-<>0B&njH>y&(Q!->NLDQ-qsxDt@&-u+h>R*-IZ+SBUEjK5m$PoL}K4w+?5r z*=<#1qC*Xa9anB^ka)j4RFUlz8Zg};+Xm{k!y5MB%YSF6eIUxM)wR|?_tg{9pK!s) z)r>WmFC2-SG^4{GZRzHmw05@LRvn)#_?TIVasFDvBWlZcs@P}RIr_z`&(Kx-UNu~+ zCE8{teYaNYWlQB_Yke5NLNitKb$sd>aN6i|7rSO#H~K`EFO%C-rPFHHItIfhD&u-4 zZe~Yz_B(6zfsx(*{%yG1!?k)J(1$;>jCKk!i7xLC$k_#e#`?61p1u2$5?1V)|x#)@dhP2$A_A z3Z6NyHf*F^*UzgX8>z-S=hc&qnz!>gF=PR;Y~PI!i=CNLjuvq$1~LHTcDd!hIR z{a0ZVSK{VCvhKku9^vuft<7AS&ThS+Mr@*A%V86qNYp&^vSQU^{U+!V`iSF6i0m9Z zNIcf0RIwNGe2_texIq`yapKzRT~tfH#%*?S&SsM8LIl}NJ{fY)7Je*u{p6$un<1A* z@ALFH@lZOtIUY^AsKSYBUvyDz+KRjSqAIfsck4y90DtEZV#-kYd(_XjpN${ZP>-o^ z=AFN&PD;%C7w7Cj@NWcV!zsIC(Tz@lPQ$)>GtO~Ib^exK6|#k1<#ov@?y_uiw-21W zGtAV4<`#5G#cm2gr_E}8NJ={kX*jgB-{L>~kd#R>%Z=YIsVrY2`RbB-iT?I% zmsJ?|A^9&GwX){Xka2B3^^py9S)f$p7i0*Ls*ejB{`ua753-rLR^azOFRLjMHwp=9 znrH3|zHl>NI!k4E6ljAIR|W8GQYOfd>Fd7 zURG{jq2Zy+D)u<;JIzUj?c}w#&lR;!gpBIQ%iprQF1KboF+aVxQ)zzEY*JKOK0Ea> zTs+@tTUH#S!Px6xQ?HS7etykZN&Mj4d!_l82UqAN(Wl(+wE#I)H?XiY^tO3|dxaqRhZVg63$J)PCZ+ zT7+asxu1-o`A*~p*D3>6{g7M{p@c}^&wS&9I}K(|&uSKoNkHSD)IH+bjb@nJmDbbg zC*{4Jj4RW=B;)i8rXMdn`qyR28B-yBkdTVeT~pP!_Xn=4T@r2%3Pvqjoyu(JA!(QV z5Y0ujZL_Y!BcIr2XH9Jbg5Mo&Qcd_@bF~7k#$$E6xBe?Hs0ZJmx;6M%gVE>LRA&aG zv<3|P@D;={{SJtk#&q4$^+#+QY2(x8=EiQTZPw z+$ya1UJ5Ymj;g#jMI_7oW?`)%(9BbvlQ=1Kc}Ltbogtpvm0H5;dk>R=S;Ua8W+Tsh z@yYBqTQm1F+Zsdpl3)lZg*2Z?MI$?8CcW%Qxa8k+6qbJT7H;po@hU!iAYfF9mtggCyh*{~oYFlc)>u(h&t#H%dnZ}e7 zl_xwZR(d@m>43CZH&#>o@eD`%)#ROiTh10wq-&G5aF)-#uLZ&=^bA3wQsa8m) zUgk5||FJrGjOt0cq#Va_&1bW-7BSq2ac0%h7EOW_`?^*PW9ri|WFZnV@mq4VyW8(O z9BiQIxni%?X2|P~Q(NCXU0YrP%c>wqZzuY!J9+p??Rl*Fd}j4gNk~l>!{8pSZS#lcA5E21^a}{_ zlW#{;eTkvJ>~Bp*(r4R^^BG$4t7nJwjEEItz1|2<_4S6nSWn{xFa14=RQ0xbJ9yo| zP1od?ROL6n0?N6l6N+uqSyS0vFg|kO%a43>HK+An#D4|llXd?5PmAnnG;=jOU2Ng% z<=aF^E<%3W@Zt2-%uH5mM?ae zm?1$kx(?m9a0!pInfOTSdH*Y7swPO@;jH^xd7t53l)lBQ|JLwf)%=VW6q0sghhG}2 zmb)KBMt&O@F7H2N6N%yS@=LXg#O(ZWy>n;SJ~a}RcP8&D?PhEC%2+(`O-AThZCzU5 zD5~W@XceoDe`Az6W8cc(+-W**Cwn@43?tihtu$lSv>{q$do}sAkDH8D`UAK`1_vFE z1A{U-l-D_}CBKx}@0?Z;XF870Z)`NnYU6UtVJljH?w$7$_tLIM=4qMjjeGF5*Xopr zT`psE=OYugygbmP>8iWj%cyyCz^E9vsCt*5svPI_L?!KnJFZ5kdL2|fc2k3#OUD>5 zKL46i_k$b6f?9b1wMAeL(-NdKvfr?Y=U8)-=`kyyoL}ajQ|1 zF%`-kw++emT6I3J`TM-sLXZSOdBbjp^Nc;DE?3vC*OI zh0`F0nL(+=)Euzze=T*5z0LLnu#p5?#AHw26n(n#PxqWhYWOQx(5-^e~u z@qJ^W3hkRtA06GLf0UFrMb)M7^$k=3A3KVKyc6#q8KsE%4}UXm zg?HkW_k8Dypq`Y$P@se{#i{?!K3 z%2L(A3iwwWyltcJ72$1&8Q=e%5*QsrT7QbD$)0AcciT#e?(|+Xqd^;O#V^&|(CNKc zqNfoj_?~Q=1n%3MkLEj(n=nI!6)pB%7nUDw)~g!Q{_Yp12GC*4%Bus^6zv=X=R_ zz}X&aMO5c34%eg}nH`g~q>${6E1E>9l$0}qc6Ot1 z8JjvP^4dH{ZbuOpBoIx|ewXzJ)| zCf3Z6IqBD?jx6a_#-$FgB#idLSM~FCR7?`)Z(KKSGCaBQC|67(=w|@ z*~qZzKr(3koL?G|cR)c&>&H8?g%+33VX#z~@rRDf^2fNN!+H$t9oeT_f4v^V27DM7 z-M_5*bUMdJMGkl5Qp-M~hB~bzgH2ds-p2WH@@){m79=HEm51 z58TuWs1;ipv15nW=)2vG`v92K|eS zba;r8h4t|4|4gG|3c()z9a&V^SVt~fvadtc8{_cSXj@6;4?7w=9DKzVpguX~s7GUn zyh>S~a-BKMm{+(o$?U4?9d{J*%9p!nj**3%A0NMS)oIVcr^+On0$(C9@wnsm{{jfP B2Gjrm delta 62480 zcmeFadz?46i-<{Cnd7oYG(fI|75y~PI!m4l!3B|Y42NkdvR)+tkpn`BIzaf7u zrwr~;1OB|ouV?nv`nexRUDX+NSL0zn2Mcl?+snSr)AtqOJ$tOnGD)zhqu z-0?S!3j}VV)oNg&Ex1}aKYmzlZf5Q<;?b3U!uZ@tXo0KC`{_HOtGsa;FLqgDOxjI8EQMv1uV+}+_|e(JGjc}cW=>&6 zNyD--az=UuoT30Vpf4*%-N>Dkku!Q+=A8TO={Cd~qY%bj{l5S_A@Dz*Er~n1bc40)eVji5)m+j=Q$4R+kvWMb{ z>DZb+#bM3IA3FLC+}7D2o=uiNL{|seQqHCM1QH2oVUMFBis%Wmb_!`s6)IH4riWX>sodh`o__fmL$fF4O~?#P$<7?BDKWB_@6c#_qU{@qu4=mXa;G_! z^Q#8^TIOBnClA_gO`FV0A2&R(v5#N;lFINtK8pPjpi^fV*iyBB8C-q#W2p9kQ0c=`3dy#SVd?LeQ$jGs&| z1A!;4J)!=X?6KLC0*wawZrfzbxdWCPCuNVz%bk!HU`xxEU$O@K>vb?(BG8hVN=ZvGENqyZH;%eou80ycH*|3&ambJUX zny8Inw*G>6_)7RxhQIXo!P1|EYrutYb$B#f1@3CO0jzW-t^MPTem#d^7Dj$SX713* z*<*$W?jGfjR32Q048ts^TTZlG9oCY)1lHd0D{c{gY59QVmn}bT`CiL2Esuvw1qKBQ z26=%%L8|3umal}h<}b4xu>5V7uYY8DSjI5i83>HV!4Bz%THZ3zZESXO!a2$FQSjCLzE|ontGccCvF|7WGai0eLnHV?4j}Kb@VX{9VGRF-Y zKRkQf$l^Eo2<8p+o~zN5O^6|@muQ{IK;&>Qmn0q6y*fmNsZ=}W>|0zp_a zJiV!3!LXs@bLvkG1ZLjsr$2OyKSQ3id>33R&?HbW$_gD|?qCI#VQ!}de~_^%T)n`b z>Zw$$o+stG2jXkx|2o4rhtKk7Xc}CB=!TZd!s^!_GkyLNE{FY=<&Cg*!WD2Ccs{I& zG6PosZi40TFQ`ZH?eT;B5i`ddu$Y1c*Spg$sr zOXk8>61^!$Z_?3~6rH&K4FA_kiB9C`imAEK?|5_pL??K3CHX6nn_F~AMVDxFX+~E} zbg4yGMs&$Vmu_@LMVD@LDMpucbV){6R9!|wGj7TfCWvlsg9&J;Gr3FZdFbx@{Gpp| zxxxMZ(2dEQqOC1(CANk(!E!}dGt1i}vsqwE{WbH~2bIhR{Cs(ot0{6FJVH~pBLU6* zWLUd$_Q-MLbJ)g5WRDwOfAWODbr0DoY?)ns{IHBk?8yIhcdti&&9Qwe{EB#pVi^Yl z9ag%(URpW7;lsY1nL8mTlj6&fycEfwKv(-O##X!TeZ;rVF7u}}H-|B!DQ4g*znMIK z)E_Y>V`RoCuk=9eNBt>#IjkixIVZcmZth>${IA1o()k6?640Kluho`i=JUlqGHtYc6I(kcB( zSe~>KDG=>go2SX|uDz^AesoSmA8K>6M~+^n>o`2rGzEtJV z)z7=rO4Z8Wy2-EB+3d&e#@0-nKz4b2nC0Ft`04suI}MhDQedTzK07qUmc!~<<~EaA zfB4Wqb!>GfBR6l{u+iC*%KNrkh1)6CIlaeni2USN(>K$gQ6_by7}7PWITGj1hrAx?8?lhmk;p+j>rSw7KMB++@{IfnR;sZ&mf+8hJ2GKY`It@Vbl zN84KN4L7b#gZzze`FEqi`~2uJ2mC#57p%U1{Ws$Yz)as2>RvpQHF!A+O9 zKv{A7{q)~cp5jlx>rb=oq|-!i3||KKI_NF={DKciSO#I;d;VT9*j7CGeSb+_bjUBL z69uclpV2RckHOlEKZ2!?g4ORXt)G)QGIQ!9*a@EP&#Jqy)sdDT`?`TI$DV;Mk7dDX&<(I= zStF&-Cs2)mdQ=+LEc(qh=v!DBs~`3CP1wq~5>`dG!s^+0SPfhDnP0(RY7_3#1aKzTU2Nk!ix-GQzOqYoF;u)UtZs^EI~5;)!JjlS}GycpK) z;ox3BzAo{y=N|X-eFdunJx}0&74*#szh&LN_A6{}8CU0KGV5WU>;r-KNv9sY0;}gw z!3ps2@xvzNu;*PyMe5LRRIK>VVcFcCyb7cD>3`i$@V|O^HwonW&%X6t8GTrM4_o>c z%ay1Ouy1`{e|F@aGcm(7dO}F~n(ZZ9!ML-Q4mO5;yd( zaJE=%<8H^-_OEqy#64T3e{8*j59jP3{mdY@N7bwiuT(7;azCx!zxIPQ3$Cs=J9FqS zo7&tNv+lCJX4(3Z-M+fM*{(wy29>$2`aK)kSH5cXf&33Pbgoe~#+_QL^@c;WI)^tT zUA^Fm&ZJ6)$qO7L|zm7igEZj%(}hGKz03mR6; zUDzTqxWsjurZ{>B+y*VqO=yxBjCXf8O$oMhon|S)b#7|2l+dn=+`?v&V0(8r(qh+1 zObNYF+)Yc21S`066H}bwu{?^CKgR7z{$;L{loC1=>!u||oC;1LkVaI{O=y}JoaF9K zN^y>(UFT^FTO`FYI-R||3qMbC=QdAq4xvO)ihHd|ah(<^;feV4T6cbn;%v2Ath@icq}Y;vg5vU;6z3tftX`z2 z-}{n+m%C|gBTj$ToJJ`|WjHIbQ^#+!_aFJ(S!wUMB%co;CAcI@GhQx*3gtm#!dMtUbm^WCz zVqI{z(~^C%192tYgh@%U7)t2%(fJU|7Q!f%xFQhf;T1yroPk&xPrvO;vD7c$I)c^G zOPSCt(W%ZMumx7g-M=v@7Q^o{3(Z-ErG&*@rmgb@mJ0DEk<+NMpUt0cqpcOv_y?bM zoh~WiqiD_C_$J9twJLr&Od!e`jHRYsB)}-f6IIXBb4c^A`7vsXj#LzF*-L&oz=b9Qt#PCS0_U`;&TE-I4ykneb`9)V=NYpLSiC{G# zF6=IBnG}nm9g3E>P7JPfot`PqX|(2ObhK4s=v+;=uxG@H)bdO8wl`-Emfc)hB!<4M z<)-zDgs?2q6X(jEIE@7w@h@J*Y$f<+8elOSia*lg`dH? zmXvHhpCtwBx^aCY&gJ#|9>;mxz;G-re1AK81WUQu6h$!3LBF0f|cyfZ;~8b@9yrO;(UXxdVN2oGDfm+cuHb; zkt}y_>*UaZ2JW5#5vTSw(G{$1a1@sBAkD0GSZXrOYr^PU8=uE}Zu&@%FCe}WI)eDP_^S@m0ptJ84gbvL3`9!G~+PU91 zE?0YUV}E@Aqr_WDtddnM+t-Ebe<^uF`|`1D6k5j&Nm62HXcKqOu!yq{(QmdEjMLP2 zCkqb;_G{`E4v#qZBKoTluY?XXb>lK4j>EvWr7&+xce-F{CWO7Ma|S`X3b?s!!NSWL z6lyqy)!%DG&&0%VheYCZ7j`BSYVD=ke?6(Nw2YY%-4jDSliawGk??v(t*skBGTHf& zkVZY=_8gcPN^I`#A^HK9ZYOsy(Z>j>ZQjNgx~he{CoAIgrI%e1{oBY%R@)%Y(nxor zwLQFM7(yC1mL*L;g4Oqe)woq4FzSM}1?z?jRz)1EdxxK|5bMSZ*4J3-46ecfO<485 zr5XDbmfY{>tA+>uRm%9HR(K0mS2uoi%UHIp&KI)u#Oj3Qc{jAWjhi+$5-Q%-ErdF@ zb@z;oIJ5ADKUC_|4uTij7Vgw85E$z29n~_HfL!V~5th-BL3xuHr(C*Wf`pN zqWQunv3j}b6I;gO#2!&OG{2);I3ePs&`^9q9qdP;)t%h9i4o@m#AwAyv2@Jun|6&6 z1U0#7MVrL%9;_B_eA8s7SZdU1`}-vYQ{BRxh;t8`U$#1V;DVLF&U-0c@rPamFbGRC z(C^zWEW3ZECB=3r+O+~KIl&vZ+Iz6%Xs!98SH_qLSs4u)HQxD5@U>TNZ2yq^eZTUt z)TTZ$Ke@xr#PT6KE87T1r4HTPv?-C$ zz1`fxDG}!wajl8-ZrV=G?!M*SR708F-L#t`&cldIS{4qsgYYLb{u!%dLGeFCJ{v!5|ATE{`c)(qFJgFE)Gwn0s7-nE=FL@6_thRzmE*qlr z5EdH?R>H)@(6{~FJ-2e!84x{XCES!$45PX3MWIIrxP|!<=Qx7zK2}w@!u9w<1&8|* zYT;G!1R)(sy+WPuv9uj9ML36~42%ww&JWYDR2I{uV`6wS78@?R^KXRIbB<0tU=4~c zHKt8?8kS$-^MvRfF8D?vzZlMM)d%}G0M6B%oo~Xru)~J740a2fN1Wdf?dp9tDfWiw z4VnXhGZ9N=`Mc+1SZch#1WsVJz;e8Ypc+H`X%Oq(G_r=cX|p5Y)rh_qJ|m>QajwWo zbS}R!5V+baNN1xiSh`1X8tk7Kei*B%yLWEOVncZm?Z(e(S!`G!FuE;}b@f86M@K_<8=IGI z9HGu$==lqwKQ4qij*Z6Nbs_ZLg;3>j(by3eLhA^1^xJYF)M9*8E4UDPoltu(UEG9d zsN03mq6?w-qM=ZQiSC{S5hrz`KjJ+6a7>tGElxDdtky@u zjyT<>L`&D2o`aJi9fS=AS2M zESv3ZSZSVH-y+mrb$I8s%Wn3&2U|qUPls`_Ag>_BE$0u!;@m?_;ZXE!Rc!XR$HQQaCXU-GV5X*bh6zVe9 zO?xB~etxd@)bvM^!wH4jT}cK5DsS&V?+fJS#mBNq_zwG)K;DXY_Z!G+r< z?<8(s;HIsKIL{zzjeEDM(6N2BbYXO(Eo!=ln(}4IjjMTk^e2{8OB7tzGKxWxmyF znScD{<~=Pjy!1YN=RM~iyw6Qr&wH2qDV%~hMzI~=j-`3Sj?Ibjc`P}a>B$l12Wxp} z%TR;mZs9W#Cu@0hi`QF(2e3M7Q*yo_l9SAWcZ+2y^@2oJ+z!{G676CqU+aQ9~?1s`+wJe?A|+HbD!;00LfnD^Y{e1j!N z;l#d4v1|M$v2)|m>#@{JZ&P+QSj+dvk63Mq<3!OfDfaQ`tkM8Z#Y!aV5^vjn>Tx%1 zYs86v!e1Eli+R%zE7hx%SB=g?SiL+;^Ev)Wzn6}8#%Y74l=PA}RE7T~?qw{$BMWiv z#cSEbNa-)HY^>fHW-^6nnaQY=kbZWKKeougQ)%OBp->wR}K zR7(;=>FeD+J0i~Q7eqavyo}}Fih54vrR;jQ@byTz@iUsh40dSJGj80@NND3TZraXB z_$TxvZxXcF;ExCszHef9k}U7RYaO8`?%p=Zq0ctBg}WloOV9d^_1}`mJ;z3Ip?N*5 zMbrBxI*(v!UU^Tz&hZPDP7$-74+I)}aXq&tI&WZU-jI*`c8QH{;hu=oabvWv3AZQ3 zVl*TL^P0QjIxI~=?>y>!fu(iq*He8{^vQYQl*G`$O>W$q5oaEvyhsIylZs(9b>~k@ zc1mxKy1HlQq*#m#jc^uX*-Ztf?!)pYueP6r7cQJ<(-Xskv3Q{4sc)&(z0q+##8P>T zDjRae7ya^Z8;^JcuoTA~e_K*4hQB*=Mh_i)(JkB;30?M*yJue{ocfXmBE5UEGmDTG zzrTmSDBZJk_&#$XPMdW7EpFWYh%;h~-)9yhZGHqx4rE2spLekuVd0Ow#8CKUH|{{h zY4q|1v0tJy4$Gf-2@fVZTd{oqtA_8$@J_@@-WuINbq0HAt6PY822t%~M@XkFuefpV zMx5MNE({pk#2PI1p4w^439R;>)f21!Ha|OY?<6{zSS`K6v`$uFHNe8Z9Gv$l&W-2v zReF20bhe66m+fxadl6>|qV>?gMCbbpmYh-d)#%Wu%28NKNsF-_u@-YHk{Bxfn!D%y zh%@xH3(m*g%dqU4WNUg0OEZPrDKD=s-Vsfi&^sv>!#21-r=A^d+Tlp(`5kWI;fV9I zO~|aBk;GpR$9)iSGGF%(y9`nuEy2<(_goSB;&pe=2a#~Oos{qH?V23Q*y*Ny7zr)i z=@xz%3GYYe@Sc+Fgm?L^!%NpC#bVfXL*FK0Y1^TxSdUtZ8O2U{5=*Y8Hav9IZr>-q zH4aOq;2|dO16clI+Mk&ei=mmsEMwBd?1?&EGosZVxA5bLGXYT!^6p8Yb$i^nPa@8z zi2ig|QyRSyO~U&GXFQhX2R-2J!c$oMT@|lMV&3%ga3AWP=phYo?{(9TG7@h^Ure#MLs|RWJx3#<=?C1n&mzwI2mJlb z_d}(3qC=g)sbC;hLvQn(N2o2el8WiQ7fbUAi&Vwm#q!=?wjpG@O!M=w{AsgrY+`t$ zpNhxKVh8>GmE8Dx1Xh2)EJo#JtgfC#OT%&Rc@H8f$>Hk>U8lbcc6JdO6iwk=`F_#X z7h?5_mK82}NbO2bPY$PgA##Uj5$f!f^9G?bFD>gmT>7w0>vSh%Tir1!7Q=6jj+}?F zI`~=mTi41TM4ifX3Qv;dxoQs~n}-gS`7qjC-7s>nbTjcc@=aKN6Ex{UA4MzH4WKnv zf4?i_TY_af_DQ1iHI`qB+~4qs){E9f7NHAWa-PA`;^KbCGyid{>-_S1CWg~LCZ+ct z?+HRZJY8%1H!KY^2O74vR-d?gzKJ+9KPkFyUdFNoF|9BA^un2(rd*HJ+H=A(LTVxt znH$KbSiCl5^coz!urczNJ>#(WYtr;&=W#-|RGjt)R$srdY?0S}7VWOwv>L0uA4j*o z!IHDRQ>>HpdDKmsJ%zH=n(#-2I(zN9@{8!-(a3c(vHD97eei`_csk-VJ?1Zb9!7cb zoPErV`ymo~^q8CWL&W)$~qx?3ZCZzJ+RP1C?D+#N&SHk`s{7Vrm-}U>uBq^c)R;AuI{>t_a zY2jg5yk=m^y-3K8RM*6C!YNOGCfUg*q~`J{$8Bv3R#VT?U!(tU%H7jC;xzlVsCe_Y z?w;Qx&S^x=8#YEdo%o%t4Nd;eEj-Wh46zMKIGrEmHPH7_zfe(V;rDLZACb_z z-@Ao>M4XzZeV5}_R_|miZSkB>x+aF6J?*Cb83~v8L0fP7pUF;lLRv1|nRvT28!HK` zj9%==@5WM<7X<==QXF>bEou@Qiu-YKVX#Ghb2K3Yl0gu(wA>2TRg@La{^DI?*(sn5 z=mUy_K|ohgj=>%Rl>SD`8Qxz%Vi54IqO8V_w7OUg%(k{z1&#qKa4gUzmOV}eS5Xd` zfbynaF0zORzdg5HhV)jNcr!R z$@OAw;hOIwYpg4?y&aXaXfJc zwDxoz04ji^ikI;qtV^tdI4XF27}n*nSzgRe@sE%+0-u87;47f(-?2uXjn=!wvQPP@ z$Eudi%e%y~*_6Cy{@|$r{aa6e1d9k>lx+3qN1%*nfEsuX=n_l+O$OKhIs5f{1*pLD zKs{0IYCw=5vWv;EtYDZQN?+XSMOnIouBbR0FIERGfwlQvY4t0$#i)X-tnlwxNow14 zVojxnuqwP3R#apC_zNq(sn!3=`4TQAK?hiqKh1J?SPkn1tAOjQ-Ot(sU~PLttes)) zk?ttZfv@B`yy?4Xfa1 zEI$itGQSARQ?FWmht=PNi)sG7O+Z&sR)z1N%Oi(iB{^)Yq!R!`enyC^GNJFEYnusYV!<`;XnxK36O zt7lzcN$Hlm!)j1}iGN`=Xn;*O5LN{@z|x0UJ;U-aSXU9w_a;#`5vq7Btc?2I=L+x~ zm_LC+{rC&3qWS3J1+elhwCVni6~D;FikRyKHzjTg&)+}dK7VW-A9oBrRihWuBXPON=1 zR+av5Sm_<&#c?*BSZlKstZlAh3{yjKmH8pA#t+TS+A=JwLswh--?1vHZ}T^?>HmAS zQ$q<=KvSFX?^sbuHeGXA4Qpl7i?wg2S^Ga`?^OC9W>f>aP=UBBtkLKOt0BE?#YMR! zdItLC@MIhRSI+;d@PFCP_gbdLO|>l)m&0CQ?f+S3{QoB_P#;`==pOq3tW(G%a1D4T ztb4i_P{dvdmNmBfur=0iTm9d$((Nam^1Wlz|0nFteFOyoRRPWMY-m z9agu)0|N&W7di99Z$W-XYcxcpaZ?Gl-R7inYbEZ?ZfU zR@5#0P{H{!{u`FVX4rK9V*0OwXW9s{65eKQvEpZ2TdWG_So{AqtL3`I-E9jj%931u zh>eZ^Pgo6JLVEF1%gb#3qO6Xl-%o_be1%OQR>qaq7OR14V5M6JE9x13DBT7bQ8ukE zw`*^smBk9a$PXod$?9U+TdXbC9dnPhi?Y(aVRf-={hp%Q|CZH@u>b05pN$YJ;eN~S zSpDxmu4q`$%!YfHa~R4OnIR?jb1uKx|I;CSN2msl=oS>Mo81*Kt?S03h1pb9^fzA9V; zZfEWGu<8#epcZw3b^RTy!0yD$1HEjzqO68rhb~Xv2&=*j%R_B?vGifqhW+)A=DqK4 z4y&MKpoDtwC@%W0AJem?|G$6dPyba=hDzo7J62;yda*vMf!Wp;%Ohie${7oEiDi$I z!Bv!%e}bpNW=$|y;-B~bp0oaW|L@QKf8PJw)$tXq)%DN&|Ki$AxQep&k$>L*|MUL; zpZEX&y#Hq}&<^p>`~UyX|6bsq_y4-@_!0`k|GfYI=l%cx zpWgp({H<}YZpch;7VHu%Zgw{d_A|Sh1>;TqL}9Lg$tUYg;0eH|Hdrl`yy!LPfKt6~gLP2=NhwN@hR=p+6rkHCrT9F%F;eG_ffN zV^a{SnavV5NvPBsp@zwBjgZwEVXuUmrhFTOa%~W%w?Vkd?3S=gLjAS~bxdAcgsE*2 zj!39y>a;_s-40=XJB0e?u!KVrTD3>G#>{PxFsD7jDG7~C^9~3}9T1jxKxk}ENH{Jb zy(2WNA?MO6Xw9cSR`I6=8Z;gidC+gk2Kq zrz51AymW-A=?F(8bTM_hA=K`MFuxl@x;ZT2kc3v<5xSeX-4W(=M>r*+r)k~;A*lz# z@*W7i%?Sy|C8YO6=wp`lL|D=j;k<-?CbbtoI`=|Y+Y4cUIVa()gu%TL2AVa!5mxs` zh`$bDuo-Y2LjUU!wn!LaoIVJ#eGta>LC7$hC2W#VsV~AXlie2~t1rS{37MvRKZJ7q z5T^G-7-@D(*d?KUe}rt4*B@bOe}p3vMw>bV5NZ!Vm_GnvtT~Jj9A_F`4~;i-Av5QC zqEB5<^hDEqAVShWgyjPfa?J?|$0ei>LYQop4nkNm2;sbhn@s9pgwBHz)(%Fbybe-y$N2@e`)G(zlXgt4O$R+!Ba zHc6;72H|0oJq96bOfbG{aAn={bw7W2Y3svtk~^Lru&&Rm#p>R){D!hATV8*1{Zo@m z-@Cp0OI7kFbx!{J&wF1vdi2))3EdkUyT_dvN$Ha^bj^wNoIrztKT7@quQCg7q1bX` zsb}yc>UqqpnZ!g{ZGw}bHD-Y5akF0ZgmI=oPnrzTTC-WS&LrFfJ!P^*Pn&I`_2zUA z^o%J#7204XLgx5HDmgfnN}e;-@(`BfAk5A~*l6}k=$wntbQ;2DGh-UUSqaA^yl5KT zjIeqV!s43|wwR+5`cFpaa0|j#b3$E-oq~`)9bubUIvrt?g!2+!HL15EWZi_Y_Ev-) z=A49bQxOK|BkVM5@)34Ph%Z3cZ3Yw|OwB{sBH<0=%s{9;4PopIguQ07ghLW4%|zH| zvS%X9xfx-vg#D)cEQF+65T?&Uc*pFPa9l$D+Yk<#yxS0#Oh-5(;eAtQHbUoH5$4ZE zIBX6}I4hym?Fb*5xwj*%&PO;U;fQH|2SWb>gynZ2d}2;Wh@F9uJ_q5bSvm({lZ5jU zJ~ydz5wd0?teuN+%$$=@ZWhAeLWHl(nnHwK65{6}oG=6CAxymuVGBa&WWdDT8SHCn z&qf)0C(5aSc|pn{l=S@HBGXQMx-a*K)kkXVykgIt)2Htl*!+}p_fM&p7S`+2D7M?= z6T#$|)Gj4Qo0ApuYjiqx=Fm4Ce+qO>9(P;0*BejoSY)bx7cisdQ|_GGscG+gYC0V- z74AYwx&vkUT_`^W%pNJnrPRM0bdu-9?PaS_~?ew4bbZC@x@TP_>`rT2Y$B>cV zOnooE^c~mtt@QS!U+NxNQFP(Q2Tk0swEhs~=6~Jy-FKU|FE)D7ww+JaAG2Y`{!a#% zI?-^% -s`(skK)D4@O3_I}B=4~a9ZoKSlm1&z#H*j0bskn8{eNXkevw6kS&kim! zN+k(LuVS}6IxA;VyX$sVzUYoe&uz@Xykgab>@r`DwF#kS;isrC{)r%2Y-H%Yo z%)K9>|GfyOBvdiYmm|a)gyqW-s+kiKHc3c-0HKCi`T#=K5`^;-YMRss5y~w^So6$rKOL)aprzHwF}9Fj10CBijkvxGVKBUE}A zp^?dc7$Ipn!d?lDP5DOL#@q1Q5$nY)Yi0F1GO_tMeWULQ3sRyIMmUs5Op%= zM4e5~C!kcbMwDiPPeNVH08v-7UX*T}wNN*cA?j{6i+Y%Zbx==}E$U^qiF%vzPeIq2 ziK0Gcx2UhF_B7PbglxH&D#G^x))Bg_iXNOMkcx%eD(c{|9rmD;#LKdYo$NhpkP9` zb@S#8J(8c?u=%%rO8l{}*Rc(&FS+uzN}ZSVs=D{Ft;ZfeS$av+l@CvQDQHEOiQ&EE@9Q z%hlV)w;OrpqUGb0emLtcy<^72ulFuoQvB%pzIB#8xPN^7N3*63T=(0?^QB)bIqRw3 zw}-~&eN=Y-AhY~=*77Npt6$NJUd7h;sgv7b)W-+6FKD!+PsW_gCPNegys=;dFMr>x!?c`IVlHwMdfUC{fT zuip86L!G%_UVFM~;Ku4he{0e1!>R4N4(NT!v8S(Dofp_t?dP|@ZFMaB;c4+ldOUbV z`K;kBE5sy>I2{^U?)la?yi&wb`6l%h+z`77H>`aHzsxY_By5r}cpJhjvt}DY)@FqG z?Fh5Yfb9t7UO?C);SS@x%23WR8KSvnv#8J{yavrP*`hnmHqm@jeg|0(y+qdOJIH#s z*)3tt7KHk*BP=v|uOlSAjBrGPYwGMoI4)uSPK3qgu!JRB5nAm+FlO#9%3flQik6z@ zyP;)fq3AwyLUg}rvj=$h?bq+w!ni-Nk2$) zwwR>{5&G{%I4@zVNqvumub360ZRVV4yXpBp^r~4Sdd&n6K|9O<(d%ZtXs2-wtD|qL zqlYPIx7myk++z|xfZj0KqBqSp(Oy&jL+C9tQMAwO7QJn%eFW_{d7=YmzvvxP=Lqz! znISr84vXG1jXs9nH*+D=`8}#U^)Xc*HqAdl|G+F1eP~XIJ~C}Sg^rk|qL0mK(I+PL zDDj`+Kv*(3fwXsUk&pAMR7uu1xaJ{~{!`*(_n|R|u89M<`*kzelKj9AU47cvJo~!XXLMPa~8xyCuvy zfl&Vk1kN-+AS8W_a702WQ|Cv7;}Yioh)~)bmaya`LaUz;%9^=9A$0x*;gp2(rui9! zvl5n{L8xd>NLYOeA^m5BN@nTL2>riBI4_}!N&N*O_B({NzaUgI=Ok>BF!(G&4YTGf zLe}>P@#hd~ngQn!%AH2oBH=2N@EgJ|36p>5*Gi7(9|52u;k}p{NfHF zjx>uGhVaHOm}fAXn>Io0v)E=;5Fy!|mazIPLZ1*qE3+bm(El7lI0hlb^o&7>{T1Ok z32jWU7{VqAnZ*#=ne`H~enTi7M(AKN!U*MlN7x~ulS#M;VV8u-7a^pYZ4#!QN2pmG zp^KSV9HI6f2nQvkn`*HLha}97Md)t!OPKQ~LQ@B!rqs_$25NbOJ2PKR()k+~8k}$gz!g#Y^!kjpSrk5j3G&3$oNGgGF zOhT?{R2t#9gvF&1CYz%YmRyX`p$x)JW?>nG&hZFmB;=VkWf9IwSXCC`W^-D?>Pry% zltY+qR+K~NUlJi)9wFcKERPU-DZ+CSW|&|FgiR7MDm_6*Ae63%FxzBQL@0L| z!VU>{n1m}3c1f6g1;SjjO~TYt2sJAq%rg@!A=JJc;h=>1rdnl$LlS0JM!4JTmoTR^ zLenY;3(brw2uWoSj!AG$qpAqUB`mIru-F`xu%s+PhiVAMEUbpmxg5e72}@0z>Ii2g ztg4Q1pE)gIb$Nt7H4v7Y6*Un0S3n3~iSVH5c_l(@MTF-htT4fv2%98i)C9J*@p-%&ZEoMang#I-V!q*^dH9fCEh^>Y2oP=#A z*brfpgv^ErubTA|vaUiX-3Vca$!LU7t~SCB2|G=~wFtW;OuiOjx7j9PY8`}{jS=23 z6B{Gcu8VL`!d_FY3Bn->vzs97Gy5gXsfWp&XCxdpZITeqN?4VI@S!;^Vf8f#eVQX2F)NxQ^lyj| zZh`QL>DdAywh_W}5{{Z+GQuVanaK#BoAna1u0<%_GSnq>EM$hZ4D~hT8l&ux@>R%O z)(T~pl*z47PK3;MDN~!E)Qq5<44Iq=O6{g72c?_}nd&JhhosC-LHRCZ4oI2P45evn zl+z(Ivo#7I9mFkCehisw+n^kmvbYV(nUMKR$`b9o9onM&5;BY0qI7N^iqGGD-3x<0 zJ^kxD;f9R{RlNI-d#gNN@!75?UYUEtyVYV>9(ZQU`wL!tZ)WiGxYeKB(cznx=T04b zYubuOer>s{%$dmx+9q}yROCS;`WyUu6e{*oe)l=EF5Z5&?at|~^Cx~*F}ZZpwy%z_ zIlR&>HK%3&S-ky@yU#bdef|&SzcLTr@Lc)ypQ=Arp?Hb=Hod-X!?-~W-*5h0b^i7% zR4)DMb5~Bwi+SSecS=98^y;Te-gf)h(`SF3^1>(A{?xJa*0EhCTrvFe#oY$nu;khK zyXx(1a^UBUTW{|2$E+*gowMzVvIVbh%`4Kp-$G_oXS%(*1&-L;8AqHCnF^^W{gY9q zr=t8BGJB-NwnV9)#`p$JUYZ76!Vw8ErcM_Pcq@eYT@b?Nu!M5_pD3nPSA^nbZdZg| z2>CZ8C%v(_Wb*g(ZfbF3rxh#LE}HnslZ$eaZvN!d{ChSJFMavy)}I95ZZTxgF9Ryv zd~nILU0Up!^~hK6H2dS#pFjAtLixL@7HPjeXb`=M-Td391*7UD{InGdnijqCVl-74?xE#I!-mVq0$zSQfF{gb|0lDqBmbCqYFI9%?M zOV;t1dZBV=d3tD8Sifm}u{k=t@EINVI{9vbM>x%+NI(kM|CB4hC0kY}6<8 zc_{o%Z9bf1s%3{hA(#2Re<(Iw@oLpLqkE|AMrs@r^6K4Kb#SPEIDED%HEtw%312qf zkE2bmbqft5dl~&VnEV&Rfh+s^?b1I?`l9c~kB5hD50xJ>#QTlk0*RAIz(4maxDPGf zYnFL(WGJ?L>l?jaR`$~5j2|z&8O2smz!Irg)RB4jum1v?Ar53eL(@Gk#tj>j znK6#Bzj}jda7*a%U}g3Bj*Sf`h86@(>j9ybDym^VMJ?OH7@2K%hT53|*+XBZXt|}h z`W2s>rT>tdadR=q29@}9WWp%{|!xwTmHZQYoN_ZyCZKmPPDMHq@(eI-lcw{Sl4m{m9JkMtf-IM>3YD5 z`aR3qp2DxHnr-!BO65Ofqx8?K8`-E8R%7$f7q7i*rPcJYfM)hrC?7`SkN0brDOOu$ z)2T15?7ysf)TYxfqDHJ{e_J5m>tKo%^~oR=s1CM4lLPdbAay7KlvaT2NvrAWKxM49 z)@pJ@6|1eYnm#>H-D*!+tu$Ki7zRk*i++PhpR&>yQgrD%M9QNt|J1bFGgi}gMn(|U zwZUroK38L_J!>_6->He!o`V(Cn7jpaZPdT;mv{wOZoRPCYL(FRTljL@i)d<0WiSs- z)8ZwoRUzEP=H;VFUU^l~(yg}DrmKe559oTuYWdYMn%jiiY~~th57{2SY7<_G)`hUH z*I-501mg+I8#}F5i||c0-5ywtz6#u8wKuG$X*k{c6=(u)TComceKAaK+iSJDgg*wl z-m+Rf!qIPz?6VrTrNE=MBX6VeCr}?Ovf2Tgt^wLGAaA^*Pm`&I*MQ+b*Sj`hL&9~) zTpd1WHLZ|dgs+6(v)Z+UdlT06zSXp9G=JowL$Kyh6QKDcP2W>ey-l@2XaY(69@Z>x z2F?)H6~xa zqn}&SZ#+L?-K9@1X-Vt1pP#har8cvE^LZ_rT%KUH6v8<`*JWt@3A6_Cf*M~ML0)JB z+>gSOx6c*P1nw9o%OrZoJhRywYIlnD)tnsb+B3*Hm3(KT}P{R!G4wXayob`*>^62Ixx_pMX!n zQSce~9DD(efiJ;vZ~}Y{PJ(a1Dex`$4(KD0wSc}j(-O4O7iV-6(4OBKv<2-!2cR!U z>Thi?<>8KdQ#pd=K}AprR0i7GtAc7kTY3$!08cLji-5jkbsgvfw39an$)Fmj4r&1H z=2w9#pah5qmw=Ms59Ut{TugJbIDt+GsX*JkzVW9mUR!zH8axi_fV!YwkZtv90{X0G2@nQ5m{+d{Ot+>nwet59 z)^cw}Beg)ZAhZD508M&La?NSYVa-|1QO(J&jBGmS2EM{R0lo(MX3{aBd*KoIW1tT_ zy$hb8p10whU>Dde@9ZJ)26z)pCqXtC1x5q?LdFl^N3a3=S)i{!=}SoZHpPeFBX9(K z3_bx@(4flT3&O|1SKv4}0lo$&!8hO(I1py%e20KOl(7T64z_{q;8pM;9~pepjH+RZavsAQwymlfe|A8~#)<4crWLv*+d>xE1JxQvhaw=AZ>g2CYB@q=43- z4Y*rV9J~&8f!#qy*&$*iMiv+c#)An!UxED*XZ{2}0!M%j3ZH;?z`Ni8(1$}#(z6+a zzl3#g&==1RfU#)Y0=y4-oyFFNy*6U&D+q@Pf6$*F4H)Wc!AOt|^u3;+z!~rhI1A2! zKfs?LNE!#kffC?i5DzW^mx2Uv886Rbs^nKDSOruCso*ro1G?!Izzp&mS7xV-D!2obQ7zhS~8^927Bgg<|SpzaJ_56~O*1rLE0K#vm-hd2;CLO{<9 zj{=>FbO<_aTBXF4&Hs|%SKtZoAkeu+k47$-1LlIZ;9crD2=uYrncxg<`vsf@--EBg zN$@E+3O)y4fMeiGa1hJ{=V#O-nXPrU=R!xfcL>6 zpbs>)2OYrg;1BR8D8^LZN~N!WSHWxGb?_X>1Ji)cK>EDeXfOth1LMI2FcD0q{F^|Y zDt#O*pk?|>P;n3o9Pkzi-voPsKEO4XbT7hniK|Hu^zhaWlpNbW;5wi_(1HFs&|s*2|Np)29rpr)9qC7Kh(~* zspc7=gYXML{+|x!Q047l7C30{Z09tw8^#XcEu|&~@x& zX7&nvO9Aqxb`7mPt+!XfD_|qgt>Ia)7CZ@bG}1EB&ZztSqu>#+0%$Ew;ukDpuF7`^ zY7fv}pgWEZNu$7xK>NaApiOol=mV|;y+LQt5p)OXAPsZ?ZGr9*aUc=sp|KRW48((r zK?!gv;BhM7dy7!g3RU15pem>YN`uQmSx^RC0V;rUpggDul&3PN2C9Ra;7V{Ur~?{; ztH3p&7PuNnmsVRlm;&`cT~HtBLA)tY0m|ISauc{QNCwS85@=yL1=iDNE6^IW0qsFM zAdkpXsX$)q1iFGQ;Lm*f3a%T567>Q-fLtiMC+G+Ig8pCtxE|=9r=iIP!@y9G0W?I? zM}XlV6DZ9{kOd|Jm8bOD9`cn~V>%9u1*&KQkf!iM;6d;JSPt$1E?5K>f*IgeFcsVc zrdUja^T5qOeVh*80tx_5_pm@TA7d_<3Fd%1!0n(8mm6kWa&w!`EI*SHTXj4cIyPr+WPuQ2bvtrH^W= zWF>gbEbI_dihlk_Gnoun|R}P zh)Kv-=D#M~kETQ`!8_o9MbQGHK2v^G{vP;iInt%6tmEJ-Am1wQ#{d`cFiJpWR+X>dj^Fr9iz&Fd1EAO7+nDrbN&bi~@SumJRgCJq!#5O@N;0I+Lw7d6gom8R5XfnMe5fgt*7FNx9=uZISeRs&Q6N?R3F z2UmhxK&@2GN~gDEN_!1x0P2IQfzsCV`C3nCgrPSD86et4Rj6(>gHu6A!t&r)lh7rm zMkUp$TXbi*lcGTf&>pli+tOl6)r}Br1zH0A6>$sD9NY+ofE&PIFo=I8+9jrKeiy=N zAQKD+BW+kMQR~FgM}QnK5$GL9S(;G>=$*${Fb0eUdJmEdG_LmK>K$A)zEja|0=i92 zfth&u-hgX)XwWAk>K|8313Csz2e$xajAn{1C8ggAR)PQBz0f6Y5ztIjgOpzR77|_n zZr58JwP*%VL;*Y-+y-WWncxm^7nl$31oJ>4m<#5ByTL|Va6Vy;<-_1!u-Muw;T7N^ z@E~{qEC=^%B<};uz*4XT7@%dM4B}O=3f1U83i?u+^sR)qfHlCMAm)|yn2RrZNp`@b zrN>;`;3>lEz*_Jmcmg~QbgFn6)~Vus_&sniXg*7iNz30(cpG>H)WqE%z=y#%pcZyj z@P&;lOZZAq8PotDqAR`DYn38;B^y@`R-V$}V&FYg!FrVz3x;V*6eAD>nqw+R_v%03 z-@$L-95@SZ0zZONU{Dw;jiHn;5hhyn)?#CoU`x$p6BxvLM27ZgUT|5rp;rI z3>v1gjL4QsQH0Qtt)46+>tJxGBnD#}3`UGS8GFjum&Q&e$-WHvzt3msNmIVx-|O{% z{r-P1Z};=L_uO;OJ@?#m&%K||=W!2Ufo}j`pzJzQR^Tn9cYxc#P2evemra5TID^ys zfD7qI01APpz%$?l@EUjtyaL_IClgAI^B@O}i)DHJNhCEz6#yr+Mt~?B^Zbdjn zP$!ge@qA448xe+!z#lU{R^&(&tFcKI9xB)Ie zV}KueGy)m|O@StWEAS-{1T^OduR2`tlN5Kr184>e1o#-GKhO{0 z?m!Qq8{iN40^a~_06t-E3A6xO17881fwn*=`MzU3E;;}c(OYk%?SS@xawN@pT*j3d z%JtW{?h5$G`CX859@~H)z=9=1&1__RsMH%^fmrYnKol?>h-X!W0wF*!Fbs$UB7nib zP+$lU4uk=m&!`T@T$l3}0%L*EKs3NA9|Lgy0)X=;05O14&Oz$Abh(*s<_*Kq)AFacm5^ME-(A}|wRUNZoupAIlDG%5U;E&zW5=YUl}4v-C` z0qcR)z)FAx$wGPth+m6;P6MZa!@x;k8?XyF0UQVR1IK_&AOkoA90U#kzXN-K-9S3< z8}JLT0#F2AgKHKd6<`5aI2PI)?SCQ_3#0T1g(Bh4$lGYBAm%AOVp?XV)ZzTi0BdO{ zz>RGIb^zOfUjgpiR)EV=dHh)_uD~f*;%h}>RvBx8nU>WfrM#>jI(kfGvj<7e`e0AWm+YluQ{Iu{R7~kI}fmGSxBzSDf3k7v7ME=ju#nn0b6-V zrbrEHX3#@D53SWDa(3&=fW%VtAmO>k%0K>#nHEg%5ZfWMG0@xk~jYF2tv@}95n z19t(Q0XKn?0^GxWdoV1SrwGJ`Rx+PE#8Xr;Y@V9y zFKmYRSgjw>FW@|(sZG* zxG?J<8&g<_;H&;%ObaFmHgqyXu){m${U->vDhv7;BKYB(IKNQA*1n#JcxtKtdqie( z;Da8g)T$s)7gv{NSR*L`1o-y7+C(Hiq%zjjpi`kjEqsRc^fa;t(GBJoN$t)EH8gHm zrD+h8&ZZuN1wZvi6G|H_*r;mIp230#zOZ|YT=ckgm|&}ZU4agSp-@euaLd0~6(%$` z4Xh|WFwje-?)XmTDVJ`c%He{oHXZ%0jIPhH7!VaTU6le+-CW%8*C?YBwGS6;?9YJ$ z+f@C=Di@1Bes#f9q=443_>RsA!J@BJk3G zh*E8fcItQ)bj@7cT-*_@n~P6F^l#oxipU6DyjHC;Mh>i9--O~L(8M>m%K=&^oi| zr%Jij`SnUzb&yVCE)l?{&ai5X5p}X^`u?Ho`KasLe9%dwW7LOKk?2hn*(0%^0cF^O z?rpX3;YFTjmV*ugxwyF+c~iH~5qKIolle<9YC$WQUk6H$gtbhjmG=Z&(hS2ia-=%L zP$F8n75NPlT1u0HRk>;yi0#Sov|vSfC{aJQqk6*ycl!iL!vnN-R$5(W|J7a)NFJCa zGWaCi~G?P@+ki0>F z&tUsU2_EVTb!b79V57c=^q63+@qo3_5tOLv(Q8iDQR5MUU$YB!Br}{7w)oe5S5N$< zR`GCR-Wv^dluUPKg+{41knGqs^e0dK#l`w?;_>tnD^@1 z{I-)L)4|QvrMZi7b1cUVC@LBjf3<D2u+R z+FTk1KRP@Hb`wbEV{6&kdCkxz@?P4`N7;Y{)ghTYzSai^z&<&mwn>cAp zN0Dhi%SCD=RX4cXubD$*(1@E$GZz>^AT^D_7+3vLvht^e^$)K0(Bc2RS2|!%Au(XP zhPHxESq>>?kYGWFCJ81`p&QAN~^9ph<~Y*94nBwxz}w zej1ZAeER^k%9ZO-wGhEtdjOX_zH2aCT)pR=b;B2jZtbmBwf3Osd6-;*Qfk}{POduL zN))W+ORjIa2Dwm=-me+ei^T+y*Uk~K!eeC-mR4V7eg4cUEY;F~O+x)piN0PEjcQSf4kHf=O zls#Fn(N$_KzHy*`*C68M=!u<;)GD49XvxSPCEUhlpPd~aeo^^2mxwYLxwWR+Qv@5W z4=8Lvv8eviT^G7|_c7ER)S9-<7u?mcttl=Mt);f6v?)T6dVlMsae|HMepG}#>m@Q9 zY85ARmdlV(N}MpHG^s2okpm0z zFGjLJ>N05SDMH5~@MXQ&&ItUfmT}N|aiWR7a&bG_mH@6wi;AuluCkaicN_JFcH}!1 zdOQq{tjG7e7jC#%e|WM%k5}4}e(JyVCW+Uvxc?yQK27LYUUy3Bx46zSZ|XH2wszNB za(o-Q)yhd(bZ#%Y182k*@Y0+1O-FZ>v~;VbO{;V_>wiV-X8c?Dl7m$&P4kXaG#_ns z=tv8`hf2yfOQqGG9Vz#FOojhwro|>7-jRZ5q76mPxQ=A@Bkq@Vq%EAU4BHOe^He$8 zk=}E@WV|+NW%%T&Q#_24kt@cn41$stcTr)lG+#mwb|sDSUll$zBX`>O>1^SdP;8vn zu)X4dI5XMx=$ok(>x;%IdY@;Vsm&Zr$qGIcJqNw2=|i*U2+nFJ+`}Q5I{Dym7&WK( z(B(O>r8!c5MJ1mK=V0E*)Su+qX?J6z$L_xN^6NKa_gd$PHY84o!(UUz+%j6hdSk(E zNRp~4^_eHsEStGn8E{2^iaL~GP=-q$#{VUcrWmYbhBoB-L$M1h9>8)W|BQq?yGp_C zzNXK;bt{e}a%jmx3f3^uquR(GRWY`IHKo{eX=N$4|Nla1HfpnP$aE2GPnkjg6XpGf z9(~4BC@NE0{dAuGOLe7HR*tGZ)8PMnUHpt9Dk|#@1t$x3x;nm+o6i5$*S=w$HdEEA zYRKVGZA3_n_$_Z@%%X2|+lIa6$;TTKS0h(nidc#$N(z-}>r%lO!6iavaXT-Dnbq5f z0klzbKPgi_smy;g0~Eq6Vv?ZJmIK@x|7o~tOS#KNR<7aw0F{8 zDh!kMWo`&b>-bXiGQpQjmt&Gv?@2wE3nR7NdP>55cXGg+TI*v?dDTUf1+n}0r0dJE zY4FBwr7D{KW&fbZQ#!3&Ylwg(-BEOsV4@z{lbn;FRZ;G@k-lN&|B9~;r#(fSbIPiGA+k39C#S#(z6y&h>9B{72 z!QRUH`X-HMgoi>$I4E=Rq@ZNMB|xDn--ML!`rGDs&UEW!IZPZUF$S3U-Po9rkzq#1 zFYg#o!_o;`Ic!!C5*yLe&4Rr;J%C1T5@HR@!SQ5ampZgJ=~G}B!+T51!kc+DVy#Y$ zZ;i_CsEnagejgws_U7JGz8}70&5G?AP3cWps4GYQ#t1`Z_NE1CSSl9vChZCsL@K!Q zsI;%Ry74b>yt*0cZt6|lL803X3RcVg!f$T-HwuU}Q2Zg6?Am;}#q`MznTC?{y(txS z)pvW-?iFxVuX|HI-{W}1Bvo*(XWB?hDrCg_-x~GTUf!(oz8{;xuVhvhsWW~&nQ*SE#0uL{qZR$g3~JQ6_m}E= z1*!L)e^L>r7l`*nF*f(7;8oaewnFS=s7MSS^s+ zv=8kx(Kx6l1=B?n4a5j0(+Zj)YWMz>{S#*TEpQ?e!!FC?aKgYNH zYhVKAA(-`OzDH6)LHo3vA_IjBN@}CTB<5ULRMvB~p~N?YqEJ^mT&~-qa8frjiP*0p|7g0^qm zxR(tL6mBSC$$I4;Ts8AWf}NqHTPU?z3&|ot!7*B`iQQE9CSTASC}xCGG$?edWQxQw z$zR+^>{8W0aXmuX=;h`fT(QZ0e@hLvjL;d5tqLOO0N3T$pDn@t!P1y#tJ=NVYoM@{ zOAg;#xW0N#pVx+xdXZFR9VF9%qB`ojc1RkOZek9tD%`t7QhQM72FMhNn#~b|sn;U_6}a2Hd*{~kq%Pb*u~9C`Fe>nAkf&~MC^-;G z*IBZ2GKI5cLl4!QJF5&7_an*TXK;TfQ~cOEzwWSkNr?suvtd%Z$6x8|OkNZ4qoKrU z7zJ_N=Aftn$$ENaH`dmw_OpS)PcErivtwTBmT|`nC4-02X4KVAkSU^qSAV>?aF4fv z;)h{$^Jh%I{iDfhy^zG|w)I%)JjYVedMr$B$4dUb;nUnFV`~=jF&ZB^W8#XZ^|tth zuWvTs+}{Uuy#Ai5nAf1I|H;#!lOhA7Z^x2;17sKk3U;Pzm!{?$I|O@!LUu|~V`=9G zA-1=&dRVHZP3p&MbN&gOX13L^`Z%Mc8hEt1Ug>9tL@(?)lse_FI265Euv0(#jrK=8-*?^ce;sZIOMrWsI4^}CoL<7EnB}F!gwm& zB-mID9540zZB?h=tlOs*s#SjDNxNCFsjW!%@5LWp(35&@7Fv8>nsu86{r`_!xTy#y=@KaTc>;o(sgoq-yS}$;?YSo259gc6=Ux;|qSL6W ztvy+MzfAvP-?Zl)A7(~su*(q%j5SfuJ4>HhRgdI^L7+8wlp31P8?Wgz)bw zzHji)O+(4f$>fi^+RJj?eP0i=DtgwrvVp=$PgA!EvGv9zNTT0G%5!(LbMp!@9>4Rc zIIp7U!n*{j{VV3%_^A~2D}sQ8sdQjF(s@%U4fncLQ>B_;3UVc%S?0NJ{^86ATmyC=q=@@1Q2jO!SA3PxJcomZaRxKSdwpCvdW?WU)`sXcvHtm!w=rTT9cn zX8foUF%beIqcut7x(~|O2?~yI$NCNr2>xp742gpE^+yr~ABRHk$~<0Nt!uq%!<}{_ zg?L0FJr%|aA^QYRmGn{sS?|Zj{f%5@{;KT(AEulQ5Tz40R8^A6AK{JKCYf#?M)acJ zFZdTP#*LGyib~^-N5bt?8V_~rWQxJ9wsW$y@>c;DihE1l;N9^OcrX5{F;KT`iEp{a}aBNwG@g*s>!&aImPuxQaY%wDmw?3W^p>n=W=dVtE2jiTNZ5>XRvS z@rWgP*Vp%8fpJRi!4k$b&>^MNo-K$)jzQk*s_99(r_IWWe8d7(d#Me2wb#0c=-K4Z6@SQ+Cbei;Wd8V zAT84QZ$fVjs$S7kluOh>vyGC(e^+s^tvt0p$7jl|LEFpL3shgz_DSJm1ywq@qQ~F{|Z4 zkretRRXZUxx98tXU`ugpx2FE&Y1QmRy^F_$(z{h^#f_G7Z)|d>*}cm7RCEGbFGWPY zCplAg#IjRYOYX0@rg}^gWuL?Z`Hv2>qT(=V%o)McMY~NBJv`~kvrf6;IN)r{Pl+)Z z-BH5R^zx-KTlTzcGDxkezm3kH5n4e7=2;4Sr8uf8JmTNu_vm~O{Cg2+a;Di zefV<1f!ItOBCv~y#f)|Sp>3p^+ItZhKyXg?uJh7XuGAEgXw$dI+ zf4gR`+TCeX;yS4Y#)fNjIFB{q+ux`UlS z?h#4hN5U+6=k~cfO5`Padx@93_9ZAR!Qx7) zeO_`Mue3??)<$b{O0vgZ1HrXXpiDdkve0ey9ULuU^89nc7J%xR3&!?jWj@A zo`wzo`MCRbZOg}o5_H1%#($wISe~ddQMp`$PTvrkn07cL{`7}UcpmA zVebbD_5r=FO>Ed$+hPdhMvet?BtNh1hg&n;zFr^dJN-%>y~x7N1!6>Gk;7jQW1`HW zan0x-2YfrBK%@{)DrRO;ufH&E3$sZ7m*AjH1*I)`tv-BvLW4i&Hv=UCBR&#H&!T;x zG|d7iD6s)$$D{9CwmUU?wpb#@H3!d< z*G-J_)w7g+7irg`vc4OJPe3kzx>#l~1wX^9ESMH=DkXs78t{c!$h zd+<_s&mk>$GAM^!?;wppT8MO94mso_O~|1*PM?va{Vou|#|o`L`T8jk?-QQ1AwL{j=Dafy*8FB$mVKmiX)_XDNnA_Y?$nEM|iT zj=2kx;BZ7cg^^W0Cpm{dAC13!$FAE}xddveb&mYGt|usX79^}WVtG|FuZ@A?8@aBr zWz6ohy%;-~Nq0^7B)*L@aHy>ikp)q-kcwnRMp`vUW z@{7CjP>K(QN{psm*#m_+iVp!lwK0W}Y&g27=cS2Tn4Y*`dBuDDHZ*I@4PO#mkfP@c z+C$gB-I=*YED=M^QZmV`$n-%8n^T%q3{<(7>(V+9YqwmKMq_X6qaK$#f8gz%yhs+F zrQjzR&|#M(12k&+V%%z><2{QmHYBK0YM~>AsK-(OXYd;8RbaERNC*9$wl@_pDR;LtayUTZVaBW zJ6uVzQ&OB%&kK~#^H}mO*8EIZnZo7NER{X*?9!)rtvowl&=fO=$_m*DDCXhx7`9YO zkBWa)OiGym2V`22fg-icNY^G;@)_GIUmX!UV;6r1!7=iGW8YdrT`QQ!n4(SZF5aG7 zUo-+SI#E2UB(}9N>_TZ+nZO2}NX8&5LGgl0-=xln6I$u}<|mjMPPe20plXdb{R-#a zYGrjP)mKAyndI8?m+CSGO6+Y7 zd{zL>w0REOQ-%UgQ(6DYS=G>;5)5Tx#XJ>5kj>oT1m*eu6 z#5TEf9T9_lIp%^D=#$Stv>mWU^BMg6L(Siw3hxmnj}PWBUI7exiE}J9jem(ywbYzd z1TU3cvXAAEDA`h2X`^#{AWf=a5k7Cm-)#N6D1rEWNCJE=ha)=QiH%)WKEYem2--yJ znwUjJuP{R8+N^rX0~+!gJC6TCKE(i)xTMS~cne=N3^6Q|!?99JrxI(G7iMY8AJ172 zY2;hXmhuA{#fTJ}guhZ8%Y%nh$d$|YY~}UHjZIzbk)i`RTvYeSqeJhYU?r?95s+-n zBeQ?7Rwmt+!gFosgmDiqtLw;?1J8FTPl}6NmN_CGzc-`R=T737{yNH zdwTa?^o1g=qFKpwKN)8jQQU{mnVEJ8jJG;Wv`>GPc5iMvjw!^hV)~S+b1HlCOU+PH zkzgkt2QD$ekzmwOVV8X5#Ycix74bnJ`2K%*Fj)4vy|@pPkJh`FfA;^sdx&U9u1D~; zrt&|Jj9PZqJTB3fFl=~Y!BhNVfwateEE+uV@QO4nvnP=tt8w1&!i4k8r9~H zM?I4E;-~=!Z!KNiX@3QcedS>O`BnT$yDZS13Yq|XmejJMrVf(6NE}z;xRnnZt_4h5 z(`S=|?PlEbu|z`60JD!)p1HeeIg>4EBE`|iXK#Ohq z?#H@o$9Uu34D~*yWVt+9VEeS2Tz)Woo1@98yM=w_@;f&}=I`+u^6OCCbJy=&>b0-? zkhxJ~ac_b9wRM&lPjA#|eD-BYlP>%-zIgK>-Bfc)rSeGsp^7G3WjuD&cO%2_pDAkW z$+f>mlRnQ((_WQc$wJehY2)VnvQW&>iC%5RM+gpW_^84)a>R)5VnRZr!o6@zj5kOe z+Q2l(t)g))`sk}^McoHzOwyNi(##QPT}Mra^txR%*M;0T--dE zuV_=QO-F{u#^3}b{bP_OTBCstyQhyGtZAT1zZ|C7rFQ?c4m)r|PW!M?!$yUV92z+? z{L7e8V&2ymPiJHXp zFC#RE>X;T&dr;v_&7^d*S(;g@Pw5@WzpJJeU6`$Dsq&=Pb2Ot$mq#zwR83zzS5v8i zX;^qn_~4kPQIVl^%U`2S-~FTJZBuIW1*<&~YQKJ1lb}ks%+#2AQMGS1b?K(Du?cO~ zK&j^!KwR;*P-9$0fCADhnHYD|h~KymFg5O?c56w6TS0UjH { - toriiClient.publishMessage(typedData, signature); + toriiClient.publishMessage(typedData, signature, true); }, config, dojoProvider, diff --git a/client/src/vite-env.d.ts b/client/src/vite-env.d.ts index 5a3036c..92b1074 100644 --- a/client/src/vite-env.d.ts +++ b/client/src/vite-env.d.ts @@ -3,6 +3,10 @@ type ImportMetaEnv = { // Auto-generated by `npx vite-envs update-types` and hot-reloaded by the `vite-env` plugin // You probably want to add `/src/vite-env.d.ts` to your .prettierignore + BASE_URL: string + MODE: string + DEV: boolean + PROD: boolean VITE_PUBLIC_TORII_URL: string VITE_PUBLIC_RPC_URL: string VITE_PUBLIC_MASTER_ADDRESS: string @@ -10,10 +14,6 @@ type ImportMetaEnv = { VITE_PUBLIC_EXPLORER_URL: string VITE_PUBLIC_FEE_TOKEN_ADDRESS: string VITE_PUBLIC_PROFILE: string - BASE_URL: string - MODE: string - DEV: boolean - PROD: boolean // @user-defined-start /* * You can use this section to explicitly extend the type definition of `import.meta.env` diff --git a/contracts/dojo_dev.toml b/contracts/dojo_dev.toml index e5ab75d..64da800 100644 --- a/contracts/dojo_dev.toml +++ b/contracts/dojo_dev.toml @@ -11,7 +11,7 @@ mappings = {} rpc_url = "http://localhost:5050/" account_address = "0x127fd5f1fe78a71f8bcd1fec63e3fe2f0486b6ecd5c86a0466c3a21fa5cfcec" private_key = "0xc5b2fcab997346f3ea1c00b002ecf6f382c5f9c9659a3894eb783c5320f912" -world_address = "0x6f130c8e150882e39cbe878c650c8f35c86579180dbc77d0c1cbe169449b5f6" +world_address = "0x2bf4d3aa0dced89d37d8c3b4ff6a05895c0af32ff3baf9b02abf8504e53eaad" [writers] # CORE diff --git a/contracts/dojo_release.toml b/contracts/dojo_release.toml deleted file mode 100644 index 2ff975d..0000000 --- a/contracts/dojo_release.toml +++ /dev/null @@ -1,56 +0,0 @@ -[world] -description = "PixeLAW world" -name = "pixelaw" -seed = "pixelaw" - -[world.socials] -x = "https://x.com/0xpixelaw" -github = "https://github.com/pixelaw" - -[namespace] -default = "pixelaw" -mappings = {} - -[env] -rpc_url = "https://api.cartridge.gg/x/pwar-dev-2/katana/" -account_address = "0x8cecdb74164f073793942ddd1c477a6549d43a5ce57f4640eadefe0a6dd8bf" -private_key = "0x422f174dedd139c6cad1c535b1a7d43a6cf224f71cb4a67e1070347a952b9d0" -world_address = "0x263ae44e5414519a5c5a135cccaf3d9d7ee196d37e8de47a178da91f3de9b34" - -[writers] -# CORE -"pixelaw-App" = ["pixelaw-actions"] -"pixelaw-AppName" = ["pixelaw-actions"] -"pixelaw-AppUser" = ["pixelaw-actions"] -"pixelaw-CoreActionsAddress" = ["pixelaw-actions"] -"pixelaw-QueueScheduled" = ["pixelaw-actions"] -"pixelaw-QueueProcessed" = ["pixelaw-actions"] -"pixelaw-Alert" = ["pixelaw-actions"] -"pixelaw-Pixel" = [ - "pixelaw-actions", - "pixelaw-paint_actions", - "pixelaw-snake_actions", -] -"pixelaw-QueueItem" = ["pixelaw-actions"] -"pixelaw-Snake" = ["pixelaw-actions", "pixelaw-snake_actions"] -"pixelaw-RTree" = ["pixelaw-actions"] -"pixelaw-Area" = ["pixelaw-actions"] -"pixelaw-SnakeSegment" = ["pixelaw-snake_actions"] -# GUILD -"pixelaw-Guild" = ["pixelaw-guild_actions"] -# P-WAR -"pixelaw-AllowedApp" = ["pixelaw-p_war_actions"] -"pixelaw-Board" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] -"pixelaw-AllowedColor" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] -"pixelaw-PaletteColors" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] -"pixelaw-PWarPixel" = ["pixelaw-p_war_actions"] -"pixelaw-Game" = ["pixelaw-p_war_actions"] -"pixelaw-GameId" = ["pixelaw-p_war_actions"] -"pixelaw-GamePalette" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] -"pixelaw-InPalette" = ["pixelaw-p_war_actions", "pixelaw-propose_actions"] -"pixelaw-Player" = ["pixelaw-p_war_actions", "pixelaw-propose_actions", "pixelaw-voting_actions"] -"pixelaw-PixelRecoveryRate" = ["pixelaw-p_war_actions"] -# PROPOSE -"pixelaw-Proposal" = ["pixelaw-propose_actions", "pixelaw-voting_actions"] -# VOTING -"pixelaw-PlayerVote" = ["pixelaw-voting_actions"] diff --git a/contracts/dojo_sepolia.toml b/contracts/dojo_sepolia.toml index 32fec3d..6bcbb83 100644 --- a/contracts/dojo_sepolia.toml +++ b/contracts/dojo_sepolia.toml @@ -8,10 +8,10 @@ default = "pixelaw" mappings = {} [env] -rpc_url = "https://starknet-sepolia.public.blastapi.io/rpc/v0_7" -keystore_path = "sepolia.deployer.keystore.json" -world_address = "0x6f130c8e150882e39cbe878c650c8f35c86579180dbc77d0c1cbe169449b5f6" -account_address = "YOUR_ACCOUNT" +rpc_url = "https://api.cartridge.gg/x/starknet/sepolia" +account_address = "0x02107b2bcC750F51E70cFb9c53583a54eAf86DaC60C6EFBDECf18F7eE398Cb89" +private_key = "0x01ef15f865960b993c0bd1c5e00b94ebd55485e39c4e68a57b08b72f0885682f" +world_address = "0x2bf4d3aa0dced89d37d8c3b4ff6a05895c0af32ff3baf9b02abf8504e53eaad" [writers] # CORE diff --git a/contracts/manifest_dev.json b/contracts/manifest_dev.json new file mode 100644 index 0000000..e6a0371 --- /dev/null +++ b/contracts/manifest_dev.json @@ -0,0 +1,3835 @@ +{ + "world": { + "class_hash": "0x45575a88cc5cef1e444c77ce60b7b4c9e73a01cbbe20926d5a4c72a94011410", + "address": "0x2bf4d3aa0dced89d37d8c3b4ff6a05895c0af32ff3baf9b02abf8504e53eaad", + "seed": "pixelaw", + "name": "p_war", + "entrypoints": [ + "uuid", + "set_metadata", + "register_namespace", + "register_event", + "register_model", + "register_contract", + "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": "()" + } + ] + }, + { + "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": "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": "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::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": "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": "0x1fbb7fd4fd72452b9a575bddb6ca06f6b854a66e8c282264bf993b54d90b9f6", + "class_hash": "0xabbea8e73f9e282fa460c36f5af8598994c6e365cbb0fe243bc1cdb283411d", + "abi": [ + { + "type": "impl", + "name": "actions__ContractImpl", + "interface_name": "dojo::contract::interface::IContract" + }, + { + "type": "interface", + "name": "dojo::contract::interface::IContract", + "items": [] + }, + { + "type": "impl", + "name": "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": "impl", + "name": "ActionsImpl", + "interface_name": "pixelaw::core::actions::IActions" + }, + { + "type": "struct", + "name": "pixelaw::core::models::pixel::Pixel", + "members": [ + { + "name": "x", + "type": "core::integer::u16" + }, + { + "name": "y", + "type": "core::integer::u16" + }, + { + "name": "app", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "color", + "type": "core::integer::u32" + }, + { + "name": "created_at", + "type": "core::integer::u64" + }, + { + "name": "updated_at", + "type": "core::integer::u64" + }, + { + "name": "timestamp", + "type": "core::integer::u64" + }, + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "text", + "type": "core::felt252" + }, + { + "name": "action", + "type": "core::felt252" + } + ] + }, + { + "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": "x", + "type": "core::integer::u16" + }, + { + "name": "y", + "type": "core::integer::u16" + }, + { + "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": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "enum", + "name": "pixelaw::core::models::pixel::PixelUpdateResult", + "variants": [ + { + "name": "Ok", + "type": "pixelaw::core::models::pixel::PixelUpdate" + }, + { + "name": "NotAllowed", + "type": "()" + }, + { + "name": "Error", + "type": "core::felt252" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "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": "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::Bounds", + "members": [ + { + "name": "x_min", + "type": "core::integer::u16" + }, + { + "name": "y_min", + "type": "core::integer::u16" + }, + { + "name": "x_max", + "type": "core::integer::u16" + }, + { + "name": "y_max", + "type": "core::integer::u16" + } + ] + }, + { + "type": "struct", + "name": "pixelaw::core::models::area::Area", + "members": [ + { + "name": "id", + "type": "core::integer::u64" + }, + { + "name": "app", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "color", + "type": "core::integer::u32" + } + ] + }, + { + "type": "enum", + "name": "core::option::Option::", + "variants": [ + { + "name": "Some", + "type": "pixelaw::core::models::area::Area" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "core::array::Span::", + "members": [ + { + "name": "snapshot", + "type": "@core::array::Array::" + } + ] + }, + { + "type": "interface", + "name": "pixelaw::core::actions::IActions", + "items": [ + { + "type": "function", + "name": "init", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "can_update_pixel", + "inputs": [ + { + "name": "for_player", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "for_system", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "pixel", + "type": "pixelaw::core::models::pixel::Pixel" + }, + { + "name": "pixel_update", + "type": "pixelaw::core::models::pixel::PixelUpdate" + }, + { + "name": "area_id_hint", + "type": "core::option::Option::" + }, + { + "name": "allow_modify", + "type": "core::bool" + } + ], + "outputs": [ + { + "type": "pixelaw::core::models::pixel::PixelUpdateResult" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "update_pixel", + "inputs": [ + { + "name": "for_player", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "for_system", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "pixel_update", + "type": "pixelaw::core::models::pixel::PixelUpdate" + }, + { + "name": "area_id", + "type": "core::option::Option::" + }, + { + "name": "allow_modify", + "type": "core::bool" + } + ], + "outputs": [ + { + "type": "pixelaw::core::models::pixel::PixelUpdateResult" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "process_queue", + "inputs": [ + { + "name": "id", + "type": "core::felt252" + }, + { + "name": "timestamp", + "type": "core::integer::u64" + }, + { + "name": "called_system", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "calldata", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "schedule_queue", + "inputs": [ + { + "name": "timestamp", + "type": "core::integer::u64" + }, + { + "name": "called_system", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "selector", + "type": "core::felt252" + }, + { + "name": "calldata", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "new_app", + "inputs": [ + { + "name": "system", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "name", + "type": "core::felt252" + }, + { + "name": "icon", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "pixelaw::core::models::registry::App" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "alert_player", + "inputs": [ + { + "name": "position", + "type": "pixelaw::core::utils::Position" + }, + { + "name": "player", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "message", + "type": "core::felt252" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "add_area", + "inputs": [ + { + "name": "bounds", + "type": "pixelaw::core::utils::Bounds" + }, + { + "name": "owner", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "color", + "type": "core::integer::u32" + }, + { + "name": "app", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "pixelaw::core::models::area::Area" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "remove_area", + "inputs": [ + { + "name": "area_id", + "type": "core::integer::u64" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "find_area_by_position", + "inputs": [ + { + "name": "position", + "type": "pixelaw::core::utils::Position" + } + ], + "outputs": [ + { + "type": "core::option::Option::" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "find_areas_inside_bounds", + "inputs": [ + { + "name": "bounds", + "type": "pixelaw::core::utils::Bounds" + } + ], + "outputs": [ + { + "type": "core::array::Span::" + } + ], + "state_mutability": "external" + } + ] + }, + { + "type": "function", + "name": "dojo_init", + "inputs": [], + "outputs": [], + "state_mutability": "view" + }, + { + "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::core::actions::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": "pixelaw-actions", + "selector": "0x16928a49cfd8cf14e9f41e9d8f873890d1ab7d23b9a312d8a72f4031159876f", + "systems": [ + "init", + "can_update_pixel", + "update_pixel", + "process_queue", + "schedule_queue", + "new_app", + "alert_player", + "add_area", + "remove_area", + "find_area_by_position", + "find_areas_inside_bounds", + "upgrade" + ] + }, + { + "address": "0x57194126e6b081642e60b11b3817936bc48d2a67aa3dc577ade10abf943c148", + "class_hash": "0x3b724650b576b7c0cfa949d634333a3a9343e7225eba6f10bf43cc8c54a68f9", + "abi": [ + { + "type": "impl", + "name": "allowed_app_actions__ContractImpl", + "interface_name": "dojo::contract::interface::IContract" + }, + { + "type": "interface", + "name": "dojo::contract::interface::IContract", + "items": [] + }, + { + "type": "impl", + "name": "allowed_app_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": "impl", + "name": "AllowedAppImpl", + "interface_name": "p_war::systems::app::IAllowedApp" + }, + { + "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": "p_war::systems::app::IAllowedApp", + "items": [ + { + "type": "function", + "name": "set_pixel", + "inputs": [ + { + "name": "default_params", + "type": "pixelaw::core::utils::DefaultParameters" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "function", + "name": "dojo_init", + "inputs": [], + "outputs": [], + "state_mutability": "view" + }, + { + "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": "p_war::systems::app::allowed_app_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": "pixelaw-allowed_app_actions", + "selector": "0x4eb94962c665465ddf98717edce32f775575e7548d61f72c0657800c5545709", + "systems": [ + "set_pixel", + "upgrade" + ] + }, + { + "address": "0xa344d3098f9827e809064357b732110959ecc462712f728707aac554aa31c1", + "class_hash": "0x22636046a79ce2dd5319e58db030611c3864250a2e864f2e56eefbbc260dfae", + "abi": [ + { + "type": "impl", + "name": "guild_actions__ContractImpl", + "interface_name": "dojo::contract::interface::IContract" + }, + { + "type": "interface", + "name": "dojo::contract::interface::IContract", + "items": [] + }, + { + "type": "impl", + "name": "guild_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": "impl", + "name": "GuildImpl", + "interface_name": "p_war::systems::guilds::IGuild" + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "p_war::systems::guilds::IGuild", + "items": [ + { + "type": "function", + "name": "create_guild", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "guild_name", + "type": "core::felt252" + } + ], + "outputs": [ + { + "type": "core::integer::u32" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "add_member", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "guild_id", + "type": "core::integer::u32" + }, + { + "name": "new_member", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "join_guild", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "guild_id", + "type": "core::integer::u32" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "remove_member", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "guild_id", + "type": "core::integer::u32" + }, + { + "name": "member", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "is_member", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "guild_id", + "type": "core::integer::u32" + }, + { + "name": "member", + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "outputs": [ + { + "type": "core::bool" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "get_guild_contract_address", + "inputs": [], + "outputs": [ + { + "type": "core::starknet::contract_address::ContractAddress" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "get_guild_points", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "guild_id", + "type": "core::integer::u32" + } + ], + "outputs": [ + { + "type": "core::integer::u32" + } + ], + "state_mutability": "external" + } + ] + }, + { + "type": "function", + "name": "dojo_init", + "inputs": [], + "outputs": [], + "state_mutability": "view" + }, + { + "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": "p_war::systems::guilds::guild_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": "pixelaw-guild_actions", + "selector": "0x4c9f59312c9c6ebd49039a1172f6596c44684651bb7a534011e2f4b164bba84", + "systems": [ + "create_guild", + "add_member", + "join_guild", + "remove_member", + "is_member", + "get_guild_contract_address", + "get_guild_points", + "upgrade" + ] + }, + { + "address": "0x348361b06c2a40ef55af3d85e6ea0f024e67687700bd9f2eddbeb70c704c950", + "class_hash": "0x503775d77a5e0499e25ee53e14f1ced56ae03a18336215a241e8d44e6be49af", + "abi": [ + { + "type": "impl", + "name": "p_war_actions__ContractImpl", + "interface_name": "dojo::contract::interface::IContract" + }, + { + "type": "interface", + "name": "dojo::contract::interface::IContract", + "items": [] + }, + { + "type": "impl", + "name": "p_war_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": "impl", + "name": "ActionsImpl", + "interface_name": "p_war::systems::actions::IActions" + }, + { + "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": "struct", + "name": "p_war::systems::guilds::IGuildDispatcher", + "members": [ + { + "name": "contract_address", + "type": "core::starknet::contract_address::ContractAddress" + } + ] + }, + { + "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::felt252" + }, + { + "name": "None", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "pixelaw::core::models::pixel::PixelUpdate", + "members": [ + { + "name": "x", + "type": "core::integer::u16" + }, + { + "name": "y", + "type": "core::integer::u16" + }, + { + "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": "interface", + "name": "p_war::systems::actions::IActions", + "items": [ + { + "type": "function", + "name": "init", + "inputs": [], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "interact", + "inputs": [ + { + "name": "default_params", + "type": "pixelaw::core::utils::DefaultParameters" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "create_game", + "inputs": [ + { + "name": "origin", + "type": "pixelaw::core::utils::Position" + } + ], + "outputs": [ + { + "type": "core::integer::u32" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "create_game_guilds", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "guild_dispatcher", + "type": "p_war::systems::guilds::IGuildDispatcher" + } + ], + "outputs": [ + { + "type": "core::array::Array::" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "get_game_id", + "inputs": [ + { + "name": "position", + "type": "pixelaw::core::utils::Position" + } + ], + "outputs": [ + { + "type": "core::integer::u32" + } + ], + "state_mutability": "view" + }, + { + "type": "function", + "name": "place_pixel", + "inputs": [ + { + "name": "app", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "default_params", + "type": "pixelaw::core::utils::DefaultParameters" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "update_pixel", + "inputs": [ + { + "name": "pixel_update", + "type": "pixelaw::core::models::pixel::PixelUpdate" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "end_game", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "function", + "name": "dojo_init", + "inputs": [], + "outputs": [], + "state_mutability": "view" + }, + { + "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": "p_war::systems::actions::p_war_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": "pixelaw-p_war_actions", + "selector": "0x60819afda106eb158f2bab7b32887de68857103d8ffb9a1683ba40f9d96e98b", + "systems": [ + "init", + "interact", + "create_game", + "create_game_guilds", + "place_pixel", + "update_pixel", + "end_game", + "upgrade" + ] + }, + { + "address": "0x717d128a1fe8718967b87146fe6f73ba487c298758b0680593db98b92392592", + "class_hash": "0x183c131707a2d915cebada4097eaef1b3391a8074366b85ac99312268fdbbb6", + "abi": [ + { + "type": "impl", + "name": "propose_actions__ContractImpl", + "interface_name": "dojo::contract::interface::IContract" + }, + { + "type": "interface", + "name": "dojo::contract::interface::IContract", + "items": [] + }, + { + "type": "impl", + "name": "propose_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": "impl", + "name": "ProposeImpl", + "interface_name": "p_war::systems::propose::IPropose" + }, + { + "type": "struct", + "name": "pixelaw::core::utils::Position", + "members": [ + { + "name": "x", + "type": "core::integer::u16" + }, + { + "name": "y", + "type": "core::integer::u16" + } + ] + }, + { + "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": "struct", + "name": "p_war::models::game::Game", + "members": [ + { + "name": "id", + "type": "core::integer::u32" + }, + { + "name": "start", + "type": "core::integer::u64" + }, + { + "name": "end", + "type": "core::integer::u64" + }, + { + "name": "proposal_idx", + "type": "core::integer::u32" + }, + { + "name": "coeff_own_pixels", + "type": "core::integer::u32" + }, + { + "name": "coeff_commits", + "type": "core::integer::u32" + }, + { + "name": "winner_config", + "type": "core::integer::u32" + }, + { + "name": "winner", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "guild_ids", + "type": "core::array::Span::" + }, + { + "name": "guild_count", + "type": "core::integer::u32" + } + ] + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "struct", + "name": "p_war::models::proposal::Proposal", + "members": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "index", + "type": "core::integer::u32" + }, + { + "name": "author", + "type": "core::starknet::contract_address::ContractAddress" + }, + { + "name": "proposal_type", + "type": "core::integer::u8" + }, + { + "name": "target_args_1", + "type": "core::integer::u32" + }, + { + "name": "target_args_2", + "type": "core::integer::u32" + }, + { + "name": "start", + "type": "core::integer::u64" + }, + { + "name": "end", + "type": "core::integer::u64" + }, + { + "name": "yes_voting_power", + "type": "core::integer::u32" + }, + { + "name": "no_voting_power", + "type": "core::integer::u32" + }, + { + "name": "is_activated", + "type": "core::bool" + } + ] + }, + { + "type": "interface", + "name": "p_war::systems::propose::IPropose", + "items": [ + { + "type": "function", + "name": "create_proposal", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "proposal_type", + "type": "core::integer::u8" + }, + { + "name": "target_args_1", + "type": "core::integer::u32" + }, + { + "name": "target_args_2", + "type": "core::integer::u32" + } + ], + "outputs": [ + { + "type": "core::integer::u32" + } + ], + "state_mutability": "external" + }, + { + "type": "function", + "name": "activate_proposal", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "index", + "type": "core::integer::u32" + }, + { + "name": "clear_data", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "add_new_color", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "index", + "type": "core::integer::u32" + }, + { + "name": "game", + "type": "p_war::models::game::Game" + }, + { + "name": "proposal", + "type": "p_war::models::proposal::Proposal" + } + ], + "outputs": [], + "state_mutability": "external" + }, + { + "type": "function", + "name": "reset_to_white", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "index", + "type": "core::integer::u32" + }, + { + "name": "game", + "type": "p_war::models::game::Game" + }, + { + "name": "proposal", + "type": "p_war::models::proposal::Proposal" + }, + { + "name": "clear_data", + "type": "core::array::Span::" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "function", + "name": "dojo_init", + "inputs": [], + "outputs": [], + "state_mutability": "view" + }, + { + "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": "p_war::systems::propose::propose_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": "pixelaw-propose_actions", + "selector": "0x4ee7028a73b7bd0e88525eaf1d60daf9a2f7e3fa14b15f3a52f27978569b58d", + "systems": [ + "create_proposal", + "activate_proposal", + "add_new_color", + "reset_to_white", + "upgrade" + ] + }, + { + "address": "0x46d2a5ac94f2f4a52082ebf7e01e6f603e9e5c7b0da82139e757ebcde877261", + "class_hash": "0x4c22bfb3bc958e6f85f440aa0f5fc665c2f33c0d45f60e31c5e62246a4e43e8", + "abi": [ + { + "type": "impl", + "name": "voting_actions__ContractImpl", + "interface_name": "dojo::contract::interface::IContract" + }, + { + "type": "interface", + "name": "dojo::contract::interface::IContract", + "items": [] + }, + { + "type": "impl", + "name": "voting_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": "impl", + "name": "VotingImpl", + "interface_name": "p_war::systems::voting::IVoting" + }, + { + "type": "enum", + "name": "core::bool", + "variants": [ + { + "name": "False", + "type": "()" + }, + { + "name": "True", + "type": "()" + } + ] + }, + { + "type": "interface", + "name": "p_war::systems::voting::IVoting", + "items": [ + { + "type": "function", + "name": "vote", + "inputs": [ + { + "name": "game_id", + "type": "core::integer::u32" + }, + { + "name": "index", + "type": "core::integer::u32" + }, + { + "name": "use_px", + "type": "core::integer::u32" + }, + { + "name": "is_in_favor", + "type": "core::bool" + } + ], + "outputs": [], + "state_mutability": "external" + } + ] + }, + { + "type": "function", + "name": "dojo_init", + "inputs": [], + "outputs": [], + "state_mutability": "view" + }, + { + "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": "p_war::systems::voting::voting_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": "pixelaw-voting_actions", + "selector": "0x6aab73ea9b21bfd9442dae40417908aacc10dd3545ee349c9694c482f9ccbc9", + "systems": [ + "vote", + "upgrade" + ] + } + ], + "models": [ + { + "members": [], + "class_hash": "0x8d77a2f263976dc4b9b7f802a0292f971bc7874e4c5ebd5ba4cbd2c0982bb", + "tag": "pixelaw-AllowedApp", + "selector": "0x4aa2705854562c8bf719f487c3c8d7b13c3d5981a2ef8a2b8662454ab20dda1" + }, + { + "members": [], + "class_hash": "0x5a16916c47b297535360a150d71547f6be1aefb3d6e735a8d94d84d154b08db", + "tag": "pixelaw-AllowedColor", + "selector": "0x22c1a7964214ed1b17ffc58c6204c0e1b665dec234c929384f196d94aecd4f1" + }, + { + "members": [], + "class_hash": "0xfb7266a7d0ee8f5288331f2d0da5c9c51d0ac0f0700f13ee47b692eee317d8", + "tag": "pixelaw-Board", + "selector": "0x124dc3e76f4ed3f4837711f41cedecca802a320158b9de00a7b11c2178744db" + }, + { + "members": [], + "class_hash": "0x1acb7503dcd4602e4d4417d031ed89f67476100706db64a45b255730eaafc38", + "tag": "pixelaw-Game", + "selector": "0x5c1fa23f91c57a8abe1fbbd9810506e80760f755a32bec3afd8c9ce1e39cc31" + }, + { + "members": [], + "class_hash": "0xa0840f5116916e59c60c930148cad0fc01ccdb94950684e0d00bb6e485b00b", + "tag": "pixelaw-GameId", + "selector": "0x1ee8756e78c92bc9c335b55e61b80e3973e3fff0f30011d964afe0f254e8bfa" + }, + { + "members": [], + "class_hash": "0x447a7379edb50e9854b93391a977bb519d32762f76b507a014055dad6e99f74", + "tag": "pixelaw-GamePalette", + "selector": "0x49013f2b735532ac5a03f978e29eff91c1384d5c3ca9bede116ebb3e8d093b8" + }, + { + "members": [], + "class_hash": "0x5c569b888ba33a482d5ec4a63009a2d4e9eced6ddeb119e7f864f86057d6f21", + "tag": "pixelaw-Guild", + "selector": "0x40e97c00653ba125f4c47d25c4869afe483b0d08badc3a85ff8779c4ae09d58" + }, + { + "members": [], + "class_hash": "0x4c8c01173825106ce9d018a9cac2e532656b4112bd4e6f347e06d8b42aca00", + "tag": "pixelaw-InPalette", + "selector": "0x7a46e3ad45c2a3929942f7b159fca9f0d5760becedb0ad2d8a083e3e2a1dfd3" + }, + { + "members": [], + "class_hash": "0x233531bdade63d9e2e44619b6da5056aca4fad36875b8f9bf9583fc640861d8", + "tag": "pixelaw-PWarPixel", + "selector": "0x15195913884de92cc197b011be399aa8f603f113600bb09a372028241ccd52d" + }, + { + "members": [], + "class_hash": "0x40ba9c2f974090e8f9e4b206e624b942e96654a25a3b6802b573fa26ffec3c7", + "tag": "pixelaw-PaletteColors", + "selector": "0x39a92a0aa39ccee2d026d433e089f1a063f2ff73fc1c0f0bcf7c21a9731687b" + }, + { + "members": [], + "class_hash": "0x4b4ba9938436d18a0b7f17f140fcab43560443222265df3ac7a56344198c227", + "tag": "pixelaw-PixelRecoveryRate", + "selector": "0x3aa284c05a1c4add28708228abefb8eadff58a064e2d56a64f573e3764f9acc" + }, + { + "members": [], + "class_hash": "0x5bdcdb2dbe7108595afcd9f1164d4cc95461bcb0c0b9a27205a41641b94e41b", + "tag": "pixelaw-Player", + "selector": "0x30a1b371016270e1d0c33e176d9d07ab01d801d8b1f0e1fd1d45534137f2ce" + }, + { + "members": [], + "class_hash": "0x4d25f283b8ff4c4c61d6e420eb061d277d451447586b38d3f20ffe35673944b", + "tag": "pixelaw-PlayerVote", + "selector": "0x326c17c626b9eecdb1744cb055eed766d8e9adf96c10aa60310c6961d79498c" + }, + { + "members": [], + "class_hash": "0x3127c49ab188fc94a8869124e62a7817f3beae38bc7231d91faf2ba795114a7", + "tag": "pixelaw-Proposal", + "selector": "0x49e1daf5238e47ac52ce3f79a684ec035e7f9e864b2979f1d0f2d46cf31c1bc" + } + ], + "events": [ + { + "members": [], + "class_hash": "0x73b9b6b2a7d30e942c7e0f3660317bbb33ed350c3cfd1658d208938834f4212", + "tag": "pixelaw-EndedGame", + "selector": "0x63cc2102a4b3877596cde2f2e0eb68416dd8ac4b552d6319bd4705ab48fda09" + }, + { + "members": [], + "class_hash": "0x7008ff3ecc4d158c72bc278dc19bc66992ae0172a813422b5106f4be6196178", + "tag": "pixelaw-GuildCreated", + "selector": "0x190791bd5d67d74c1a3e7e908a7faa1097dc88444fc9cdbe1e4f17d4eb275c2" + }, + { + "members": [], + "class_hash": "0x4fbe95d4ad6d53278422d08cdb5cf07b0c92e1b95be94ee46f343e3c7da0861", + "tag": "pixelaw-MemberAdded", + "selector": "0x5d030a1690f08a7cdd65ea908927c4d28ca6464b700fd14d7ba601e6a5a6b7b" + }, + { + "members": [], + "class_hash": "0x41e0d78ef4c485c7ae37ea2c3ac39f22de8c874b13e2b9eacc97126bc5f726f", + "tag": "pixelaw-MemberRemoved", + "selector": "0x31bc155f610ea9b75a636476db4c4b09c0c75929e2ee378ff21f421df968a0e" + }, + { + "members": [], + "class_hash": "0x25ed6eb5e8c235624310b0668daa8d6b0066ea6511c493325bbbc60512096cf", + "tag": "pixelaw-ProposalActivated", + "selector": "0x54cf9af9951fc42af752b63b2402d7b3a50e99d28973ea368bf03d4d559b9ab" + }, + { + "members": [], + "class_hash": "0x773aebad8fb402564afc53bb5fb53f742673d5f77c8bded89d40093e2574075", + "tag": "pixelaw-ProposalCreated", + "selector": "0x2695c2b5813023020f748292a15196fa26b6a28de03d9b0d98fe03f3383cb2b" + }, + { + "members": [], + "class_hash": "0x71ac8ea1f5058d737fec9736515588b565cb0d95f39b4c2cd405f0e298d06e3", + "tag": "pixelaw-StartedGame", + "selector": "0x681f18fed97923a1fa8abc421f42125d7af9a14c1cb2dbbf21cc0ee998ba644" + }, + { + "members": [], + "class_hash": "0x799caf2579bea3e9cf98e6cced9899ac6733ee30b1bb5e59b6085cd27c2c2da", + "tag": "pixelaw-Voted", + "selector": "0x2658eb5934f0ca3746e650c1cf0d5656f5ed5f2ce59aba3fafac0a7c80c093f" + } + ] +} \ No newline at end of file From eed4845fe44eda75b602df34ede10a8e39e99885 Mon Sep 17 00:00:00 2001 From: Asuma Yamada Date: Thu, 5 Dec 2024 05:41:12 +0900 Subject: [PATCH 13/18] fix: ci error --- client/bun.lockb | Bin 330820 -> 331012 bytes client/package.json | 70 +++++++++++++++++++------------------- client/src/types/index.ts | 2 +- client/src/vite-env.d.ts | 32 ++++++++--------- 4 files changed, 52 insertions(+), 52 deletions(-) diff --git a/client/bun.lockb b/client/bun.lockb index 7fd6be1d8ed1d293c9d0a37cdd3c52ef904ac5d2..eb01d8a05625cc5c2cc7a8f5bbe776527a6b179e 100755 GIT binary patch delta 57229 zcmeFad0b6v`#-+-u1&jy5QQXTAtc$&gRv-tQsz=BDk(#8vNKnNEZpWf3Yn*nd8h~- zQ<*al$2<@5dtYnayVK`+&hvSm@8|RT{CD=t)%&{M_jKLYJ*<1J+RLdWwWcqtHNUl0 z>^I%GFON6uF6`-8oOb2aHg~@{ch-%4G-ZE-EbI9RzlM#iqLk6cA-%u3;%b|n@s>(W zY-rH%vEcf(lgU&vSyEh3TpZ;YVk?tXgWb?hCaVY30h$3HwU@~n0M7u;fg6Dhfir*> zz%ZWf$w>QdqAKCweWVx^XvAk;`q%;>nW!_m8_pcw1X!6Rka zE>cUwBje(!%QqAZdU_RL_T^;L+}Vl6-UDnD(?%VSsC0{8iK<>s>g{t+5)Jg9-I}{>X{E{ z=`R&C1CpQBIM(ei^+yMG74V<^B>V$N?%fB{oGj*ef#be@QhZtm3UyTtI%>@t1Egkx zf+NNz#DvPmM}$VvOmG<}g>NAymLaN}#nA>lHQRKcFj3XOtNUOnn;g!Q@8cuJhQ^JR z$uB*=z`2SuQm ztOW{V1L>4x4uvw*;usPd8e<(gCXyT)9~3Ez(mJ9mb;}Jl1v_Z?=-6mf)M1ElP`{aG z_(*A}y8&s4TX5S5NK@oJT5SNl2y6n}4r~Za=X^AG&OBcL^q7E@J@Z^EVWML^>B z0;!#4Kuk$ZQfOT8xQNIQnQyE#x=z5_$k3EyHI84$Nc=;fG14yqX*)U0F_Ys$j!7IN zIRMVdX5sZP_iDNw~G(pAfUlXPA`6R5ZV&3OuqEy+$adBgVqC;dZlcne! z)vkovOQlF?C$@ItYFCJMg^4Q#^Cd~U^t4M(yArfZNIT=TOG&#V zwJSxtB(+OSyHvGHO}kQBpvQE<)$WN-7zzzds}@jb+J)kR7mY1hwq6>u;XoRz$k6e$ zWyu0L-<4x;Ae9&QzKA&4+jY{a_yCgl(^zn{N|t3v^*us5&52{crog@HWc|fWG$Jf| zbS$RBh=}MAYfOeNo21Rvkt25L(ZhqrVu$^&yLARCA_tFUN)2E=k0(bvWC`D@H_%vY zmgvy9nAlKMzW~`O04u?*a6W0KU%|CJ!s?FUhEz9trIO`FS zL1957#nxo0+0s-U52SMAVk4|a#$j#^Lq)WQdGiWe18Fz60Mcf(Y`cWo^lCgmPEz8c z`L$N+-;*7Z<0Ip&6M~{5WkIoFF+s6$p*O)(K#g`us0*ZeR|8cvx5FYw2M0yQ$=;(P z%6Jz@9xmH0?c!%()9TIyl4IH#pyjpswUN_0q>bpyJyJxp5qtofR=d~%n%mlfc4(j> z?E1XHq65;-RTpRuJ_ktK$=m&sqYdR!MRB1~<3nR{xJNpbFGIQ+P#5)3{->~MD9iKn z8B7tYL}ML)SlC>ntLEVmslK47kWkFB(3`NS+@Q)5MvbCVw@elrI%XUlOYR+$B3=Zf zDSU!s;c=<7~7bA2c^py3U+hFu-$ zWZ6pUgP1!X-a%eG-rb7hfr{y0A zg?i)zq~W#&QbWyvRB*sciGKq}so)JBv3)@5*(TnB-(N`$EP_oD@CTCP9vp3e)Xryg zv>xy-P(wYuhB-hRoOU0H4UHQeIX+Z&6g)L3J}9t`h}#8Q>SOBCR&ER~*d#T5T zK-yLed3rFA>|-CKat%I8kxKrE_)|rVKS`d=08)dKI3m<>p<`t-Anx4J7NgxZr}flMyWfu?e~ z=pY_mi1(9`aDW_s0G=G~3A+K%UkB0IZC1CjQqXHyUGOwNU^0B)D#1NY#g;Pc)P#Qu%V@1eEo<^rO89y37!oth4_X6!{i@hE6@7kezWf0{7RGZe9P8t z2#Gm!D89zcaqBz(%Cnnpw^QH1wo!D4Nr^WvhSfT|x!b@}*^F~D7Y0o~*<(}e(AwEP zV^iMPoxQ!F>EeA?y*&D7`HmUhrP`-itExs8C3ioxK&WmpOs`tMxt5;WmNgL$Sa{l> ztNW(OXk)giO=_15YQMDU(;ruFxTvy`V$kX0*ZDw4r zdfzY8cdbv}UA@sgUA^V6M_&4zpJyz*X=bTcd*-E9YYq0T7fhP>7UG*P5n`G&6g(}H zg?pBHLUl`%>L=pX9Juc0eL1IJ(xmOxGrtIztilEN7E3HkKF{e1ncA4bfLPfiO{>HyPj#K{!Qvxj$bIuZ)rKKH2LP( zojnWm?pT=C(08e-c(N@az5o3&pF<}g z5gItL+p6q4k>7^-Wt2QmW{nqQ7QXfBIe2pww`o}pi(>kizFU3A&NpFj-IdP5eA~8q z+d^5@vb5hVb|14XmJ0zsZFlF{^{yur$G6?>>08A>=%;RP`N&2l>w}q!jo`n0E`q1E zsrY@$r)M<}b`sv$npjS3CzEymPcxrFW~!O0#Wq&{`Ky{0wQU9c!LF((Tbaz2S`~~s zs#Q*QGMRt5l@4n_x%C3ppmM8Q2Ryhew=!T2E4P$tnJl>63WN1$xs$N|EN5Ylr>^BW z$H6LZU3m^xA0cgsvz~)Y7Vu{#SbrADht(Nrl?7jWwaU;@CUb_RD;W8!RfAzs*W`jx zd$npgtd64P>!DWNhJ}AgO2O!iy`GayhQ?6L*G{eKRc;lPh)G?MR9P@`RI9!tiE5My zM!oHI(UOzk)80uj%ULKGZv>5rkqbrcYE>>Q>X%gaXIN5gRK5#BCs{>q_Ifa+$|&hBEL6ygHSd9- z!4d~UF}a7(J<3&ayN8epsP8QlM7gR0QI?`9wX+-+YCwS^C$(y+kJOGrNLQ;>J*OTJ31vL#@09%TX}2b5d6CO`4CLlcIZX zAvM-jwFZP#vk|8E9aw+HxV^8mnxqDjVM%GUn(n|tW@>zzy&jsP)})L{P^Bsn6~&Q0 zf_{XXZeN;=Y0Oy<3XQ4M%VJo(J=B7gO92o&sfvfi9m7Pw3XA%RY3Zs~nfhUMN$okR zmHo&P4DFp%OQB&SN~$8HBTOCrg@SReswHTEiei>}sO7f=ukmgQ>;6LOcvt0b{jo5F zw9n3Zq=*$_{N+CcuL*7{M{Fy!wsZs|XSHfPEUeBXeIb3Ey&g{z$5#GY@QQa+*#~N~ zBRq<+fkHvNt9*l?N^p~36}%GM6jlR-)C5;$_yC!#hme-wq}mOwgV<=gqgwt!@S5nR z=sQqIo#?7sJy6?08q6Ez7R^p$Omu8)2ovp9Jc`J_FIe&igY8>BygXbODrZHwaRvcRF|~jMZhBOvAD5sY=K4FjY{f<#RfrA-|HEllJJp@oWCyJ(qgsHmlvYj2=Q_4$m}rf!8M zd7zAu$@)_XMOchbkcwpyiy0>rraCG2LGu)#T z<(l3&ZEEjwZArOyuUxYnugw<&t*hiqx%Q)6>o`H1nhdS8nD2bKRy|(J^()twXf^CU z`SaaW1_{!DV-FmFD+;%;x^T!!=9Y9NIsuC&9jtL`)jL?NB@26X!->+A60g(>|A|8C z0$0^sPU7N@g?I`UO%}{06!4fNEoz)6F#qSlqB$t7h9X$B0peJJ1#k3Q`P{{V_kx9G zjun&wjn7TgcN!MWTdBTZusXo1B-U=1SfK`06fC|nu+yCv@)xX3>k38jYE?g2 z{wR&(7}nZmSW?Zj^*)5vRcfcFTG>KFTSs9BCshbx%!Jdq9CwY^%N zEvQzzsnoM&G8=HXqB^P-;j@L*)vn4tb8t))(pEbuYov)M252M8wG+_%#Z;5IS}ht{ zKao38uGO9=-W{N9I5Zq4p&fvRgXwA~mF|3Lgk|En+HJm&y3SQK0VItZJjCL-4~zW8 zc8#q(C|z2Gl_*WVUGUoArmVYwwoso9PReo60!8ftG(S;mEND|FL+dMYMbHL|TI+?h z!BSZUElAY9KpQL=ZgSRLMEffx9)=bwY8H!W2PH14T)PWRs?M2d9ascS%J-q1^I1YW zEy}7kKywm1Wu#Us?k*7uvRsv|mWumTmXk6D8g@Ns`=DVzh4!;Nwc|1^mkJI0Gg7ZX zlSscA-CC=)`G!H`zCaV}Q~d#rHWTrVN!e}A>GNLrC52s@ecjst-$EaW6yA z-{Y!mxDmf`$d06&h zIZD&bl*(a`A8D@#gExQ;C>|E|Tu-c|02cWs-6mJclH!2Poi04Es2nazur#o!%dilY zz1%|l+N+f>$P%~PmYb#eqzh6QEIX9Z7cWm4uzHGZ74^2)gFyo)_EXVqi;()&RW)&o zv+XemauBuY-QZBk2H`*cjA>RBbM(m*Zr&haphosq6u`a_wApfa>bs%xqgni@|G+LHe_x;o= zi^J0N#twmqO@&3h7q5e=ORy*>&Nsell}WDT4h{zg?Db&KB*HK+!9>m#3Qps0r<}yX zReglzBxdoAS1Z~c5mL|KuH^_#LweY-<%pnv)>ZN9h|vA4tFq-$)F)20G0=9lORH`cx8OM*?A?S#^8jZiEN}A@ zT8j=j2VvQYX}(9*D#b}@j)*5ZMaPpuYJsaN5hU*`c7VOG+KSyukGI!@(LpruXiQb_ zl(cb3?F7PdkXjwDRxCIr=%060o&bqn1UM-TPGhPHX%n54-q4)IhZV`tXo`x>tMXv+ zy%piCbVfRyOO<|}jlQGEy)4%G8`n)D#| z5-b{OaS9w)sJ&IbHjOS%A^C!S z5w2w*X$nh6sGG1Tbl62u+@L@@?4h#>YK3!wp#Qt8D*R8fKMujLs5pFFtyX=4B}JZE zXm(D}zwD}tJtuVvE#Mi;^>ach$X4eiU$Djbz?bua{uMk=0LjM+``$fRJk;=|VWDm{M!x~ppGC2f3ZEQ?@Ck)e%MS)`qK z^eC(oENPTzgP#tIJB%j)yNZPFC9aB>MM7$ctIGQK@{Z!X9s0YVf5TO^0;C%}!zd-d z7g*FUF&2t?mxY2GuF77QQBElIc2X?4EOfu=s=X({QT1|SlZq&t%AJ0 zkhe0jHN^#-4wkCcH>FKqT=a@HH-&;ySH<2tg8qG1Rkgd)jwc1j4;Hx&3x_5FR$Fm9 zJqfL&#A7lj@0AA>x!lMSH=YD&_Q-|V*h{V22}`OgJxZ;7E#<=9wR5SoG@=~ayC#*qIMqEHP!;+k(3&r3LPHb|%U)b7YoJN>(FyZ8tPZFhdmbKiG<>do-cFa`8L%iP(jMFE!RRfyfkkio zLKI4dm$A3;i@_al3&2#_a|8W!~)cQ_dmpd9&px$;x5jW-=R@Aabm7s7Qc~vD{TaLiqc-KSo>Dcf9I;W z^H%8o&Q(?KoiyL8(=|rr2dkr44_)~gESe_p!e6a;@J{Id-c{B7y_5xO8*V4Ul0r;3 zO!r{*6pN=%vDf<`^$4+gk4*rUl!Tgi(BuoP5IPP7L$eqAh|`^N z87%z91>5sGXgt5STIu;!J`(Y{58UmN@B@fa&qeMcEdA3xZ#^{&G@{h1LNc!>gWZoy~IjA_KXL&TC)~ zxr?f;LN4|Pn|gb-&UA%bFz~e#F4^ktJta3$Y7{c;?tFW%h`QjF;EjN_dHVkW)er0)ph7yMIj6pyZ?2)`c z6i^8}mfPciRN(|5eF!Q2H(({;RGvPa<4n%a0aiu&G9Y~jsoj-w{D~7OYd}!N>wr|@ zCZ1t4=eGjsLr7{ieo(m`KvQ5ourlxxkVfPRkUkZW@?Qr}_1^+gmfLa-eu|1zu#_j< z2a-b%fmHDeZolOC8mI^UGmt)nHG%plWB@b<)&{l&8UpQsHGtiLgl4Vo@D^ z$l^#tFp%37k@5}V{Qm?g0z-LuLaI+Qj1zNNKC+$3GxdxE4I&1|U_O!SnqUQu;=oPDtgl zfYiZk&J)UIY^J`vst4t#FQd_iknA1YCZzJaIlqVVgfuk{kw8cd@cR!3}UGOYun*UA3CU9&$ckq9Rn*VJD|I6|ifAXBheiQFWMI?R;_{P8s zKstO};rR$@$gTlt2(NSgzeCDb%*)-N{51bX<=-GRbc;7YNEO}Yc!%R%o=!;V_kdLH zKDQt6^ol61KO(5WL!N<<)F<2~r1YoUCZvj=bN&VA2}ym0AC&$ENafxV$&n)Zk=sDA zeUYGypLoJwAyxQ=r&mNO_m%U6v|%Zz6^@jy!)-#UN6BraF50IIl{oQNNOh}tdPSs) z48S)Aw&v-Cl;4KigyfJT=Uq5YNafu$oN)UKr1M>O@HFXq18EBm08+sLJU=0IU?8_E zBIO$lp057E9K(1%EjA^E8j9r!e}xKmyN0|D`%yz~qM^zrAul!h8!tmhb|SYcB5h*n zoUe$Ke*xzSDQb&=6s=W2N?*;>38^z{b?GmHB}L4zj%OgG0_!<$08&yWeo)0*$oMyi zPS)f{t8F|xA+@`M+l182PHq!Y^?SJe{{w2IqaLsDPz5CQD1H#0pK$)E zh9^Ab#4~Oa(gpbww<{tw{F(EFWPbrtkG^rfB2xNy&J$9;GLD*GJmIg97NQc}rV1(n zsh}Q(;a?!-Q}O)zK)P`=q{0sgj7L4AW?ywuZWaBfb)c; z4#f|0G!#hbBRGZuX$VGgdlZm9gw*HJKqc+RV|j*g9LIB<0Hhu#aC;(_ zD+SVx)=MCLfYQT=Hz3G?_dJ1+>`y>)=o`1oxGhJNiB|&2kxD=cd=>nlGh;mBnsoY%L<~#CoU4i%~^TrQq*9S=T_apLOAhj2O zbn4GQp06U3AA`Zunx+@d(5C`Q$ASvPKW6y1HaR*96%$5sjN%Ou5+BWNLb6A5TPE9k zLSFapXK~`_{rxQN?`Ls;KZ~RN3ZK89#Yu7a^U<5MQ~%#RYvY0cv%!CG;O}Q~Qb5#n zrNxJku4VKLjy{B>{{1ZOzk7y95&QdD-2d`f+W+=pAhwdfpT+(CEbgzK!O>1eJndu^ zpTQANHeDtDeild3`1@HLMdAOKXL5f(i<3h6_p`XZc&tK4gukD~{rxOXdY1P0vpD{& z>_2%%M@#2_{w!|4qP={Q!u@IU@4-i|3AM!ii?I54u)cw-lSF4?mg*mq0 z)9G#h*bblf-?b7RSvo$Lx4Zww>WBL;-tgJt#FO?T&cv;{F}i5N&-+JC&T0BGKP=d9 zZGp}>-6GxnX@lhU)w~C8>h>zy`=Cv=f~V@m3p%i|CvJTk_hrw$mLBHQ?pLn5W8fao zclyI-HJH2Ww@W>DmPHw_+O2tdD?H5x=Q z5ox1AY-c4PF-K$H=Y z!@S}^d?6w`4#Xk$m59u-azpQ<{cNrcU1kt=`_#tV@O8lvy-LmmC#=6~)NV>lpEa^V zzlCuo=JowfRy{P;Dn8~#JCh;Ni(X6(ZlF`9$;xQkGxU9hu;j9x6or6sXvd7AaFj(v zg3uc;&-Iz}a`OElE$?`^Jqp{OK0Wl#T-DB@VfL<{*JqXOC^1=+{^0zs{ihS;$vW;Gh2_09C5so& zElsZMwb6F#?tT6bj)WL>Ns4@6)9KB=X3ce+3)|b~$9tq_yFPFK{Mzz&qb{GcJ2GH$ zuFcDpP1^TmX^C&#aJ?>r}CL_AszyIC@H`;S2re{SgEdR`GYZFPr>SMR%3 zQ+@8aGI&!*;bBwV*5^YedUUqw-Fdy0-kli}KGhIP+bum`(>v-^3H_y}cA}QBqUosi z3#w&hiD>60^O_7IQv)Jl`KZqSXJ z5gBb7u6#aj-qA)48q^Q)*SWI8)V!bJoX>Vmn>D$5#CuzQ{`2ilk!F2jVzzhx%Ce`(O}qo|6}KAxw&~HY)rW;A+)9aZ zsj_i~!E#le^9k?n{X-5mZl!DRUESYk{Hbf9;ZdKy^>S=HVTQIag~Ud%z~m{3__E=AZozKmInK~bhWlT=8&1{aByX#Zr85HyqI1o`FGO~?|bA` ze_8Ko(w0YOb~oGeWSI56Iybg=aI0Fc?8Lz<+t*bIso*RALcaW?+c?y|sc$QfXK$-0 zmic904SP4FDckdF*jtz2A3fdLwc2FuzOYfqh4H2vHD>|_^x1TF=ssI@M#IYe7DvXY zPW)=K%Znw>#1MU)1%KZ%k7W33KMNhmNCxqqy(Qu)5q>EkKC-nbAeJP9P^NL5Qz3*7d-Jp5 z;C&NQoeq67ez1Gksw+<>R4bg~*Dbz*N$9Ik(DXVf3$xux}mN$soxhSY1*-6gtF zrs?nLo=3W_Iyv@TSW)cbO2*j@;`By%`0d_%fo0D@9HQo++d3614t6ygabwwyc^m3w z4?S;I`9?;YjN#;8a}_8o#a&T!Xx?i`{;>!uP3WdlS&fUJ_B0IV=G2l!%oJKp3-UL@W_N z_y{2Cu%!YB&xIh$h%jYd3qgD#B6}f-dh9C^nTtRSUIfC7Wi0{`uo#5lVi4vma4`ry z1|pXT3#MWq4iFK=Ks07KM1(H^VYUQBQx>rVgvnA6g+w%Grb|KO5s|nQgcZvtB7PYN z>t!HXvV>(IESH10O@uYGS`MO^h_vM(+OQHLl2?FmSpmX^rK|v9zY@etB5aw%N)S(p zSh*5}9eYN^l2sslR)J8nrK>=At_D#?gah+h4dM$C*{eY~v9CmAt^qN44G0&OwFX4M zS`db7LAbHNwIKA?fygDogQ?bmI6y?yIuM;$4iVw&L71%v(S=2<2Vt@SL?IE~nCS)( zc|;^`0O7^*iHOetVVwb@2TRDnfyJ8@5%@5xjewqP3PCScLeQJpYy$YQ6oNjil%Owj z$OQCb=>&f48G%3Z$O80dO99MtGa4z&LL-69Ycu!(Y%Re+_LX1|^W6d%%(4J1U@I~k zZbjyyEO0CMVQeQs5L0CXf>{v3aF#<5!i=^7LRkdC2zHzxjG1l+gtIXO5iFlzB(vB7 z7{w9@B3ThZ6tmh1h-Om=Mza!v7-q8zFovZN#IjO?IOeb$FqWkgjAPFLY{?$D>az!~ zPGC#-P)GMtM~O&aUVA}&AtHM(h)L`#5t;iy4BiJKk!9@z5wIVG;eHSr7PudT-T@G~ zL`-3-10W6%5p@8>G?qg|cn%1&91t^DL=Fg(gCGitn8i#Fg2*Ex@gRs4mQO_dArRJw zK+I+dhd@{!263B+G-h=eL@^O*he6C^B}63Wf^f+Nk;t=FsC#$0YY)^yOBb2o<+U99Pp z*GoUs&aa-%*k7OO(r=-)2aM$`;SAi(JPvo2$Kn4<=6f7OzzGn0iCE3#CqU?(1QB`y z#9C&7BJy=?CwTdKraB4Oz=8-eSPsEPW^@X$iA4}(vf~6<%=9!Wia&#j5>KO|Ei9i1 z%dhH5iU{f4%UtDeCT=1!M=+ZxnFF3@#O41y~oQh zk16Y$({aj_%CDA0{x&1=L&u!{%N#3oDVtfHMYYAKmZhCVJKI?a2)bv<1MFle1h{7* z*v%aB0k~%&*vp;~>|-7UfcON{fx^ z_iooB+AqGVkNslb%Gu9NUp9Ac^n8NQ`Gq=m?lZl1=llO$w{Ur4TI}zvtPt1H(-+|H zab|Q8{W!rQ2u`x&1gDtkCBSJmhTsg#CpgP2iU4^mfgqn15fm`1-vQ^?6oT`tgrJbw zTn1cVDFhc;DZwS?a0O7r(g}WN&j>CvkE?(y%1`jV@_M@rJAMnJ~rHW+B>t~E1vb<%GvXd3V&vQ7n3&Q9wq?}()TcF zpAz9$3IYe|QV>h-fl%HDfrIpY5T2zV_7d@x$sd6DLPY2T5Z~EOA~NrTFn)-e-ZD80 zeu(Q}zymO+iTNdGBOig$dkCiR5emtf>0=Z+Kt$qW5IQWMi10@ste=2TvVaoCAATnQq$R)yzsa}H!cm+b)17cM?~UVG=#$*5%KRpSib{- z!`?d(mhVB_Cc>Ioy$4ZDMA~~a+(yBIyP?+P4`5DHtv1Z&1G3nE1Yzb0!j_d1@sx-z zA5n=NOCe&(ClD)%P%{sTqvvN3g>OJOuxAweFGQHpkUO!rlq2&C2p^h!F6`My5CLC_ z_=GE^8~+OpT2#7bKHcS4_xHSO+p*i|4pSSYeVo?rbD!g-0n3y9XWid1{k!$i7mB4L zetfE)?3TZ^_Gq80=1uD!!biJTeR_ZSFy#KiF(>Nn zxjgMe6P>4H^dA|FkGwW4X{YI=lS76*4)DwmT4*xmXGWRL&|yV(FLDm0=HI$&>RE9o z_NeGxv#hG?nBB@6OEWZ?8{chSQFy&iU#HgT-qpMUPCL%^-e9g8*6eIm2h&LtGwfUH zX1b3rc)a4E{q~&8Gd5T~pI^PumSul~dsh+;dB;9;+S>M!($V~b)fa=UzFw0rzDZg> z!7y}XNqHn$5{9frWRZZ@lO0IKw5u z=wP6+U*k`%!FThD2g%ux@0jP=pD|8d*w@b(CzBr-r@>z^PTeXtRrZHfY5eQewbN_d z*gC={-sbCv*QYxDD%zOrZtZjb(rb&sEhg^perjaX^7O@7*&loQCNH#m6mn+Jy9e)Y zojG{!Z6%ib1A*A0X}Tylz~#>VY}5P~mE1!0lh1!UuHWhQhS_yhUyW{8wZ5}z>*%z7 z7iOXces?jt7jB3$c#1g-dNUg=IqJL>?hsPen)(LSj2b4xA-UGTS!DNX8Hp} z@-GmHKS21hd=QK56mJSG$${-ANL4>hDT@ZOhdLW{dAV#qqA}m!P z%qoG1ViA=<6cbTM#As$(8AP%^h{Vbu#;|-M>w$=433?!&5^@2f$*sULc^9;0ijnN zL>UoNn3o}l14LvSf|$m>5)p0$VsKRuGgwwt5GFN17*+!@iv?B#kw-)>5h+Yn9YlOh z5K+}Z%w{=6Sk?kzW&|RQMHqo7CZdptdCas1h-70Bi8Vl^vwR}#YlE<^2|{2AH9ffBsT<+Xa-^@%O}F# z0)%w~5W87I0}xM%xJ|@fW@QdyNh1(x<{l<&{>z_ZLa5M8H^UPr@nt@ zd7rTC8=6(!4sW_NyYT$A%*v{Q=V2j*CnxWGb?V}+D^ogNz8F%OzU;5Ph0}h0TfA)U z8aQNY{uo8wHa|M_d~;=mCTn{9F^?g$y7Wm2p5ydluXF4q=hn0InjH^xA2Ks*rUa?`#UB*VP#Zr z8S2HYhgW07_dqkmH@h*2lk6)I;mtt|ZUW*o%W49`#1e#IQxIoaU{erzMC1~Y&s5Do z#9M)gY6jvQ%OS$D1qid|APQMTa}dQu6cTZfnOcHKZV4jM5=0TpC&IoJ2x}`4msx@p zh^Iu{CgLiyY5`)2HHfqpAg;3#B0O7zaA^smgr&3u@r8(&MBHQ!tw3b90kN_bh}-NL z5dm#M_*jFu%a&S$(6a$iMnoy|Y7OE55!tOlJYZjm2yX{sa2pVhSXLVlCbl39+k$w) z0^5SfBO;fGXG~=SBECI{C>szjSPl`Eb|B2!fq2Ox+JPu0qL7H!%+wY{at9EJwjkcJ zd?N5_D#W8bi1#d^J&317+$Q29v$6xRgswzsb|5~p5+XbuK)7@O@s*`?0P%&0mqdJL zc-IQz;Rs@-8bld;Mnr%U2p@Y8zt~cH5PHra%0MV^Gtk|EPQt`wJAl#AVc&=ecL6il z5sXrYZFZ!iuqzltCoq+D*Z?OmdBo&`!3~1S85PI7frxSjVZd^Tuyj`#YWA%dd1ivm zsuk+E+ppdwUUh1#SZWmRADWW2m*r~mf7|$QdVRZf`NLfInkTdzzwzAWypCO}t=D`C zaG1UCj~2^Xe66qmwcni=7oc%;u+9GY&v$fP{!M?HEu^-WXE&AnU&q$JI=UwG}x3Cx?`afy1?IR%+wYBCVQX* ziLM}wSUwT<9YI*TfvCywx_*oh5x0pjW>)SXmUIG<<_@9`D01 zUJ_A{IdlY(*#*SPjv&lfgeQoAt{@8O_;1cky+G)71Ci(j!h+=!aexTx?jRbogzg~1 zJweon^X*)Cz6LCF0ohc9^bP3flWRC+o5QOWS3-*#>|X83)WXYioLi>xf`wqCOh zyO|u{UP^*X%`1A>r?bnGpamK8mOhJ1n^&}8;Q6lIJreFXp4fH&!S54q9jbcrNbZ35 zLl$a&U0pIFVnt9J>lIPk&8>nqMz7eZYS$w_!a$q~y7XUh$t){YY;^GYhpPQbk1JHV z=0fYT2lH!x7}4BkQb*r0O#>Zj21o32-|m#xYDVHbi>0eaw(ZmQ)caXa)AEW}RGFm? zeyeZ$szSY1+V3}u@f^N=o<<`oSvC&-2c=G98~h^Tm~~Be&Gf`0ehjb&ZOu zRG&B5-|Y0dZz*k!)NS_1*PPjVpQ2g)rVqAGcsrU`Oy8_(QPJUJ%@<~5Jr8U3dTK`c z-q?0Cj(5M+V%vOGK;Ey_%@%7qObK)Q`phi*S)s)z@8fe{=G$~ik14Lc_4Vo)pI>c@ z+oy*g7b{kXk!V@5;&t1njXjrhK$zirC1hfwnsF&MOYhF_9(?5JgDDpR2G{MpW=-O| zE+cwiMib} z_0$#q?GCQ&Cps+CqoK2|SZ_m*?S^-jRqr@GKRxhWQtCmg_764D9z723sJEo&!?#rm zi&o7#5o^5Y?asITqdq5Xc3M^1bzz?aVQV!@C&hJ`W9%)yw+LU}ql#Nstk`F3gwvMh zJ?-yWj|rHS-Z<=Nt4Z63-;mwP?BtwhK5XiP;uG$(W{+q(Ieb!zf11qUWRroz*XUYZ zI${^4vD3JG%hl%|C!yjt6)WD$6id#VKPY^1;lA( zb=~vi>;ZLNobo{0Gxdz?4eKmiri=>N7khNEu0hq-?t6H>G$-0ttoKs0UKcjJTj}0Y z^VQ-M`6l!w1o@d+8xg#wKK7KKO{cY}-ACYNojdp+9|MJV=#Th;y zr@3rxUS-BTv0~}(Q*0_$+<%GDw%5z5oiWa9JV#+`6=>FP_NwnyT)TTNuk3cp{Y#`(O=%4 zr4ZP$Qi2Z5!3Usb={|~Hh@0ety$oJrx_O;GJ2u$jBR@=qESa zVvD~3mdTR59P#1|W)Y#d%NhnMkae)aTgkJsm|%sTa-JVvpR^x2x+zfHSo@!QKOQXo zuXl8O+PMFAh+>w))FMp$LV6N$9fnByU~q{gJNwpaJa>6 zv`DqJq1yg~RyBXoYE|m2A^ktP_=bJb*fnsPSxi;bW9Jjl#E7-LiD{IL?U)Tt>^wEQ zNo@8_JUGvtc##Y_e3!EQ*P@-|V#HbGL`8k&xPug>DZLbZ*}aL1TCDygMU|>1hyM)c zlO60%h@ufylQa=ESINbfRjKAl(7ycZ?UV39bX@PVjv6 zG7AUJo#dP`IC^^zeYEe`qA2$RNB+=zwhYj|_--p#p79bdOmEO>!Z~^o7pe4~xg_ZH zxx(|+h3?I{tDK`@^WoezAgT2s^f!g{DdzcTC^fq{S;EN%AnC72Xbf*~&K&wB2z_pX z!#`O=NInniZO&PMqc=y;Fx=&38$sU>j)vhL=NdzwAeGg~N_pWXAQL1~eB~JV)f5s4 zq0d8JxEb_Np6?Ma+Z-IdgNmZ|gy*w_POp%o&r={p&70AVxi;YFje9gS?>W~NdLwcDLHWQ*S~m9} z^!doScF?u2`1!;+T1vn3D0~KofApSW*%8it<@xNug+eHj^i@gf99}_5|Nn~k(R}Bm z8YV7a;)h;KMj7oP{ZJu=yo_@W(7RDA@%hO)N9fVeDdfL6=LCH;bn%1yR3F|xD$aTu z201uf(=_z|b;-^kBatRNqbu~YoHGSSOVbUaf=(Yg=2C_35bYO0>4Zw02jm#a(h$<& zl8SVMYz9ZeMaL}4*9o#kQ5iq+Y0Jj6)v2jz$J4riqL(O9Mp;|vb}=ncDKFvwpw5MnTTz@T6d>CX#$L#JR6*B=}O z!w2#ljgV8}JYP@fZ@4oNoa+Vd9p^@ZLpAiOS=k3(Hj?M_1-D6;W+^^Voa_UAJcPWD z=3HOs@thmYcG~FFbd2FiI6cXJpkDHA4Cnlz)2m#_k66xC=if-Z)p`F<8y$VQhTghB zZ(^X=K+r2BdO~_ZdP966eIRs|*b2#pY=h7hVkd;I3cDeDAbTPEAp0Q)AUTkOkVBBe zkX*W+$QVdd~b#3s0s3CV(B@PlPEvZEk$wV@Z*`9Wyvxj^W`;tuhEI6&y4(hNfP z%$ATEkU9`rdi5Z~FhznPNsvScU0i(dxJak5ojX+ewHf_xsxzbuq$-52D?1=`DcK7- z0yzeu`^OW^+D@mQ@)yQmm-*P~s9A`uPFsy1hSVR@A3|T>`-zr+LB2pfL+Hg|?;#%` z^wO}`kQb0YATJ?wJ$(v%2zdmdH=EJh(r!Ys(bjd~1;|CnB}ftEGKAiYQn?Z~G(9LP zh(5#s;sxmesSYuM)P&Sxz8x^UKQYq3AoNz2w~%)bdS%Ni$ZN=R$P36H5b@7`77I+5k5bvoH>fZ7$(3DOzT z1!4i|hSr84#6uzVVbgUq95R);*kd&5$~cD&h8naG>LLieJ+?2TAH*Nh9})lwgbaX$ zqDFd0ZUN*xq!7{w{2X8!M1U-WEP`~0&>M~QAS#w`uVc$}9dw###Mj24U%C(lgx(f6 z4Ka8Fj0TQ|+=E^Uq3dNaqy#bmgD?alKo&vFAq^oGkj9WEkfx9pkd_c@h#jN@L=CZr zI4EUowS$h*$QgzU#1+yB(wXgb&}popcOo^woXG&v6>Tf=wvY$R-HAEO#YjAfy=0lt3;)HZd0`9ks6#eoaRl=oNz_5sN%XJ|r0u35kX@L%isU zN>|XMkmC?~a~i!(Z7XB}M1U-Wq_fjbI_9Q^s7?W)6UutXcF1P5x`mZF=`;_dS5?J8 z#z3r4drL?whz;ZgYWV~58bX&zx-6DLG9Vivn;`U_IR;q*Sq51SSpiwe5}kGGXf~iV z92mv-CbdVEc90GbdWYB-$X5uxe{44LJOMhxGrG+f4QT=02GS4SH-!YDuEwzGtgV3j zjxs9b`++n$klu8d2P}ZlnR>4-P8|E8jAIrqI(3xmk=~!B+hOhnK@Em|#F_1A3x_P04 z3JxZ%WtEV43oD0K~$(6Q(kD|OMSsp<(T9?9canX68J!!Jf}C`ytk9zP2IaNj)d zG)>_W1&ap37D7i#8gDbmTLhlAQ(8|HD~c1{lAb~NLqNLLo`l{5NCQQGEl7WsMiNIE1LLKg=*SYSSNmFYqe|5_hNmt7hF8f`pyke!1RK=L6cAjcucAi0nY zkoAzmkd6Cu-F4dNSZTQoo_-LR133WM1lbS4(=XXRX4+ZD$tD0Qu2`}|5Gsmp$ncy- zb`*kci?$Z?V4r1EI_uOkqwdq5X#k0W1VK(iA|d-&PG=okB{i7O-geeed%T2t8$x}0 z0J#q-h1`YQfY7YI11W}FgZ$zjZC|dl^e#FzyHFLBm5N-4ltBI|E9a;m)SNb5+pk+< zRT`>7o1|@ps=oIZJmsU}gp`-c-s85GqfvMUc?zL=ogV1PbM}d5#Fi|)u z^7kNLaU2kb;|mO0s-m;_p$*h$a33IVA@3n?AX*3Bab9avo^qW{>4rNtnoio{xBV@K)q(e|5k%A@5f#`>>@TRUYa4m<{$e+q(j8d3!mgn!lVij`3i={i7;{?(NI z*Mp$>=TXo)Ko=G5X#96hXh)Z38I3MEqm5WaXS7kP=y);O|1VSFK5VT6|1JWwYt@9% zF^`UW<59K}FbP;0NPn$o1gQ?G2B``$gwQYO^dTyUrV4)0H|&fdwIDP_Oo4Qb)ACxR z^m>rG5E^s(G=gryxrRXcO-}=e8HE1V3d%z|IkgHxX<8j+qsl94f&}UjUDN3Xk9y+@ z>;a);*klM@{}Unfzg0|tjE8tax80uwOt8ZjoJI} z-uJ!9+M;N=T4asVqGXI@jhRY}b&x`oK}m>E_N;@UhY+%FF$UK*Bgu??-&L{>#**C_ z^8Y^X;u^o2-}3qVeLi33yyraUInQ~X=R9Y5@4eBFA%bmkUF7Nj%#Eq}7|BORK0?+9 z+yTC&;d(wYGPgzmA19fXkCuLbKfuRHmXdpBIzGlSZA+j9&>RQ^n6{amdPoJW@el+I z2h<^Qhdhk0koE$CkPoKFZ-v_BxIf;anEeW7J4L)LUAIH1aO`?Fjr2w zoIepc1(*y>0&KyeDlifG@jwcY3`_u~0&DQ29iKMXQ>Fv(=W>#j zrr}`*MFtC%>+%k14zLjT0hkAHd$p}P2S)HxA-Se8IS=i1y%wZfc3ySU@fo)SPiTKHUi9xm+wW$v%-JY;F@(SGFy~_ebg>Q zXi$wEb}x!JeS~yBa30`AHd`_VWrqkAOwXZghzUIi5nAYSkUv1JLxpdWFC%*ixCmST z*l>@5u4v9I`Qw;@Kr`Se%6*V}1D-$wpccSepc;S+;0!nc+?^v*d!Q;%1>k96gS0YW z0hsf3d_`m`0IaVvNHstNI%j)*Kv_7l#Yo=+Z-GC7X8;TL3h5i*HSiL60Xzq|oS!-U z3vdOGcSr^B)B+-)15CAuXJ*Kh2g(Bc$5i-+!wRqjSW5O!YouJxumiJdfCJzT*m4
T;*0QrUh zGh&9UR<3J|l$oiTWDT;`xJ^^!SzC4R{3Y@{p&|g*Y!f^uvs%AEh9zg!`Xk>D1Z;{% zfFHo4V7vJOY=5>fn?&*tq}&k;s*aEa@&Kd}BK>rLtWDM|^M+QFC6zKE|DBpv01LrR z$4=H3XaNKP?0kVpdBiP0DQ~XSad{i$dE}9R3&8wTS~ex;TYpm4j{g`B6LE(sBPQZe za;Iw9cH|AfeBcLQ62P|}-vD6%pSVH+ehb4lBOL%fiFE=d0zCmfIClrS0^NXbfeCE? z@jwc|`EkHlU<@!CNCZX#!+{Y%0x%313d8}CKyM%%=mkUo(ZF{=A7G&J9D{TKz`?FR z(tbb`kla^!;6kqC#tbz-82MOWkWxMbDVMRW;{g_I2~^GAJ_`9HfCXZ~=K*tpIRI;F zDli3@415pFX8X@VCKZ?o%mAhX(*Q1KSc5S)=CYl@LLd!T0I+muCQr0JWY? zw+>hfECbR3reSj|<@vuDnI%9bumV^PaA&IluH*blU=^?iU?$sut-xkr6Tr+i08GCg zU|!rQ3(mYZ0`?fl7Nl9gj{x)iDH;ED2G~*d06d!Az%D=?0hclOnP)*mqcJ*V7;^GDeJ%#5XD zO)%4vMx@qDjX?8h8!ls^xjpCEoNOj8;{mZrZUUdysrh8KI}@u+?kagzS{^lz;GR;> z%$e~6K-JbC$a5zuQ>IrtNWI&LiVSOvvRbQx^0OfNl3D za2{YGnTAtlsXa4%~YlGm{|5tpE=JnnD1WM-+6Yb?Up_FZdK zRtES@lO@2+nW5@ZoK^rn@03UVY1!w`JW|#imvansLFx=R0ggaB^v{31QaXolMGe3e zs18g;IiFRyQ7wSC$-Hg$LY_Y+(*W=Q+=2Q)J-`j93-D{R+5qo&xD8+P@x3eGx%vZd z!to#e2?3@e^(e37>pv62Z{G@s>~veaASB&L6>RiU7E666yk#znwBxNc-_7r{rHfY6 z$eZG33AQzQp$1#al)lli-^KKcj31Cay_Z9?279!c@P;0q9{2!3kPmqe7u;%u;casz zP=+HlM;co+vQ?Goodi)6?(Nag1D$U4p_Ji5uy&^pog6OM`sRWXOHfL^koz~sZ9RWP z)OdUNGE0*J)aX&OQ+f7N!T5w{-A7>^R2|OB7*a*Sa zuPrE?z~cHBp?;m7wv07W3_y(|Y7W;ZShs7<(Q(F_$qgxk+pYnHGbp-mdoZoH`QFJ! zieDA3NtsK(O6+>2xv}O>Lwbm|dI2AIV1?akIeXfnlOYR?6wbcnJW@#1ooE8Pl4Yb| zqig&n{8BPSIVp>FoxEvlg3zB5dJ7iiEi__N7#_u&$u&{<$uQxVP^6(j1BC|E&LB9E zb&_CZ3jKO{cv1Z%LGKU*&9NnYLho(vR;zx1WG5dFh@DT(Hw$+78uHjABp-;9gaPEy&DmwaM)$cmh0_z>rP!Zr9xP7i)gEST+$)%Ps9FWx~Je zOJ>mOqt-zdHc@C*!eB~L%aE_B((7aX2{kHSL>( zaj2=%-$y0gq3@>{of2OuIWx!TNLt1FOxcCZLnvY@oJ;m9XD+G}B8Qr_JNgD5taNg{ z(IH!fP!dA%Uk|XSXJf}qr^rN|{0>02KIr>LC{|-uAJf-9=_B`}vf>}+;&ORP~*dT|{moo%! zZRJpkn*lw!hSKyIf}7R@&xqmWJVND=G%b`a&wyP>E;m!lsb~f~QK9}@sl7h8y&O** z7v&Wu?zOouSw)KbC)!iaOk*#`c7+jwO&N(q7R;Tx&JwDY$iF^?B@6Z+9Y>w}e|J!x z+V=l6TRv~Em|Sx7>B1;Qksql(3ks@(NHOMrcMRXs9pm4`JRj9n{$ro`kA@<3J z)vAF)nfrft$bVMZXW`cRfAy>XQ8`#I{(FZqQx_A8Sd0~YC;6m-%WpIwO&ITc5}&H$ zwcpa)Z$@VR{kc-$!P<_qrBX9G{-+}?uB`r*gM%mbdOjvMsTv7(4i7<49!-O?!zsz8 zUc6R=O5Ti^;8#FEpcT5%Ai|ns-bLO#Rw=IDdjFPlv%#s6hj&AeR_j8`nW7#jIQ+#V zg|9kr$9x4SJUtq*6!u-|JYieu(VeO<6ucd*zLhDzeG*t*f2pV+dpx!?*oo|<*oDG) zCVaL~2*)=ZJ1i1n^)-87^AFC$kM?|1ZCzqHUIBchjf+SbuVSn$(mYlKtE66_@1arejDu{X1-Bw8OC*+kNv zFH5a{Wg{oCaPP6;_rtkYX|*$H7EULZAe^@gr#Z_J&O3#Zekn8%0bUisE6^;n-sU#} z?Tsx4hf^3Rd`E+Vx8Qe+zP=e+w{whJ%0h8IylFI{s`$nMEV)3wrmVO3;t~h0-=4T)Xf56SM1}@RBz`L;6z03c*H%x}Q^z z8Tu9McM^XJ1;NcV{J8Ij9+gJ8{ur?4paAe`lhs?uP?*8M0OgeKh#(BFmM6i?(SrT{IP8$7m{7M(nS7L8n$?ubmz(A6@oZSF!5# z{h|pX=7hJzXa_~^5Uic0{25U3@ufrho8xTaI>o8qnUAQg^^+% znXeV>eD^5?KQwvhI&fBcs*&KdQgirKiqn`?oqsUa+@>=I!Mcg0sXswg1;TX_%O=SY^O)KFT3>}8J}cl(EIWJX%m!h+{@_?SW*)F=^0IgE zyki#3-3zx3CQZlDkc~p(#|>@YWGdPy*jC<+YZi{+e^#u%!zOTfkrqGv;IIi(ux1Ym z*d+9qIos3zO~Qcx@`Oxzn}wYgefz}5yC>pG(XQ2x3GWAm)5G3E4eh`Ql$C`5J!}HK zL#m9$A$fv)kXig>;OW;#4%=YtejeT&%jQsnEkad)KaTvjzQ;~)V=#%I zD2MQIBR2Z93;A=kR3j-aWg?B+0o+3N?F^jI^>NU;tz6;N}mOWKLE=O^^G z*0`}s@J||Ay>bWV$N}GNEn2jZlClE*R8#Eb zd2e!MBUOoOlhg)lQ}K?{)+UKUTAS?fb1Yx)ENxkm=%i)I`U@# zIZ}X?YW}3928^e~r9~o;V!WN^4gCQ+eTlJLq8l`noOfZyZjF=I(wN;}u4`yI7&8{r zLZV1fgt#`be;co~s|SoVSR99-t#3_b9oX0=rdNEk+DnWS9ZQ?z zr@gx{fD)GwsoQn*1O&b%F5wbEiA%CnQ-zxD2JaG=Mv34&4Fv&y0CEP?mAHaSba!b# z2>xMb*s%`<{v@>Os7@wvg*@BKgeHxQtNXZxR^#vC#hXkMJ!;se`d?|bt+TuT9b=6z zYMj}~$4@@64-3boDYr>GBvf(jj4Df1twZXFblASm8?&_LPZ74TjbpaI(y3xZnd=~6 zM=5ZzvntoLl2!`lUX4NV95oyV>`c4XaHun4zEr~%CLdOi;|IZ8Z=NYzepv8#og-RK zm@H99>x@e#4f=qE$s>~@4kHcDq~&-nO&@-ENuNpQKL{!Mc<^L-X0O=R`Tf{aoh5;# z55(hu@{c zvCv41?Z1H+j$2IGdM)LE62DDjegGTX>~-XJ0QZr8>*WT6>pJ$?FuxCuTfE|UArQN4 zpm_%b4^!@E$p#A7ind|%pg7)%{+=~zZr7VbUrUOUEFIZ5Hhu_NU3vX|zdg%uKef=f zZ1p;VbnK zn`M(-Nv%~J&?B`hxUdRPGkr4^=Rl3Yicw!&b+uWs{#G-ILh2`d3wa3QcI~yTbn+mS zg)hGAa|Lf)dA85R9Jbsh`{2Vjee!!(HftyeDCuk&YFP9?DmdGfpHP!GFsvPjo{nF^ z6+G!gu22omLJxBVH?#TM-yf974q|l#@p5^ceEcvKwJ>%-l&c_e&K8XduCQETm)$1@@JoiC`vwuTB zvcIwyQ{e${yS{=7;HSQ&YpC=IAv8FLgoT#2vB+qD2*GvJ0j>kORGhcfZ%)!@OSN!Tc+Ts zO6pm<0ZSit4b=jrcfD=}oj!_PePf95uV(ybt(vLqDgK1e(BqqZvNJ}dUwPKLAPN_3 zP5Jd=BYaI2HGHXZ`BHq=?w9p@Yc)Oh(fJcXsy1;Sg`b3*A|fT86i(`|{UY;N`M$xZ zUlMb1Wxy*zBI4@pU#QP1;hr`un}Sax(09+4DZgJ76#dL$Ljx=cSQPoF&?lQxm|_qp zc+uF|xqH>;P0fFn77b}>9g$7jPvbgjJScea)w@1Fxyq|cv=oP=+qqe&;e)M3?&ebm z-_v`ktshUh^lZ|f0r#~E#g(g}(YLJXP6P!mSXg1(vndP|emS7vQMVuIw#@g;mSTkh z%i0;Grp^~X`H$$_6O!@Km)jO*QwDQCaX^WCiQ^nu-{Eh&tctDny4v?XP{W$H%AW1wW{A- zmA$6vB)&P6Mq~0Sm$J`+kI5mr3O;H>ec&Nkc{``B*ws2Vb&cEt`sWrc&SOEE{;O;N zpU!(?&gXiKm4+!Xg#qTA$3Em=RV3Z%K}9fP{R`*~4ia$zOV*X6lyw18+&)T&xqRy} zddKOWW8`@e3OjsER`#(+x^B&D?e~+Ufh;B_frqHyMNm2(r-hsh1_?0AZnTtW(gc3#37W^-Cr*uj1lT?)G1j+I(S>#^Lz zTVEd(R3*?c9 z-fS;W+dN#*w7*2R^Wd>okdrw~^>7Wl_gguQ(kryy>yj)_oxeWpy6I^3$XJ8kg7am` z`{zTI$}=6$7pw(;e2_wONU$k4`U=i7;9T)4ZGDAT@%~uLuadq1y7jp#pAsH5@6pY- zy){BStRzjfudY&90W94I6ud36>2l&$eb-#R*X2(Iz@f3V$pD4@WKi&g>U3>%oqBrz z{#wm&lvto7EmyGD&%*<+^RL(S37&MtDMeubA(mey=j#w+o5G-8)wmyeelzN^L?P|G z_Ftt=*P+EDS1IMX;HJkpH)J`(|!*%p~q~#GB)gzN7>x)yF3c~9qHIS3i|`;6gWL>|T6MS3-l=J0b-9z8@$ntvaAptmS| zj6$n?+IkIeLRBaDORap_AoV)#UKUnsbUQ^rL~EaXins{@T7ZJJQvS+| z1>JU*AF2odijaJAd-PYeycwv{8oKNq-OPiWcdLCq2 zK6&0kx*TZ{(yV-Peu#8;K8-`U->(WM*W@;JpFecAmN@xxRL?_=CHhEoulL6oH~V{1 zjr4}|Q9d0AtBP#d%C*G!Zsk)~6thQVOV*TBlvK{s&KIm|{&3itmD2q*#{5(Lx zkw@q}a{ApgJ>N2N|2Tdm!-e>~V|{*R%U{+ULlBi}a8?btO`FhGnMRVeWW!-$lnlrb zKoVYkE^QDHM2;1*`PKQU%#eRjj_gLCN1PJ5DADMj>Qv|YI5m|3hL{+JAo4LBso`n* z4SL8kSdJ?;I>dH$@|M!_v*HEU(w+*|bowFAJZh|i%8GdUtL{<#5q#-0J*tsabt%>P ze^F>92CCEwBfo?PavZFUKK#5m&_;`#@4U&VVAfNNCDyOV+wtW`5K_ix#f$> z`8n;L`9u*L^HrT3s=P|Hqhn8TaUkpQqxrS!y7Jjrjm3ZS7L{CI`XXI|p`_7P5q(Uc znJ=Hi_f%6LV5%!$DeD=A^9e(RSana;5fnFfegQXEm9M(Hq67|^4)}RzUXT4sUx!Oy z3lknt9&Z)CeMGNb2-`mwLG7;O2`EWc3W-`QZvt)oVxG%WVPJI7n~{Z0_~XF5^TRaS zjY!G+Ilti1^*ok6!L6wDCLJ+!+f^!l1>s8dH0_D!)c-Yh;{Snss@tghh!UHa`e3zF zbuDk7yw%N-Z4tIndTd>PyOg3k#_GL}kwL4&&}i zs`MAU?(AcEzpZaGe#E`YS|??~BA~r~DQ|Q<7P{1Z(7ZYumLm|_R(eG}|AN`Dhns^` zU-}a4`ictBi@NclO78?eebOu05X+Aauz0jb#3g_flEHZLD~fn0d5pA$R)?d84%LyA zXL|ci3ULyxs#$r~{ml{JW#iuelOO6&z`HBMHM;iD==T;FaDx(AoKEg}IAVNoIlhbKx0v1~y{0Wj8$PAUZ(ox$(3GcEfp3RVz3i9ro|rFu zyc(HoM-4Bb>l-hK>uC3E8Nc_$N5-JplHRw z0%po*z0MWxPmbz7I>^{jNv~dIb|t+nmTO9SI(mOd#kZZ& z%VEuy^lI}m(`rnUP5yhwqrVNjR(7Npp6jB%#w%-^zJ9kKe>;svmlXrF?t5qt(q#8N zvj0u;_dTvjtW-P%_dRU88RNP&`@wZ}d?KFNv>%q7^msDI?&%bzet*?6i{>cx zw+bU??+)nyV+Nl2BI4GiPW!_8&m6P?&lY%I?X*BQsc!3$Z_MPuWS7_RpbUm`Vyup| zy+mh28w)Yli8}fs>*gtTsZbj);5-rrj1KqmN5<26%oyizemC~Ftb2T4YTibyLibvW zv1Nz#jgIO!d{9(8Eo~!K<1%NO-$o>ZOH+}|T)bs=ejffFJ~F#Ta^kNrr+q=9JJkyk zJ5X3p(Ui)z5iK?Tw6(J6N>|#5cJ$#(u{wW21TiLC{+)P#%HWDzP>pp_wDT0K;(PuIT@%h2@@ z(SkxlMKAi$9<_)0v0{7CoGZL2u7fC2_b}0lwug${KR({3Cn2IGz3D7ErG?||fkfun zMO;8(9l>*8d+`n(>LPx{obXA(P>ic}2eFDuyM(*eQ>~7oH&yB=+S2Xn5c)}b(ZbNB zqc~R}^RA-3jikE3_{e@SiSEN=8VngexDT}az8i-7eOE}?ySrGHhI4LNS9Flw6(&K> zL6W9cTzu4snAqXNBI9Es-J@gr^@|!39~Id*!96}|aO{XE_hEhc=c(z;Inj|ayNh)N zT(%lcb{8*e>2^=N`;vxa*-h+5`@7*$?ZT8|SpbOc$pQqj)K+BP9b?_vQ*0;=g1mcS zbkdmGcZZsidx^C*-m(ey_7Ypm`MnZ_Aun7!>#p--H=*2_qO)mS)R4HyL3Cv%H1~81 z^x`>RY-Z>>OPr;lS3ihf7;euNt#n*ko<`5daGA)kW4^fC6o2$Ab}_6r>xNj4e9UwX z`0KZ#g~r>kXo)zu3>_OS+8Ac965p7T#c0ut4lWi~D_x|*%+oiDHMCxhXv;>it7W*q zhc70B^h(K=mEivC4hL38?JBBI)on(h}9swPAwCb%a=_8AlvGt50MG9lVM zX2`IZel)ZnCO^n(QQ7@sU0SNsIg?NyGq;%m!@aK4m7$tCT~*5IiLw~2uCkoFw@qwC zPJ+&nJ{T}@cDuozHMWRf$}NgSU3sdVE#mJoZ4@g~bEv#3e@1|vWk7sn9P}9#pD@fl zGA@R;Y{InuIR}Q{u}N$}W}C&%iZSiz`^^~Hn9X7hith*2Y|Mf3v$ADtdj&!ulvvT> zO_=|c4~SOWPA#rN;RnPDT=H}X2xlD-|N6AL{-+OCRNC{5e27an(E9<5VUAcj7pA^C$uM|Q;DY`*vN`>bQ@sz|wdsEzMFW{Dy zcD@sPX?zUU@5QU4p`xiyCsdZBY(vRgeWm~X=*I=32NgzvLmT3s!UaUu>7Cj`1srB2+T1#44FFUq% zrSa*TPK8f)ULU_~UgnYSIgVla%li(qJlN2o^8QP|R#D05(_!f#3&rE+8Sz#s?en%W znOY`Gj0uQ|p}4qqGFf%lb{%B0df<9sb8uOEnd}$veXs@i7`OpA6>JIC^7s)vzB||q zdJ8a>Qv+-Y{*3bLgYSV6-zf1C0@WalsU(wC2A_sq1ssjkhT!4t1kXypm^&*aKcj;K z0%PH)&hOgLs|ZsnwJ;tR850|bMuZ29vxyuzMiwiatW;MU7#0&x?K-QF$!ejvXH8@> zV{m;}$-hK!9oR=*B;E$D4LjIPN}mE-azmLOis7pXs{f~kG0c|A8e zi|y1VGDI|`3c5)hHVU>0?77{gj`M*{4s_yN(nIQxhhR#V!}%==qzd=LCI?f&lrPgm zCNl!p@|4MHfR$ispcTriA=And^%0;E>e^E#YY0Axf@*?iDWn2k_mW2B8s|(fjaVv} zMsOyWS{4PSd>y@|0g8qv1{T^i1Ee&Iz*Jcx=lKIAr($7Og&xA$A53NU z1JkVX;OxS=S%0aQ*7-{D(eYzqXjsD|M~c(som}#fr_(0R@Z-*p42?|~7c7el4GyOa zy9Z0XxE%9}=E)q+8=;d!D>#S7L{6X@#2?@qXeZ=gj9eMk>dKHg<=yLbH-nCWL!XONH8icg-tzp z6-*9a36Sj5V6uZpN*oqB9?g`=9+0g?#5kL<(D2Y$Sx}%^8j#d#JhoM@3G-*%2~zv z-8d<}kaI5Q1DrR4Ys!Yo5*LdBS>j~Qp_~VSY3+C8+@7-~=jxmT12A^@tVNfqkv^I8 z+jyaK)sAh~O_b)`GB8br*-E7j4}v2CBZERCM&Fn!4eKga3>M4`J8I?ArA(iuNmZVPO7BxMd985wPZmD*&clz!4IY0L+4ZVRSe*O1%Kkgf^rli+6H4PcrZ{Isc-_!1RU zm)r##3x$S_w9Dp6%J=!wwEG=wh7>uR_kd~It>8QrOe=a6XKyg|gFTpLNfR(N$rMbz zS{+QiI2rX&d{?=&uvae;M?ssYTagZkAlGPXpwWwt3=12N5&ipm=&($3@PB7rV9WXY z!Z1Mvv>^VA1ya6s=uYB={7BcW8{IUO=JTKHLN{%7>mz#=dW5zd-F(;0XWhclEj--< z(k)2cLe#Af-NMqX1Kk4CEmYn5(JfTn!lMPOr7_X1K-~grj-jCGSZ#weeLk(1=0Gsc z!U*iz%{EJ8YR>sA*a+#vg5zi_lO5%H8t46B8d`Br42_YkM7gw9KGK#?5ofRtNhsSY z6>N+QGcyqWllgsR1DYF*c}Ubif#~TGAJ&1Vqb52gi=1dxu%ag;O<~YE4c_wT=W+D;t7o{^X)q>gJ=I zcb%5f?cw$&Fr{A!rt~vfN%kVxG^{f@hlhp-+XRi2O@dAC1jHmn1da`jjh1X-bS)2U zr5tHWd^;zV^&B=WqR@zt;ONlU7}s2>iJ>t8(a`}3GM%sYkdB%j6d5i~@@ufE?!d56 zYN;$GOR{4^g2Tcv7w5yKa>s+o7uSm-*Guex05zsMT1*iwq=>}cd4gx{jtb>vVS4R| z%AKxB#kIXAe68K8xh9VfE42u<;jj(~4jL7sy&>tkLZfa7ee1N+8s$sJ%Rw-8*qOW1 z)?|54a?0_Jq>qjq7evm#E|3PGJ#_MEEo|aZI7o4+7!t_SdvM+JzBEtjK^Lbj^cqON z6FSzTHnBYf+9UNJN(=QM9H8E~1e>mUh8IZ{tmhSa!={Dl45mHQmdBq)dTPLCAbNzXj8da|b$2*^^*$C=*Q6VIHNY<7pxS)S?J54R?PqRn!Aa87DoL zbYs|*@f+{4+hA&04sXDR7g7ZWVN(xG0F&b*IrjxqJtp9KU>R6TE&Os@+LClzNOW*a zWLR9V>>+fjP`p{jJ-~I?VoShO!G18cXe-y}y_H)08cdsaD;_@sO!n{Zq3>E5neE?72Usa(l!61$LtSh@YcR&Q}y|ObY*9`A6b@Uo#_>FwWwHFv7ybAn@Q? z!A0(<5ZoJB3GofA4Eo(4@@Pn5VijS117Fv4uh^uww&x0MGb&eU-!P)%q$zhVkFIrY zM~@*zvRM~qFPDFc)}K@2de`hgZly^%eae!H(nr|uyi-7XVkA`=DtmHFPOb;99f%f+wa=&p`KvX z%u4WW=3`W6_LY_!svO+3`puXtUvhJ53)`Em6!u!12(DJ!jfMtXI{&hl!L*np_aDD* zX*^kYW|d=gDrWtm+b+GX=Ulw>+{|ZKt5F3m`v%z9J;~~yIBAd3_L2bwMJ;Mr^qeT< zTZb6bnt$i_0T<6~5nP+E6dpD=S=PeN=;NJ6wKt?aa_Q8zXMeM44|WM5EqsNX7FH(r zElq1wcB-bRqw+KFZ9XIS>F$K3gMN?tBKWlQHS#RU4O6|@)IYv{=#`?m!`|=T-g0gw zt*+9ob-RtJb98PyU6z6`i-QiYfBbIss>a8>gl!*vriLB8m$83WPH~4_UdV6XX1`H~e7O+Pq0N4ijz0B-?dRI;U)iT>6(Oi|2i2ao zxYiI-J2)slv=#0IIxAYW6H@%0)w9~kWX_m)3L&7gM%}N2Og6CGN`p1H+)~=gaC53l zIULq7ou$f#H9|-o;b_oNCL5`f)mm78X1NPX%CcdGoqtCL5A*?^^eFUp-d7Q1C zOy*l|Erj)Fz9Lw-AWPI2HrQ#@P3&bdM_777z(9?9JS=LNTnOl(QSXPJX7tL@NAYMM+4u+zws1k)fF^=D}Cf*OymXyYVx zjM#X?sjyrSr$oVscWNQ{bTCk7L#6JL3q|%C<5F1Y_e29q1GE;5J2Vs1wLw)FI_fNR z$S7EpOGUZV8)3D9r4R?;8Y~(rnXo~lQ8!1GQk)47WIu%*x;>^ zcNF|ayQo$my0hRv+CiO<5DhEJ8KRNb7feH3R5RRUvL1qYh=ck(LNt^rak#1?D7AY- zca6NeU>fS88V{|PkQ(M_fKrAcsn|sIC|EwQ6aqPP5EhNB6!#q#%|OZO+f61LQ*PaZ zHB7Vu4%itW4|Z#wFb&p-a!cJqY847`vok0+EHUFMxl3+J<-5ZAvyer9vF^d@RbHf( zhfD^6S2qq8ij}%san3_XiEvgl^%U-af;|PZNN4p%bSw3aRMBHtfBHA7r?fhyxExq$ zHBVU;b<&7PBU#z2Vt0)Ai**ndEkUW2%4i2IR>>L)i@I2}40pkzW-4Sd8AeMZ&AVaV zx`k=k!%prk3?ApKE`|1|FHR^zYIHy^jd~U=X*3Aps2cU5P^zti!oQDj zC(2p99|C3|cjaBV6@XRU8YM`*N;}0QSTs?k#y*8bGeNRE`c-WDI#|>#a&dwe!;)&C zrO+L{Ku%+tI&0MPU||s>C1#iE3|WG|orAhEE+MczCRP;!;_dWc3=~pFIjGf`ZIl_C zj+;jAB^1QDDAo=X%qBRiUm*%B0RGStvl%2=C>IICg@Oq#>YdPN5h{fMM~&(!EGMDR z!9m>^jUt^|VkZ>DyQtH+f`yi6X8@xOqVJfswb2k=Luqt+mRmHOJKDV zT^bu-m~37^jh23VvD_^+>D|8d(+fvT8jnd-1d^ z7$KM?I;-jhz;~gr*ijDwM=Dd5git53^!o^5i;&7wHySA|K#UE}ooHANh{Hzgs8OfG zqAtMrbl0d~@|3VX+ZhDvc3Ik-B4J4r4bxSX4oj-Em{N(AS_J8uNdmldqnGCT9ax=VNwcv2D5;;-;@&wB z7R@sQ+P)R5M+tXkIjinc64AHXqoro*2}MyFbq`oA#eyu+1yf;>r|4)ujpEj5!EBDR z>RqTzHbgL=d$L&#qY?L{b544H<>WC3DmB0^H^ZG=XP znsc~J7A%G~Av9bJDI#>C0EDC*$I3PHNSz092o0hfiu_1n@O&(fC`>)Uf4+mNSu~w6 z6pASi9WM`6iP6OlLda80w*et{F;rY0Y8$K563Rm-%R}n%y4XJDp;hIfB80k2zQpN5 z;pL(I<)Ko9x{B$XCg?)b%0p+$L+W@Qi@nHisf&6tY+6`YN;t0%atq50^Q)9w*yU60 z3=*UP#jF{nQ3t|mg>2Y2I%?EQVReKh9^{I134)p6tp3SGY)QCEu$?H)6-*^tjcOmP z-hw%{GT9{EDNpO6Gc4K?aSej)dpayTSeVg>JIv#xWBn^EJ~dHZ$H_D&sl0Irkt>zN zJX>M?S;Bo-d{K1L$ejeg6)x)dDN=f@s6HC?8CV068_O80t=?3rZ^Z3aJpdN1HlMrJtO{Pm5?q6e! z($xlta77kK!a;n+}+%YnUZU zST{>|UqF_8c10@?7PbzWX^6}HOI(XNGFec0++tWE<(B_k$-80t2RD~``q>s-{^=gDMkp;V?>qbQgsn5}nK zHCce`LBV{zgK7pszGCQZd8qwDI^rodsXX)mq5h)QevvLT2cf>AR)CO?7_weW8wc{L z$0J1JETiF2>|HFFZE{vWqiD&$m3Ded#O(oB7&!=0gTza6Rkfv9ID&sC2lWtyXbEGP zV4#v=(Z-8Tu+_*P38tG}RK1spd+cThRT@IrcM(zuGT8tzGzcN=z|i&~gdG?m)pBvi zL}(;J*nttcfDm?Igjy!+Vv`WU4h-!rLcxOnR!6-R;*(a5@?sE@(j7raN~gbGr+FhJ`ll8U^27ie zhPEM6n1b>Pe!N{vML2! z2Ph7174GbFR_kxmm4{iW=(0^1yx&|YN>VP<$ z321waz9^Lj&V?G-ebu=0d>o6=gSU4JRY5EP;0CA{% z_DYpVUAG)o`4m&HA3GmXW8y=__HxL#L7TSfu+6>DdmbA#^2eD_CTm4~m(^;xj zuw3cxQ1t{MEWVBo>Q;eue^*+JouEtp+!R@XizIVwH!34}%Go#bH}w{Ycyg34fZMVxrw zs&+eGZs8K@-fcmr9DD6M|Wuvw9swshxC_avN3~vDKKNYWsLRA zMa5wZF!iiXOIN*;`(wC;gB?@vAS@bQ={om4j}r$*-QhQ>Oq7BxI~Ep|iSEJ`)jl34 zJ>q>2i%OBv9+IWVhQmVIu`W`}3caT@L&Prp24nXO>VU>54 zV)j`f<+`)_I7C`AxOBqSR0fOs59T#8gp?c3>Urg2z#xtK94yL? zrN2(2Hp$U-Kb;irIYP=!XZ3Q3)F`?*(fX7MFPI8AK4#|%DG)D0?1+@; zniqBk=gWH=u5^ag6;W^n)@)eR5?D7i>SM5^{-v$tE38&xA(r+UmDL3rz0`FM>Ij6S z!m*7gHeV3#S?mMfR zU!@6N=;ELrMj@$nSSib3@pXgN<-wxOM(XUJ+`<&aWbS%R>TGEdB*LQpldN;Fs1)=O zrtcS6R0B#u4K1!qa|yEm(`G0vso!Z%thg?i6*;SOAxbL>$CX0=hL8f${ziFM!Lxa= zq$GFY2g@NfHfSJ3?H0}*INizW~rOq zlF6bVsvycKhJXI)A->@QB&I!GABh^{azlDJ>YcB<(ZoimIGHaDe(bEcbyrAv?5u8c zPulmSUW$W7ZGeS~j9+235jWPy2z8cpx)doa?^&c8L6*1)r69zojyE31!;;D>iqNQx z?u)5#Cix@OTPh19aU7PfWMN*{eSnKm(V{Io5S9 zQq43qSHa@lgM9B`NiEz^gmd=~T`4qJNwDn1<#Q4tPq8j)SCyyI8pKYG$GUE?`U|P& z98_Bo!c!#N(&;^uF3hkPu>SkQ>WtjDZ1KYMeTa-TfJ7hEOJPafM6>7-S>%z*_7x31-2zNOXqe;!e7+0Imvlw@ z*MiwcXZ51j()NJc+724UsnNr@`TbK)Q>JTjM#z2ii z@2zm>le60Wt&{{?A|7+Ch2I_)a$I=MBB1;^2>yJ`1rC#&@i?tM1Ke3*G z9F6)htnx{&?(|8TVB$rCY9=f@!GD6I9s<5%^|d~iC-0?Eje!L{!$Extq5ddTO?N_y zI$wmrxHF9VqPtVUeyiRIi*^TGljG{D^ox*k$XVU8M4B?VXF@NB!J-v{i(1^R?G9+frfhQD;SbsgQEiS-r1R>Q}_!MEs06RNLaKR37>LDJ+MC5nB`f@E!aIvxzRuVsBa)Qps!cR%qZu7!4y@G#}iYqK7LTXU$|b8 z70k;(-kSAlD7TW!Sa?JEaIFeS1CW$>6qx)Cvx@6$t6}ft_HK&Ahu9Q+4ovxTIbQ(N z8GH?F0KUWZdt846rU7^grq5HkRu_;wevSz8@C}&KyyXdrDdR_O6I1XLe$)gTz>6y2 zn&3KMYp@}>Be(|G9ZcnVf$>k~jUSZXM@tq3z|>MdZdYVVIGF4IFHA$>&+`*gdBeD^ zr2w^TB$yHggDGw_=TI;?7ER*cmBfU8e>|A<1g=lw_GB=9h^f9ruo-?SPL_fI z#jT+qe`6|e9dzQ2U@CYMPxntu@tb)(G3DC^rV4j*otVcGEY~LX$Y%u{l8;MSCyx; zr2uV*W?Ud9M}7fQLJO`}WH}4B!qg!@nj@MvuXbQcY0HyWWGbd3*NG`evzI2SE7yss z+OFLG@0iN#ro?Kb0($Wb{}ZMHym-EUVv6#?4@%buOpXoU>4|Bx9I50}XC#mK-(;#d z5akjFfoZCY0+SNz!HCw|b$dJs(49!J5Azz@LmAtwC^w}}-jwIvo4ML*+mMW!iGOv%76c>Mo_ zDc>uekC@7P&G`-Iw@SJf#0LQ}!8{Tt8zoktUs z{)6j3xlT+|TS-6u##Fo>*DEsVDy|dLW>k&a;K5=$s&j#uDmLaeF%?jQ+ZCC7s?GI^ zO!@0VZ^R0zeXwLsFlqDa2Bzp9JR30;@6PRtOzAwKQ&eyKpbM>jJY7Ym3$swJ6VtSc zaJ?c^`sG|FrVe6Y>hbk@ zm^qYS15ZFqP29w7Vv66)ZDO*waNY{0s2%vBWQDcmb=k|>as%;)*s?toi%&(S0`_v9 zm@3@IZDNYw&uwDz_#n6c2P|#y|CE6ao@`!VMJDMaeh{DG@&5^v!)KA6_#EdPJ$}IC z@Pde`rRTvkwwJk1Oc}3mo0uHD4W@MWz!dcmKPX)h8UF=SPd(=8p6DjW69|;2m`6M( z10P~4@CCPt>1ZtBc15OirCcW_`zx3l^quP!nc}r&Jc5`K{^TsDX5sTsOxvqI;;8@w zFy*Vv)Bh7wI(lyfaaAzgAX!NHv@%NsT0!szzWN;>XAdery^@>dKL%B{& z!2tXqM@NGxK7?~9n1&!sv@!nS2+)U^IwJ~9QXGCz#tEF`IVXUr#gn)_8B8Bys&G2j zXK*_SjDNC4_(2sf<-8m$9|0km3oF6&A*O_@!Q{|7Zf^ur#hbal9ZVl$O1F#iUak}C zu{=}kq|}asTqY(v6HLWrfvLKqU@GPW*H3Z%4A*nHeGyFg^SFJ5^L5U*I2V9v=Ppw5 zoBBr(=$7XVm_Ec*@q5mnxK2!Z378!E&h4MvR-%_l*9Vg$24L#=YWP8y+4aFlDzgOB zBDJd2LaMj}1j=X!rj~aC)8{YD%FN^zVuv{+n#$?Iv-JQ|4ln$mdV7N#fuq3WZ!AUr zjj5VA9-qMDD>B7T;yN*vJGl}%j6Mj6C%`P8fS4+p%WYz6;9_q76H|Kyo^J(DSCPqq zmC$KmHiOB5EtSwL3T)*Wh{@i@ZDM(*mqKpw@AE7gkbj?N{rf!Y-{)EXKF`8d@PF|D zO)OS?Fh{%fzt6L1%f-hPOvl@Q_Z*ATQ9PYq|31(9_j%U;(sQZ5K9-_M_Mbgi>+#ow zG?D*(o`s9rf1hXl`#kI4=UM+g&-%-AEjqLReV#QGk09tN#J|t8{(YYH@AEA2g8%>M zc~+sVJW=6Vy;hAzw>b+{26xAzfmb!mp z?S+j(3Z4f&YO0@o_1m(BxruE)GzffoEZ+E+bNUl5x%ci}r*XrYA#6xp*1V+CQa(t&oyo_6 z(wHBJ`Hn+$_BcfEWa=mg22l{gqadWSED{cpU>*%&4-1V(&b{m;Q3f-O0qtW^MEhAT z(XY%h7Ic6mfLMGivKGc7YbLWE55a0YgoWcFWU&Gg@=0)tllSz(H%H1pdR^C#f606< zy;DpbANZv~!M>)=?!Wsusl}bL6))7u1wA~|UTiwqz21n2!=sy=>gPAJRDLUU{>%7| z)3WZ>_q0%$*sv*aauZe-j*7CG2X%wp1XPqB0pU0+ii7ZMf;?N>wASY3@vP6OZIK^x zcE9Qu*}O$dm(ADq&YkwKUfrs%Z&qDmo_K!c#$7GiPx`H7mq*d;JsIHvi~GKqG&NJ> z-*;$KdWHT!UG6<@J$D$lQk}Y=(jiG$u_@~Gl;4(yw=ap6`z#KrHvLOTp39?-&2sCO zK2n?3UvxD;%Cqmc6MN4OoxHC~8%tl0hi^CMZt2UM667XYuj+9tYp%HFeMa~^!(y?u5YWQTfSEE8lRUt`fiFX z{SKjSdYq}~-qRiLD(^m9HsRz$kGearHdwcG`i^IHjIhHmN-MM`t`qyw01~Ru| zO$+)uT2{52b@5K?#3~K$jcM8KO898QMKd?An0?4{=enT{#}-%G+pML-!N<`V^;*=t z*m2vB2By0_8$Ku+K5_r|*{5$XuSs$f*L1_FOLKl4yn6P^sbrJdbx-b^Zr~p>N9$I1 z$)bkKV-8uietWUe@oul9_jRmUvtK8z`|?BUOsogGopGvkuy^-w%=O2ZMqaU$wEn3}eI$C|36(pk7R*5uyr$H!SNz)+YlQ2sQ;V!$Xg)n!T z+_0C~?!8$xwPVheS-f)@r19L)v)|hh*-rXSmlwJm_59esVf>NgH^*wvO>d#l-+B7( z7yZ}IYL0J~zw`Em#?7i;@4lwuG%IAq(^0J5bQG%`Z_~=#zVDq47YC=WZ*6pC=hggC zx9cXPJIfRvyY4L7aag%5QPJo5X(kL|vWc~NXS znd;F2FxluHKL~LF1O>kHIuJh+uHlb&-)fW z21Cw0&n=7}^y$RcMNt_8jwHJt?w>W@f1Ih)+2D1bOm{V(%d(SD(fGNj=o33R7Zt_N zLq$!JAbep_Nf4~&L%2yoDYKjhA)ka<^B{a(u zv|{R8vp-%xHL}IT29phjRr$I(a8&exlhZG~P6-}=@3!^P<7RPj?f0(=oVb4Nu(Xer z&3&d_9TA*2#=_)vg+csT-e7E(7fw2#yM1!!ojnI0ejZ)v(1ZKMeSCfQS&ZDdsNNH! z(jBk5w@IF6P%qhZhHtN&`9os%?6>f$`CHJK3D>ML7qr*LY*(?ug>sW#8`A&quQgyn z{9(h@$EVlZKfyYB;ikH+tusEv?`(gl-`N*FVJ=4+);u43u1|fZ!`&k{o15K=KG1k+ z%{PCr_*dx}^yXFFdXTeKi_q$oi!gOBx2W;8iQR~@YrQu0E$+If_Tag{@5p%TIr3Cc zY43-LTl&bO_N?vN^is!GdNVY6o=-;GPdfFa%eneFFW=R^^sH@Jr3%F=na5%j>%JJh zo4y#mt74@jl#t-R1cE+GTLNMG5(tJ%A*h+(QV70FA!L(Kg{hZ8Fjxj5d>I5omPNuL z63hh%)mf+jAq21BW_ctSGt=b|OqN5KvK&H9mPLNk`O8p8I~5DeEqux5U1Ao#9-M?za>x(0toWKtZh1I2umUw%8H2mnf-1gw%d)wsk@PQI4g!A zAHm%AfCAVmqLJ(!Q6Tf!3kqTzh=N%u(J0m@12meY5rr`MK2Rw0BO1dph{iJYeoz<- zAPQ$$L=nvRS5PDiB^t+05=Al71E6RYMHItwiDH@MLC|=X0Ale6;cDSQxH^GZXHr8m zsiBz=5?BEV`6M_Uf-s3C9fC0T5QJAGOkws}5bUxbq-H_TvSJdRk>GV0!Zfz(Foczd zA(W9YgLxc*;C=)``Vk1TSSbl5B={eNFo&fbg|Pi71jB3yNz5-Bf^Rm2Y!c=(^)Uzr z#~_3sgRqcgk#L9v^WzW}v(V!ZLXJboBVj2sJpsYw1cWIkAP6j%gd7rVPC`g#2`3@M zpM+3I0%O*vAXuHk?(aQ)+W4PU3fJ}&W_DO>e`)B0^XqPmx)n7!G}GbeM)!H{iwx42 z?d<+x;Ii$mrnSsQo&rSV)rInZIgW092-;>tG z_|JU#3(Gr&6EFER{9Vn8PQ%~1r_q3Jzd=Z4OMio4_Zx&yB&=hr&OmrZLfIJz8<@vg zOofeX1JNc{O0=2vIS1Op(ulS)c@AhB^CQ~MGKkWc8x`c6gMyq;w-T&d)|SirzpHth*<7a9Jb?4ZS=IyU|I3(BW$!%nM?dztT4ScS5aX8g;Y5$hT=^Hh=1N&q} zcWny3PM>$d>{wIv)zPaSR%@-FbSAarmv-B#Md+I?TKr<8UYes%9zJ!Zv3Png?X&>w6S(Np%0=o$042P$S8h@P`jq8F@BA?PJbBf^!y zeb8&>NA!ke5WQt;jJX&6*&W?S?~n`o&9g?suj#9&&-{{^zIuwVPOu0~UhnszYS*sm zt!qte=5TIlp0LdM!>qQIpCqJjv7cAJ;Ox8RHqX~Tm^rD>O=ehxJLKiDS+l=?x!*+P zx^r=@kYO?lyVm;Z7j8$7ru{a1!o3!Lla~bd+`VvF?OBIgc)wbFvj40avHd5nzm;e) zBh|=s|7D8`1O1_*cZtKk#ozrn+-Z5!>Uj~#N!L6RS5NKV?m~gK&z!|4%Gw(DTl{Il zulfy5ErTDdeE(7=*JgW!`hL4n-SX2ShZa{)*B-*M;htAu;>U(n+=4%>v3E6a>%jDO z7@B_W(A8~6{iTOXtJ@yUPumjVyL|h(I?gTEUmU!0;{n^K8-pME^~&sjFYQ?CuR|-k z_esv?eZ_ek|2tM_lOn7nT+A0?C0RX!aFYaF%>ND{pM+VzL%_v633DGquzdufj7@t4 z!R`r!CnWr2Z68B;Mndvqc~6C0!G3>?YF7RMrP~uEQL=(kByoQVA(aFbD}Dl@gaofY zAn3DIe?Zv&3_=+RYUc42f^RW|^rsN2uu>8XogNzlUP1_e4xuK?A|Z!_g{2T`v#TW#;$K0?djX*?Yx@;~)oTbhUqUctmaib> zlTi2yLOo{v8p7N+RK{xv=B$7OySEUW-axQmNpB!LBjFVZmh9a-2rJ(~`1BSVVDT)$1Ja&lpM9`n>5M&rxf5H;-N!pE_rHAA@%HioUzgVP8SrJA(5#7f zt<2Y)HeV@~gJ<1+QhtB6LWrX!oZ9s0v&OtrRyel{~b7P`G) zr2EKcEoQEsnQ=a#SLu^FdHb`|Vt=%DpT6YSRI5={)s`8X_H?os-uG68S=@wK(`c2v zhr9kC;6E;)KS0?20fOO22)Ka$2*LLwglrOU0sRSr!6yjepCH(xImcmA6kU{dIB4p>8e_zi*tnV)OAF%am%SFk(YjH>NRasvh3<~X+6{U zOx3H4x~(yLU@)kHYpvPI&nPzJGwQJ^K|OfZ@&$s)7YH}MKxoerXhd^Jc=Z*6Ewldy zA-)8M#Zk9|9zVU`*1S?$Xnp4P(+P&}EaSF&+K;T~{oA76H>S&?gWluLV(-1+tcCvT z>)$XOE9;;8dBX;)>9q&9zFKeHs|ucIDh^?8`{(WAP6P?j1rrbYd&}akulRh;ea{o4 z$lYc`Er#DSkNSIa^(}8l2sFbcTH|2*K?3~bUZuOwfGkr|Oq( zS({?AzwT`Kef*Q~2^HM4XC7r}b$%(jA-xRU;J`{rnEMsoaD8L%E;kx1p7Q>vaogv2 zI=_2b{qy2Z*Nzz94H?*`$M}NLHM?itsUv?;V5Bvue)8MiUNaNwde5<(5!fzbT57FP zdq-BN$EjjBX!;&)WUSzM&glw45E#_v54|F{bk-Ua#_4FMfw% zV48P&aqO8mb)Q2vK81fgp15=H63vebp>O?ut>V>C`$t;*OOMA{)2sY+ai3YGf_pB^ z?)s%QjMeeokliD|>^VSuQAiR+3z5*XLs=yG|L~0*$uX&Hf{ypwsFm?M7Ey zG}XKMFn5hDS?@tI*6cBo{TnNbq3QTMzY%i9egnbBh zA=%!{S`QgQLFmH@NH9@Aa8g0&$C6YKa!7bZ!T@Gp2|~OQLTV)lgIF;MR(cS; z^db1MRr(O}^%T|E4}FCv?!r6_Ak0-EMY;h}__I?%R5EEGJ+7pl8hkaknoCx@yy;B zLVPs{sm2f{uwoLdszdOq0U?2{ssSONgfbE)F^`%M<{CjruL)raD<#3s7=nK-2wIj_ z3&JxJ3~NJ}#{6nSSXl!?HVHGBx()>Qnh?V4K$yj{NGKt}ye@<}EVM3!?X@7}k&whp zO(6KzhA_nh!hDuXfOl}# zQauPcB)lRanc3He5N`@0wLS#Kib=3CgWzQjVHI0t4k4d}G7?rZk6$3ntp_3f7YM1W zlmxr_5d1A5tYc{w5T21>*Z{%?=GOqiN^=O=By3`8O9<}2KnS;lu!UujP(p%vLkQbg zXhR6wEg&4LS9UCP?XcIr`-<0-2d(R3di!V2{nDXVHipg`)W64(iwmNylaoH^o3(Id z*^Lw?y*^J!UNmjbUAJ)~uPlDnVElv*Hk9%c3y{cRF@!pV>F1=wRQ@jb;SbXme}=Eg-D4f{;zZX{K%o!QC1{cuNRpSQZH-B$(SkILAV5AZ%|AA&-PyX4(pZ zZwm-hT0ywLa!D{~3Bjf{gglne8p0tG3Q4%ktlK~cv4OC#4TP(#fCQ6P5S-dVxXzN= zLdYTE6$v+)eLD#8ts$hggK(P_lVH^bf>(P81#DG&2>B$Gk#LuJbbv6oErj$A5DHl- z33lxu_}fBwz|w3XJR`xdBZMO6*Ac?X_7Jj3c*N8i2<{yqglix?VOb=UkYH{H;VBEX zgRtEeLLLdl%+wx&Z$}7I>><2hxg;29AlP(*@QNjLf^dk0LK5CEYX=A+b`TaiKzPRr zNHDR7;N%G5150v*kVC>N5QzMGg^Qu4tNO3YvFuyD-m1CXJN0mw;2r4tV~aE1XLY;6LQ%1-&TzNH z1@4-6f&cm}vH#5#guI8iC#$VwHD1uIUpFY@ai^oGt7K*`p;&c? zG6lCf3R5MU_zFrsDcx|NqNt~2%icnn+XD*jy?ZLml`Q2Q6gzh)1KvZiP_m8hp*$l+ zh1&&%CF=SNWu*s{@t>hILS0{=xO+l*MGiJ$_U>@7goIRg2+deA1i2M+^8i`1RYc9% zJE9iM!&5Ox+p^+FpU-OMk$pP4)vlw>v^$KS&+K=)r=ih7hpo}uJloCix)iwOkA8K% z>~>tTO|Li8Y@gShxNjdq@@pK9yJGrc^7k?4V=Ii2O~rC=P3v_2(V%@fFM@A9X>`Rx zm2s-d!qMxR*IwVfT~z02<%j&+a*7Mi#RhQ1+);edLT}Gp64jEg!Mr9w& zTvDOnR?O5J?zd)9L~U3uQCnu|Lu2KQme2A*%iFW7J_>K4W(P<7%@n=NLwyvRtBRr6 zVT%58!_)2X^+p-~kQLq)S&O}!sQAEK`znxbgrb*<(y{uZ6!@Ox0DMa_Gh?CRi=15< zqVS=Z+Pc3LJjh@A>sxeI)y+%_QOr@8E*m9&{VS0)`U|@FGH~K0XojrMAVq6S-JhX~ z87);$$#j2L^c=M6nQ*0xTy)?>n8HAj7n!+xq2jAN(Ur>rsv9I$XX}72CU1R~{^{C( zWW>j1;0u7{;{{RsGY@Ht#X(^Yrz+|z zEHl}UsfsZw`u4ytc#UNvF@2a;VPM=T>(5RX{~9C9?xU~};cIE&#XuUy2EFH$ESIfs&| z6ZOS}m19Drzh@nEfxVuoc&$ji#O}{h%u}_$LU}O->QY|Ah{&K|o6!m5(jXg`%dCR4 zG+Wq9a{km+jK`nVI?jQ1_!`Y9U8fo1Pk_e8h6YFXx`{svSFx}EY)CCR&6*D7eS+@H zOj)QfQ<#cV9OF(?QTO-W#6c5hY-QbFdRsP%y`HG}Oa)Y4jHLMPVWRCfwtI-8Gij!} zKg5PV+SrQvfQl3UC>xDM53$vMnN8&V&dmDD6u+&hY}G>AD?YYm4_YgoSiLq%4=qVF z*7U_=`s_i8n4;qERn`*~eA%6A_-Z5l?N0Hdd-ab#EGw?j>whROeYLeY*XR77RHxpygVal;i86blOE#6#7UAUyTcPUf#wI$=PuWp zBHV|kyT|i3gLa7b!hN2OCMCTVhYn@<)Axz!-nQIORha*g%FI;m(m|pHhdjq}l3KL&T zf00N=ONPYiD44n$uTGTFk|E6q8ZAv1K%ZA^$|U0oTi}d3!i2zz*bpPYt7@jL87&2mIY3uwP5{07W(+`w3LPSJXhZa{+p9&mrJ2a0ECC(Cd-t z+?xo{Q8yWg17h{CFvqh(2c<(>Q}pBpxUv~Y1y%qIpqDlI0Ce=xQMU_72Qrwyqte@W z6M~z8Ex=Y_8_RH1cG1p9Z~;JTv@75SbOyQr7C;ZwHWa-}uezjH@6q8n3P=R#{F@2P z0%ikqfVlvjfpq3A02Tst*3sFv1Xv0z0|dZFfw$!LL7*?t9~b}(1O@@Vz*baFZyPNH z9sm!42GFO1wZJT3HZTY91oYWSCuMt89R%yLcTUP?TKcv_b##akfVXbR=nY;o&{_0` zuLy7?Kra(}54-~CO=iyl`r^&lnZO}HjywuL38;Wd03EUhfEu8~wG^NW=L`id1kw=L0c-*2ZKSIKKi~x_ehJW9 zV^=X7SEZ(pG2EVshSOWz!qE8hzy)9)5CMz>nxTW}P^CkZ-duGWpjT$mYqWL)%YkHI z1t72ku1X8jDkx3{d_}DrfOKFDYE5OYT$RoI=oLlLKn&0vrMCoZfOfzul=2#Q2hd6R z5qJb_1GWQc0KHml6_5g~0aAgrz&aN0rmU;oh}!6yo!*yY3v>iDz;`713VZ|T#Z&W< zrWou9&*-Ki3K#_V0>go^Xh9=jILdQInnnO!cIyGxke6QlrbW3k0eUG8y>;uN9;&A6 z>r5aEm;huWaR#s-*aEBt_M+fLz$m~KpaYjKJ30V#rP~ki0(t}V%H+Gqa}S_bcU|M< zQrXjhdB9X481c^ZPB6M4>;~APFuLfA03rdpmZ3`*x>V6a99@GQ1?akq?!~-;*C>Rp ztMZZmE^rEnh86{c0u=6r_&B7E0g8a%fk(h&;0Yc>Dtj8PL9)v*uL9Rtcvq!^UuEPf zgIUoFdVB3UU_I~#S?GO(bkXz%_yBwY=tAfV@H=oHpz9sFzL^M!wKL-`%0d57W5*vz z{Sctbn`Z!Z*iK*`a?S;20dyBluPG~`qZ*%;gBdP)nrdn5r2(O9#@0Y9pe4{4s0Gvn zXqnP-rDaRY_YCsWQtkq{0j>c3LJ|Gq*9m}5W%{DTE`WX$ZzaG0dZtG^C~ceceW`|W zTs6{EQvg3vC|=twdj;eJc(Nh80OSHWz$xG)Z~{0E&}=&j909gu=5=2L%Yy}Pi!&nm!rGw2j1bu-)z+r&090RC$U2(+cfU|6=hq9hIHJ`T8 zDnK|801O4ffPpO60|x_Dbe_pQm736(2o?a3fagFl@Bp|E&`iG#PI!)(f0lVs{tjUggDh*h^r?RS+DlPnngp`poQNjNd{{;GDK<6~2qh(2He+P7Od+|-6W(| zQxE)ilaacVx{(T^kFFOgmPPqxSiIE8ian<51uZ3}?v}bk8UpI#|IPt93Zx#R;rP1~ zx`O|yTyjP?9NZbL=y}CVI!FHQ#6K;^zgMp70ouQ60Qvx(l5wb51x^IhS4@lnBcQsR z4ePC}>{k`x%77X$0O&Vs=o>Dz0Qx_08deiFK}G5BGLa0AlV$=-NW zKz~AjqUg?tTv!X3R|r#bT~<2W$$f0SvL*nz?gXZbT6bUy&<2XKnk~arh0X9Gjpe10B;wat@pyE0L z9RNz(9u4O1~XTS|`1zZ41OV=>qR-(`qMt6YzpGwz8s*u`2SExgQ z9tihj8GV(_Dp7qAGB(gh>5Ok}B>O0bX#FA4Urd+)OyprIfl4JNJprIwgqgq$zyu}M z1*RjM2+%DA-AYUYW&<<=`~VcsKblPRi_Qyxi^w-0Op_yt4oI54G)!|L%mZ{oNlbBz zpe+U%unbrVP+_`)#M#d>`rsxd8S-*K09F9x#|>Wm4usQybpZL10#LQ9z-xh2U=6Su zSPyIiwgOv#&A=vLBd`J34$#?6`RVYdo$%6YTTesbdAT{GK=VKHF z&@dba1|dJi=OcUzI7Oq>zS>O$>7MEa__~}u@2l)=>IwTc>`d@m@Ed@>LnbvHfTs055aMsiRO7>2MCtN`S|52Pc9KLb{X z`vj)$`3n9Hd;>~>65tC!I@w?8+5S%i8X*(SCj&qqPy>~LDu5wi1XKg612qAf<8{E~ zFojLHPH{FUsvfvL@c;Gp9bi=*P5<0`4ydSz29$CU>;-9;VvC498dNN(v7jg*7$b-c z6#?5TQS7gdVne~M*uA0%7F6uLfF)QGjWLE;qA`l!Z%*MVf&Ab1`<~~YJU{oGo!Qyh znc3Mrd+xnB0Xzstlr@1Bps^Bc0k)u3JT7>5#v^M4Gyr%s^-(qioPowb6Tl7NMojm{ zwH{zWERfA92}H@VR131@*jn7i3)i1oh$mzG5d6a?W%IKs*{rNFo0I*={$dyKNIe1e zA-jux%)Vy7vK!dks&cBLEm6;%2LrVLjw>~0cmTK_h7&DgB@19C4m=JhX68;f@YDbs z13}*cg8&xJ;ol17r<=~U;2(*)eE`0PaG^8y^ZcZd4$J{&1Cs%M!0G~Y0y+X6fc8LV z;48o%_!^i5^a6SU0YEpPJJ17|2*dyrfbqaMU@R~O7!5=MqqGS0k+}E{_!bxegagBY zen1}}5a*U+8{+W@X#0xSSjI=gNSuo_qjECiT`-SKZ=5wI9o4lDx*;J#J@ zOyleLWc;%NSOu_<&A>(=4M+u8*jj)aqyQ|8JLOTc@O6M4MzR6rdSDa4g0}$v0LRHL zfCsY^*a4^mKwZ2<;0n&5dX#*oQw^vJ@NqD|Sm86CFFOJ#faTpnc>wqWcnzEajsdTLm%t15{|Q`V12=)+f!~1Vz+vE5;2Dq!J0at;`z-b@@P&Gb+ zYgXbQzzVQ(taMu_@~Kj+j5;8uG2e0EB%tzhojRa+X66dD5fgF&Hq#}5J39kh1TFyQ z0Uq61fN87{gZa7SHhirr%*wGPSY{~$ikGx!hSC~w9c!)9*`MqtuHzB0OW3r`r_$7G z_B->cGVUtZs2#A=6Jrz*z6xGl%UFDTVcxt{&c zve~kq)=M(uQOTM<0N8hh0GpPzluYC6PkG{* ziOs}}tRat(Bby_YEy1Jlg95DqUjQ>v`pZUtpM7)MWRlGk_K613aE$EQ@(~Kzu&TgDENNF#Df{ z@ZmAfc{aBNuGtNhQC0%(;+p624*<^uK4j)d=F?n0yW_)VK6GZ`+@Ts^Tvi22cFF@T zu4DgyR)KrfC0wt^y$8StuC;+$fD^#SaQugcbUgomX6BpMz1C4=3 zz%0};o!jhyFc*}cKb_g}`J_9*hsfi=n%f^2`0rLZx)3DPH@poJa%}4cc{Fo%cXc=M z1+fAaugNwo-$l&o9cHOfDNjA<%48u-H!M8z+lY|h=;23Z53+CVc2KJc@{*dG4AztD zM4@rraJ}?No`mrzt3Xy{;e__pXZIFFO_1Kz%hdzPSWmGN1%ICl3a8DJBG<3yk2?uj zO=VekK*5Td;N11+2XQ;Eofb8ES8wQtWlT>+69pTeYMzqK6P$7igcQHeN0@<7vla!Pa#A zmk2*<6Dn9&IEzbXv>8jiVud~U$Y<-(f(jPii?uu%+F@1sz3A5v=jeG|Mod zCdGycc2p3Ge{M|?YM|C#5N);YIE@%C*i-#DVT$1H>OmXg1W%eWTyUV3qi|;I;p$Eo zMnPVic){9CFS(44>=tZrt>-vM+9lZ7CnH@}hCUm=|24FJaKldUE?mg|-$>cJ1Y1oe z#7HPC{0NaoXsb;kv?*kaI`I1E`lYl zwI#oWC=1(C!YuSxuAS_&b!j0{ClAF`(`q~*fMcd1?Mgs@E$AZ`0rbNn!P*gmO~TLw zk2(p9>Mh-Wy>pws#wKx8HA(Qqw^A-nMU%s{Jqg1dF%5=F`Ce$Ez0;1|rwKL{?m&Pm z1W4?*)NrQIQKgkvX_T~37^2pitF?;uEK?G9X@Q_GCT4b^tm#5~ZuD8bI^@KT_!OiN zqzYB}N~ohP!B$u8dlhmCo7#3}zjh9$LD%3J*@-55I*~tYS<BVro!(9f347kd}m`mTH%`qNInn;dUt_)MWW54!+_~3+4z` zjyz4CqaPjmahu)YLes#xGmHw!@vpjHSN2Sk?Pep-o53aHQ;pMNQz-HLxh3_VO|g=^ z>U5Xec>aA(s+|-^`@3$^!D2$r3ilIlr*{xxJ<;@VIm01c z_fz2TaP{QW;nSVY%@rDJ+jN(*uX!7AVwF!=*`4g>AuhMb^-MoEU(l<3%Dt2BW`LZ> zYc9W25Oc`-XGtDCl^{iU#L-1oEi}&r{_O7MDec~`&aQj zzUT0NONUw|g3Aod9@B-+s_%>aS7P=Q`%%`${%TL@G$0|<E&vNc5 z5mF_@+RD+b=Eu*c!2c)n*y4-l-z^n9)oJp7G1EVeM|I%mN%@}*^tY7$zcb2zzjppt zR^Xr+pDZ|O8qoQ4EVw(91v^bMI-4v^#jj6wT_M=ocMgY>!W5k897c2qJ*^=`Q<@mu^zJSfs=Q4>BraIOKtru9la@gh+hWL1#sH`2@baJ z{%yCK&4_i%G0G}OnsxA04YFT{Jyv7t&Uc;^u}*NV&2 z$gipv;|EiVRKef=F=7TveB9r(qj>JeYjb1RL-1 zN-N9NGZ&wkdZn`53XdKpmx5)TueEx;U9Ww4*C;QP=Az66Mn8z+C_{vn(Fww1MF`zv>zB>3 zAjD8@gD@0-r=7-a6l!VHhm+p{Snl9(I=4{>!x!SKWC+&u)h3~)eZ_G3N$HSP^=gCW zFP|oAys+VB4eHa>O|X7jT7g0r3_gCMF&ld&WaNdHS|eY4I9=L=v8)CMKT$O+oZQ{Q za@J)d$6-)vgED9Shn0ppRi7FuKZH}w&4?3ige?81HucKCZr47?$l*jiHbVU*`vw( zv+s?RYZ3IERjCpsZx!#|%U-orf4I4bXAl^~8xIy#Yl{@5Em7EaQ237ixNy@KH9Ea9 z^7W-iF!)4(fuq>HZSr7)Sru4J6%?yb)@_a(@w|M!D@MxvD9YM`0jyIv%2)MuKA`#c zIU~nDP;g?NkXtT*IzIXCn2~ZiiYjeIT-;SSj+s2~RR3qKpONGDDDne`x9MnEM&oJ? zJvDP4t~GMlDwLts-&d&OX!VDY;zDz`V$^LEhTK0A9Anc07aJJ@=_nZR+jh56=n}xk zj~A6|wEuZ^`uI~uzNMqdavRj#rf`fLvhL%Jg&BCfR?Ty4G_~J`a4n3Xm~BEbmsZ;a zfBbAi@OJbNMU%G+U414^lGEqe@;}$_((TMSWfr>Q#e+f_-&gN2H@4duP`u?ywP+F* zZASuIGl^`{g}w3;0XXY$@5Ox1Z!k#p$LYAs(6_Fr@s=O5UH;DEyVj~l<$vvb!!*GuxH?d)z)ShpV2qfd6(G~hZY%5rdg z8oh^Zx_UF@uHE0;we(7h?Cx_ih+;5^|bn(lnqZOQX(5(O5O%th0J1v?-0>v|2v2+K|t z-o;pI%xB9pEEXkCgVBwfmK*DN@DDV`GX+P;qS-WUAA-6HUEGJD#?L$%Fum%{k=t!< zz9g!r?Ta-cR%bW|YBVQ@{b1-027E#yA@6A-)mgOZypaJvI0*)A+#DLYAEsUkMw~|` zIM}WEdFvsknnuPQb0`HIKDpqq1IKsWd@4;F(>2k^@j#*MU6FnB&QGbyM#}p+^c-#N zZIhJA*JtVZE7ztCw$e1lzJ>pj2I6e)wLo4BRxF@C2BC3WPEgpUnKi$gnz`3Nny7OI^w&;Xj~l9gOg8 z(DFF1m1jO0+iJ<>AY3f1WL9Ppv$UMqYC>o-D7tA_l-O6T%k>D0PCOlAY`P+Xb{>SU zyr4OoZ`#*uzWrshxxbO4)CEoI0}EOa+DgZDR4-m|^e%O2Z&49M$p%X5O=4e z)nAa&3-ge zEY`|L)w$;`Jhcl5!ilQfh6bJ&bh_!FRzSO)Z`|LQC+(k)^yGo(D0jRQSxYM~Vx?TR zmeS8-!k69mM!J6<${m3y-f}H896ugW+XK(;s&aQh;eDa@&c9-peeXHSNO`X)H>&2# z?CZDcHdiTh>5^boTenVLPD&2WQsV*&A34&H6u~YmNx55iyR&BZ#b$@Qxz~4hK*m-K#yXj+I+>@E?^y)xMjD+ZSUd54xnZj8`Fpi&tC_d5(888j zKk!P$<+e-- z0)@BTEj+&NZ8!A?UVYFRuS>D1R0ydy&Q9{dRd$mV`7Hx&x=0*)*Jk8*5(oX8vIP%~ zo)&BnY#sIZ*o30wytTUnKTNq82xhpOJ4#EXXQ$!tovD-wvDE&EP+dCY-<2zP%R3}n z?eSDfKO%%_uclJz+X@ug!hzzPjxA`yPx;)v{_Dg)pZQM_Pw83OFt3 zZ5pJ>wg}9-?_ACC>q%&ViGp_uxkm+^c5@p2gjTve;Nti^V)1x$r#&IRD`Uf6JTr~F zjtP37li;ufM@+`+rlu`AZv_Xh+dlXJhtk8I)A5Vi4&PQ!X$#At?aE^qDtg&}Oz_uz zz(?EJFQ@0mTGY^9kKwltl8H_3Z=#yV!TD?xH9HQ@kYV!Un%hR-BR|a?Iz`f2dRQ91 zg;Kzwy}N~;bBo-qR6a*=(*NR*1engv94qj$^ES<_!QQt^E8=@1+?Up(3NB1(J7&^ zX11Y9uFzVeI#1gmjb@yNIj+L(6=68HD&>bdF5L4}F$dOTC7N_q;RN1mj{39t+pZ&e z+JnPO-XSZYqehk*AM#w$E0IX5&tiiv znZTXgE(+gjm1Ow8$}~G+BVI8cr%zni_rd5lumE<`ykRdZZ;{<4LFZ8xwalzWYtIUH zrm(%DZG71&yQ~~nwoaHJ7zZb!F`0o|)3sH2D&m-oGe;R&oL_>M)sd9o%d5$hw&CTY z;aaRvTT7!Z3tq0{GURC=nwon0{_;-YFYLFtfr5uF-p9{4OtIIH0_TB)``;h< zO^uhWsvMTuHs`j>4%5zSNM@E^VmW4Z#bC zb<=O)Jg&+SI&cH2-R1~AyMergd$XGu=ii@wk&>k(sYp?!`TU&|R#iCV%u>JhgR~aSPvD&}-Xq*+ZUz z2P3ZKcyRLO0FXVDbW2FkJ~~Vmd5{gCHq3+Ud-gufTd*ke{rv2K~&-RhDL8Reho5yHKJ~;hO)4#b?TBs$x z%NN3R&gbMn{OQ0rFX!dU>PQnnddl}YM{&2&fuF+RzSQ63(d_ZL@|uNsG=b8)ZzJb7 zJ-_r0#-cPJ{T)20b~`WcGfqv}9i~g#vP7$Ciy98ff0Q@v4qj62K5t0BBh=Msg^Px3 zcZJ?soyQef%e-M0+ooR_%7@KLP`0>2?F(>nGx{186u|Ue(3X3d!qWO=h`sQ-*S#{@~bhifx@ZtW)N z9>O|@KBx&^Qe&TH|9~CR)l_NSq&{M{FXkopWLe-Wb%|k@40#8`y)7SqD2wP=Xvz}Daya{ zD2eN<=2Ir>DeFgUa_sXd=>;l1^Qj1`YQM~FZ;o{XU3X<`ja{LhjvmvZTSgPZFWB0!@W-mTJWyY>RM8} ztPN*>HOkx!3j21;^?qAU&cTmNv5oM*r->n-nmmTAqbOgYyqHfz_&z_M3f>9Urtrw) ze9C%@st@^;4w8?>Z8--_PVL?$IQ<;wd&M;lps>L=y@;9BZ+R_)qH=S5LhClYM_XMN zaM*#vrvBqv_ZB200Z45TWFfc79d7j*4~`l`cgY$%D8mM$e`DB!7Jr}I=y@1Xk-zi`XrPaYIxL3-`5d~$yc zgCd4XM4co-4J2Kcd-4=6G$bxqUjD~sQioVQ@XgtKl)|C*X~#-4eQ~I%vemd$@6|@@ zenDK8E1-g3Aqi8+5~c2VfgEZk&0mdQ*J;jVquo?9TmT1q)_Pt{t)jg1_lz9g_sQ=W z{N{UKeyXkbpykuA7cb=ZP8?!L4&6cF2`U6mnElgI9iJ6)ykJL{l27x{RyP$me z7&rG2c7BrW;T3hFmnFMo{r+1tL?c!g-A&Zq!GY+pHpNyU0+p-3?O&Kwz?(27$dz7HXBC@4&A5t| z6!c2Aous;A&|+p)WtrL96b_UfVnvp(1@Rw@BIg|&pO?SLOMtH9)bUSlX&sF*QpW82 zWXh?@1XFMKYb-djHlKQ4tFB2UNBc>AiC`&iqAd9=^)t6A18l+j!_`Q`oFVFUt(B6~ z`py@U_L2k2a1FviT}WqR4pc{5o0+-Gv-)j*sEi!rQ+rf6Spz9j)xc3>Uatmt@ywGg zqE};CSN3wQuAWPzaF#OJn9C}LUJZu*qHVJZJoUVkUQdEs(&@CIz`)u+IhzmV@o1cfa)cxUChtX89^ZEEAl zTuMzn?cI@h-a#@m;4S8#0&b>4QqP`c;fFX6bq8pO@HmGmrDj>7rhaD zd~{GWXnx;cu5`SqsN|`x$i^k1j5VDsHKMehloDgb@u7Q;VE+Q$^c|ql9lB?jZd3=6 z^`C_D-zK8!sZ!>BAuZF2dhKWDkVa*!#Im6=eV=}qH}m$ zvrqX;9+l^!VUv!oO2Oj07&W|YA4DIu_|X5hzsODy!*pdco_bF!1;p&__i{sn&51jg zE)_jOpZw(K(F{LjOP2)EzuPROv&dx^tHdSxBSw3EkQb*#v*mK;z}z8I{muE1d$FD`O5JCYq1ty`)~l!x`W=b2L@ZdaJl2=|R( zpSpioSr7Ah^t@*x<(CtEwR!u=uDs}LnYUlI=!|CG=QJ@EMFi=75eu^A2|XvSU+cwn z)<-Afo*yeeuDsy-+XCC)H!1Y&(4Do+&OR#KtZ}!d%2um7y z4)>f$);lgSozbYngj?qF$TWt_<;8KPbi9)2WC*hma~x?}xLC{ZwW}CdiKh9AwP|n% z(W%^+Vd0@6<3>_~rRYG(9mJM~Mqi3l9zO+sw7qCcPL;&!`00Hyk}O(+0as46sHI3` z(LwA%*E@)3@xi>c9mTK6!v~}aokSfq=#Q)TP9lEAO)zz${hh>oI%bc$hF^&m)JtPp z+pzO1v6En`cO5%?5?T0*b!fdm8V>SDn*x8a7FF^WE0MFmsHd_1q6bBFg%-Q~MMtX9 zRs4oV28coA+g*G_J9~*{OnpMR0b)&jr)B3r(TXcX`WPTCqlZ02JF3?SeGlm>S{ht> ziVFqqp(;gm6CFR}zt;`Q?dT@XqS^ss7s?70?L0kL!QkkKV3+WSkdV+(e$l}p5iu^~ zBHTue`)+7xbaZI&u(2-Dq2EQ04|N$cjDLfie(%p_>mypy2Z$i|KG3jdAJLkx@Z}n) zRt~>3Jw76G9PO%x8YpH(rv1f!w2SQqMu^ZhV0HMW0CYOO?LpW2i%ZPzu2l@Jt%#rXfv66uX zi6>p0y?Cg8!-Av7Mn{AU4|R(Q9TgQka%k|FP#>>x(IZEX3yq%WG6uv^!zpnN?0@+i z1XhP6ajwQtX`Wckl&;JbTTso#Vnuv42Fl>7zQjaF7NeJ_#o~4|7`$dO{MoLrXio*> z#qv~cv$&q3Juz^n(QtV}vWO3q7-lAm-<9JKYRVDyB~6+rS{ur(6W^NAZ#fw4jm=`s za{Of>jvtSs;uln9i|9+WqafBX2e*D(V5bvD#4qrbrTinJeU(wcW5-1Yk8~Lp`CU|S zbSOSa2jA>Iimrr?hXp7hqdM9rYoh!QyiyRde zG2A6MIy!hFz1bo*q`C*Nk88gbKD6A2f8w@^Ei59&xI_hy4R?tcH6|hi>&gzX9^Kt4 zR{A0`YHUO#REdlp8yYj#Wo+=!kyNVz=GBvIOgx8e;`aiDWQ*+#>vxDx1h{J69JPRbNFl6RKahz1@OTwToW2|#~AYK%FTs;h$hvH5<5i3q}+WSEqq~w_)MPhYBlOpkmNHGHtC}?O# zNn1pF2e>sl)GvJ8cfq5=#<=m%%KJ&fa2qiuaulU-&#u{ss=0e$Rl5wiZ4-L5M{GcY z_lmtJqc-Y>>_Z45`pjsR0a;|?0Wr4N4@>Fv0!&NE4_=v=JsZ2@wn~;*U%-yo@I-4` zL6CDKrhz49Kvo6QEDcWi Date: Thu, 5 Dec 2024 05:41:40 +0900 Subject: [PATCH 14/18] fix: format cairo code --- contracts/src/lib.cairo | 2 +- contracts/src/models/board.cairo | 2 +- contracts/src/models/payments.cairo | 2 +- contracts/src/systems/actions.cairo | 81 ++++++++++++---------- contracts/src/systems/app.cairo | 51 +++++++------- contracts/src/systems/guilds.cairo | 43 +++++------- contracts/src/systems/payments.cairo | 30 ++++---- contracts/src/systems/propose.cairo | 88 ++++++++++++++++-------- contracts/src/systems/utils.cairo | 8 +-- contracts/src/systems/voting.cairo | 29 ++++---- contracts/src/tests/test_games.cairo | 19 ++--- contracts/src/tests/test_guilds.cairo | 67 ++++++++++-------- contracts/src/tests/test_proposals.cairo | 50 ++++++++------ contracts/src/tests/test_setup.cairo | 2 +- contracts/src/tests/utils.cairo | 75 ++++++++++++++------ 15 files changed, 321 insertions(+), 228 deletions(-) diff --git a/contracts/src/lib.cairo b/contracts/src/lib.cairo index 5eb2d3a..059860f 100644 --- a/contracts/src/lib.cairo +++ b/contracts/src/lib.cairo @@ -20,9 +20,9 @@ mod models { #[cfg(test)] mod tests { - mod test_setup; mod test_games; mod test_guilds; mod test_proposals; + mod test_setup; mod utils; } diff --git a/contracts/src/models/board.cairo b/contracts/src/models/board.cairo index bb409ef..ea2767b 100644 --- a/contracts/src/models/board.cairo +++ b/contracts/src/models/board.cairo @@ -28,4 +28,4 @@ struct GameId { #[key] y: u32, value: usize -} \ No newline at end of file +} diff --git a/contracts/src/models/payments.cairo b/contracts/src/models/payments.cairo index 1fbf727..c197801 100644 --- a/contracts/src/models/payments.cairo +++ b/contracts/src/models/payments.cairo @@ -26,4 +26,4 @@ struct TreasuryInfo { #[key] dummy_key: u32, treasury_address: ContractAddress -} \ No newline at end of file +} diff --git a/contracts/src/systems/actions.cairo b/contracts/src/systems/actions.cairo index 4d8efcc..eea7fb1 100644 --- a/contracts/src/systems/actions.cairo +++ b/contracts/src/systems/actions.cairo @@ -1,8 +1,8 @@ use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; use p_war::models::board::Position; +use p_war::models::game::Game; use p_war::systems::guilds::{IGuildDispatcher, IGuildDispatcherTrait}; use pixelaw::core::models::pixel::PixelUpdate; -use p_war::models::game::Game; use pixelaw::core::utils::DefaultParameters; use starknet::ContractAddress; @@ -12,11 +12,11 @@ pub trait IActions { fn init(ref self: T); fn interact(ref self: T, default_params: DefaultParameters); fn create_game(ref self: T, origin: Position) -> usize; - fn create_game_guilds(ref self: T, game_id: usize, guild_dispatcher: IGuildDispatcher) -> Array; + fn create_game_guilds( + ref self: T, game_id: usize, guild_dispatcher: IGuildDispatcher + ) -> Array; fn get_game_id(self: @T, position: Position) -> usize; - fn place_pixel( - ref self: T, app: ContractAddress, default_params: DefaultParameters - ); + fn place_pixel(ref self: T, app: ContractAddress, default_params: DefaultParameters); fn update_pixel(ref self: T, pixel_update: PixelUpdate); fn end_game(ref self: T, game_id: usize); } @@ -24,6 +24,10 @@ pub trait IActions { // dojo decorator #[dojo::contract(namespace: "pixelaw", nomapping: true)] mod p_war_actions { + use dojo::event::EventStorage; + use dojo::model::{ModelStorage, ModelValueStorage}; + use dojo::world::WorldStorageTrait; + use dojo::world::{IWorldDispatcherTrait}; use p_war::constants::{ APP_KEY, APP_ICON, GAME_ID, OUT_OF_BOUNDS_GAME_ID, DEFAULT_RECOVERY_RATE, INITIAL_COLOR, GAME_DURATION, DEFAULT_AREA, @@ -34,6 +38,7 @@ mod p_war_actions { allowed_color::{AllowedColor, PaletteColors, InPalette, GamePalette}, allowed_app::AllowedApp }; + use p_war::systems::app::{IAllowedApp, IAllowedAppDispatcher, IAllowedAppDispatcherTrait}; use p_war::systems::guilds::{IGuildDispatcher, IGuildDispatcherTrait}; use p_war::systems::utils::{check_game_status}; use pixelaw::core::actions::{ @@ -41,19 +46,14 @@ mod p_war_actions { IActionsDispatcherTrait as ICoreActionsDispatcherTrait }; use pixelaw::core::models::{pixel::PixelUpdate, registry::App}; + use pixelaw::core::utils::{ + get_callers, get_core_actions, Direction, Position, DefaultParameters + }; use starknet::{ ContractAddress, get_block_timestamp, get_caller_address, get_contract_address, get_tx_info, contract_address_const, }; use super::{IActions, IActionsDispatcher, IActionsDispatcherTrait}; - use dojo::model::{ModelStorage, ModelValueStorage}; - use dojo::world::WorldStorageTrait; - use dojo::event::EventStorage; - use pixelaw::core::utils::{ - get_callers, get_core_actions, Direction, Position, DefaultParameters - }; - use p_war::systems::app::{IAllowedApp, IAllowedAppDispatcher, IAllowedAppDispatcherTrait}; - use dojo::world::{IWorldDispatcherTrait}; #[derive(Copy, Drop, Serde)] #[dojo::event] @@ -107,7 +107,9 @@ mod p_war_actions { let board: Board = world.read_model(GAME_ID); if position.x < board.origin.x || position.x >= board.origin.x - + (board.width.try_into().unwrap()) || position.y < board.origin.y || position.y >= board.origin.y + + (board.width.try_into().unwrap()) + || position.y < board.origin.y + || position.y >= board.origin.y + (board.height.try_into().unwrap()) { return OUT_OF_BOUNDS_GAME_ID; // OUT_OF_BOUNDS_GAME_ID for out of bounds }; @@ -167,8 +169,12 @@ mod p_war_actions { if color_idx > 8 { break; }; - let allowed_color = AllowedColor { game_id: id, color: *a.at(color_idx), is_allowed: true }; - let palette_colors = PaletteColors { game_id: id, idx: color_idx, color: *a.at(color_idx) }; + let allowed_color = AllowedColor { + game_id: id, color: *a.at(color_idx), is_allowed: true + }; + let palette_colors = PaletteColors { + game_id: id, idx: color_idx, color: *a.at(color_idx) + }; let in_palette = InPalette { game_id: id, color: *a.at(color_idx), value: true }; world.write_model(@allowed_color); world.write_model(@palette_colors); @@ -178,19 +184,23 @@ mod p_war_actions { println!("create_game 2"); // set default recovery_rate - let pixel_recovery_rate = PixelRecoveryRate { game_id: id, rate: DEFAULT_RECOVERY_RATE }; + let pixel_recovery_rate = PixelRecoveryRate { + game_id: id, rate: DEFAULT_RECOVERY_RATE + }; let game_palette = GamePalette { game_id: id, length: 9 }; world.write_model(@pixel_recovery_rate); world.write_model(@game_palette); - println!("create_game 2.1"); + println!("create_game 2.1"); id // emit event that game has started } // initialize guilds for the game - fn create_game_guilds(ref self: ContractState, game_id: usize, guild_dispatcher: IGuildDispatcher) -> Array { + fn create_game_guilds( + ref self: ContractState, game_id: usize, guild_dispatcher: IGuildDispatcher + ) -> Array { let mut guild_ids = ArrayTrait::new(); guild_ids.append(guild_dispatcher.create_guild(game_id, 'Fire')); guild_ids.append(guild_dispatcher.create_guild(game_id, 'Water')); @@ -244,22 +254,23 @@ mod p_war_actions { assert(check_game_status(game.status()), 'game is not ongoing: actions1'); println!("set_pixel BEGIN"); - core_actions.update_pixel( //new - player_address, - system, - PixelUpdate { - x: default_params.position.x, - y: default_params.position.y, - color: Option::Some(default_params.color), - timestamp: Option::None, - text: Option::None, - app: Option::None, - owner: Option::None, - action: Option::None - }, - Option::None, - false - ); + core_actions + .update_pixel( //new + player_address, + system, + PixelUpdate { + x: default_params.position.x, + y: default_params.position.y, + color: Option::Some(default_params.color), + timestamp: Option::None, + text: Option::None, + app: Option::None, + owner: Option::None, + action: Option::None + }, + Option::None, + false + ); println!("set_pixel END"); player.num_owns += 1; diff --git a/contracts/src/systems/app.cairo b/contracts/src/systems/app.cairo index 8be12cc..b470b7c 100644 --- a/contracts/src/systems/app.cairo +++ b/contracts/src/systems/app.cairo @@ -1,8 +1,8 @@ use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; -use pixelaw::core::utils::DefaultParameters; use pixelaw::core::models::pixel::PixelUpdate; +use pixelaw::core::utils::DefaultParameters; use starknet::{ContractAddress, get_contract_address}; -use super::actions::{IActionsDispatcher, IActionsDispatcherTrait}; // Add this import +use super::actions::{IActionsDispatcher, IActionsDispatcherTrait}; // Add this import #[starknet::interface] trait IAllowedApp { @@ -13,17 +13,17 @@ trait IAllowedApp { #[dojo::contract(namespace: "pixelaw", nomapping: true)] mod allowed_app_actions { - use super::IAllowedApp; - use pixelaw::core::utils::DefaultParameters; - use pixelaw::core::models::pixel::PixelUpdate; - use starknet::{ContractAddress, get_contract_address}; + use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; use pixelaw::core::actions::{ IActionsDispatcher as ICoreActionsDispatcher, IActionsDispatcherTrait as ICoreActionsDispatcherTrait }; - use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; + use pixelaw::core::models::pixel::PixelUpdate; + use pixelaw::core::utils::DefaultParameters; use pixelaw::core::utils::get_core_actions; - + use starknet::{ContractAddress, get_contract_address}; + use super::IAllowedApp; + #[abi(embed_v0)] impl AllowedAppImpl of IAllowedApp { fn set_pixel(ref self: ContractState, default_params: DefaultParameters) { @@ -33,22 +33,23 @@ mod allowed_app_actions { let player = starknet::get_tx_info().unbox().account_contract_address; let system = get_contract_address(); - core_actions.update_pixel( - player, - system, - PixelUpdate { - x: default_params.position.x, - y: default_params.position.y, - color: Option::Some(default_params.color), - timestamp: Option::None, - text: Option::None, - app: Option::None, - owner: Option::None, - action: Option::None - }, - Option::None, - false - ); + core_actions + .update_pixel( + player, + system, + PixelUpdate { + x: default_params.position.x, + y: default_params.position.y, + color: Option::Some(default_params.color), + timestamp: Option::None, + text: Option::None, + app: Option::None, + owner: Option::None, + action: Option::None + }, + Option::None, + false + ); } } -} \ No newline at end of file +} diff --git a/contracts/src/systems/guilds.cairo b/contracts/src/systems/guilds.cairo index c4fafbc..9de6c24 100644 --- a/contracts/src/systems/guilds.cairo +++ b/contracts/src/systems/guilds.cairo @@ -5,16 +5,10 @@ use starknet::{ContractAddress, get_caller_address}; #[starknet::interface] pub trait IGuild { - fn create_guild( - ref self: T, game_id: usize, guild_name: felt252 - ) -> usize; //returns guild ID - fn add_member( - ref self: T, game_id: usize, guild_id: usize, new_member: ContractAddress - ); + fn create_guild(ref self: T, game_id: usize, guild_name: felt252) -> usize; //returns guild ID + fn add_member(ref self: T, game_id: usize, guild_id: usize, new_member: ContractAddress); fn join_guild(ref self: T, game_id: usize, guild_id: usize); - fn remove_member( - ref self: T, game_id: usize, guild_id: usize, member: ContractAddress - ); + fn remove_member(ref self: T, game_id: usize, guild_id: usize, member: ContractAddress); fn is_member(ref self: T, game_id: usize, guild_id: usize, member: ContractAddress) -> bool; fn get_guild_contract_address(ref self: T) -> ContractAddress; fn get_guild_points(ref self: T, game_id: usize, guild_id: usize) -> usize; @@ -22,6 +16,9 @@ pub trait IGuild { #[dojo::contract(namespace: "pixelaw", nomapping: true)] mod guild_actions { + use dojo::event::EventStorage; + use dojo::model::{ModelStorage, ModelValueStorage}; + use dojo::world::WorldStorageTrait; use p_war::models::{ game::{Game, Status, GameTrait}, guilds::{Guild}, board::{GameId, Board, Position, PWarPixel}, player::{Player}, allowed_app::AllowedApp, @@ -29,11 +26,8 @@ mod guild_actions { use starknet::{ ContractAddress, get_block_timestamp, get_caller_address, get_contract_address, get_tx_info }; - use dojo::model::{ModelStorage, ModelValueStorage}; - use dojo::world::WorldStorageTrait; - use dojo::event::EventStorage; use super::{IGuild}; - + #[derive(Copy, Drop, Serde)] #[dojo::event] pub struct GuildCreated { @@ -43,7 +37,7 @@ mod guild_actions { guild_name: felt252, creator: ContractAddress } - + #[derive(Copy, Drop, Serde)] #[dojo::event] pub struct MemberAdded { @@ -52,7 +46,7 @@ mod guild_actions { guild_id: usize, member: ContractAddress } - + #[derive(Copy, Drop, Serde)] #[dojo::event] pub struct MemberRemoved { @@ -112,15 +106,12 @@ mod guild_actions { world.write_model(@game); println!("set guild"); let caller = get_caller_address(); - world.emit_event(@GuildCreated {game_id, guild_id, guild_name, creator: caller}); + world.emit_event(@GuildCreated { game_id, guild_id, guild_name, creator: caller }); guild_id } fn add_member( - ref self: ContractState, - game_id: usize, - guild_id: usize, - new_member: ContractAddress + ref self: ContractState, game_id: usize, guild_id: usize, new_member: ContractAddress ) { let mut world = self.world(@"pixelaw"); let caller = get_caller_address(); @@ -194,7 +185,7 @@ mod guild_actions { } i += 1; }; - + assert(member_found, 'Member not in guild'); guild.members = updated_members.span(); @@ -202,10 +193,12 @@ mod guild_actions { // Save the updated guild world.write_model(@guild); - world.emit_event(@MemberRemoved {game_id, guild_id, member}) + world.emit_event(@MemberRemoved { game_id, guild_id, member }) } - fn is_member(ref self: ContractState, game_id: usize, guild_id: usize, member: ContractAddress) -> bool { + fn is_member( + ref self: ContractState, game_id: usize, guild_id: usize, member: ContractAddress + ) -> bool { let mut world = self.world(@"pixelaw"); let guild: Guild = world.read_model((game_id, guild_id)); let mut is_member = false; @@ -225,11 +218,11 @@ mod guild_actions { fn get_guild_contract_address(ref self: ContractState) -> ContractAddress { let guild_contract_address = get_contract_address(); - + guild_contract_address } - fn get_guild_points(ref self: ContractState , game_id: usize, guild_id: usize) -> usize { + fn get_guild_points(ref self: ContractState, game_id: usize, guild_id: usize) -> usize { // Get the guild let mut world = self.world(@"pixelaw"); let mut guild: Guild = world.read_model((game_id, guild_id)); diff --git a/contracts/src/systems/payments.cairo b/contracts/src/systems/payments.cairo index cf42265..8301678 100644 --- a/contracts/src/systems/payments.cairo +++ b/contracts/src/systems/payments.cairo @@ -1,7 +1,7 @@ -use starknet::{ContractAddress, get_caller_address}; -use p_war::models::payments::{GamePayments, PlayerPayment, TreasuryInfo}; use p_war::models::game::Game; use p_war::models::guilds::Guild; +use p_war::models::payments::{GamePayments, PlayerPayment, TreasuryInfo}; +use starknet::{ContractAddress, get_caller_address}; #[starknet::interface] pub trait IPayments { @@ -15,8 +15,8 @@ pub trait IPayments { mod payments { // use super::*; - use dojo::model::{ModelStorage, ModelValueStorage}; use dojo::event::EventStorage; + use dojo::model::{ModelStorage, ModelValueStorage}; const PRIZE_POOL_PERCENTAGE: u256 = 90; const TREASURY_PERCENTAGE: u256 = 10; @@ -44,7 +44,9 @@ mod payments { #[abi(embed_v0)] impl PaymentsImpl of IPayments { - fn initialize_game_payments(ref self: ContractState, game_id: u32, participation_fee: u256) { + fn initialize_game_payments( + ref self: ContractState, game_id: u32, participation_fee: u256 + ) { let game_payments = GamePayments { game_id: game_id, participation_fee: participation_fee, @@ -69,9 +71,7 @@ mod payments { game_payments.treasury_balance += treasury_amount; let player_payment = PlayerPayment { - game_id: game_id, - player: caller, - amount_paid: fee + game_id: game_id, player: caller, amount_paid: fee }; set!(world, (game_payments, player_payment)); @@ -82,7 +82,7 @@ mod payments { fn payout_winning_guild(ref self: ContractState, game_id: u32, winning_guild_id: u32) { let mut game_payments = get!(world, game_id, (GamePayments)); let guild = get!(world, (game_id, winning_guild_id), (Guild)); - + let total_payout = game_payments.prize_pool; let members_count = guild.member_count; let payout_per_member = total_payout / members_count.into(); @@ -106,15 +106,17 @@ mod payments { game_payments.prize_pool = 0; set!(world, (game_payments)); - emit!(world, WinningGuildPaidOut { game_id: game_id, guild_id: winning_guild_id, total_amount: total_payout }); + emit!( + world, + WinningGuildPaidOut { + game_id: game_id, guild_id: winning_guild_id, total_amount: total_payout + } + ); } fn set_treasury_address(ref self: ContractState, treasury_address: ContractAddress) { - let treasury_info = TreasuryInfo { - dummy_key: 0, - treasury_address: treasury_address - }; + let treasury_info = TreasuryInfo { dummy_key: 0, treasury_address: treasury_address }; set!(world, (treasury_info)); } } -} \ No newline at end of file +} diff --git a/contracts/src/systems/propose.cairo b/contracts/src/systems/propose.cairo index 44ba21d..480a56e 100644 --- a/contracts/src/systems/propose.cairo +++ b/contracts/src/systems/propose.cairo @@ -8,23 +8,34 @@ use p_war::models::{ #[starknet::interface] pub trait IPropose { fn create_proposal( + ref self: T, game_id: usize, proposal_type: u8, target_args_1: u32, target_args_2: u32 + ) -> usize; + fn activate_proposal(ref self: T, game_id: usize, index: usize, clear_data: Span); + fn add_new_color(ref self: T, game_id: usize, index: usize, game: Game, proposal: Proposal); + fn reset_to_white( ref self: T, game_id: usize, - proposal_type: u8, - target_args_1: u32, - target_args_2: u32 - ) -> usize; - fn activate_proposal( - ref self: T, game_id: usize, index: usize, clear_data: Span + index: usize, + game: Game, + proposal: Proposal, + clear_data: Span ); - fn add_new_color(ref self: T, game_id: usize, index: usize, game: Game, proposal: Proposal); - fn reset_to_white(ref self: T, game_id: usize, index: usize, game: Game, proposal: Proposal, clear_data: Span); } // dojo decorator #[dojo::contract(namespace: "pixelaw", nomapping: true)] mod propose_actions { - use p_war::constants::{PROPOSAL_DURATION, NEEDED_YES_VOTING_POWER, DISASTER_SIZE, PROPOSAL_FACTOR}; + use dojo::event::EventStorage; + use dojo::model::{ModelStorage, ModelValueStorage}; + use dojo::world::WorldStorageTrait; + use p_war::constants::{ + PROPOSAL_DURATION, NEEDED_YES_VOTING_POWER, DISASTER_SIZE, PROPOSAL_FACTOR + }; + use p_war::models::{ + game::{Game, Status, GameTrait}, proposal::{Proposal, PixelRecoveryRate}, + board::{GameId, Board, Position, PWarPixel}, player::{Player}, allowed_app::AllowedApp, + allowed_color::{AllowedColor, PaletteColors, InPalette, GamePalette} + }; use p_war::systems::utils::{check_game_status}; use pixelaw::core::actions::{ IActionsDispatcher as ICoreActionsDispatcher, @@ -36,15 +47,7 @@ mod propose_actions { ContractAddress, get_block_timestamp, get_caller_address, get_contract_address, get_tx_info }; use super::{IPropose}; - use dojo::model::{ModelStorage, ModelValueStorage}; - use dojo::world::WorldStorageTrait; - use dojo::event::EventStorage; - use p_war::models::{ - game::{Game, Status, GameTrait}, proposal::{Proposal, PixelRecoveryRate}, - board::{GameId, Board, Position, PWarPixel}, player::{Player}, allowed_app::AllowedApp, - allowed_color::{AllowedColor, PaletteColors, InPalette, GamePalette} - }; - + #[derive(Copy, Drop, Serde)] #[dojo::event] pub struct ProposalCreated { @@ -55,7 +58,7 @@ mod propose_actions { target_args_1: u32, target_args_2: u32 } - + #[derive(Copy, Drop, Serde)] #[dojo::event] pub struct ProposalActivated { @@ -112,7 +115,16 @@ mod propose_actions { player.num_commit = player.num_commit + 1; world.write_model(@player); - world.emit_event(@ProposalCreated { game_id, index: game.proposal_idx, proposal_type, target_args_1, target_args_2 }); + world + .emit_event( + @ProposalCreated { + game_id, + index: game.proposal_idx, + proposal_type, + target_args_1, + target_args_2 + } + ); new_proposal.index } @@ -131,7 +143,7 @@ mod propose_actions { assert(proposal.yes_voting_power > proposal.no_voting_power, 'yes is not more than no'); assert(proposal.is_activated == false, 'this is already activated'); assert(check_game_status(game.status()), 'game is not ongoing: propose2'); - + // activate the proposal. if proposal.proposal_type == 1 { self.add_new_color(game_id, index, game, proposal); @@ -154,7 +166,16 @@ mod propose_actions { proposal.is_activated = true; world.write_model(@proposal); - world.emit_event(@ProposalActivated {game_id, index, proposal_type: proposal.proposal_type, target_args_1: proposal.target_args_1, target_args_2: proposal.target_args_2}) + world + .emit_event( + @ProposalActivated { + game_id, + index, + proposal_type: proposal.proposal_type, + target_args_1: proposal.target_args_1, + target_args_2: proposal.target_args_2 + } + ) } // add new color to the palette, if the color is added, the oldest color become unusable. @@ -184,7 +205,8 @@ mod propose_actions { is_in_palette.value = true; world.write_model(@is_in_palette); - let mut palette_color: PaletteColors = world.read_model((game_id, game_palette.length)); + let mut palette_color: PaletteColors = world + .read_model((game_id, game_palette.length)); palette_color.color = new_color; world.write_model(@palette_color); @@ -213,14 +235,16 @@ mod propose_actions { last_palette_color.color = new_color; world.write_model(@last_palette_color); - let mut old_in_pallet: InPalette = world.read_model((game_id, oldest_color.color)); + let mut old_in_pallet: InPalette = world + .read_model((game_id, oldest_color.color)); old_in_pallet.value = false; world.write_model(@old_in_pallet); is_in_palette.value = true; world.write_model(@is_in_palette); - let mut old_color_allowed: AllowedColor = world.read_model((game_id, oldest_color.color)); + let mut old_color_allowed: AllowedColor = world + .read_model((game_id, oldest_color.color)); old_color_allowed.is_allowed = false; world.write_model(@old_color_allowed); }; @@ -228,12 +252,19 @@ mod propose_actions { } fn reset_to_white( - ref self: ContractState, game_id: usize, index: usize, game: Game, proposal: Proposal, clear_data: Span + ref self: ContractState, + game_id: usize, + index: usize, + game: Game, + proposal: Proposal, + clear_data: Span ) { assert(proposal.proposal_type == 2, 'not reset to white proposal'); let mut world = self.world(@"pixelaw"); // Reset to white by color - let core_actions = get_core_actions(ref world); // TODO: should we use p_war_actions insted of core_actions??? + let core_actions = get_core_actions( + ref world + ); // TODO: should we use p_war_actions insted of core_actions??? let system = get_caller_address(); let target_args_1: u32 = proposal.target_args_1; @@ -277,7 +308,8 @@ mod propose_actions { if (previous_pwarpixel.owner != starknet::contract_address_const::<0x0>()) { // get the previous player's info - let mut previous_player: Player = world.read_model(previous_pwarpixel.owner); + let mut previous_player: Player = world + .read_model(previous_pwarpixel.owner); previous_player.num_owns -= 1; world.write_model(@previous_player); diff --git a/contracts/src/systems/utils.cairo b/contracts/src/systems/utils.cairo index 6a5d703..944ef6b 100644 --- a/contracts/src/systems/utils.cairo +++ b/contracts/src/systems/utils.cairo @@ -1,3 +1,6 @@ +use dojo::event::EventStorage; +use dojo::model::{ModelStorage, ModelValueStorage}; +use dojo::world::storage::WorldStorage; use dojo::world::{IWorldDispatcher, IWorldDispatcherTrait}; use p_war::models::{ @@ -8,10 +11,7 @@ use p_war::models::{ use starknet::{ ContractAddress, get_block_timestamp, get_caller_address, get_contract_address, get_tx_info }; -use dojo::model::{ModelStorage, ModelValueStorage}; -use dojo::event::EventStorage; -use dojo::world::storage::WorldStorage; pub fn check_game_status(status: Status) -> bool { status == Status::Pending || status == Status::Ongoing -} \ No newline at end of file +} diff --git a/contracts/src/systems/voting.cairo b/contracts/src/systems/voting.cairo index 014e7b0..851beeb 100644 --- a/contracts/src/systems/voting.cairo +++ b/contracts/src/systems/voting.cairo @@ -1,21 +1,19 @@ // define the interface #[starknet::interface] pub trait IVoting { - fn vote( - ref self: T, game_id: usize, index: usize, use_px: u32, is_in_favor: bool - ); + fn vote(ref self: T, game_id: usize, index: usize, use_px: u32, is_in_favor: bool); } // dojo decorator #[dojo::contract(namespace: "pixelaw", nomapping: true)] mod voting_actions { + use dojo::event::EventStorage; + use dojo::model::{ModelStorage, ModelValueStorage}; + use dojo::world::WorldStorageTrait; use p_war::models::{player::{Player}, proposal::{PlayerVote, Proposal}}; use starknet::{ContractAddress, get_caller_address, get_block_timestamp}; use super::IVoting; - use dojo::model::{ModelStorage, ModelValueStorage}; - use dojo::world::WorldStorageTrait; - use dojo::event::EventStorage; - + #[derive(Copy, Drop, Serde)] #[dojo::event] struct Voted { @@ -30,11 +28,7 @@ mod voting_actions { #[abi(embed_v0)] impl VotingImpl of IVoting { fn vote( - ref self: ContractState, - game_id: usize, - index: usize, - use_px: u32, - is_in_favor: bool + ref self: ContractState, game_id: usize, index: usize, use_px: u32, is_in_favor: bool ) { let mut world = self.world(@"pixelaw"); let player_address = get_caller_address(); @@ -63,7 +57,16 @@ mod voting_actions { world.write_model(@proposal); world.write_model(@player_vote); - world.emit_event(@Voted {game_id, index, timestamp: get_block_timestamp(), voter: player_address, is_in_favor}); + world + .emit_event( + @Voted { + game_id, + index, + timestamp: get_block_timestamp(), + voter: player_address, + is_in_favor + } + ); } } } diff --git a/contracts/src/tests/test_games.cairo b/contracts/src/tests/test_games.cairo index 67ae275..2c3dfe6 100644 --- a/contracts/src/tests/test_games.cairo +++ b/contracts/src/tests/test_games.cairo @@ -1,9 +1,7 @@ -use p_war::tests::utils::{deploy_p_war}; +use dojo::event::EventStorage; use dojo::model::{ModelStorage, ModelValueStorage}; use dojo::world::{WorldStorage, WorldStorageTrait}; -use dojo::event::EventStorage; -use pixelaw_test_helpers::{setup_core_initialized}; -use starknet::{class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp}}; +use p_war::tests::utils::{deploy_p_war}; use p_war::{ models::{ game::{Game}, board::{Board, GameId, Position}, proposal::{Proposal}, @@ -17,15 +15,17 @@ use p_war::{ constants::{PROPOSAL_DURATION} }; use pixelaw::core::{ - models::{ - pixel::{Pixel, PixelUpdate}, - }, + models::{pixel::{Pixel, PixelUpdate},}, actions::{ actions as core_actions, IActionsDispatcher as ICoreActionsDispatcher, IActionsDispatcherTrait as ICoreActionsDispatcherTrait }, utils::{DefaultParameters, Position as PixelawPosition} }; +use pixelaw_test_helpers::{setup_core_initialized}; +use starknet::{ + class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp} +}; const COLOR: u32 = 0x000000ff; @@ -33,7 +33,10 @@ const COLOR: u32 = 0x000000ff; #[available_gas(999_999_999)] fn test_game_created() { let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); - let (_world, p_war_actions, _propose_action, _voting_action, _guild, _allowed_app) = deploy_p_war(ref world); + let (_world, p_war_actions, _propose_action, _voting_action, _guild, _allowed_app) = + deploy_p_war( + ref world + ); // caller let _caller = starknet::contract_address_const::<0x0>(); diff --git a/contracts/src/tests/test_guilds.cairo b/contracts/src/tests/test_guilds.cairo index 88ad525..973c759 100644 --- a/contracts/src/tests/test_guilds.cairo +++ b/contracts/src/tests/test_guilds.cairo @@ -1,15 +1,10 @@ -use p_war::tests::utils::{deploy_p_war, print_all_colors}; +use dojo::event::EventStorage; use dojo::model::{ModelStorage, ModelValueStorage}; use dojo::world::{WorldStorage, WorldStorageTrait}; -use dojo::event::EventStorage; -use pixelaw_test_helpers::{setup_core_initialized}; -use starknet::{class_hash::Felt252TryIntoClassHash, ContractAddress, - testing::{set_block_timestamp, set_account_contract_address, set_contract_address}, - get_block_timestamp, contract_address_const}; +use p_war::tests::utils::{deploy_p_war, print_all_colors}; use p_war::{ models::{ - game::{Game}, board::{Board, GameId, Position}, proposal::{Proposal}, - guilds::{Guild}, + game::{Game}, board::{Board, GameId, Position}, proposal::{Proposal}, guilds::{Guild}, allowed_app::AllowedApp, allowed_color::{AllowedColor, PaletteColors}, }, systems::{ @@ -21,15 +16,19 @@ use p_war::{ constants::{GAME_DURATION, PROPOSAL_DURATION} }; use pixelaw::core::{ - models::{ - pixel::{Pixel, PixelUpdate}, - }, + models::{pixel::{Pixel, PixelUpdate},}, actions::{ actions as core_actions, IActionsDispatcher as ICoreActionsDispatcher, IActionsDispatcherTrait as ICoreActionsDispatcherTrait }, utils::{DefaultParameters, Position as PixelawPosition, is_pixel_color} }; +use pixelaw_test_helpers::{setup_core_initialized}; +use starknet::{ + class_hash::Felt252TryIntoClassHash, ContractAddress, + testing::{set_block_timestamp, set_account_contract_address, set_contract_address}, + get_block_timestamp, contract_address_const +}; const WHITE_COLOR: u32 = 0xFFFFFFFF; const RED_COLOR: u32 = 0xFF000000; @@ -44,7 +43,10 @@ fn test_guild_operations() { // Initialize the world and the actions let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); - let (_world, p_war_actions, _propose_action, _voting_action, guild_actions, _allowed_app) = deploy_p_war(ref world); + let (_world, p_war_actions, _propose_action, _voting_action, guild_actions, _allowed_app) = + deploy_p_war( + ref world + ); println!("setup done"); @@ -109,7 +111,10 @@ fn test_guild_operations() { fn test_guild_points() { // Initialize the world and the actions let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); - let (_world, p_war_actions, _propose_action, _voting_action, guild_actions, _allowed_app) = deploy_p_war(ref world); + let (_world, p_war_actions, _propose_action, _voting_action, guild_actions, _allowed_app) = + deploy_p_war( + ref world + ); println!("setup"); let PLAYER_1 = contract_address_const::<0x1337>(); @@ -156,7 +161,7 @@ fn test_guild_points() { color: WHITE_COLOR } ); - + //add member set_account_contract_address(PLAYER_1); set_contract_address(PLAYER_1); @@ -167,15 +172,15 @@ fn test_guild_points() { set_account_contract_address(PLAYER_2); set_contract_address(PLAYER_2); p_war_actions - .interact( - DefaultParameters { - player_override: Option::None, - system_override: Option::None, - area_hint: Option::None, - position: GAME_PAINT_POSITION, - color: WHITE_COLOR - } - ); + .interact( + DefaultParameters { + player_override: Option::None, + system_override: Option::None, + area_hint: Option::None, + position: GAME_PAINT_POSITION, + color: WHITE_COLOR + } + ); p_war_actions .interact( DefaultParameters { @@ -187,7 +192,6 @@ fn test_guild_points() { } ); - let guild_points = guild_actions.get_guild_points(game_id, guild_id); println!("test: guild_points: {}", guild_points); assert(guild_points == 4, 'Guild points mismatch'); @@ -198,7 +202,10 @@ fn test_guild_points() { fn test_guild_creation() { // Initialize the world and the actions let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); - let (_world, p_war_actions, _propose_action, _voting_action, guild_actions, _allowed_app) = deploy_p_war(ref world); + let (_world, p_war_actions, _propose_action, _voting_action, guild_actions, _allowed_app) = + deploy_p_war( + ref world + ); // Setup players let PLAYER_1 = contract_address_const::<0x1337>(); @@ -216,31 +223,31 @@ fn test_guild_creation() { ); let game_id: u32 = p_war_actions.get_game_id(GAME_ORIGIN_POSITION); - + // Create guilds for the game set_account_contract_address(PLAYER_1); set_contract_address(PLAYER_1); let guild_ids: Array = p_war_actions.create_game_guilds(game_id, guild_actions); - + // Create a guild let guild_id: u32 = *guild_ids.at(0); println!("guild_id: {}", guild_id); let guild: Guild = world.read_model((game_id, guild_id)); println!("guild_name: {:?}", guild.guild_name); assert(guild.guild_name == 'Fire', 'Guild name mismatch'); - + let guild_id_2 = *guild_ids.at(1); println!("guild_id_2: {}", guild_id_2); let guild: Guild = world.read_model((game_id, guild_id_2)); println!("guild_name_2: {:?}", guild.guild_name); assert(guild.guild_name == 'Water', 'Guild name mismatch'); - + let guild_id_3 = *guild_ids.at(2); println!("guild_id_3: {}", guild_id_3); let guild: Guild = world.read_model((game_id, guild_id_3)); println!("guild_name_3: {:?}", guild.guild_name); assert(guild.guild_name == 'Earth', 'Guild name mismatch'); - + let guild_id_4 = *guild_ids.at(3); println!("guild_id_4: {}", guild_id_4); let guild: Guild = world.read_model((game_id, guild_id_4)); diff --git a/contracts/src/tests/test_proposals.cairo b/contracts/src/tests/test_proposals.cairo index ee36ac9..81ee8a0 100644 --- a/contracts/src/tests/test_proposals.cairo +++ b/contracts/src/tests/test_proposals.cairo @@ -1,13 +1,10 @@ -use p_war::tests::utils::{deploy_p_war}; +use dojo::event::EventStorage; use dojo::model::{ModelStorage, ModelValueStorage}; use dojo::world::{WorldStorage, WorldStorageTrait}; -use dojo::event::EventStorage; -use pixelaw_test_helpers::{setup_core_initialized}; -use starknet::{class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp}, get_tx_info, get_block_timestamp}; +use p_war::tests::utils::{deploy_p_war}; use p_war::{ models::{ - game::{Game}, board::{Board, GameId, Position}, proposal::{Proposal}, - player::{Player}, + game::{Game}, board::{Board, GameId, Position}, proposal::{Proposal}, player::{Player}, allowed_app::AllowedApp, allowed_color::{AllowedColor, PaletteColors}, }, systems::{ @@ -18,15 +15,18 @@ use p_war::{ constants::{DEFAULT_AREA, PROPOSAL_DURATION, GAME_DURATION} }; use pixelaw::core::{ - models::{ - pixel::{Pixel, PixelUpdate}, - }, + models::{pixel::{Pixel, PixelUpdate},}, actions::{ actions as core_actions, IActionsDispatcher as ICoreActionsDispatcher, IActionsDispatcherTrait as ICoreActionsDispatcherTrait }, utils::{DefaultParameters, Position as PixelawPosition, is_pixel_color} }; +use pixelaw_test_helpers::{setup_core_initialized}; +use starknet::{ + class_hash::Felt252TryIntoClassHash, ContractAddress, testing::{set_block_timestamp}, + get_tx_info, get_block_timestamp +}; const WHITE_COLOR: u32 = 0xFFFFFFFF; const NEW_COLOR: u32 = 0xAABBCCFF; @@ -43,7 +43,9 @@ const VOTE_PIXEL_COUNT: u32 = 3; #[available_gas(999_999_999)] fn test_add_color() { let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); - let (_world, p_war_actions, propose_action, voting_action, _guild, _allowed_app) = deploy_p_war(ref world); + let (_world, p_war_actions, propose_action, voting_action, _guild, _allowed_app) = deploy_p_war( + ref world + ); let default_params = DefaultParameters { player_override: Option::None, @@ -105,9 +107,7 @@ fn test_add_color() { let newest_color_allowed: AllowedColor = world.read_model((id, newest_color.color)); println!( - "@@@@@ NEWEST_ALLOWED: {}, {} @@@@", - newest_color.color, - newest_color_allowed.is_allowed + "@@@@@ NEWEST_ALLOWED: {}, {} @@@@", newest_color.color, newest_color_allowed.is_allowed ); assert(oldest_color_allowed.is_allowed == false, 'the oldest became unusable'); @@ -120,7 +120,9 @@ fn test_add_color() { #[available_gas(999_999_999)] fn test_reset_to_white() { let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); - let (_world, p_war_actions, propose_action, voting_action, _guild, _allowed_app) = deploy_p_war(ref world); + let (_world, p_war_actions, propose_action, voting_action, _guild, _allowed_app) = deploy_p_war( + ref world + ); // Create a game. // This creates a 10x10 grid to the bottom-right of the start_position @@ -173,7 +175,8 @@ fn test_reset_to_white() { // Retrieve the pixel that was reset assert( - is_pixel_color(ref world, GAME_PAINT_POSITION, WHITE_COLOR), 'Pixel should be entirely white' + is_pixel_color(ref world, GAME_PAINT_POSITION, WHITE_COLOR), + 'Pixel should be entirely white' ); // Now try to paint on it again @@ -188,7 +191,9 @@ fn test_reset_to_white() { } ); - assert(is_pixel_color(ref world, GAME_PAINT_POSITION, RED_COLOR), 'Pixel should be entirely red'); + assert( + is_pixel_color(ref world, GAME_PAINT_POSITION, RED_COLOR), 'Pixel should be entirely red' + ); // Now try to paint on it again p_war_actions @@ -203,7 +208,8 @@ fn test_reset_to_white() { ); assert( - is_pixel_color(ref world, GAME_PAINT_POSITION, WHITE_COLOR), 'Pixel should be entirely white' + is_pixel_color(ref world, GAME_PAINT_POSITION, WHITE_COLOR), + 'Pixel should be entirely white' ); } @@ -211,7 +217,9 @@ fn test_reset_to_white() { #[available_gas(999_999_999)] fn test_expand_area() { let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); - let (_world, p_war_actions, propose_action, voting_action, _guild, _allowed_app) = deploy_p_war(ref world); + let (_world, p_war_actions, propose_action, voting_action, _guild, _allowed_app) = deploy_p_war( + ref world + ); let default_params = DefaultParameters { player_override: Option::None, @@ -253,7 +261,9 @@ fn test_expand_area() { #[available_gas(999_999_999)] fn test_extend_game_end() { let (mut world, _core_actions, _player_1, _player_2) = setup_core_initialized(); - let (_world, p_war_actions, propose_action, voting_action, _guild, _allowed_app) = deploy_p_war(ref world); + let (_world, p_war_actions, propose_action, voting_action, _guild, _allowed_app) = deploy_p_war( + ref world + ); let default_params = DefaultParameters { player_override: Option::None, @@ -293,4 +303,4 @@ fn test_extend_game_end() { let game: Game = world.read_model(id); assert(game.end > GAME_DURATION + 60 * 60 - 1, 'game end extended'); -} \ No newline at end of file +} diff --git a/contracts/src/tests/test_setup.cairo b/contracts/src/tests/test_setup.cairo index 3b099d2..921c63f 100644 --- a/contracts/src/tests/test_setup.cairo +++ b/contracts/src/tests/test_setup.cairo @@ -1,5 +1,5 @@ -use p_war::tests::utils::{deploy_p_war}; use dojo::world::WorldStorage; +use p_war::tests::utils::{deploy_p_war}; use pixelaw_test_helpers::{setup_core_initialized}; #[test] diff --git a/contracts/src/tests/utils.cairo b/contracts/src/tests/utils.cairo index 1794730..0315df2 100644 --- a/contracts/src/tests/utils.cairo +++ b/contracts/src/tests/utils.cairo @@ -1,24 +1,25 @@ // import test utils -use dojo_cairo_test::{ - spawn_test_world, NamespaceDef, TestResource, ContractDefTrait, ContractDef, - WorldStorageTestTrait -}; // import world dispatcher use debug::PrintTrait; use dojo::model::{ModelStorage}; -use dojo::world::{ - world, IWorldDispatcher, IWorldDispatcherTrait, WorldStorageTrait, WorldStorage +use dojo::world::{world, IWorldDispatcher, IWorldDispatcherTrait, WorldStorageTrait, WorldStorage}; +use dojo_cairo_test::{ + spawn_test_world, NamespaceDef, TestResource, ContractDefTrait, ContractDef, + WorldStorageTestTrait }; // import test utils use p_war::{ models::{ - player::{Player, m_Player}, - game::{Game, m_Game}, + player::{Player, m_Player}, game::{Game, m_Game}, board::{Board, m_Board, GameId, m_GameId, PWarPixel, m_PWarPixel}, - proposal::{Proposal, m_Proposal, PixelRecoveryRate, m_PixelRecoveryRate, PlayerVote, m_PlayerVote}, - guilds::{Guild, m_Guild}, - allowed_app::{AllowedApp, m_AllowedApp}, - allowed_color::{AllowedColor, m_AllowedColor, PaletteColors, m_PaletteColors, InPalette, m_InPalette, GamePalette, m_GamePalette}, + proposal::{ + Proposal, m_Proposal, PixelRecoveryRate, m_PixelRecoveryRate, PlayerVote, m_PlayerVote + }, + guilds::{Guild, m_Guild}, allowed_app::{AllowedApp, m_AllowedApp}, + allowed_color::{ + AllowedColor, m_AllowedColor, PaletteColors, m_PaletteColors, InPalette, m_InPalette, + GamePalette, m_GamePalette + }, }, systems::{ actions::{p_war_actions, IActionsDispatcher, IActionsDispatcherTrait}, @@ -40,7 +41,16 @@ use starknet::class_hash::Felt252TryIntoClassHash; use zeroable::Zeroable; -pub fn deploy_p_war(ref world: WorldStorage) -> (WorldStorage, IActionsDispatcher, IProposeDispatcher, IVotingDispatcher, IGuildDispatcher, IAllowedAppDispatcher) { +pub fn deploy_p_war( + ref world: WorldStorage +) -> ( + WorldStorage, + IActionsDispatcher, + IProposeDispatcher, + IVotingDispatcher, + IGuildDispatcher, + IAllowedAppDispatcher +) { let ndef = namespace_def(); let cdefs = contract_defs(); @@ -105,7 +115,15 @@ pub fn contract_defs() -> Span { cdefs } -pub fn setup_pwar_apps(world: WorldStorage) -> (IActionsDispatcher, IProposeDispatcher, IVotingDispatcher, IGuildDispatcher, IAllowedAppDispatcher) { +pub fn setup_pwar_apps( + world: WorldStorage +) -> ( + IActionsDispatcher, + IProposeDispatcher, + IVotingDispatcher, + IGuildDispatcher, + IAllowedAppDispatcher +) { let (p_war_actions_address, _) = world.dns(@"p_war_actions").unwrap(); let p_war_actions = IActionsDispatcher { contract_address: p_war_actions_address }; @@ -118,7 +136,7 @@ pub fn setup_pwar_apps(world: WorldStorage) -> (IActionsDispatcher, IProposeDisp let (guild_address, _) = world.dns(@"guild_actions").unwrap(); let guild_actions = IGuildDispatcher { contract_address: guild_address }; - let (allowed_app_address, _) = world.dns(@"allowed_app_actions").unwrap(); + let (allowed_app_address, _) = world.dns(@"allowed_app_actions").unwrap(); let allowed_app_actions = IAllowedAppDispatcher { contract_address: allowed_app_address }; (p_war_actions, propose_actions, voting_actions, guild_actions, allowed_app_actions) @@ -126,8 +144,25 @@ pub fn setup_pwar_apps(world: WorldStorage) -> (IActionsDispatcher, IProposeDisp pub fn setup_pwar_apps_initialized( world: WorldStorage -) -> (IActionsDispatcher, IProposeDispatcher, IVotingDispatcher, IGuildDispatcher, IAllowedAppDispatcher) { - let (p_war_actions, propose_actions, voting_actions, guild_actions, allowed_app_actions): (IActionsDispatcher, IProposeDispatcher, IVotingDispatcher, IGuildDispatcher, IAllowedAppDispatcher) = setup_pwar_apps(world); +) -> ( + IActionsDispatcher, + IProposeDispatcher, + IVotingDispatcher, + IGuildDispatcher, + IAllowedAppDispatcher +) { + let ( + p_war_actions, propose_actions, voting_actions, guild_actions, allowed_app_actions + ): ( + IActionsDispatcher, + IProposeDispatcher, + IVotingDispatcher, + IGuildDispatcher, + IAllowedAppDispatcher + ) = + setup_pwar_apps( + world + ); p_war_actions.init(); // propose_actions.init(); // voting_actions.init(); @@ -142,11 +177,7 @@ pub fn print_all_colors(ref world: WorldStorage, id: u32) { loop { let color: PaletteColors = world.read_model((id, i)); let allowed_color: AllowedColor = world.read_model((id, color.color)); - println!( - "@@@@@ COLOR: {}, {} @@@@", - color.color, - allowed_color.is_allowed - ); + println!("@@@@@ COLOR: {}, {} @@@@", color.color, allowed_color.is_allowed); i += 1; if i == 9 { break; From c4dcb2e0bc7397a168cd26cb17b0b038a3b728b8 Mon Sep 17 00:00:00 2001 From: Asuma Yamada Date: Thu, 5 Dec 2024 05:52:01 +0900 Subject: [PATCH 15/18] fix: keystore config --- contracts/dojo_sepolia.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/dojo_sepolia.toml b/contracts/dojo_sepolia.toml index 6bcbb83..eb41875 100644 --- a/contracts/dojo_sepolia.toml +++ b/contracts/dojo_sepolia.toml @@ -10,7 +10,7 @@ mappings = {} [env] rpc_url = "https://api.cartridge.gg/x/starknet/sepolia" account_address = "0x02107b2bcC750F51E70cFb9c53583a54eAf86DaC60C6EFBDECf18F7eE398Cb89" -private_key = "0x01ef15f865960b993c0bd1c5e00b94ebd55485e39c4e68a57b08b72f0885682f" +keystore_path = "sepolia.deployer.keystore.json" world_address = "0x2bf4d3aa0dced89d37d8c3b4ff6a05895c0af32ff3baf9b02abf8504e53eaad" [writers] From 98bde36c8936ac564287918358faed21b0682307 Mon Sep 17 00:00:00 2001 From: Asuma Yamada Date: Thu, 5 Dec 2024 05:52:51 +0900 Subject: [PATCH 16/18] fix: add comment --- contracts/dojo_sepolia.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/dojo_sepolia.toml b/contracts/dojo_sepolia.toml index eb41875..151baed 100644 --- a/contracts/dojo_sepolia.toml +++ b/contracts/dojo_sepolia.toml @@ -10,6 +10,7 @@ mappings = {} [env] rpc_url = "https://api.cartridge.gg/x/starknet/sepolia" account_address = "0x02107b2bcC750F51E70cFb9c53583a54eAf86DaC60C6EFBDECf18F7eE398Cb89" +# can be generated with `starkli signer keystore from-key sepolia.deployer.keystore.json` keystore_path = "sepolia.deployer.keystore.json" world_address = "0x2bf4d3aa0dced89d37d8c3b4ff6a05895c0af32ff3baf9b02abf8504e53eaad" From f763f61fb41c8456e1d7642a1193604382f86364 Mon Sep 17 00:00:00 2001 From: Asuma Yamada Date: Thu, 5 Dec 2024 05:55:46 +0900 Subject: [PATCH 17/18] tweak --- contracts/.gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/.gitignore b/contracts/.gitignore index 7904cb3..cdd0585 100644 --- a/contracts/.gitignore +++ b/contracts/.gitignore @@ -3,4 +3,5 @@ target generated .idea manifests -sepolia.deployer.keystore.json \ No newline at end of file +sepolia.deployer.keystore.json +sepolia.deployer.keystore.jsonc From 9d72e05eccd54bbae9be1b0da319a591d9b42fb7 Mon Sep 17 00:00:00 2001 From: OwnerOfJK Date: Sun, 12 Jan 2025 20:26:58 +0100 Subject: [PATCH 18/18] updated README --- README.md | 4 ++-- client/.gitignore | 1 + client/src/vite-env.d.ts | 32 ++++++++++++++++---------------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 889fb60..d9380b3 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ otherwise, ```bash # Run Katana -katana --disable-fee --allowed-origins "*" --db-dir katana +katana --allowed-origins "*" --db-dir katana ``` #### Terminal two @@ -68,7 +68,7 @@ sozo build sozo migrate apply # Start Torii -torii --world 0x263ae44e5414519a5c5a135cccaf3d9d7ee196d37e8de47a178da91f3de9b34 --allowed-origins "*" +torii --world 0x2bf4d3aa0dced89d37d8c3b4ff6a05895c0af32ff3baf9b02abf8504e53eaad --allowed-origins "*" ``` ### How to deploy diff --git a/client/.gitignore b/client/.gitignore index dbc4bd7..1fad730 100644 --- a/client/.gitignore +++ b/client/.gitignore @@ -11,6 +11,7 @@ node_modules dist dist-ssr *.tsbuildinfo +bun.lockb .env.production diff --git a/client/src/vite-env.d.ts b/client/src/vite-env.d.ts index a4496a2..5a3036c 100644 --- a/client/src/vite-env.d.ts +++ b/client/src/vite-env.d.ts @@ -3,17 +3,17 @@ type ImportMetaEnv = { // Auto-generated by `npx vite-envs update-types` and hot-reloaded by the `vite-env` plugin // You probably want to add `/src/vite-env.d.ts` to your .prettierignore - BASE_URL: string; - MODE: string; - DEV: boolean; - PROD: boolean; - VITE_PUBLIC_TORII_URL: string; - VITE_PUBLIC_RPC_URL: string; - VITE_PUBLIC_MASTER_ADDRESS: string; - VITE_PUBLIC_MASTER_PRIVATE_KEY: string; - VITE_PUBLIC_EXPLORER_URL: string; - VITE_PUBLIC_FEE_TOKEN_ADDRESS: string; - VITE_PUBLIC_PROFILE: string; + VITE_PUBLIC_TORII_URL: string + VITE_PUBLIC_RPC_URL: string + VITE_PUBLIC_MASTER_ADDRESS: string + VITE_PUBLIC_MASTER_PRIVATE_KEY: string + VITE_PUBLIC_EXPLORER_URL: string + VITE_PUBLIC_FEE_TOKEN_ADDRESS: string + VITE_PUBLIC_PROFILE: string + BASE_URL: string + MODE: string + DEV: boolean + PROD: boolean // @user-defined-start /* * You can use this section to explicitly extend the type definition of `import.meta.env` @@ -22,16 +22,16 @@ type ImportMetaEnv = { */ SSR: boolean; // @user-defined-end -}; +} interface ImportMeta { // Auto-generated by `npx vite-envs update-types` - url: string; + url: string - readonly hot?: import("vite-envs/types/hot").ViteHotContext; + readonly hot?: import('vite-envs/types/hot').ViteHotContext - readonly env: ImportMetaEnv; + readonly env: ImportMetaEnv - glob: import("vite-envs/types/importGlob").ImportGlobFunction; + glob: import('vite-envs/types/importGlob').ImportGlobFunction }