From 204dd7e81ce6e2d533e9304eb6ff9fcfd22baec3 Mon Sep 17 00:00:00 2001 From: Nasr Date: Wed, 15 Oct 2025 12:18:45 -0500 Subject: [PATCH 01/16] feat(uniffi): bindings for all uniffi platforms --- Cargo.lock | 365 ++++++++++++++++++++++++++++- Cargo.toml | 2 + crates/c/build.rs | 4 + src/bin/uniffi-bindgen.rs | 4 + src/dojo.udl | 470 ++++++++++++++++++++++++++++++++++++++ src/dojo_full.udl.bak | 335 +++++++++++++++++++++++++++ src/uniffi/README.md | 307 +++++++++++++++++++++++++ src/uniffi/achievement.rs | 239 +++++++++++++++++++ src/uniffi/activity.rs | 76 ++++++ src/uniffi/aggregation.rs | 49 ++++ src/uniffi/contract.rs | 85 +++++++ src/uniffi/controller.rs | 41 ++++ src/uniffi/core.rs | 260 +++++++++++++++++++++ src/uniffi/entity.rs | 130 +++++++++++ src/uniffi/event.rs | 47 ++++ src/uniffi/mod.rs | 32 +++ src/uniffi/query.rs | 271 ++++++++++++++++++++++ src/uniffi/schema.rs | 331 +++++++++++++++++++++++++++ src/uniffi/token.rs | 209 +++++++++++++++++ src/uniffi/transaction.rs | 128 +++++++++++ 20 files changed, 3384 insertions(+), 1 deletion(-) create mode 100644 src/bin/uniffi-bindgen.rs create mode 100644 src/dojo.udl create mode 100644 src/dojo_full.udl.bak create mode 100644 src/uniffi/README.md create mode 100644 src/uniffi/achievement.rs create mode 100644 src/uniffi/activity.rs create mode 100644 src/uniffi/aggregation.rs create mode 100644 src/uniffi/contract.rs create mode 100644 src/uniffi/controller.rs create mode 100644 src/uniffi/core.rs create mode 100644 src/uniffi/entity.rs create mode 100644 src/uniffi/event.rs create mode 100644 src/uniffi/mod.rs create mode 100644 src/uniffi/query.rs create mode 100644 src/uniffi/schema.rs create mode 100644 src/uniffi/token.rs create mode 100644 src/uniffi/transaction.rs diff --git a/Cargo.lock b/Cargo.lock index 87c8b47..eb7bf5e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -123,6 +123,48 @@ dependencies = [ "term", ] +[[package]] +name = "askama" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4744ed2eef2645831b441d8f5459689ade2ab27c854488fbab1fbe94fce1a7" +dependencies = [ + "askama_derive", + "itoa", + "percent-encoding", + "serde", + "serde_json", +] + +[[package]] +name = "askama_derive" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d661e0f57be36a5c14c48f78d09011e67e0cb618f269cca9f2fd8d15b68c46ac" +dependencies = [ + "askama_parser", + "basic-toml", + "memchr", + "proc-macro2", + "quote", + "rustc-hash 2.1.1", + "serde", + "serde_derive", + "syn 2.0.106", +] + +[[package]] +name = "askama_parser" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf315ce6524c857bb129ff794935cf6d42c82a6cff60526fe2a63593de4d0d4f" +dependencies = [ + "memchr", + "serde", + "serde_derive", + "winnow", +] + [[package]] name = "assert_matches" version = "1.5.0" @@ -263,6 +305,15 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "basic-toml" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a" +dependencies = [ + "serde", +] + [[package]] name = "bit-set" version = "0.8.0" @@ -645,6 +696,29 @@ dependencies = [ "serde_core", ] +[[package]] +name = "cargo-platform" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror 2.0.16", +] + [[package]] name = "cbindgen" version = "0.27.0" @@ -965,12 +1039,39 @@ dependencies = [ "anyhow", "dojo-types", "dojo-world", +<<<<<<< HEAD +======= + "futures", + "futures-channel", + "gloo-timers", + "gloo-utils", + "hex", + "instant", + "js-sys", + "keyring", + "lazy_static", + "num-bigint", + "num-traits", + "open", + "parking_lot", + "serde", + "serde-wasm-bindgen", + "serde_json", +>>>>>>> 52edff74 (feat(uniffi): bindings for all uniffi platforms) "starknet", "starknet-crypto", "stream-cancel", + "thiserror 2.0.16", "tokio", "torii-client", "torii-proto", +<<<<<<< HEAD +======= + "tower-http 0.6.6", + "tsify-next", + "uniffi", + "uniffi_bindgen", +>>>>>>> 52edff74 (feat(uniffi): bindings for all uniffi platforms) "url", ] @@ -1174,6 +1275,15 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs-err" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] + [[package]] name = "funty" version = "2.0.0" @@ -1312,6 +1422,12 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + [[package]] name = "gloo-timers" version = "0.3.0" @@ -1337,6 +1453,17 @@ dependencies = [ "web-sys", ] +[[package]] +name = "goblin" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b363a30c165f666402fe6a3024d3bec7ebc898f96a4a23bd1c99f8dbf3f4f47" +dependencies = [ + "log", + "plain", + "scroll", +] + [[package]] name = "good_lp" version = "1.14.0" @@ -2051,6 +2178,12 @@ dependencies = [ "walkdir", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -2098,6 +2231,16 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "nu-ansi-term" version = "0.50.1" @@ -2276,7 +2419,7 @@ version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" dependencies = [ - "siphasher", + "siphasher 1.0.1", ] [[package]] @@ -2318,6 +2461,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] +<<<<<<< HEAD +======= +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +>>>>>>> 52edff74 (feat(uniffi): bindings for all uniffi platforms) name = "portable-atomic" version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3045,6 +3203,26 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "scroll" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ab8598aa408498679922eff7fa985c25d58a90771bd6be794434c5277eab1a6" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1783eabc414609e28a5ba76aee5ddd52199f7107a0b24c2e9746a1ecc34a683d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", +] + [[package]] name = "scrypt" version = "0.10.0" @@ -3080,6 +3258,16 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +dependencies = [ + "serde", + "serde_core", +] + [[package]] name = "serde" version = "1.0.225" @@ -3264,6 +3452,12 @@ dependencies = [ "libc", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "siphasher" version = "1.0.1" @@ -3288,6 +3482,12 @@ version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + [[package]] name = "smol_str" version = "0.3.2" @@ -3646,6 +3846,15 @@ dependencies = [ "windows-sys 0.61.0", ] +[[package]] +name = "textwrap" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" +dependencies = [ + "smawk", +] + [[package]] name = "thiserror" version = "1.0.69" @@ -4365,6 +4574,151 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "uniffi" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c866f627c3f04c3df068b68bb2d725492caaa539dd313e2a9d26bb85b1a32f4e" +dependencies = [ + "anyhow", + "cargo_metadata", + "uniffi_bindgen", + "uniffi_build", + "uniffi_core", + "uniffi_macros", + "uniffi_pipeline", +] + +[[package]] +name = "uniffi_bindgen" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c8ca600167641ebe7c8ba9254af40492dda3397c528cc3b2f511bd23e8541a5" +dependencies = [ + "anyhow", + "askama", + "camino", + "cargo_metadata", + "fs-err", + "glob", + "goblin", + "heck 0.5.0", + "indexmap 2.11.3", + "once_cell", + "serde", + "tempfile", + "textwrap", + "toml", + "uniffi_internal_macros", + "uniffi_meta", + "uniffi_pipeline", + "uniffi_testing", + "uniffi_udl", +] + +[[package]] +name = "uniffi_build" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e55c05228f4858bb258f651d21d743fcc1fe5a2ec20d3c0f9daefddb105ee4d" +dependencies = [ + "anyhow", + "camino", + "uniffi_bindgen", +] + +[[package]] +name = "uniffi_core" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7a5a038ebffe8f4cf91416b154ef3c2468b18e828b7009e01b1b99938089f9" +dependencies = [ + "anyhow", + "bytes", + "once_cell", + "static_assertions", +] + +[[package]] +name = "uniffi_internal_macros" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c2a6f93e7b73726e2015696ece25ca0ac5a5f1cf8d6a7ab5214dd0a01d2edf" +dependencies = [ + "anyhow", + "indexmap 2.11.3", + "proc-macro2", + "quote", + "syn 2.0.106", +] + +[[package]] +name = "uniffi_macros" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64c6309fc36c7992afc03bc0c5b059c656bccbef3f2a4bc362980017f8936141" +dependencies = [ + "camino", + "fs-err", + "once_cell", + "proc-macro2", + "quote", + "serde", + "syn 2.0.106", + "toml", + "uniffi_meta", +] + +[[package]] +name = "uniffi_meta" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a138823392dba19b0aa494872689f97d0ee157de5852e2bec157ce6de9cdc22" +dependencies = [ + "anyhow", + "siphasher 0.3.11", + "uniffi_internal_macros", + "uniffi_pipeline", +] + +[[package]] +name = "uniffi_pipeline" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c27c4b515d25f8e53cc918e238c39a79c3144a40eaf2e51c4a7958973422c29" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.11.3", + "tempfile", + "uniffi_internal_macros", +] + +[[package]] +name = "uniffi_testing" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4adb08eb5589849231dc0626ba0f9a1297925fd751f0740fc630ae934dd9c5e" +dependencies = [ + "anyhow", + "camino", + "cargo_metadata", + "fs-err", + "once_cell", +] + +[[package]] +name = "uniffi_udl" +version = "0.30.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0adacdd848aeed7af4f5af7d2f621d5e82531325d405e29463482becfdeafca" +dependencies = [ + "anyhow", + "textwrap", + "uniffi_meta", + "weedle2", +] + [[package]] name = "untrusted" version = "0.9.0" @@ -4654,6 +5008,15 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "weedle2" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "998d2c24ec099a87daf9467808859f9d82b61f1d9c9701251aea037f514eae0e" +dependencies = [ + "nom", +] + [[package]] name = "winapi-util" version = "0.1.11" diff --git a/Cargo.toml b/Cargo.toml index c558277..981536d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ members = [ "crates/dojo-core", "crates/c", "crates/wasm", + "crates/uniffi", ] [workspace.package] @@ -63,6 +64,7 @@ num-traits = "0.2.19" dojo-core = { path = "crates/dojo-core" } c = { path = "crates/c" } wasm = { path = "crates/wasm" } +uniffi = { path = "crates/uniffi" } [patch.crates-io] crunchy = { git = "https://github.com/nmathewson/crunchy", branch = "cross-compilation-fix" } diff --git a/crates/c/build.rs b/crates/c/build.rs index 09b6c34..db29751 100644 --- a/crates/c/build.rs +++ b/crates/c/build.rs @@ -3,6 +3,10 @@ use std::env; fn main() { let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + // Generate UniFFI scaffolding + uniffi::generate_scaffolding("src/dojo.udl") + .expect("Failed to generate UniFFI scaffolding"); + cbindgen::Builder::new() .with_config({ let mut config = cbindgen::Config { diff --git a/src/bin/uniffi-bindgen.rs b/src/bin/uniffi-bindgen.rs new file mode 100644 index 0000000..a5b7643 --- /dev/null +++ b/src/bin/uniffi-bindgen.rs @@ -0,0 +1,4 @@ +fn main() { + uniffi_bindgen::main() +} + diff --git a/src/dojo.udl b/src/dojo.udl new file mode 100644 index 0000000..e5c7e8d --- /dev/null +++ b/src/dojo.udl @@ -0,0 +1,470 @@ +// Simplified UDL - just the types that work easily with UniFFI +// Complex recursive types (Primitive, Ty, Clause, etc.) should be handled +// via procmacros in Rust rather than UDL + +namespace dojo { +}; + +// Core types +[Custom] +typedef string FieldElement; + +[Custom] +typedef string U256; + +// Enums +enum PaginationDirection { + "Forward", + "Backward", +}; + +enum OrderDirection { + "Asc", + "Desc", +}; + +enum ContractType { + "WORLD", + "ERC20", + "ERC721", + "ERC1155", + "UDC", + "OTHER", +}; + +enum CallType { + "Execute", + "ExecuteFromOutside", +}; + +enum PatternMatching { + "FixedLen", + "VariableLen", +}; + +enum LogicalOperator { + "And", + "Or", +}; + +enum ComparisonOperator { + "Eq", + "Neq", + "Gt", + "Gte", + "Lt", + "Lte", + "In", + "NotIn", + "Contains", + "ContainsAll", + "ContainsAny", + "ArrayLengthEq", + "ArrayLengthGt", + "ArrayLengthLt", +}; + +// Basic structures +dictionary Signature { + FieldElement r; + FieldElement s; +}; + +dictionary OrderBy { + string field; + OrderDirection direction; +}; + +dictionary Pagination { + string? cursor; + u32? limit; + PaginationDirection direction; + sequence order_by; +}; + +// Controller +dictionary Controller { + FieldElement address; + string username; + u64 deployed_at_timestamp; +}; + +dictionary ControllerQuery { + Pagination pagination; + sequence contract_addresses; + sequence usernames; +}; + +// Token types +dictionary Token { + FieldElement contract_address; + U256? token_id; + string name; + string symbol; + u8 decimals; + string metadata; + U256? total_supply; +}; + +dictionary TokenBalance { + U256 balance; + FieldElement account_address; + FieldElement contract_address; + U256? token_id; +}; + +dictionary TokenContract { + FieldElement contract_address; + string name; + string symbol; + u8 decimals; + string metadata; + string token_metadata; + U256? total_supply; +}; + +dictionary AttributeFilter { + string trait_name; + string trait_value; +}; + +dictionary TokenQuery { + sequence contract_addresses; + sequence token_ids; + sequence attribute_filters; + Pagination pagination; +}; + +dictionary TokenBalanceQuery { + sequence contract_addresses; + sequence account_addresses; + sequence token_ids; + Pagination pagination; +}; + +dictionary TokenContractQuery { + sequence contract_addresses; + sequence contract_types; + Pagination pagination; +}; + +dictionary TokenTransfer { + string id; + FieldElement contract_address; + FieldElement from_address; + FieldElement to_address; + U256 amount; + U256? token_id; + u64 executed_at; + string? event_id; +}; + +dictionary TokenTransferQuery { + sequence contract_addresses; + sequence account_addresses; + sequence token_ids; + Pagination pagination; +}; + +// Contract +dictionary Contract { + FieldElement contract_address; + ContractType contract_type; + u64? head; + u64? tps; + u64? last_block_timestamp; + FieldElement? last_pending_block_tx; + u64 updated_at; + u64 created_at; +}; + +dictionary ContractQuery { + sequence contract_addresses; + sequence contract_types; +}; + +// Transaction types +dictionary TransactionCall { + FieldElement contract_address; + string entrypoint; + sequence calldata; + CallType call_type; + FieldElement caller_address; +}; + +dictionary Transaction { + FieldElement transaction_hash; + FieldElement sender_address; + sequence calldata; + FieldElement max_fee; + sequence signature; + FieldElement nonce; + u64 block_number; + string transaction_type; + u64 block_timestamp; + sequence calls; + sequence unique_models; +}; + +dictionary TransactionFilter { + sequence transaction_hashes; + sequence caller_addresses; + sequence contract_addresses; + sequence entrypoints; + sequence model_selectors; + u64? from_block; + u64? to_block; +}; + +dictionary TransactionQuery { + TransactionFilter? filter; + Pagination pagination; +}; + +// Aggregation +dictionary AggregationQuery { + sequence aggregator_ids; + sequence entity_ids; + Pagination pagination; +}; + +dictionary AggregationEntry { + string id; + string aggregator_id; + string entity_id; + U256 value; + string display_value; + u64 position; + string model_id; + u64 created_at; + u64 updated_at; +}; + +// Activity +dictionary ActionCount { + string action_name; + u32 count; +}; + +dictionary Activity { + string id; + FieldElement world_address; + string namespace; + FieldElement caller_address; + u64 session_start; + u64 session_end; + u32 action_count; + sequence actions; + u64 updated_at; +}; + +dictionary ActivityQuery { + sequence world_addresses; + sequence namespaces; + sequence caller_addresses; + u64? from_time; + u64? to_time; + Pagination pagination; +}; + +// Achievement +dictionary AchievementTask { + string task_id; + string description; + u32 total; + u32 total_completions; + f64 completion_rate; + u64 created_at; +}; + +dictionary Achievement { + string id; + FieldElement world_address; + string namespace; + string entity_id; + boolean hidden; + u32 index; + u32 points; + string start; + string end; + string group; + string icon; + string title; + string description; + sequence tasks; + string? data; + u32 total_completions; + f64 completion_rate; + u64 created_at; + u64 updated_at; +}; + +dictionary AchievementQuery { + sequence world_addresses; + sequence namespaces; + boolean? hidden; + Pagination pagination; +}; + +dictionary TaskProgress { + string task_id; + u32 count; + boolean completed; +}; + +dictionary PlayerAchievementProgress { + Achievement achievement; + sequence task_progress; + boolean completed; + f64 progress_percentage; +}; + +dictionary PlayerAchievementStats { + u32 total_points; + u32 completed_achievements; + u32 total_achievements; + f64 completion_percentage; + u64? last_achievement_at; + u64 created_at; + u64 updated_at; +}; + +dictionary PlayerAchievementEntry { + FieldElement player_address; + PlayerAchievementStats stats; + sequence achievements; +}; + +dictionary PlayerAchievementQuery { + sequence world_addresses; + sequence namespaces; + sequence player_addresses; + Pagination pagination; +}; + +dictionary AchievementProgression { + string id; + string achievement_id; + string task_id; + FieldElement world_address; + string namespace; + FieldElement player_id; + u32 count; + boolean completed; + u64? completed_at; + u64 created_at; + u64 updated_at; +}; + +// Schema types - Complex enums with associated data + +[Enum] +interface Primitive { + I8(i8 value); + I16(i16 value); + I32(i32 value); + I64(i64 value); + I128(sequence value); + U8(u8 value); + U16(u16 value); + U32(u32 value); + U64(u64 value); + U128(sequence value); + U256(U256 value); + Bool(boolean value); + Felt252(FieldElement value); + ClassHash(FieldElement value); + ContractAddress(FieldElement value); + EthAddress(FieldElement value); +}; + +[Enum] +interface MemberValue { + Primitive(Primitive value); + String(string value); + List(sequence values); +}; + +dictionary Member { + string name; + Ty ty; + boolean key; +}; + +dictionary Struct { + string name; + sequence children; +}; + +dictionary EnumOption { + string name; + Ty ty; +}; + +dictionary EnumType { + string name; + u8 option; + sequence options; +}; + +dictionary FixedSizeArray { + sequence array; + u32 size; +}; + +[Enum] +interface Ty { + Primitive(Primitive value); + Struct(Struct value); + Enum(EnumType value); + Tuple(sequence values); + Array(sequence values); + FixedSizeArray(FixedSizeArray value); + ByteArray(string value); +}; + +[Enum] +interface ValueType { + String(string value); + Int(i64 value); + UInt(u64 value); + Bool(boolean value); + Bytes(sequence value); +}; + +// Query types - Complex enums for query building + +dictionary KeysClause { + sequence keys; + PatternMatching pattern_matching; + sequence models; +}; + +dictionary MemberClause { + string model; + string member; + ComparisonOperator operator; + MemberValue value; +}; + +dictionary CompositeClause { + LogicalOperator operator; + sequence clauses; +}; + +[Enum] +interface Clause { + HashedKeys(sequence keys); + Keys(KeysClause clause); + Member(MemberClause clause); + Composite(CompositeClause clause); +}; + +// Error type +[Error] +enum DojoError { + "ClientError", + "SerializationError", + "NetworkError", + "InvalidInput", +}; diff --git a/src/dojo_full.udl.bak b/src/dojo_full.udl.bak new file mode 100644 index 0000000..10d7a3f --- /dev/null +++ b/src/dojo_full.udl.bak @@ -0,0 +1,335 @@ +namespace dojo { +}; + +// Core types +[Custom] +typedef string FieldElement; + +[Custom] +typedef string U256; + +// Simple Enums (no associated data) +enum PaginationDirection { + "Forward", + "Backward", +}; + +enum OrderDirection { + "Asc", + "Desc", +}; + +enum ContractType { + "WORLD", + "ERC20", + "ERC721", + "ERC1155", + "UDC", + "OTHER", +}; + +enum CallType { + "Execute", + "ExecuteFromOutside", +}; + +// Basic structures +dictionary Signature { + FieldElement r; + FieldElement s; +}; + +dictionary OrderBy { + string field; + OrderDirection direction; +}; + +dictionary Pagination { + string? cursor; + u32? limit; + PaginationDirection direction; + sequence order_by; +}; + +// Controller +dictionary Controller { + FieldElement address; + string username; + u64 deployed_at_timestamp; +}; + +dictionary ControllerQuery { + Pagination pagination; + sequence contract_addresses; + sequence usernames; +}; + +// Token types +dictionary Token { + FieldElement contract_address; + U256? token_id; + string name; + string symbol; + u8 decimals; + string metadata; + U256? total_supply; +}; + +dictionary TokenBalance { + U256 balance; + FieldElement account_address; + FieldElement contract_address; + U256? token_id; +}; + +dictionary TokenContract { + FieldElement contract_address; + string name; + string symbol; + u8 decimals; + string metadata; + string token_metadata; + U256? total_supply; +}; + +dictionary AttributeFilter { + string trait_name; + string trait_value; +}; + +dictionary TokenQuery { + sequence contract_addresses; + sequence token_ids; + sequence attribute_filters; + Pagination pagination; +}; + +dictionary TokenBalanceQuery { + sequence contract_addresses; + sequence account_addresses; + sequence token_ids; + Pagination pagination; +}; + +dictionary TokenContractQuery { + sequence contract_addresses; + sequence contract_types; + Pagination pagination; +}; + +dictionary TokenTransfer { + string id; + FieldElement contract_address; + FieldElement from_address; + FieldElement to_address; + U256 amount; + U256? token_id; + u64 executed_at; + string? event_id; +}; + +dictionary TokenTransferQuery { + sequence contract_addresses; + sequence account_addresses; + sequence token_ids; + Pagination pagination; +}; + +// Contract +dictionary Contract { + FieldElement contract_address; + ContractType contract_type; + u64? head; + u64? tps; + u64? last_block_timestamp; + FieldElement? last_pending_block_tx; + u64 updated_at; + u64 created_at; +}; + +dictionary ContractQuery { + sequence contract_addresses; + sequence contract_types; +}; + +// Transaction types (simplified - no complex Call type) +dictionary TransactionCall { + FieldElement contract_address; + string entrypoint; + sequence calldata; + CallType call_type; + FieldElement caller_address; +}; + +dictionary Transaction { + FieldElement transaction_hash; + FieldElement sender_address; + sequence calldata; + FieldElement max_fee; + sequence signature; + FieldElement nonce; + u64 block_number; + string transaction_type; + u64 block_timestamp; + sequence calls; + sequence unique_models; +}; + +dictionary TransactionFilter { + sequence transaction_hashes; + sequence caller_addresses; + sequence contract_addresses; + sequence entrypoints; + sequence model_selectors; + u64? from_block; + u64? to_block; +}; + +dictionary TransactionQuery { + TransactionFilter? filter; + Pagination pagination; +}; + +// Aggregation +dictionary AggregationQuery { + sequence aggregator_ids; + sequence entity_ids; + Pagination pagination; +}; + +dictionary AggregationEntry { + string id; + string aggregator_id; + string entity_id; + U256 value; + string display_value; + u64 position; + string model_id; + u64 created_at; + u64 updated_at; +}; + +// Activity +dictionary ActionCount { + string action_name; + u32 count; +}; + +dictionary Activity { + string id; + FieldElement world_address; + string namespace; + FieldElement caller_address; + u64 session_start; + u64 session_end; + u32 action_count; + sequence actions; + u64 updated_at; +}; + +dictionary ActivityQuery { + sequence world_addresses; + sequence namespaces; + sequence caller_addresses; + u64? from_time; + u64? to_time; + Pagination pagination; +}; + +// Achievement +dictionary AchievementTask { + string task_id; + string description; + u32 total; + u32 total_completions; + f64 completion_rate; + u64 created_at; +}; + +dictionary Achievement { + string id; + FieldElement world_address; + string namespace; + string entity_id; + boolean hidden; + u32 index; + u32 points; + string start; + string end; + string group; + string icon; + string title; + string description; + sequence tasks; + string? data; + u32 total_completions; + f64 completion_rate; + u64 created_at; + u64 updated_at; +}; + +dictionary AchievementQuery { + sequence world_addresses; + sequence namespaces; + boolean? hidden; + Pagination pagination; +}; + +dictionary TaskProgress { + string task_id; + u32 count; + boolean completed; +}; + +dictionary PlayerAchievementProgress { + Achievement achievement; + sequence task_progress; + boolean completed; + f64 progress_percentage; +}; + +dictionary PlayerAchievementStats { + u32 total_points; + u32 completed_achievements; + u32 total_achievements; + f64 completion_percentage; + u64? last_achievement_at; + u64 created_at; + u64 updated_at; +}; + +dictionary PlayerAchievementEntry { + FieldElement player_address; + PlayerAchievementStats stats; + sequence achievements; +}; + +dictionary PlayerAchievementQuery { + sequence world_addresses; + sequence namespaces; + sequence player_addresses; + Pagination pagination; +}; + +dictionary AchievementProgression { + string id; + string achievement_id; + string task_id; + FieldElement world_address; + string namespace; + FieldElement player_id; + u32 count; + boolean completed; + u64? completed_at; + u64 created_at; + u64 updated_at; +}; + +// Error type +[Error] +enum DojoError { + "ClientError", + "SerializationError", + "NetworkError", + "InvalidInput", +}; diff --git a/src/uniffi/README.md b/src/uniffi/README.md new file mode 100644 index 0000000..5b17f1e --- /dev/null +++ b/src/uniffi/README.md @@ -0,0 +1,307 @@ +# UniFFI Types - Organized by Category + +This directory contains UniFFI-compatible Rust types for Dojo, organized by functional category for better maintainability and discoverability. + +## File Structure + +``` +src/uniffi/ +├── mod.rs # Module definitions and re-exports +├── core.rs # Core types and utilities +├── achievement.rs # Achievement system types +├── activity.rs # Activity tracking types +├── aggregation.rs # Data aggregation types +├── contract.rs # Smart contract types +├── controller.rs # Controller/account types +├── entity.rs # Entity, Model, and World types +├── event.rs # Event and Message types +├── query.rs # Query and filtering types +├── schema.rs # Schema definition types +├── token.rs # Token and NFT types +└── transaction.rs # Transaction types +``` + +## Module Organization + +### `core.rs` - Core Types and Utilities +The foundation module containing: +- **Type Definitions**: `FieldElement`, `U256` (as hex strings) +- **Error Handling**: `DojoError` enum +- **Pagination**: `Pagination`, `PaginationDirection`, `OrderBy`, `OrderDirection` +- **Common Types**: `Signature`, `Call`, `BlockId`, `BlockTag` +- **Helper Functions**: Conversion between internal types and strings + +**Key Types:** +- `FieldElement` - String representation of Starknet field elements +- `U256` - String representation of 256-bit unsigned integers +- `DojoError` - Comprehensive error handling +- `Pagination` - Cursor-based pagination support + +### `controller.rs` - Controller Types +Account and controller management: +- `Controller` - Account controller information +- `ControllerQuery` - Query for controllers + +**Use Cases:** +- Account management +- Username lookups +- Deployment tracking + +### `token.rs` - Token Types +ERC20, ERC721, and ERC1155 token support: +- `Token` - Token information +- `TokenBalance` - Token balance per account +- `TokenContract` - Token contract metadata +- `TokenTransfer` - Transfer event data +- `TokenQuery`, `TokenBalanceQuery`, `TokenContractQuery`, `TokenTransferQuery` +- `AttributeFilter` - NFT attribute filtering + +**Use Cases:** +- Token balance queries +- NFT metadata retrieval +- Transfer history +- Token searches with filters + +### `contract.rs` - Contract Types +Smart contract information and queries: +- `Contract` - Contract metadata +- `ContractType` - Enum for contract types (WORLD, ERC20, ERC721, etc.) +- `ContractQuery` - Query contracts by address or type + +**Use Cases:** +- Contract discovery +- Type-based filtering +- Deployment information + +### `transaction.rs` - Transaction Types +Transaction data and queries: +- `Transaction` - Full transaction information +- `TransactionCall` - Individual contract call +- `TransactionFilter` - Advanced transaction filtering +- `TransactionQuery` - Query transactions +- `CallType` - Execute vs ExecuteFromOutside + +**Use Cases:** +- Transaction history +- Call analysis +- Block explorer functionality + +### `schema.rs` - Schema Types +Type system and schema definitions: +- `Primitive` - Primitive type values (integers, felts, bools, etc.) +- `Ty` - Type definitions (Struct, Enum, Array, Tuple, etc.) +- `Struct` - Struct definition +- `Enum` - Enum definition +- `Member` - Struct/enum member +- `MemberValue` - Runtime value +- `ValueType` - Value type variants + +**Use Cases:** +- Schema introspection +- Dynamic typing +- Model definitions +- Data serialization + +### `query.rs` - Query Types +Powerful querying and filtering: +- `Query` - Main query structure +- `Clause` - Query clauses (HashedKeys, Keys, Member, Composite) +- `KeysClause` - Key-based filtering +- `MemberClause` - Member-based filtering +- `CompositeClause` - Logical composition (AND/OR) +- `PatternMatching` - Key pattern matching +- `ComparisonOperator` - Rich comparison operators +- `LogicalOperator` - AND/OR operators + +**Use Cases:** +- Entity queries +- Complex filtering +- Model data retrieval +- Historical queries + +### `entity.rs` - Entity Types +Core game entity types: +- `Entity` - Game entity with models +- `Model` - Model definition +- `World` - World state + +**Use Cases:** +- Entity management +- Model introspection +- World state queries + +### `event.rs` - Event Types +Blockchain event handling: +- `Event` - Starknet event +- `Message` - Signed message + +**Use Cases:** +- Event listening +- Message verification +- Event history + +### `aggregation.rs` - Aggregation Types +Data aggregation and leaderboards: +- `AggregationEntry` - Aggregated data entry +- `AggregationQuery` - Query aggregations + +**Use Cases:** +- Leaderboards +- Statistics +- Rankings + +### `activity.rs` - Activity Types +Player activity tracking: +- `Activity` - Player activity session +- `ActivityQuery` - Query player activity +- `ActionCount` - Action frequency + +**Use Cases:** +- Player analytics +- Session tracking +- Engagement metrics + +### `achievement.rs` - Achievement Types +Achievement and progression system: +- `Achievement` - Achievement definition +- `AchievementTask` - Individual task +- `PlayerAchievementProgress` - Player's progress +- `PlayerAchievementStats` - Player's achievement stats +- `AchievementProgression` - Detailed progression +- `TaskProgress` - Task completion status +- Corresponding query types + +**Use Cases:** +- Achievement systems +- Progression tracking +- Player rewards +- Gamification + +## Usage Examples + +### Querying Entities +```rust +use uniffi::{Query, Clause, MemberClause, ComparisonOperator, Primitive}; + +let query = Query { + world_addresses: vec!["0x123...".to_string()], + clause: Some(Clause::Member(MemberClause { + model: "Player".to_string(), + member: "level".to_string(), + operator: ComparisonOperator::Gte, + value: MemberValue::Primitive(Primitive::U32(10)), + })), + pagination: Default::default(), + no_hashed_keys: false, + models: vec!["Player".to_string()], + historical: false, +}; +``` + +### Token Balance Query +```rust +use uniffi::{TokenBalanceQuery, Pagination}; + +let query = TokenBalanceQuery { + contract_addresses: vec!["0xabc...".to_string()], + account_addresses: vec!["0xdef...".to_string()], + token_ids: vec![], + pagination: Pagination::default(), +}; +``` + +### Achievement Progress +```rust +use uniffi::{PlayerAchievementQuery, Pagination}; + +let query = PlayerAchievementQuery { + world_addresses: vec!["0x123...".to_string()], + namespaces: vec!["game".to_string()], + player_addresses: vec!["0xplayer...".to_string()], + pagination: Pagination::default(), +}; +``` + +## Design Principles + +### 1. **Category-Based Organization** +Types are grouped by their domain purpose rather than technical structure: +- Easy to find related types +- Clear separation of concerns +- Logical grouping for documentation + +### 2. **Minimal Dependencies** +Each module imports only what it needs: +- `core` has no internal dependencies +- Other modules depend on `core` +- Cross-references are minimal and explicit + +### 3. **Consistent Patterns** +All modules follow the same patterns: +- Types use `FieldElement` and `U256` as strings +- Conversions to/from proto types +- Clear documentation of purpose + +### 4. **Self-Documenting** +File names and organization make the purpose clear: +- `token.rs` - obviously token-related +- `achievement.rs` - clearly achievement system +- No need to read code to understand scope + +## Adding New Types + +When adding new types: + +1. **Determine Category**: Which module does it belong to? +2. **Create/Update Module**: Add to existing or create new category file +3. **Update mod.rs**: Add module declaration and re-exports +4. **Update UDL**: Add type definitions to `src/dojo.udl` +5. **Document**: Update this README + +Example - Adding a new "Quest" system: + +```rust +// src/uniffi/quest.rs +use super::core::*; + +#[derive(Debug, Clone)] +pub struct Quest { + pub id: String, + pub name: String, + // ... +} +``` + +Update `mod.rs`: +```rust +pub mod quest; +pub use quest::*; +``` + +## Benefits of This Organization + +### For Developers +- ✅ Quick discovery of related types +- ✅ Easy navigation +- ✅ Clear module boundaries +- ✅ Reduced cognitive load + +### For Maintenance +- ✅ Easy to add new categories +- ✅ Changes are localized +- ✅ Dependencies are explicit +- ✅ Better IDE support + +### For Documentation +- ✅ Self-organizing +- ✅ Category-based docs +- ✅ Clear examples per category +- ✅ Easy to generate docs + +## See Also + +- [UniFFI Documentation](https://mozilla.github.io/uniffi-rs/) +- [UNIFFI_CONVERSION.md](../../UNIFFI_CONVERSION.md) - Detailed conversion guide +- [CONVERSION_SUMMARY.md](../../CONVERSION_SUMMARY.md) - Complete type mapping +- [dojo.udl](../dojo.udl) - UniFFI interface definition + diff --git a/src/uniffi/achievement.rs b/src/uniffi/achievement.rs new file mode 100644 index 0000000..ae67098 --- /dev/null +++ b/src/uniffi/achievement.rs @@ -0,0 +1,239 @@ +// Achievement types +use super::core::*; + +#[derive(Debug, Clone)] +pub struct AchievementTask { + pub task_id: String, + pub description: String, + pub total: u32, + pub total_completions: u32, + pub completion_rate: f64, + pub created_at: u64, +} + +impl From for AchievementTask { + fn from(val: torii_proto::AchievementTask) -> Self { + AchievementTask { + task_id: val.task_id, + description: val.description, + total: val.total, + total_completions: val.total_completions, + completion_rate: val.completion_rate, + created_at: val.created_at.timestamp() as u64, + } + } +} + +#[derive(Debug, Clone)] +pub struct Achievement { + pub id: String, + pub world_address: FieldElement, + pub namespace: String, + pub entity_id: String, + pub hidden: bool, + pub index: u32, + pub points: u32, + pub start: String, + pub end: String, + pub group: String, + pub icon: String, + pub title: String, + pub description: String, + pub tasks: Vec, + pub data: Option, + pub total_completions: u32, + pub completion_rate: f64, + pub created_at: u64, + pub updated_at: u64, +} + +impl From for Achievement { + fn from(val: torii_proto::Achievement) -> Self { + let tasks: Vec = val.tasks.into_iter().map(|t| t.into()).collect(); + + Achievement { + id: val.id, + world_address: felt_to_field_element(val.world_address), + namespace: val.namespace, + entity_id: val.entity_id, + hidden: val.hidden, + index: val.index, + points: val.points, + start: val.start, + end: val.end, + group: val.group, + icon: val.icon, + title: val.title, + description: val.description, + tasks, + data: val.data, + total_completions: val.total_completions, + completion_rate: val.completion_rate, + created_at: val.created_at.timestamp() as u64, + updated_at: val.updated_at.timestamp() as u64, + } + } +} + +#[derive(Debug, Clone)] +pub struct AchievementQuery { + pub world_addresses: Vec, + pub namespaces: Vec, + pub hidden: Option, + pub pagination: Pagination, +} + +impl From for torii_proto::AchievementQuery { + fn from(val: AchievementQuery) -> Self { + torii_proto::AchievementQuery { + world_addresses: val + .world_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + namespaces: val.namespaces, + hidden: val.hidden, + pagination: val.pagination.into(), + } + } +} + +#[derive(Debug, Clone)] +pub struct TaskProgress { + pub task_id: String, + pub count: u32, + pub completed: bool, +} + +impl From for TaskProgress { + fn from(val: torii_proto::TaskProgress) -> Self { + TaskProgress { task_id: val.task_id, count: val.count, completed: val.completed } + } +} + +#[derive(Debug, Clone)] +pub struct PlayerAchievementProgress { + pub achievement: Achievement, + pub task_progress: Vec, + pub completed: bool, + pub progress_percentage: f64, +} + +impl From for PlayerAchievementProgress { + fn from(val: torii_proto::PlayerAchievementProgress) -> Self { + let task_progress: Vec = val.task_progress.into_iter().map(|t| t.into()).collect(); + + PlayerAchievementProgress { + achievement: val.achievement.into(), + task_progress, + completed: val.completed, + progress_percentage: val.progress_percentage, + } + } +} + +#[derive(Debug, Clone)] +pub struct PlayerAchievementStats { + pub total_points: u32, + pub completed_achievements: u32, + pub total_achievements: u32, + pub completion_percentage: f64, + pub last_achievement_at: Option, + pub created_at: u64, + pub updated_at: u64, +} + +impl From for PlayerAchievementStats { + fn from(val: torii_proto::PlayerAchievementStats) -> Self { + PlayerAchievementStats { + total_points: val.total_points, + completed_achievements: val.completed_achievements, + total_achievements: val.total_achievements, + completion_percentage: val.completion_percentage, + last_achievement_at: val.last_achievement_at.map(|t| t.timestamp() as u64), + created_at: val.created_at.timestamp() as u64, + updated_at: val.updated_at.timestamp() as u64, + } + } +} + +#[derive(Debug, Clone)] +pub struct PlayerAchievementEntry { + pub player_address: FieldElement, + pub stats: PlayerAchievementStats, + pub achievements: Vec, +} + +impl From for PlayerAchievementEntry { + fn from(val: torii_proto::PlayerAchievementEntry) -> Self { + let achievements: Vec = + val.achievements.into_iter().map(|a| a.into()).collect(); + + PlayerAchievementEntry { + player_address: felt_to_field_element(val.player_address), + stats: val.stats.into(), + achievements, + } + } +} + +#[derive(Debug, Clone)] +pub struct PlayerAchievementQuery { + pub world_addresses: Vec, + pub namespaces: Vec, + pub player_addresses: Vec, + pub pagination: Pagination, +} + +impl From for torii_proto::PlayerAchievementQuery { + fn from(val: PlayerAchievementQuery) -> Self { + torii_proto::PlayerAchievementQuery { + world_addresses: val + .world_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + namespaces: val.namespaces, + player_addresses: val + .player_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + pagination: val.pagination.into(), + } + } +} + +#[derive(Debug, Clone)] +pub struct AchievementProgression { + pub id: String, + pub achievement_id: String, + pub task_id: String, + pub world_address: FieldElement, + pub namespace: String, + pub player_id: FieldElement, + pub count: u32, + pub completed: bool, + pub completed_at: Option, + pub created_at: u64, + pub updated_at: u64, +} + +impl From for AchievementProgression { + fn from(val: torii_proto::AchievementProgression) -> Self { + AchievementProgression { + id: val.id, + achievement_id: val.achievement_id, + task_id: val.task_id, + world_address: felt_to_field_element(val.world_address), + namespace: val.namespace, + player_id: felt_to_field_element(val.player_id), + count: val.count, + completed: val.completed, + completed_at: val.completed_at.map(|t| t.timestamp() as u64), + created_at: val.created_at.timestamp() as u64, + updated_at: val.updated_at.timestamp() as u64, + } + } +} + diff --git a/src/uniffi/activity.rs b/src/uniffi/activity.rs new file mode 100644 index 0000000..29c37e3 --- /dev/null +++ b/src/uniffi/activity.rs @@ -0,0 +1,76 @@ +// Activity types +use super::core::*; +use chrono::DateTime; + +#[derive(Debug, Clone)] +pub struct ActionCount { + pub action_name: String, + pub count: u32, +} + +#[derive(Debug, Clone)] +pub struct Activity { + pub id: String, + pub world_address: FieldElement, + pub namespace: String, + pub caller_address: FieldElement, + pub session_start: u64, + pub session_end: u64, + pub action_count: u32, + pub actions: Vec, + pub updated_at: u64, +} + +impl From for Activity { + fn from(val: torii_proto::Activity) -> Self { + let actions: Vec = val + .actions + .into_iter() + .map(|(name, count)| ActionCount { action_name: name, count }) + .collect(); + + Activity { + id: val.id, + world_address: felt_to_field_element(val.world_address), + namespace: val.namespace, + caller_address: felt_to_field_element(val.caller_address), + session_start: val.session_start.timestamp() as u64, + session_end: val.session_end.timestamp() as u64, + action_count: val.action_count, + actions, + updated_at: val.updated_at.timestamp() as u64, + } + } +} + +#[derive(Debug, Clone)] +pub struct ActivityQuery { + pub world_addresses: Vec, + pub namespaces: Vec, + pub caller_addresses: Vec, + pub from_time: Option, + pub to_time: Option, + pub pagination: Pagination, +} + +impl From for torii_proto::ActivityQuery { + fn from(val: ActivityQuery) -> Self { + torii_proto::ActivityQuery { + world_addresses: val + .world_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + namespaces: val.namespaces, + caller_addresses: val + .caller_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + from_time: val.from_time.map(|t| DateTime::from_timestamp(t as i64, 0).unwrap()), + to_time: val.to_time.map(|t| DateTime::from_timestamp(t as i64, 0).unwrap()), + pagination: val.pagination.into(), + } + } +} + diff --git a/src/uniffi/aggregation.rs b/src/uniffi/aggregation.rs new file mode 100644 index 0000000..1d964bb --- /dev/null +++ b/src/uniffi/aggregation.rs @@ -0,0 +1,49 @@ +// Aggregation types +use super::core::*; + +#[derive(Debug, Clone)] +pub struct AggregationQuery { + pub aggregator_ids: Vec, + pub entity_ids: Vec, + pub pagination: Pagination, +} + +impl From for torii_proto::AggregationQuery { + fn from(val: AggregationQuery) -> Self { + torii_proto::AggregationQuery { + aggregator_ids: val.aggregator_ids, + entity_ids: val.entity_ids, + pagination: val.pagination.into(), + } + } +} + +#[derive(Debug, Clone)] +pub struct AggregationEntry { + pub id: String, + pub aggregator_id: String, + pub entity_id: String, + pub value: U256, + pub display_value: String, + pub position: u64, + pub model_id: String, + pub created_at: u64, + pub updated_at: u64, +} + +impl From for AggregationEntry { + fn from(val: torii_proto::AggregationEntry) -> Self { + AggregationEntry { + id: val.id, + aggregator_id: val.aggregator_id, + entity_id: val.entity_id, + value: u256_to_uniffi(val.value), + display_value: val.display_value, + position: val.position, + model_id: val.model_id, + created_at: val.created_at.timestamp() as u64, + updated_at: val.updated_at.timestamp() as u64, + } + } +} + diff --git a/src/uniffi/contract.rs b/src/uniffi/contract.rs new file mode 100644 index 0000000..4f88575 --- /dev/null +++ b/src/uniffi/contract.rs @@ -0,0 +1,85 @@ +// Contract types +use super::core::*; + +#[derive(Debug, Clone)] +pub enum ContractType { + WORLD, + ERC20, + ERC721, + ERC1155, + UDC, + OTHER, +} + +impl From for ContractType { + fn from(val: torii_proto::ContractType) -> Self { + match val { + torii_proto::ContractType::WORLD => ContractType::WORLD, + torii_proto::ContractType::ERC20 => ContractType::ERC20, + torii_proto::ContractType::ERC721 => ContractType::ERC721, + torii_proto::ContractType::ERC1155 => ContractType::ERC1155, + torii_proto::ContractType::UDC => ContractType::UDC, + torii_proto::ContractType::OTHER => ContractType::OTHER, + } + } +} + +impl From for torii_proto::ContractType { + fn from(val: ContractType) -> Self { + match val { + ContractType::WORLD => torii_proto::ContractType::WORLD, + ContractType::ERC20 => torii_proto::ContractType::ERC20, + ContractType::ERC721 => torii_proto::ContractType::ERC721, + ContractType::ERC1155 => torii_proto::ContractType::ERC1155, + ContractType::UDC => torii_proto::ContractType::UDC, + ContractType::OTHER => torii_proto::ContractType::OTHER, + } + } +} + +#[derive(Debug, Clone)] +pub struct Contract { + pub contract_address: FieldElement, + pub contract_type: ContractType, + pub head: Option, + pub tps: Option, + pub last_block_timestamp: Option, + pub last_pending_block_tx: Option, + pub updated_at: u64, + pub created_at: u64, +} + +impl From for Contract { + fn from(val: torii_proto::Contract) -> Self { + Contract { + contract_type: val.contract_type.into(), + head: val.head, + tps: val.tps, + last_block_timestamp: val.last_block_timestamp, + last_pending_block_tx: val.last_pending_block_tx.map(felt_to_field_element), + updated_at: val.updated_at.timestamp() as u64, + created_at: val.created_at.timestamp() as u64, + contract_address: felt_to_field_element(val.contract_address), + } + } +} + +#[derive(Debug, Clone)] +pub struct ContractQuery { + pub contract_addresses: Vec, + pub contract_types: Vec, +} + +impl From for torii_proto::ContractQuery { + fn from(val: ContractQuery) -> Self { + torii_proto::ContractQuery { + contract_addresses: val + .contract_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + contract_types: val.contract_types.into_iter().map(|t| t.into()).collect(), + } + } +} + diff --git a/src/uniffi/controller.rs b/src/uniffi/controller.rs new file mode 100644 index 0000000..6951fce --- /dev/null +++ b/src/uniffi/controller.rs @@ -0,0 +1,41 @@ +// Controller types +use super::core::*; + +#[derive(Debug, Clone)] +pub struct Controller { + pub address: FieldElement, + pub username: String, + pub deployed_at_timestamp: u64, +} + +impl From for Controller { + fn from(val: torii_proto::Controller) -> Self { + Controller { + address: felt_to_field_element(val.address), + username: val.username, + deployed_at_timestamp: val.deployed_at.timestamp() as u64, + } + } +} + +#[derive(Debug, Clone)] +pub struct ControllerQuery { + pub pagination: Pagination, + pub contract_addresses: Vec, + pub usernames: Vec, +} + +impl From for torii_proto::ControllerQuery { + fn from(val: ControllerQuery) -> Self { + torii_proto::ControllerQuery { + pagination: val.pagination.into(), + contract_addresses: val + .contract_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + usernames: val.usernames, + } + } +} + diff --git a/src/uniffi/core.rs b/src/uniffi/core.rs new file mode 100644 index 0000000..0af019e --- /dev/null +++ b/src/uniffi/core.rs @@ -0,0 +1,260 @@ +// Core types - FieldElement, U256, Error, Pagination, Signature, Call, BlockId + +// Newtype wrappers for custom type conversions +// These will be represented as strings in the UDL via [Custom] attribute + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FieldElement(pub String); + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct U256(pub String); + +// Custom type converter implementations for UniFFI +// Note: uniffi::custom_type! is called by the generated scaffolding from the UDL +// The UniffiCustomTypeConverter trait is defined in the generated scaffolding +impl crate::UniffiCustomTypeConverter for FieldElement { + type Builtin = String; + + fn into_custom(val: Self::Builtin) -> uniffi::Result { + Ok(FieldElement(val)) + } + + fn from_custom(obj: Self) -> Self::Builtin { + obj.0 + } +} + +impl crate::UniffiCustomTypeConverter for U256 { + type Builtin = String; + + fn into_custom(val: Self::Builtin) -> uniffi::Result { + Ok(U256(val)) + } + + fn from_custom(obj: Self) -> Self::Builtin { + obj.0 + } +} + +// Helper functions to convert between internal types and UniFFI types +pub fn felt_to_field_element(felt: starknet::core::types::Felt) -> FieldElement { + FieldElement(format!("0x{:064x}", felt)) +} + +pub fn field_element_to_felt(fe: &FieldElement) -> Result { + starknet::core::types::Felt::from_hex(&fe.0).map_err(|_| DojoError::InvalidInput) +} + +pub fn u256_to_uniffi(u: crypto_bigint::U256) -> U256 { + U256(format!("0x{:064x}", u)) +} + +pub fn uniffi_to_u256(u: &U256) -> Result { + let s = u.0.strip_prefix("0x").unwrap_or(&u.0); + let bytes = hex::decode(s).map_err(|_| DojoError::InvalidInput)?; + Ok(crypto_bigint::U256::from_be_slice(&bytes)) +} + +// Error types +#[derive(Debug, thiserror::Error)] +pub enum DojoError { + #[error("Client error: {0}")] + ClientError(String), + #[error("Serialization error: {0}")] + SerializationError(String), + #[error("Network error: {0}")] + NetworkError(String), + #[error("Invalid input")] + InvalidInput, +} + +impl From for DojoError { + fn from(e: anyhow::Error) -> Self { + DojoError::ClientError(e.to_string()) + } +} + +// Pagination +#[derive(Debug, Clone)] +pub enum PaginationDirection { + Forward, + Backward, +} + +impl From for torii_proto::PaginationDirection { + fn from(val: PaginationDirection) -> Self { + match val { + PaginationDirection::Forward => torii_proto::PaginationDirection::Forward, + PaginationDirection::Backward => torii_proto::PaginationDirection::Backward, + } + } +} + +impl From for PaginationDirection { + fn from(val: torii_proto::PaginationDirection) -> Self { + match val { + torii_proto::PaginationDirection::Forward => PaginationDirection::Forward, + torii_proto::PaginationDirection::Backward => PaginationDirection::Backward, + } + } +} + +#[derive(Debug, Clone)] +pub enum OrderDirection { + Asc, + Desc, +} + +impl From for torii_proto::OrderDirection { + fn from(val: OrderDirection) -> Self { + match val { + OrderDirection::Asc => torii_proto::OrderDirection::Asc, + OrderDirection::Desc => torii_proto::OrderDirection::Desc, + } + } +} + +impl From for OrderDirection { + fn from(val: torii_proto::OrderDirection) -> Self { + match val { + torii_proto::OrderDirection::Asc => OrderDirection::Asc, + torii_proto::OrderDirection::Desc => OrderDirection::Desc, + } + } +} + +#[derive(Debug, Clone)] +pub struct OrderBy { + pub field: String, + pub direction: OrderDirection, +} + +impl From for torii_proto::OrderBy { + fn from(val: OrderBy) -> Self { + torii_proto::OrderBy { field: val.field, direction: val.direction.into() } + } +} + +impl From for OrderBy { + fn from(val: torii_proto::OrderBy) -> Self { + OrderBy { field: val.field, direction: val.direction.into() } + } +} + +#[derive(Debug, Clone)] +pub struct Pagination { + pub cursor: Option, + pub limit: Option, + pub direction: PaginationDirection, + pub order_by: Vec, +} + +impl From for torii_proto::Pagination { + fn from(val: Pagination) -> Self { + torii_proto::Pagination { + cursor: val.cursor, + limit: val.limit, + direction: val.direction.into(), + order_by: val.order_by.into_iter().map(|o| o.into()).collect(), + } + } +} + +impl From for Pagination { + fn from(val: torii_proto::Pagination) -> Self { + Pagination { + cursor: val.cursor, + limit: val.limit, + direction: val.direction.into(), + order_by: val.order_by.into_iter().map(|o| o.into()).collect(), + } + } +} + +// Note: Page is not included in UniFFI as it doesn't support generics. +// If you need paginated results, use the specific query methods that return +// collections directly (e.g., Vec, Vec, etc.) + +// Signature +#[derive(Debug, Clone)] +pub struct Signature { + pub r: FieldElement, + pub s: FieldElement, +} + +impl From for starknet::core::crypto::Signature { + fn from(val: Signature) -> Self { + Self { + r: field_element_to_felt(&val.r).unwrap(), + s: field_element_to_felt(&val.s).unwrap(), + } + } +} + +impl From for Signature { + fn from(val: starknet::core::crypto::Signature) -> Self { + Signature { r: felt_to_field_element(val.r), s: felt_to_field_element(val.s) } + } +} + +// Call +#[derive(Debug, Clone)] +pub struct Call { + pub to: FieldElement, + pub selector: String, + pub calldata: Vec, +} + +impl From for starknet::core::types::Call { + fn from(val: Call) -> Self { + starknet::core::types::Call { + to: field_element_to_felt(&val.to).unwrap(), + selector: starknet::core::utils::get_selector_from_name(&val.selector).unwrap(), + calldata: val.calldata.into_iter().map(|f| field_element_to_felt(&f).unwrap()).collect(), + } + } +} + +impl From for starknet::core::types::FunctionCall { + fn from(val: Call) -> Self { + starknet::core::types::FunctionCall { + contract_address: field_element_to_felt(&val.to).unwrap(), + entry_point_selector: starknet::core::utils::get_selector_from_name(&val.selector).unwrap(), + calldata: val.calldata.into_iter().map(|f| field_element_to_felt(&f).unwrap()).collect(), + } + } +} + +// BlockId and BlockTag +#[derive(Debug, Clone)] +pub enum BlockTag { + Latest, + PreConfirmed, +} + +impl From for starknet::core::types::BlockTag { + fn from(val: BlockTag) -> Self { + match val { + BlockTag::Latest => starknet::core::types::BlockTag::Latest, + BlockTag::PreConfirmed => starknet::core::types::BlockTag::PreConfirmed, + } + } +} + +#[derive(Debug, Clone)] +pub enum BlockId { + Hash(FieldElement), + Number(u64), + Tag(BlockTag), +} + +impl From for starknet::core::types::BlockId { + fn from(val: BlockId) -> Self { + match val { + BlockId::Hash(hash) => starknet::core::types::BlockId::Hash(field_element_to_felt(&hash).unwrap()), + BlockId::Number(number) => starknet::core::types::BlockId::Number(number), + BlockId::Tag(tag) => starknet::core::types::BlockId::Tag(tag.into()), + } + } +} + diff --git a/src/uniffi/entity.rs b/src/uniffi/entity.rs new file mode 100644 index 0000000..5e7c7cb --- /dev/null +++ b/src/uniffi/entity.rs @@ -0,0 +1,130 @@ +// Entity, Model, and World types +use super::core::*; +use super::schema::{Struct, Ty}; +use chrono::DateTime; + +#[derive(Debug, Clone)] +pub struct Entity { + pub world_address: FieldElement, + pub hashed_keys: FieldElement, + pub models: Vec, + pub created_at: u64, + pub updated_at: u64, + pub executed_at: u64, +} + +impl From for torii_proto::schema::Entity { + fn from(val: Entity) -> Self { + torii_proto::schema::Entity { + world_address: field_element_to_felt(&val.world_address).unwrap(), + hashed_keys: field_element_to_felt(&val.hashed_keys).unwrap(), + models: val.models.into_iter().map(|m| m.into()).collect(), + created_at: DateTime::from_timestamp(val.created_at as i64, 0).unwrap(), + updated_at: DateTime::from_timestamp(val.updated_at as i64, 0).unwrap(), + executed_at: DateTime::from_timestamp(val.executed_at as i64, 0).unwrap(), + } + } +} + +impl From for Entity { + fn from(val: torii_proto::schema::Entity) -> Self { + Entity { + world_address: felt_to_field_element(val.world_address), + hashed_keys: felt_to_field_element(val.hashed_keys), + models: val.models.into_iter().map(|m| m.into()).collect(), + created_at: val.created_at.timestamp() as u64, + updated_at: val.updated_at.timestamp() as u64, + executed_at: val.executed_at.timestamp() as u64, + } + } +} + +#[derive(Debug, Clone)] +pub struct Model { + pub world_address: FieldElement, + pub schema: Ty, + pub namespace: String, + pub name: String, + pub selector: FieldElement, + pub packed_size: u32, + pub unpacked_size: u32, + pub class_hash: FieldElement, + pub contract_address: FieldElement, + pub layout: String, + pub use_legacy_store: bool, +} + +impl From for Model { + fn from(value: torii_proto::Model) -> Self { + let layout = serde_json::to_string(&value.layout).unwrap(); + + Model { + world_address: felt_to_field_element(value.world_address), + schema: value.schema.into(), + name: value.name, + namespace: value.namespace, + selector: felt_to_field_element(value.selector), + packed_size: value.packed_size, + unpacked_size: value.unpacked_size, + class_hash: felt_to_field_element(value.class_hash), + contract_address: felt_to_field_element(value.contract_address), + layout, + use_legacy_store: value.use_legacy_store, + } + } +} + +impl From for torii_proto::Model { + fn from(value: Model) -> Self { + let layout = serde_json::from_str(&value.layout).unwrap(); + + torii_proto::Model { + world_address: field_element_to_felt(&value.world_address).unwrap(), + schema: value.schema.into(), + namespace: value.namespace, + name: value.name, + selector: field_element_to_felt(&value.selector).unwrap(), + packed_size: value.packed_size, + unpacked_size: value.unpacked_size, + class_hash: field_element_to_felt(&value.class_hash).unwrap(), + contract_address: field_element_to_felt(&value.contract_address).unwrap(), + layout, + use_legacy_store: value.use_legacy_store, + } + } +} + +#[derive(Debug, Clone)] +pub struct World { + pub world_address: FieldElement, + pub models: Vec, +} + +impl From for World { + fn from(value: torii_proto::World) -> Self { + let models: Vec = value.models.into_values().map(|v| v.into()).collect(); + + World { world_address: felt_to_field_element(value.world_address), models } + } +} + +impl From for torii_proto::World { + fn from(value: World) -> Self { + let models: Vec = value.models.into_iter().map(|m| m.into()).collect(); + let models = models + .into_iter() + .map(|m| { + ( + dojo_types::naming::compute_selector_from_names(&m.namespace, &m.name), + m, + ) + }) + .collect(); + + torii_proto::World { + world_address: field_element_to_felt(&value.world_address).unwrap(), + models, + } + } +} + diff --git a/src/uniffi/event.rs b/src/uniffi/event.rs new file mode 100644 index 0000000..9c57692 --- /dev/null +++ b/src/uniffi/event.rs @@ -0,0 +1,47 @@ +// Event and Message types +use super::core::*; + +#[derive(Debug, Clone)] +pub struct Event { + pub keys: Vec, + pub data: Vec, + pub transaction_hash: FieldElement, +} + +impl From for torii_proto::Event { + fn from(val: Event) -> Self { + torii_proto::Event { + keys: val.keys.into_iter().map(|k| field_element_to_felt(&k).unwrap()).collect(), + data: val.data.into_iter().map(|d| field_element_to_felt(&d).unwrap()).collect(), + transaction_hash: field_element_to_felt(&val.transaction_hash).unwrap(), + } + } +} + +impl From for Event { + fn from(val: torii_proto::Event) -> Self { + Event { + keys: val.keys.into_iter().map(felt_to_field_element).collect(), + data: val.data.into_iter().map(felt_to_field_element).collect(), + transaction_hash: felt_to_field_element(val.transaction_hash), + } + } +} + +#[derive(Debug, Clone)] +pub struct Message { + pub message: String, + pub signature: Vec, + pub world_address: FieldElement, +} + +impl From for torii_proto::Message { + fn from(val: Message) -> Self { + torii_proto::Message { + message: val.message, + signature: val.signature.into_iter().map(|s| field_element_to_felt(&s).unwrap()).collect(), + world_address: field_element_to_felt(&val.world_address).unwrap(), + } + } +} + diff --git a/src/uniffi/mod.rs b/src/uniffi/mod.rs new file mode 100644 index 0000000..7abd7b4 --- /dev/null +++ b/src/uniffi/mod.rs @@ -0,0 +1,32 @@ +// UniFFI module - exposes Dojo types to multiple languages +// This module provides a cleaner, idiomatic API compared to C FFI + +// Core types and utilities +pub mod core; + +// Domain-specific type modules +pub mod achievement; +pub mod activity; +pub mod aggregation; +pub mod contract; +pub mod controller; +pub mod entity; +pub mod event; +pub mod query; +pub mod schema; +pub mod token; +pub mod transaction; + +// Re-export all public types for convenience +pub use achievement::*; +pub use activity::*; +pub use aggregation::*; +pub use contract::*; +pub use controller::*; +pub use core::*; +pub use entity::*; +pub use event::*; +pub use query::*; +pub use schema::*; +pub use token::*; +pub use transaction::*; diff --git a/src/uniffi/query.rs b/src/uniffi/query.rs new file mode 100644 index 0000000..7ca87dd --- /dev/null +++ b/src/uniffi/query.rs @@ -0,0 +1,271 @@ +// Query types - Query, Clause, KeysClause, MemberClause, CompositeClause +use super::core::*; +use super::schema::MemberValue; + +#[derive(Debug, Clone)] +pub enum PatternMatching { + FixedLen, + VariableLen, +} + +impl From for torii_proto::PatternMatching { + fn from(val: PatternMatching) -> Self { + match val { + PatternMatching::FixedLen => torii_proto::PatternMatching::FixedLen, + PatternMatching::VariableLen => torii_proto::PatternMatching::VariableLen, + } + } +} + +impl From for PatternMatching { + fn from(val: torii_proto::PatternMatching) -> Self { + match val { + torii_proto::PatternMatching::FixedLen => PatternMatching::FixedLen, + torii_proto::PatternMatching::VariableLen => PatternMatching::VariableLen, + } + } +} + +#[derive(Debug, Clone)] +pub struct KeysClause { + pub keys: Vec>, + pub pattern_matching: PatternMatching, + pub models: Vec, +} + +impl From for torii_proto::KeysClause { + fn from(val: KeysClause) -> Self { + torii_proto::KeysClause { + keys: val + .keys + .into_iter() + .map(|k| k.map(|s| field_element_to_felt(&s).unwrap())) + .collect(), + pattern_matching: val.pattern_matching.into(), + models: val.models, + } + } +} + +impl From for KeysClause { + fn from(val: torii_proto::KeysClause) -> Self { + KeysClause { + models: val.models, + keys: val.keys.into_iter().map(|k| k.map(felt_to_field_element)).collect(), + pattern_matching: val.pattern_matching.into(), + } + } +} + +#[derive(Debug, Clone)] +pub enum LogicalOperator { + And, + Or, +} + +impl From for torii_proto::LogicalOperator { + fn from(val: LogicalOperator) -> Self { + match val { + LogicalOperator::And => torii_proto::LogicalOperator::And, + LogicalOperator::Or => torii_proto::LogicalOperator::Or, + } + } +} + +impl From for LogicalOperator { + fn from(val: torii_proto::LogicalOperator) -> Self { + match val { + torii_proto::LogicalOperator::And => LogicalOperator::And, + torii_proto::LogicalOperator::Or => LogicalOperator::Or, + } + } +} + +#[derive(Debug, Clone)] +pub enum ComparisonOperator { + Eq, + Neq, + Gt, + Gte, + Lt, + Lte, + In, + NotIn, + Contains, + ContainsAll, + ContainsAny, + ArrayLengthEq, + ArrayLengthGt, + ArrayLengthLt, +} + +impl From for torii_proto::ComparisonOperator { + fn from(val: ComparisonOperator) -> Self { + match val { + ComparisonOperator::Eq => torii_proto::ComparisonOperator::Eq, + ComparisonOperator::Neq => torii_proto::ComparisonOperator::Neq, + ComparisonOperator::Gt => torii_proto::ComparisonOperator::Gt, + ComparisonOperator::Gte => torii_proto::ComparisonOperator::Gte, + ComparisonOperator::Lt => torii_proto::ComparisonOperator::Lt, + ComparisonOperator::Lte => torii_proto::ComparisonOperator::Lte, + ComparisonOperator::In => torii_proto::ComparisonOperator::In, + ComparisonOperator::NotIn => torii_proto::ComparisonOperator::NotIn, + ComparisonOperator::Contains => torii_proto::ComparisonOperator::Contains, + ComparisonOperator::ContainsAll => torii_proto::ComparisonOperator::ContainsAll, + ComparisonOperator::ContainsAny => torii_proto::ComparisonOperator::ContainsAny, + ComparisonOperator::ArrayLengthEq => torii_proto::ComparisonOperator::ArrayLengthEq, + ComparisonOperator::ArrayLengthGt => torii_proto::ComparisonOperator::ArrayLengthGt, + ComparisonOperator::ArrayLengthLt => torii_proto::ComparisonOperator::ArrayLengthLt, + } + } +} + +impl From for ComparisonOperator { + fn from(val: torii_proto::ComparisonOperator) -> Self { + match val { + torii_proto::ComparisonOperator::Eq => ComparisonOperator::Eq, + torii_proto::ComparisonOperator::Neq => ComparisonOperator::Neq, + torii_proto::ComparisonOperator::Gt => ComparisonOperator::Gt, + torii_proto::ComparisonOperator::Gte => ComparisonOperator::Gte, + torii_proto::ComparisonOperator::Lt => ComparisonOperator::Lt, + torii_proto::ComparisonOperator::Lte => ComparisonOperator::Lte, + torii_proto::ComparisonOperator::In => ComparisonOperator::In, + torii_proto::ComparisonOperator::NotIn => ComparisonOperator::NotIn, + torii_proto::ComparisonOperator::Contains => ComparisonOperator::Contains, + torii_proto::ComparisonOperator::ContainsAll => ComparisonOperator::ContainsAll, + torii_proto::ComparisonOperator::ContainsAny => ComparisonOperator::ContainsAny, + torii_proto::ComparisonOperator::ArrayLengthEq => ComparisonOperator::ArrayLengthEq, + torii_proto::ComparisonOperator::ArrayLengthGt => ComparisonOperator::ArrayLengthGt, + torii_proto::ComparisonOperator::ArrayLengthLt => ComparisonOperator::ArrayLengthLt, + } + } +} + +#[derive(Debug, Clone)] +pub struct MemberClause { + pub model: String, + pub member: String, + pub operator: ComparisonOperator, + pub value: MemberValue, +} + +impl From for torii_proto::MemberClause { + fn from(val: MemberClause) -> Self { + torii_proto::MemberClause { + member: val.member, + model: val.model, + operator: val.operator.into(), + value: val.value.into(), + } + } +} + +impl From for MemberClause { + fn from(val: torii_proto::MemberClause) -> Self { + MemberClause { + model: val.model, + member: val.member, + operator: val.operator.into(), + value: val.value.into(), + } + } +} + +#[derive(Debug, Clone)] +pub struct CompositeClause { + pub operator: LogicalOperator, + pub clauses: Vec, +} + +impl From for torii_proto::CompositeClause { + fn from(val: CompositeClause) -> Self { + torii_proto::CompositeClause { + operator: val.operator.into(), + clauses: val.clauses.into_iter().map(|c| c.into()).collect(), + } + } +} + +impl From for CompositeClause { + fn from(val: torii_proto::CompositeClause) -> Self { + CompositeClause { + operator: val.operator.into(), + clauses: val.clauses.into_iter().map(|c| c.into()).collect(), + } + } +} + +#[derive(Debug, Clone)] +pub enum Clause { + HashedKeys { keys: Vec }, + Keys { clause: KeysClause }, + Member { clause: MemberClause }, + Composite { clause: CompositeClause }, +} + +impl From for torii_proto::Clause { + fn from(val: Clause) -> Self { + match val { + Clause::HashedKeys { keys } => torii_proto::Clause::HashedKeys( + keys.into_iter().map(|k| field_element_to_felt(&k).unwrap()).collect(), + ), + Clause::Keys { clause } => torii_proto::Clause::Keys(clause.into()), + Clause::Member { clause } => torii_proto::Clause::Member(clause.into()), + Clause::Composite { clause } => torii_proto::Clause::Composite(clause.into()), + } + } +} + +impl From for Clause { + fn from(val: torii_proto::Clause) -> Self { + match val { + torii_proto::Clause::HashedKeys(keys) => { + Clause::HashedKeys { keys: keys.into_iter().map(felt_to_field_element).collect() } + } + torii_proto::Clause::Keys(clause) => Clause::Keys { clause: clause.into() }, + torii_proto::Clause::Member(clause) => Clause::Member { clause: clause.into() }, + torii_proto::Clause::Composite(clause) => Clause::Composite { clause: clause.into() }, + } + } +} + +#[derive(Debug, Clone)] +pub struct Query { + pub world_addresses: Vec, + pub pagination: Pagination, + pub clause: Option, + pub no_hashed_keys: bool, + pub models: Vec, + pub historical: bool, +} + +impl From for torii_proto::Query { + fn from(val: Query) -> Self { + torii_proto::Query { + world_addresses: val + .world_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + pagination: val.pagination.into(), + clause: val.clause.map(|c| c.into()), + models: val.models, + no_hashed_keys: val.no_hashed_keys, + historical: val.historical, + } + } +} + +impl From for Query { + fn from(val: torii_proto::Query) -> Self { + Query { + world_addresses: val.world_addresses.into_iter().map(felt_to_field_element).collect(), + pagination: val.pagination.into(), + clause: val.clause.map(|c| c.into()), + models: val.models, + no_hashed_keys: val.no_hashed_keys, + historical: val.historical, + } + } +} + diff --git a/src/uniffi/schema.rs b/src/uniffi/schema.rs new file mode 100644 index 0000000..bc88eff --- /dev/null +++ b/src/uniffi/schema.rs @@ -0,0 +1,331 @@ +// Schema types - Primitive, Ty, Struct, Enum, Member +use super::core::*; + +#[derive(Debug, Clone)] +pub enum Primitive { + I8 { value: i8 }, + I16 { value: i16 }, + I32 { value: i32 }, + I64 { value: i64 }, + I128 { value: Vec }, // 16 bytes + U8 { value: u8 }, + U16 { value: u16 }, + U32 { value: u32 }, + U64 { value: u64 }, + U128 { value: Vec }, // 16 bytes + U256 { value: U256 }, + Bool { value: bool }, + Felt252 { value: FieldElement }, + ClassHash { value: FieldElement }, + ContractAddress { value: FieldElement }, + EthAddress { value: FieldElement }, +} + +impl From for dojo_types::primitive::Primitive { + fn from(value: Primitive) -> Self { + match value { + Primitive::I8 { value: v } => dojo_types::primitive::Primitive::I8(Some(v)), + Primitive::I16 { value: v } => dojo_types::primitive::Primitive::I16(Some(v)), + Primitive::I32 { value: v } => dojo_types::primitive::Primitive::I32(Some(v)), + Primitive::I64 { value: v } => dojo_types::primitive::Primitive::I64(Some(v)), + Primitive::I128 { value: v } => { + let mut bytes = [0u8; 16]; + bytes.copy_from_slice(&v); + dojo_types::primitive::Primitive::I128(Some(i128::from_be_bytes(bytes))) + } + Primitive::U8 { value: v } => dojo_types::primitive::Primitive::U8(Some(v)), + Primitive::U16 { value: v } => dojo_types::primitive::Primitive::U16(Some(v)), + Primitive::U32 { value: v } => dojo_types::primitive::Primitive::U32(Some(v)), + Primitive::U64 { value: v } => dojo_types::primitive::Primitive::U64(Some(v)), + Primitive::U128 { value: v } => { + let mut bytes = [0u8; 16]; + bytes.copy_from_slice(&v); + dojo_types::primitive::Primitive::U128(Some(u128::from_be_bytes(bytes))) + } + Primitive::U256 { value: v } => dojo_types::primitive::Primitive::U256(Some(uniffi_to_u256(&v).unwrap())), + Primitive::Bool { value: v } => dojo_types::primitive::Primitive::Bool(Some(v)), + Primitive::Felt252 { value: v } => { + dojo_types::primitive::Primitive::Felt252(Some(field_element_to_felt(&v).unwrap())) + } + Primitive::ClassHash { value: v } => { + dojo_types::primitive::Primitive::ClassHash(Some(field_element_to_felt(&v).unwrap())) + } + Primitive::ContractAddress { value: v } => { + dojo_types::primitive::Primitive::ContractAddress(Some(field_element_to_felt(&v).unwrap())) + } + Primitive::EthAddress { value: v } => { + dojo_types::primitive::Primitive::EthAddress(Some(field_element_to_felt(&v).unwrap())) + } + } + } +} + +impl From for Primitive { + fn from(value: dojo_types::primitive::Primitive) -> Self { + match value { + dojo_types::primitive::Primitive::I8(v) => Primitive::I8 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::I16(v) => Primitive::I16 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::I32(v) => Primitive::I32 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::I64(v) => Primitive::I64 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::I128(v) => { + Primitive::I128 { value: v.unwrap_or(0).to_be_bytes().to_vec() } + } + dojo_types::primitive::Primitive::U8(v) => Primitive::U8 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::U16(v) => Primitive::U16 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::U32(v) => Primitive::U32 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::U64(v) => Primitive::U64 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::U128(v) => { + Primitive::U128 { value: v.unwrap_or(0).to_be_bytes().to_vec() } + } + dojo_types::primitive::Primitive::U256(v) => { + Primitive::U256 { value: v.map(u256_to_uniffi).unwrap_or_else(|| U256("0x0".to_string())) } + } + dojo_types::primitive::Primitive::Bool(v) => Primitive::Bool { value: v.unwrap_or(false) }, + dojo_types::primitive::Primitive::Felt252(v) => { + Primitive::Felt252 { value: v.map(felt_to_field_element).unwrap_or_else(|| FieldElement("0x0".to_string())) } + } + dojo_types::primitive::Primitive::ClassHash(v) => { + Primitive::ClassHash { value: v.map(felt_to_field_element).unwrap_or_else(|| FieldElement("0x0".to_string())) } + } + dojo_types::primitive::Primitive::ContractAddress(v) => { + Primitive::ContractAddress { value: v.map(felt_to_field_element).unwrap_or_else(|| FieldElement("0x0".to_string())) } + } + dojo_types::primitive::Primitive::EthAddress(v) => { + Primitive::EthAddress { value: v.map(felt_to_field_element).unwrap_or_else(|| FieldElement("0x0".to_string())) } + } + } + } +} + +#[derive(Debug, Clone)] +pub enum MemberValue { + Primitive { value: Primitive }, + String { value: String }, + List { values: Vec }, +} + +impl From for torii_proto::MemberValue { + fn from(val: MemberValue) -> Self { + match val { + MemberValue::Primitive { value } => torii_proto::MemberValue::Primitive(value.into()), + MemberValue::String { value } => torii_proto::MemberValue::String(value), + MemberValue::List { values } => { + torii_proto::MemberValue::List(values.into_iter().map(|v| v.into()).collect()) + } + } + } +} + +impl From for MemberValue { + fn from(val: torii_proto::MemberValue) -> Self { + match val { + torii_proto::MemberValue::Primitive(value) => MemberValue::Primitive { value: value.into() }, + torii_proto::MemberValue::String(value) => MemberValue::String { value }, + torii_proto::MemberValue::List(values) => { + MemberValue::List { values: values.into_iter().map(|v| v.into()).collect() } + } + } + } +} + +#[derive(Debug, Clone)] +pub struct FixedSizeArray { + pub array: Vec, + pub size: u32, +} + +#[derive(Debug, Clone)] +pub enum Ty { + Primitive { value: Primitive }, + Struct { value: Struct }, + Enum { value: EnumType }, + Tuple { values: Vec }, + Array { values: Vec }, + FixedSizeArray { value: FixedSizeArray }, + ByteArray { value: String }, +} + +impl From for Ty { + fn from(val: dojo_types::schema::Ty) -> Self { + match val { + dojo_types::schema::Ty::Primitive(primitive) => Ty::Primitive { value: primitive.into() }, + dojo_types::schema::Ty::Struct(struct_) => Ty::Struct { value: struct_.into() }, + dojo_types::schema::Ty::Enum(enum_) => Ty::Enum { value: enum_.into() }, + dojo_types::schema::Ty::Tuple(tuple) => { + Ty::Tuple { values: tuple.into_iter().map(|t| t.into()).collect() } + } + dojo_types::schema::Ty::Array(array) => { + Ty::Array { values: array.into_iter().map(|t| t.into()).collect() } + } + dojo_types::schema::Ty::FixedSizeArray((ty, size)) => Ty::FixedSizeArray { value: FixedSizeArray { + array: ty.into_iter().map(|t| t.into()).collect(), + size, + }}, + dojo_types::schema::Ty::ByteArray(array) => Ty::ByteArray { value: array }, + } + } +} + +impl From for dojo_types::schema::Ty { + fn from(val: Ty) -> Self { + match val { + Ty::Primitive { value } => dojo_types::schema::Ty::Primitive(value.into()), + Ty::Struct { value } => dojo_types::schema::Ty::Struct(value.into()), + Ty::Enum { value } => dojo_types::schema::Ty::Enum(value.into()), + Ty::Tuple { values } => { + dojo_types::schema::Ty::Tuple(values.into_iter().map(|t| t.into()).collect()) + } + Ty::Array { values } => { + dojo_types::schema::Ty::Array(values.into_iter().map(|t| t.into()).collect()) + } + Ty::FixedSizeArray { value: fixed_size_array } => dojo_types::schema::Ty::FixedSizeArray(( + fixed_size_array.array.into_iter().map(|t| t.into()).collect(), + fixed_size_array.size, + )), + Ty::ByteArray { value } => dojo_types::schema::Ty::ByteArray(value), + } + } +} + +#[derive(Debug, Clone)] +pub struct Member { + pub name: String, + pub ty: Ty, + pub key: bool, +} + +impl From for Member { + fn from(value: dojo_types::schema::Member) -> Self { + Member { name: value.name, ty: value.ty.into(), key: value.key } + } +} + +impl From for dojo_types::schema::Member { + fn from(value: Member) -> Self { + dojo_types::schema::Member { name: value.name, ty: value.ty.into(), key: value.key } + } +} + +#[derive(Debug, Clone)] +pub struct Struct { + pub name: String, + pub children: Vec, +} + +impl From for dojo_types::schema::Struct { + fn from(value: Struct) -> Self { + dojo_types::schema::Struct { + name: value.name, + children: value.children.into_iter().map(|c| c.into()).collect(), + } + } +} + +impl From for Struct { + fn from(value: dojo_types::schema::Struct) -> Self { + Struct { + name: value.name, + children: value.children.into_iter().map(|c| c.into()).collect(), + } + } +} + +#[derive(Debug, Clone)] +pub struct EnumOption { + pub name: String, + pub ty: Ty, +} + +impl From for EnumOption { + fn from(value: dojo_types::schema::EnumOption) -> Self { + EnumOption { name: value.name, ty: value.ty.into() } + } +} + +impl From for dojo_types::schema::EnumOption { + fn from(value: EnumOption) -> Self { + dojo_types::schema::EnumOption { name: value.name, ty: value.ty.into() } + } +} + +#[derive(Debug, Clone)] +pub struct EnumType { + pub name: String, + pub option: u8, + pub options: Vec, +} + +impl From for EnumType { + fn from(value: dojo_types::schema::Enum) -> Self { + EnumType { + name: value.name, + option: value.option.unwrap_or(0), + options: value.options.into_iter().map(|o| o.into()).collect(), + } + } +} + +impl From for dojo_types::schema::Enum { + fn from(value: EnumType) -> Self { + dojo_types::schema::Enum { + name: value.name, + option: Some(value.option), + options: value.options.into_iter().map(|o| o.into()).collect(), + } + } +} + +#[derive(Debug, Clone)] +pub enum ValueType { + String { value: String }, + Int { value: i64 }, + UInt { value: u64 }, + Bool { value: bool }, + Bytes { value: Vec }, +} + +impl From for torii_proto::ValueType { + fn from(val: ValueType) -> Self { + match val { + ValueType::String { value: v } => torii_proto::ValueType::String(v), + ValueType::Int { value: v } => torii_proto::ValueType::Int(v), + ValueType::UInt { value: v } => torii_proto::ValueType::UInt(v), + ValueType::Bool { value: v } => torii_proto::ValueType::Bool(v), + ValueType::Bytes { value: v } => torii_proto::ValueType::Bytes(v), + } + } +} + +impl From for ValueType { + fn from(val: torii_proto::ValueType) -> Self { + match val { + torii_proto::ValueType::String(v) => ValueType::String { value: v }, + torii_proto::ValueType::Int(v) => ValueType::Int { value: v }, + torii_proto::ValueType::UInt(v) => ValueType::UInt { value: v }, + torii_proto::ValueType::Bool(v) => ValueType::Bool { value: v }, + torii_proto::ValueType::Bytes(v) => ValueType::Bytes { value: v }, + } + } +} + +#[derive(Debug, Clone)] +pub struct Value { + pub primitive_type: Primitive, + pub value_type: ValueType, +} + +impl From for Value { + fn from(val: torii_proto::Value) -> Self { + Value { primitive_type: val.primitive_type.into(), value_type: val.value_type.into() } + } +} + +impl From for torii_proto::Value { + fn from(val: Value) -> Self { + torii_proto::Value { + primitive_type: val.primitive_type.into(), + value_type: val.value_type.into(), + } + } +} + diff --git a/src/uniffi/token.rs b/src/uniffi/token.rs new file mode 100644 index 0000000..439a513 --- /dev/null +++ b/src/uniffi/token.rs @@ -0,0 +1,209 @@ +// Token types +use super::core::*; + +#[derive(Debug, Clone)] +pub struct Token { + pub contract_address: FieldElement, + pub token_id: Option, + pub name: String, + pub symbol: String, + pub decimals: u8, + pub metadata: String, + pub total_supply: Option, +} + +impl From for Token { + fn from(val: torii_proto::Token) -> Self { + Token { + token_id: val.token_id.map(u256_to_uniffi), + contract_address: felt_to_field_element(val.contract_address), + name: val.name, + symbol: val.symbol, + decimals: val.decimals, + metadata: val.metadata, + total_supply: val.total_supply.map(u256_to_uniffi), + } + } +} + +#[derive(Debug, Clone)] +pub struct TokenBalance { + pub balance: U256, + pub account_address: FieldElement, + pub contract_address: FieldElement, + pub token_id: Option, +} + +impl From for TokenBalance { + fn from(val: torii_proto::TokenBalance) -> Self { + TokenBalance { + balance: u256_to_uniffi(val.balance), + account_address: felt_to_field_element(val.account_address), + contract_address: felt_to_field_element(val.contract_address), + token_id: val.token_id.map(u256_to_uniffi), + } + } +} + +#[derive(Debug, Clone)] +pub struct TokenContract { + pub contract_address: FieldElement, + pub name: String, + pub symbol: String, + pub decimals: u8, + pub metadata: String, + pub token_metadata: String, + pub total_supply: Option, +} + +impl From for TokenContract { + fn from(val: torii_proto::TokenContract) -> Self { + Self { + contract_address: felt_to_field_element(val.contract_address), + name: val.name, + symbol: val.symbol, + decimals: val.decimals, + token_metadata: val.token_metadata, + total_supply: val.total_supply.map(u256_to_uniffi), + metadata: val.metadata, + } + } +} + +#[derive(Debug, Clone)] +pub struct AttributeFilter { + pub trait_name: String, + pub trait_value: String, +} + +impl From for torii_proto::TokenAttributeFilter { + fn from(val: AttributeFilter) -> Self { + torii_proto::TokenAttributeFilter { trait_name: val.trait_name, trait_value: val.trait_value } + } +} + +#[derive(Debug, Clone)] +pub struct TokenQuery { + pub contract_addresses: Vec, + pub token_ids: Vec, + pub attribute_filters: Vec, + pub pagination: Pagination, +} + +impl From for torii_proto::TokenQuery { + fn from(val: TokenQuery) -> Self { + torii_proto::TokenQuery { + contract_addresses: val + .contract_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + token_ids: val.token_ids.into_iter().map(|t| uniffi_to_u256(&t).unwrap()).collect(), + attribute_filters: val.attribute_filters.into_iter().map(|f| f.into()).collect(), + pagination: val.pagination.into(), + } + } +} + +#[derive(Debug, Clone)] +pub struct TokenBalanceQuery { + pub contract_addresses: Vec, + pub account_addresses: Vec, + pub token_ids: Vec, + pub pagination: Pagination, +} + +impl From for torii_proto::TokenBalanceQuery { + fn from(val: TokenBalanceQuery) -> Self { + torii_proto::TokenBalanceQuery { + contract_addresses: val + .contract_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + account_addresses: val + .account_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + token_ids: val.token_ids.into_iter().map(|t| uniffi_to_u256(&t).unwrap()).collect(), + pagination: val.pagination.into(), + } + } +} + +#[derive(Debug, Clone)] +pub struct TokenContractQuery { + pub contract_addresses: Vec, + pub contract_types: Vec, + pub pagination: Pagination, +} + +impl From for torii_proto::TokenContractQuery { + fn from(val: TokenContractQuery) -> Self { + torii_proto::TokenContractQuery { + contract_addresses: val + .contract_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + contract_types: val.contract_types.into_iter().map(|t| t.into()).collect(), + pagination: val.pagination.into(), + } + } +} + +#[derive(Debug, Clone)] +pub struct TokenTransfer { + pub id: String, + pub contract_address: FieldElement, + pub from_address: FieldElement, + pub to_address: FieldElement, + pub amount: U256, + pub token_id: Option, + pub executed_at: u64, + pub event_id: Option, +} + +impl From for TokenTransfer { + fn from(val: torii_proto::TokenTransfer) -> Self { + TokenTransfer { + id: val.id, + contract_address: felt_to_field_element(val.contract_address), + from_address: felt_to_field_element(val.from_address), + to_address: felt_to_field_element(val.to_address), + amount: u256_to_uniffi(val.amount), + token_id: val.token_id.map(u256_to_uniffi), + executed_at: val.executed_at.timestamp() as u64, + event_id: val.event_id, + } + } +} + +#[derive(Debug, Clone)] +pub struct TokenTransferQuery { + pub contract_addresses: Vec, + pub account_addresses: Vec, + pub token_ids: Vec, + pub pagination: Pagination, +} + +impl From for torii_proto::TokenTransferQuery { + fn from(val: TokenTransferQuery) -> Self { + torii_proto::TokenTransferQuery { + contract_addresses: val + .contract_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + account_addresses: val + .account_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + token_ids: val.token_ids.into_iter().map(|t| uniffi_to_u256(&t).unwrap()).collect(), + pagination: val.pagination.into(), + } + } +} + diff --git a/src/uniffi/transaction.rs b/src/uniffi/transaction.rs new file mode 100644 index 0000000..8d0657a --- /dev/null +++ b/src/uniffi/transaction.rs @@ -0,0 +1,128 @@ +// Transaction types +use super::core::*; + +#[derive(Debug, Clone)] +pub enum CallType { + Execute, + ExecuteFromOutside, +} + +impl From for CallType { + fn from(val: torii_proto::CallType) -> Self { + match val { + torii_proto::CallType::Execute => CallType::Execute, + torii_proto::CallType::ExecuteFromOutside => CallType::ExecuteFromOutside, + } + } +} + +#[derive(Debug, Clone)] +pub struct TransactionCall { + pub contract_address: FieldElement, + pub entrypoint: String, + pub calldata: Vec, + pub call_type: CallType, + pub caller_address: FieldElement, +} + +impl From for TransactionCall { + fn from(val: torii_proto::TransactionCall) -> Self { + TransactionCall { + contract_address: felt_to_field_element(val.contract_address), + entrypoint: val.entrypoint, + calldata: val.calldata.into_iter().map(felt_to_field_element).collect(), + call_type: val.call_type.into(), + caller_address: felt_to_field_element(val.caller_address), + } + } +} + +#[derive(Debug, Clone)] +pub struct Transaction { + pub transaction_hash: FieldElement, + pub sender_address: FieldElement, + pub calldata: Vec, + pub max_fee: FieldElement, + pub signature: Vec, + pub nonce: FieldElement, + pub block_number: u64, + pub transaction_type: String, + pub block_timestamp: u64, + pub calls: Vec, + pub unique_models: Vec, +} + +impl From for Transaction { + fn from(val: torii_proto::Transaction) -> Self { + Transaction { + transaction_hash: felt_to_field_element(val.transaction_hash), + sender_address: felt_to_field_element(val.sender_address), + calldata: val.calldata.into_iter().map(felt_to_field_element).collect(), + max_fee: felt_to_field_element(val.max_fee), + signature: val.signature.into_iter().map(felt_to_field_element).collect(), + nonce: felt_to_field_element(val.nonce), + block_number: val.block_number, + transaction_type: val.transaction_type, + block_timestamp: val.block_timestamp.timestamp() as u64, + calls: val.calls.into_iter().map(|c| c.into()).collect(), + unique_models: val.unique_models.into_iter().map(felt_to_field_element).collect(), + } + } +} + +#[derive(Debug, Clone)] +pub struct TransactionFilter { + pub transaction_hashes: Vec, + pub caller_addresses: Vec, + pub contract_addresses: Vec, + pub entrypoints: Vec, + pub model_selectors: Vec, + pub from_block: Option, + pub to_block: Option, +} + +impl From for torii_proto::TransactionFilter { + fn from(val: TransactionFilter) -> Self { + torii_proto::TransactionFilter { + transaction_hashes: val + .transaction_hashes + .into_iter() + .map(|h| field_element_to_felt(&h).unwrap()) + .collect(), + caller_addresses: val + .caller_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + contract_addresses: val + .contract_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + entrypoints: val.entrypoints, + model_selectors: val + .model_selectors + .into_iter() + .map(|s| field_element_to_felt(&s).unwrap()) + .collect(), + from_block: val.from_block, + to_block: val.to_block, + } + } +} + +#[derive(Debug, Clone)] +pub struct TransactionQuery { + pub filter: Option, + pub pagination: Pagination, +} + +impl From for torii_proto::TransactionQuery { + fn from(val: TransactionQuery) -> Self { + torii_proto::TransactionQuery { + filter: val.filter.map(|f| f.into()), + pagination: val.pagination.into(), + } + } +} + From 4a04b29cc23ab6c26148aa77664720931c1aeb59 Mon Sep 17 00:00:00 2001 From: Nasr Date: Wed, 15 Oct 2025 12:59:54 -0500 Subject: [PATCH 02/16] added swift and python bindings --- Cargo.lock | 14 + bindings/python/dojo.py | 5818 ++++++++++++++++++++++++++++++ bindings/swift/DojoEngine.swift | 5294 +++++++++++++++++++++++++++ src/bin/uniffi-bindgen-kotlin.rs | 55 + src/bin/uniffi-bindgen-python.rs | 65 + src/bin/uniffi-bindgen-swift.rs | 71 + src/bin/uniffi-bindgen.rs | 4 - src/dojo_full.udl.bak | 335 -- src/uniffi/core.rs | 30 +- uniffi.toml | 22 + 10 files changed, 11343 insertions(+), 365 deletions(-) create mode 100644 bindings/python/dojo.py create mode 100644 bindings/swift/DojoEngine.swift create mode 100644 src/bin/uniffi-bindgen-kotlin.rs create mode 100644 src/bin/uniffi-bindgen-python.rs create mode 100644 src/bin/uniffi-bindgen-swift.rs delete mode 100644 src/bin/uniffi-bindgen.rs delete mode 100644 src/dojo_full.udl.bak create mode 100644 uniffi.toml diff --git a/Cargo.lock b/Cargo.lock index eb7bf5e..6b836cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1037,6 +1037,18 @@ name = "dojo-core" version = "1.8.3" dependencies = [ "anyhow", +<<<<<<< HEAD +======= + "axum 0.8.4", + "base64 0.22.1", + "cainome", + "camino", + "cargo_metadata", + "cbindgen", + "chrono", + "crypto-bigint", + "directories", +>>>>>>> 7a31aa79 (added swift and python bindings) "dojo-types", "dojo-world", <<<<<<< HEAD @@ -4581,7 +4593,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c866f627c3f04c3df068b68bb2d725492caaa539dd313e2a9d26bb85b1a32f4e" dependencies = [ "anyhow", + "camino", "cargo_metadata", + "clap", "uniffi_bindgen", "uniffi_build", "uniffi_core", diff --git a/bindings/python/dojo.py b/bindings/python/dojo.py new file mode 100644 index 0000000..beaf4a6 --- /dev/null +++ b/bindings/python/dojo.py @@ -0,0 +1,5818 @@ +# This file was autogenerated by some hot garbage in the `uniffi` crate. +# Trust me, you don't want to mess with it! + +# Common helper code. +# +# Ideally this would live in a separate .py file where it can be unittested etc +# in isolation, and perhaps even published as a re-useable package. +# +# However, it's important that the details of how this helper code works (e.g. the +# way that different builtin types are passed across the FFI) exactly match what's +# expected by the rust code on the other side of the interface. In practice right +# now that means coming from the exact some version of `uniffi` that was used to +# compile the rust component. The easiest way to ensure this is to bundle the Python +# helpers directly inline like we're doing here. + +from __future__ import annotations +import os +import sys +import ctypes +from dataclasses import dataclass +import enum +import struct +import contextlib +import datetime +import threading +import itertools +import traceback +import typing +import platform + + +# Used for default argument values +_DEFAULT = object() # type: typing.Any + + +class _UniffiRustBuffer(ctypes.Structure): + _fields_ = [ + ("capacity", ctypes.c_uint64), + ("len", ctypes.c_uint64), + ("data", ctypes.POINTER(ctypes.c_char)), + ] + + @staticmethod + def default(): + return _UniffiRustBuffer(0, 0, None) + + @staticmethod + def alloc(size): + return _uniffi_rust_call(_UniffiLib.ffi_dojo_c_rustbuffer_alloc, size) + + @staticmethod + def reserve(rbuf, additional): + return _uniffi_rust_call(_UniffiLib.ffi_dojo_c_rustbuffer_reserve, rbuf, additional) + + def free(self): + return _uniffi_rust_call(_UniffiLib.ffi_dojo_c_rustbuffer_free, self) + + def __str__(self): + return "_UniffiRustBuffer(capacity={}, len={}, data={})".format( + self.capacity, + self.len, + self.data[0:self.len] + ) + + @contextlib.contextmanager + def alloc_with_builder(*args): + """Context-manger to allocate a buffer using a _UniffiRustBufferBuilder. + + The allocated buffer will be automatically freed if an error occurs, ensuring that + we don't accidentally leak it. + """ + builder = _UniffiRustBufferBuilder() + try: + yield builder + except: + builder.discard() + raise + + @contextlib.contextmanager + def consume_with_stream(self): + """Context-manager to consume a buffer using a _UniffiRustBufferStream. + + The _UniffiRustBuffer will be freed once the context-manager exits, ensuring that we don't + leak it even if an error occurs. + """ + try: + s = _UniffiRustBufferStream.from_rust_buffer(self) + yield s + if s.remaining() != 0: + raise RuntimeError(f"junk data left in buffer at end of consume_with_stream {s.remaining()}") + finally: + self.free() + + @contextlib.contextmanager + def read_with_stream(self): + """Context-manager to read a buffer using a _UniffiRustBufferStream. + + This is like consume_with_stream, but doesn't free the buffer afterwards. + It should only be used with borrowed `_UniffiRustBuffer` data. + """ + s = _UniffiRustBufferStream.from_rust_buffer(self) + yield s + if s.remaining() != 0: + raise RuntimeError(f"junk data left in buffer at end of read_with_stream {s.remaining()}") + +class _UniffiForeignBytes(ctypes.Structure): + _fields_ = [ + ("len", ctypes.c_int32), + ("data", ctypes.POINTER(ctypes.c_char)), + ] + + def __str__(self): + return "_UniffiForeignBytes(len={}, data={})".format(self.len, self.data[0:self.len]) + + +class _UniffiRustBufferStream: + """ + Helper for structured reading of bytes from a _UniffiRustBuffer + """ + + def __init__(self, data, len): + self.data = data + self.len = len + self.offset = 0 + + @classmethod + def from_rust_buffer(cls, buf): + return cls(buf.data, buf.len) + + def remaining(self): + return self.len - self.offset + + def _unpack_from(self, size, format): + if self.offset + size > self.len: + raise InternalError("read past end of rust buffer") + value = struct.unpack(format, self.data[self.offset:self.offset+size])[0] + self.offset += size + return value + + def read(self, size): + if self.offset + size > self.len: + raise InternalError("read past end of rust buffer") + data = self.data[self.offset:self.offset+size] + self.offset += size + return data + + def read_i8(self): + return self._unpack_from(1, ">b") + + def read_u8(self): + return self._unpack_from(1, ">B") + + def read_i16(self): + return self._unpack_from(2, ">h") + + def read_u16(self): + return self._unpack_from(2, ">H") + + def read_i32(self): + return self._unpack_from(4, ">i") + + def read_u32(self): + return self._unpack_from(4, ">I") + + def read_i64(self): + return self._unpack_from(8, ">q") + + def read_u64(self): + return self._unpack_from(8, ">Q") + + def read_float(self): + v = self._unpack_from(4, ">f") + return v + + def read_double(self): + return self._unpack_from(8, ">d") + +class _UniffiRustBufferBuilder: + """ + Helper for structured writing of bytes into a _UniffiRustBuffer. + """ + + def __init__(self): + self.rbuf = _UniffiRustBuffer.alloc(16) + self.rbuf.len = 0 + + def finalize(self): + rbuf = self.rbuf + self.rbuf = None + return rbuf + + def discard(self): + if self.rbuf is not None: + rbuf = self.finalize() + rbuf.free() + + @contextlib.contextmanager + def _reserve(self, num_bytes): + if self.rbuf.len + num_bytes > self.rbuf.capacity: + self.rbuf = _UniffiRustBuffer.reserve(self.rbuf, num_bytes) + yield None + self.rbuf.len += num_bytes + + def _pack_into(self, size, format, value): + with self._reserve(size): + # XXX TODO: I feel like I should be able to use `struct.pack_into` here but can't figure it out. + for i, byte in enumerate(struct.pack(format, value)): + self.rbuf.data[self.rbuf.len + i] = byte + + def write(self, value): + with self._reserve(len(value)): + for i, byte in enumerate(value): + self.rbuf.data[self.rbuf.len + i] = byte + + def write_i8(self, v): + self._pack_into(1, ">b", v) + + def write_u8(self, v): + self._pack_into(1, ">B", v) + + def write_i16(self, v): + self._pack_into(2, ">h", v) + + def write_u16(self, v): + self._pack_into(2, ">H", v) + + def write_i32(self, v): + self._pack_into(4, ">i", v) + + def write_u32(self, v): + self._pack_into(4, ">I", v) + + def write_i64(self, v): + self._pack_into(8, ">q", v) + + def write_u64(self, v): + self._pack_into(8, ">Q", v) + + def write_float(self, v): + self._pack_into(4, ">f", v) + + def write_double(self, v): + self._pack_into(8, ">d", v) + + def write_c_size_t(self, v): + self._pack_into(ctypes.sizeof(ctypes.c_size_t) , "@N", v) +# A handful of classes and functions to support the generated data structures. +# This would be a good candidate for isolating in its own ffi-support lib. + +class InternalError(Exception): + pass + +class _UniffiRustCallStatus(ctypes.Structure): + """ + Error runtime. + """ + _fields_ = [ + ("code", ctypes.c_int8), + ("error_buf", _UniffiRustBuffer), + ] + + # These match the values from the uniffi::rustcalls module + CALL_SUCCESS = 0 + CALL_ERROR = 1 + CALL_UNEXPECTED_ERROR = 2 + + @staticmethod + def default(): + return _UniffiRustCallStatus(code=_UniffiRustCallStatus.CALL_SUCCESS, error_buf=_UniffiRustBuffer.default()) + + def __str__(self): + if self.code == _UniffiRustCallStatus.CALL_SUCCESS: + return "_UniffiRustCallStatus(CALL_SUCCESS)" + elif self.code == _UniffiRustCallStatus.CALL_ERROR: + return "_UniffiRustCallStatus(CALL_ERROR)" + elif self.code == _UniffiRustCallStatus.CALL_UNEXPECTED_ERROR: + return "_UniffiRustCallStatus(CALL_UNEXPECTED_ERROR)" + else: + return "_UniffiRustCallStatus()" + +def _uniffi_rust_call(fn, *args): + # Call a rust function + return _uniffi_rust_call_with_error(None, fn, *args) + +def _uniffi_rust_call_with_error(error_ffi_converter, fn, *args): + # Call a rust function and handle any errors + # + # This function is used for rust calls that return Result<> and therefore can set the CALL_ERROR status code. + # error_ffi_converter must be set to the _UniffiConverter for the error class that corresponds to the result. + call_status = _UniffiRustCallStatus.default() + + args_with_error = args + (ctypes.byref(call_status),) + result = fn(*args_with_error) + _uniffi_check_call_status(error_ffi_converter, call_status) + return result + +def _uniffi_check_call_status(error_ffi_converter, call_status): + if call_status.code == _UniffiRustCallStatus.CALL_SUCCESS: + pass + elif call_status.code == _UniffiRustCallStatus.CALL_ERROR: + if error_ffi_converter is None: + call_status.error_buf.free() + raise InternalError("_uniffi_rust_call_with_error: CALL_ERROR, but error_ffi_converter is None") + else: + raise error_ffi_converter.lift(call_status.error_buf) + elif call_status.code == _UniffiRustCallStatus.CALL_UNEXPECTED_ERROR: + # When the rust code sees a panic, it tries to construct a _UniffiRustBuffer + # with the message. But if that code panics, then it just sends back + # an empty buffer. + if call_status.error_buf.len > 0: + msg = _UniffiFfiConverterString.lift(call_status.error_buf) + else: + msg = "Unknown rust panic" + raise InternalError(msg) + else: + raise InternalError("Invalid _UniffiRustCallStatus code: {}".format( + call_status.code)) + +def _uniffi_trait_interface_call(call_status, make_call, write_return_value): + try: + return write_return_value(make_call()) + except Exception as e: + call_status.code = _UniffiRustCallStatus.CALL_UNEXPECTED_ERROR + call_status.error_buf = _UniffiFfiConverterString.lower(repr(e)) + +def _uniffi_trait_interface_call_with_error(call_status, make_call, write_return_value, error_type, lower_error): + try: + try: + return write_return_value(make_call()) + except error_type as e: + call_status.code = _UniffiRustCallStatus.CALL_ERROR + call_status.error_buf = lower_error(e) + except Exception as e: + call_status.code = _UniffiRustCallStatus.CALL_UNEXPECTED_ERROR + call_status.error_buf = _UniffiFfiConverterString.lower(repr(e)) +# Initial value and increment amount for handles. +# These ensure that Python-generated handles always have the lowest bit set +_UNIFFI_HANDLEMAP_INITIAL = 1 +_UNIFFI_HANDLEMAP_DELTA = 2 + +class _UniffiHandleMap: + """ + A map where inserting, getting and removing data is synchronized with a lock. + """ + + def __init__(self): + # type Handle = int + self._map = {} # type: Dict[Handle, Any] + self._lock = threading.Lock() + self._counter = _UNIFFI_HANDLEMAP_INITIAL + + def insert(self, obj): + with self._lock: + return self._insert(obj) + + """Low-level insert, this assumes `self._lock` is held.""" + def _insert(self, obj): + handle = self._counter + self._counter += _UNIFFI_HANDLEMAP_DELTA + self._map[handle] = obj + return handle + + def get(self, handle): + try: + with self._lock: + return self._map[handle] + except KeyError: + raise InternalError(f"_UniffiHandleMap.get: Invalid handle {handle}") + + def clone(self, handle): + try: + with self._lock: + obj = self._map[handle] + return self._insert(obj) + except KeyError: + raise InternalError(f"_UniffiHandleMap.clone: Invalid handle {handle}") + + def remove(self, handle): + try: + with self._lock: + return self._map.pop(handle) + except KeyError: + raise InternalError(f"_UniffiHandleMap.remove: Invalid handle: {handle}") + + def __len__(self): + return len(self._map) +# Types conforming to `_UniffiConverterPrimitive` pass themselves directly over the FFI. +class _UniffiConverterPrimitive: + @classmethod + def lift(cls, value): + return value + + @classmethod + def lower(cls, value): + return value + +class _UniffiConverterPrimitiveInt(_UniffiConverterPrimitive): + @classmethod + def check_lower(cls, value): + try: + value = value.__index__() + except Exception: + raise TypeError("'{}' object cannot be interpreted as an integer".format(type(value).__name__)) + if not isinstance(value, int): + raise TypeError("__index__ returned non-int (type {})".format(type(value).__name__)) + if not cls.VALUE_MIN <= value < cls.VALUE_MAX: + raise ValueError("{} requires {} <= value < {}".format(cls.CLASS_NAME, cls.VALUE_MIN, cls.VALUE_MAX)) + +class _UniffiConverterPrimitiveFloat(_UniffiConverterPrimitive): + @classmethod + def check_lower(cls, value): + try: + value = value.__float__() + except Exception: + raise TypeError("must be real number, not {}".format(type(value).__name__)) + if not isinstance(value, float): + raise TypeError("__float__ returned non-float (type {})".format(type(value).__name__)) + +# Helper class for wrapper types that will always go through a _UniffiRustBuffer. +# Classes should inherit from this and implement the `read` and `write` static methods. +class _UniffiConverterRustBuffer: + @classmethod + def lift(cls, rbuf): + with rbuf.consume_with_stream() as stream: + return cls.read(stream) + + @classmethod + def lower(cls, value): + with _UniffiRustBuffer.alloc_with_builder() as builder: + cls.write(value, builder) + return builder.finalize() + +# Contains loading, initialization code, and the FFI Function declarations. +# Define some ctypes FFI types that we use in the library + +""" +Function pointer for a Rust task, which a callback function that takes a opaque pointer +""" +_UNIFFI_RUST_TASK = ctypes.CFUNCTYPE(None, ctypes.c_void_p, ctypes.c_int8) + +def _uniffi_future_callback_t(return_type): + """ + Factory function to create callback function types for async functions + """ + return ctypes.CFUNCTYPE(None, ctypes.c_uint64, return_type, _UniffiRustCallStatus) + +def _uniffi_load_indirect(): + """ + This is how we find and load the dynamic library provided by the component. + For now we just look it up by name. + """ + if sys.platform == "darwin": + libname = "lib{}.dylib" + elif sys.platform.startswith("win"): + # As of python3.8, ctypes does not seem to search $PATH when loading DLLs. + # We could use `os.add_dll_directory` to configure the search path, but + # it doesn't feel right to mess with application-wide settings. Let's + # assume that the `.dll` is next to the `.py` file and load by full path. + libname = os.path.join( + os.path.dirname(__file__), + "{}.dll", + ) + else: + # Anything else must be an ELF platform - Linux, *BSD, Solaris/illumos + libname = "lib{}.so" + + libname = libname.format("dojo_c") + path = os.path.join(os.path.dirname(__file__), libname) + lib = ctypes.cdll.LoadLibrary(path) + return lib + +def _uniffi_check_contract_api_version(lib): + # Get the bindings contract version from our ComponentInterface + bindings_contract_version = 30 + # Get the scaffolding contract version by calling the into the dylib + scaffolding_contract_version = lib.ffi_dojo_c_uniffi_contract_version() + if bindings_contract_version != scaffolding_contract_version: + raise InternalError("UniFFI contract version mismatch: try cleaning and rebuilding your project") + +def _uniffi_check_api_checksums(lib): + pass + +# A ctypes library to expose the extern-C FFI definitions. +# This is an implementation detail which will be called internally by the public API. + +_UniffiLib = _uniffi_load_indirect() +_UniffiLib.ffi_dojo_c_rustbuffer_alloc.argtypes = ( + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rustbuffer_alloc.restype = _UniffiRustBuffer +_UniffiLib.ffi_dojo_c_rustbuffer_from_bytes.argtypes = ( + _UniffiForeignBytes, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rustbuffer_from_bytes.restype = _UniffiRustBuffer +_UniffiLib.ffi_dojo_c_rustbuffer_free.argtypes = ( + _UniffiRustBuffer, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rustbuffer_free.restype = None +_UniffiLib.ffi_dojo_c_rustbuffer_reserve.argtypes = ( + _UniffiRustBuffer, + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rustbuffer_reserve.restype = _UniffiRustBuffer +_UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK = ctypes.CFUNCTYPE(None,ctypes.c_uint64,ctypes.c_int8, +) +_UNIFFI_FOREIGN_FUTURE_DROPPED_CALLBACK = ctypes.CFUNCTYPE(None,ctypes.c_uint64, +) +class _UniffiForeignFutureDroppedCallbackStruct(ctypes.Structure): + _fields_ = [ + ("handle", ctypes.c_uint64), + ("free", _UNIFFI_FOREIGN_FUTURE_DROPPED_CALLBACK), + ] +_UniffiLib.ffi_dojo_c_rust_future_poll_u8.argtypes = ( + ctypes.c_uint64, + _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_poll_u8.restype = None +_UniffiLib.ffi_dojo_c_rust_future_cancel_u8.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_cancel_u8.restype = None +_UniffiLib.ffi_dojo_c_rust_future_complete_u8.argtypes = ( + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rust_future_complete_u8.restype = ctypes.c_uint8 +_UniffiLib.ffi_dojo_c_rust_future_free_u8.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_free_u8.restype = None +_UniffiLib.ffi_dojo_c_rust_future_poll_i8.argtypes = ( + ctypes.c_uint64, + _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_poll_i8.restype = None +_UniffiLib.ffi_dojo_c_rust_future_cancel_i8.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_cancel_i8.restype = None +_UniffiLib.ffi_dojo_c_rust_future_complete_i8.argtypes = ( + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rust_future_complete_i8.restype = ctypes.c_int8 +_UniffiLib.ffi_dojo_c_rust_future_free_i8.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_free_i8.restype = None +_UniffiLib.ffi_dojo_c_rust_future_poll_u16.argtypes = ( + ctypes.c_uint64, + _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_poll_u16.restype = None +_UniffiLib.ffi_dojo_c_rust_future_cancel_u16.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_cancel_u16.restype = None +_UniffiLib.ffi_dojo_c_rust_future_complete_u16.argtypes = ( + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rust_future_complete_u16.restype = ctypes.c_uint16 +_UniffiLib.ffi_dojo_c_rust_future_free_u16.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_free_u16.restype = None +_UniffiLib.ffi_dojo_c_rust_future_poll_i16.argtypes = ( + ctypes.c_uint64, + _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_poll_i16.restype = None +_UniffiLib.ffi_dojo_c_rust_future_cancel_i16.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_cancel_i16.restype = None +_UniffiLib.ffi_dojo_c_rust_future_complete_i16.argtypes = ( + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rust_future_complete_i16.restype = ctypes.c_int16 +_UniffiLib.ffi_dojo_c_rust_future_free_i16.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_free_i16.restype = None +_UniffiLib.ffi_dojo_c_rust_future_poll_u32.argtypes = ( + ctypes.c_uint64, + _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_poll_u32.restype = None +_UniffiLib.ffi_dojo_c_rust_future_cancel_u32.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_cancel_u32.restype = None +_UniffiLib.ffi_dojo_c_rust_future_complete_u32.argtypes = ( + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rust_future_complete_u32.restype = ctypes.c_uint32 +_UniffiLib.ffi_dojo_c_rust_future_free_u32.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_free_u32.restype = None +_UniffiLib.ffi_dojo_c_rust_future_poll_i32.argtypes = ( + ctypes.c_uint64, + _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_poll_i32.restype = None +_UniffiLib.ffi_dojo_c_rust_future_cancel_i32.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_cancel_i32.restype = None +_UniffiLib.ffi_dojo_c_rust_future_complete_i32.argtypes = ( + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rust_future_complete_i32.restype = ctypes.c_int32 +_UniffiLib.ffi_dojo_c_rust_future_free_i32.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_free_i32.restype = None +_UniffiLib.ffi_dojo_c_rust_future_poll_u64.argtypes = ( + ctypes.c_uint64, + _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_poll_u64.restype = None +_UniffiLib.ffi_dojo_c_rust_future_cancel_u64.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_cancel_u64.restype = None +_UniffiLib.ffi_dojo_c_rust_future_complete_u64.argtypes = ( + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rust_future_complete_u64.restype = ctypes.c_uint64 +_UniffiLib.ffi_dojo_c_rust_future_free_u64.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_free_u64.restype = None +_UniffiLib.ffi_dojo_c_rust_future_poll_i64.argtypes = ( + ctypes.c_uint64, + _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_poll_i64.restype = None +_UniffiLib.ffi_dojo_c_rust_future_cancel_i64.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_cancel_i64.restype = None +_UniffiLib.ffi_dojo_c_rust_future_complete_i64.argtypes = ( + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rust_future_complete_i64.restype = ctypes.c_int64 +_UniffiLib.ffi_dojo_c_rust_future_free_i64.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_free_i64.restype = None +_UniffiLib.ffi_dojo_c_rust_future_poll_f32.argtypes = ( + ctypes.c_uint64, + _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_poll_f32.restype = None +_UniffiLib.ffi_dojo_c_rust_future_cancel_f32.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_cancel_f32.restype = None +_UniffiLib.ffi_dojo_c_rust_future_complete_f32.argtypes = ( + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rust_future_complete_f32.restype = ctypes.c_float +_UniffiLib.ffi_dojo_c_rust_future_free_f32.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_free_f32.restype = None +_UniffiLib.ffi_dojo_c_rust_future_poll_f64.argtypes = ( + ctypes.c_uint64, + _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_poll_f64.restype = None +_UniffiLib.ffi_dojo_c_rust_future_cancel_f64.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_cancel_f64.restype = None +_UniffiLib.ffi_dojo_c_rust_future_complete_f64.argtypes = ( + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rust_future_complete_f64.restype = ctypes.c_double +_UniffiLib.ffi_dojo_c_rust_future_free_f64.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_free_f64.restype = None +_UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer.argtypes = ( + ctypes.c_uint64, + _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer.restype = None +_UniffiLib.ffi_dojo_c_rust_future_cancel_rust_buffer.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_cancel_rust_buffer.restype = None +_UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer.argtypes = ( + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer.restype = _UniffiRustBuffer +_UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer.restype = None +_UniffiLib.ffi_dojo_c_rust_future_poll_void.argtypes = ( + ctypes.c_uint64, + _UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK, + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_poll_void.restype = None +_UniffiLib.ffi_dojo_c_rust_future_cancel_void.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_cancel_void.restype = None +_UniffiLib.ffi_dojo_c_rust_future_complete_void.argtypes = ( + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.ffi_dojo_c_rust_future_complete_void.restype = None +_UniffiLib.ffi_dojo_c_rust_future_free_void.argtypes = ( + ctypes.c_uint64, +) +_UniffiLib.ffi_dojo_c_rust_future_free_void.restype = None +_UniffiLib.ffi_dojo_c_uniffi_contract_version.argtypes = ( +) +_UniffiLib.ffi_dojo_c_uniffi_contract_version.restype = ctypes.c_uint32 + +_uniffi_check_contract_api_version(_UniffiLib) +# _uniffi_check_api_checksums(_UniffiLib) + + + +# Public interface members begin here. + + +class _UniffiFfiConverterString: + @staticmethod + def check_lower(value): + if not isinstance(value, str): + raise TypeError("argument must be str, not {}".format(type(value).__name__)) + return value + + @staticmethod + def read(buf): + size = buf.read_i32() + if size < 0: + raise InternalError("Unexpected negative string length") + utf8_bytes = buf.read(size) + return utf8_bytes.decode("utf-8") + + @staticmethod + def write(value, buf): + utf8_bytes = value.encode("utf-8") + buf.write_i32(len(utf8_bytes)) + buf.write(utf8_bytes) + + @staticmethod + def lift(buf): + with buf.consume_with_stream() as stream: + return stream.read(stream.remaining()).decode("utf-8") + + @staticmethod + def lower(value): + with _UniffiRustBuffer.alloc_with_builder() as builder: + builder.write(value.encode("utf-8")) + return builder.finalize() + + +class _UniffiFfiConverterTypeFieldElement: + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value, buf) + + @staticmethod + def read(buf): + return _UniffiFfiConverterString.read(buf) + + @staticmethod + def lift(value): + return _UniffiFfiConverterString.lift(value) + + @staticmethod + def check_lower(value): + return _UniffiFfiConverterString.check_lower(value) + + @staticmethod + def lower(value): + return _UniffiFfiConverterString.lower(value) + + +FieldElement = str + +class _UniffiFfiConverterBoolean: + @classmethod + def check_lower(cls, value): + return not not value + + @classmethod + def lower(cls, value): + return 1 if value else 0 + + @staticmethod + def lift(value): + return value != 0 + + @classmethod + def read(cls, buf): + return cls.lift(buf.read_u8()) + + @classmethod + def write(cls, value, buf): + buf.write_u8(value) + +class _UniffiFfiConverterUInt32(_UniffiConverterPrimitiveInt): + CLASS_NAME = "u32" + VALUE_MIN = 0 + VALUE_MAX = 2**32 + + @staticmethod + def read(buf): + return buf.read_u32() + + @staticmethod + def write(value, buf): + buf.write_u32(value) + +class _UniffiFfiConverterFloat64(_UniffiConverterPrimitiveFloat): + @staticmethod + def read(buf): + return buf.read_double() + + @staticmethod + def write(value, buf): + buf.write_double(value) + +class _UniffiFfiConverterUInt64(_UniffiConverterPrimitiveInt): + CLASS_NAME = "u64" + VALUE_MIN = 0 + VALUE_MAX = 2**64 + + @staticmethod + def read(buf): + return buf.read_u64() + + @staticmethod + def write(value, buf): + buf.write_u64(value) + +@dataclass +class AchievementTask: + def __init__(self, *, task_id:str, description:str, total:int, total_completions:int, completion_rate:float, created_at:int): + self.task_id = task_id + self.description = description + self.total = total + self.total_completions = total_completions + self.completion_rate = completion_rate + self.created_at = created_at + + + + + def __str__(self): + return "AchievementTask(task_id={}, description={}, total={}, total_completions={}, completion_rate={}, created_at={})".format(self.task_id, self.description, self.total, self.total_completions, self.completion_rate, self.created_at) + def __eq__(self, other): + if self.task_id != other.task_id: + return False + if self.description != other.description: + return False + if self.total != other.total: + return False + if self.total_completions != other.total_completions: + return False + if self.completion_rate != other.completion_rate: + return False + if self.created_at != other.created_at: + return False + return True + +class _UniffiFfiConverterTypeAchievementTask(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return AchievementTask( + task_id=_UniffiFfiConverterString.read(buf), + description=_UniffiFfiConverterString.read(buf), + total=_UniffiFfiConverterUInt32.read(buf), + total_completions=_UniffiFfiConverterUInt32.read(buf), + completion_rate=_UniffiFfiConverterFloat64.read(buf), + created_at=_UniffiFfiConverterUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.task_id) + _UniffiFfiConverterString.check_lower(value.description) + _UniffiFfiConverterUInt32.check_lower(value.total) + _UniffiFfiConverterUInt32.check_lower(value.total_completions) + _UniffiFfiConverterFloat64.check_lower(value.completion_rate) + _UniffiFfiConverterUInt64.check_lower(value.created_at) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.task_id, buf) + _UniffiFfiConverterString.write(value.description, buf) + _UniffiFfiConverterUInt32.write(value.total, buf) + _UniffiFfiConverterUInt32.write(value.total_completions, buf) + _UniffiFfiConverterFloat64.write(value.completion_rate, buf) + _UniffiFfiConverterUInt64.write(value.created_at, buf) + +class _UniffiFfiConverterSequenceTypeAchievementTask(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeAchievementTask.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeAchievementTask.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeAchievementTask.read(buf) for i in range(count) + ] + +class _UniffiFfiConverterOptionalString(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiFfiConverterString.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiFfiConverterString.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiFfiConverterString.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + +@dataclass +class Achievement: + def __init__(self, *, id:str, world_address:FieldElement, namespace:str, entity_id:str, hidden:bool, index:int, points:int, start:str, end:str, group:str, icon:str, title:str, description:str, tasks:typing.List[AchievementTask], data:typing.Optional[str], total_completions:int, completion_rate:float, created_at:int, updated_at:int): + self.id = id + self.world_address = world_address + self.namespace = namespace + self.entity_id = entity_id + self.hidden = hidden + self.index = index + self.points = points + self.start = start + self.end = end + self.group = group + self.icon = icon + self.title = title + self.description = description + self.tasks = tasks + self.data = data + self.total_completions = total_completions + self.completion_rate = completion_rate + self.created_at = created_at + self.updated_at = updated_at + + + + + def __str__(self): + return "Achievement(id={}, world_address={}, namespace={}, entity_id={}, hidden={}, index={}, points={}, start={}, end={}, group={}, icon={}, title={}, description={}, tasks={}, data={}, total_completions={}, completion_rate={}, created_at={}, updated_at={})".format(self.id, self.world_address, self.namespace, self.entity_id, self.hidden, self.index, self.points, self.start, self.end, self.group, self.icon, self.title, self.description, self.tasks, self.data, self.total_completions, self.completion_rate, self.created_at, self.updated_at) + def __eq__(self, other): + if self.id != other.id: + return False + if self.world_address != other.world_address: + return False + if self.namespace != other.namespace: + return False + if self.entity_id != other.entity_id: + return False + if self.hidden != other.hidden: + return False + if self.index != other.index: + return False + if self.points != other.points: + return False + if self.start != other.start: + return False + if self.end != other.end: + return False + if self.group != other.group: + return False + if self.icon != other.icon: + return False + if self.title != other.title: + return False + if self.description != other.description: + return False + if self.tasks != other.tasks: + return False + if self.data != other.data: + return False + if self.total_completions != other.total_completions: + return False + if self.completion_rate != other.completion_rate: + return False + if self.created_at != other.created_at: + return False + if self.updated_at != other.updated_at: + return False + return True + +class _UniffiFfiConverterTypeAchievement(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Achievement( + id=_UniffiFfiConverterString.read(buf), + world_address=_UniffiFfiConverterTypeFieldElement.read(buf), + namespace=_UniffiFfiConverterString.read(buf), + entity_id=_UniffiFfiConverterString.read(buf), + hidden=_UniffiFfiConverterBoolean.read(buf), + index=_UniffiFfiConverterUInt32.read(buf), + points=_UniffiFfiConverterUInt32.read(buf), + start=_UniffiFfiConverterString.read(buf), + end=_UniffiFfiConverterString.read(buf), + group=_UniffiFfiConverterString.read(buf), + icon=_UniffiFfiConverterString.read(buf), + title=_UniffiFfiConverterString.read(buf), + description=_UniffiFfiConverterString.read(buf), + tasks=_UniffiFfiConverterSequenceTypeAchievementTask.read(buf), + data=_UniffiFfiConverterOptionalString.read(buf), + total_completions=_UniffiFfiConverterUInt32.read(buf), + completion_rate=_UniffiFfiConverterFloat64.read(buf), + created_at=_UniffiFfiConverterUInt64.read(buf), + updated_at=_UniffiFfiConverterUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.id) + _UniffiFfiConverterTypeFieldElement.check_lower(value.world_address) + _UniffiFfiConverterString.check_lower(value.namespace) + _UniffiFfiConverterString.check_lower(value.entity_id) + _UniffiFfiConverterBoolean.check_lower(value.hidden) + _UniffiFfiConverterUInt32.check_lower(value.index) + _UniffiFfiConverterUInt32.check_lower(value.points) + _UniffiFfiConverterString.check_lower(value.start) + _UniffiFfiConverterString.check_lower(value.end) + _UniffiFfiConverterString.check_lower(value.group) + _UniffiFfiConverterString.check_lower(value.icon) + _UniffiFfiConverterString.check_lower(value.title) + _UniffiFfiConverterString.check_lower(value.description) + _UniffiFfiConverterSequenceTypeAchievementTask.check_lower(value.tasks) + _UniffiFfiConverterOptionalString.check_lower(value.data) + _UniffiFfiConverterUInt32.check_lower(value.total_completions) + _UniffiFfiConverterFloat64.check_lower(value.completion_rate) + _UniffiFfiConverterUInt64.check_lower(value.created_at) + _UniffiFfiConverterUInt64.check_lower(value.updated_at) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.id, buf) + _UniffiFfiConverterTypeFieldElement.write(value.world_address, buf) + _UniffiFfiConverterString.write(value.namespace, buf) + _UniffiFfiConverterString.write(value.entity_id, buf) + _UniffiFfiConverterBoolean.write(value.hidden, buf) + _UniffiFfiConverterUInt32.write(value.index, buf) + _UniffiFfiConverterUInt32.write(value.points, buf) + _UniffiFfiConverterString.write(value.start, buf) + _UniffiFfiConverterString.write(value.end, buf) + _UniffiFfiConverterString.write(value.group, buf) + _UniffiFfiConverterString.write(value.icon, buf) + _UniffiFfiConverterString.write(value.title, buf) + _UniffiFfiConverterString.write(value.description, buf) + _UniffiFfiConverterSequenceTypeAchievementTask.write(value.tasks, buf) + _UniffiFfiConverterOptionalString.write(value.data, buf) + _UniffiFfiConverterUInt32.write(value.total_completions, buf) + _UniffiFfiConverterFloat64.write(value.completion_rate, buf) + _UniffiFfiConverterUInt64.write(value.created_at, buf) + _UniffiFfiConverterUInt64.write(value.updated_at, buf) + +class _UniffiFfiConverterOptionalUInt64(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiFfiConverterUInt64.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiFfiConverterUInt64.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiFfiConverterUInt64.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + +@dataclass +class AchievementProgression: + def __init__(self, *, id:str, achievement_id:str, task_id:str, world_address:FieldElement, namespace:str, player_id:FieldElement, count:int, completed:bool, completed_at:typing.Optional[int], created_at:int, updated_at:int): + self.id = id + self.achievement_id = achievement_id + self.task_id = task_id + self.world_address = world_address + self.namespace = namespace + self.player_id = player_id + self.count = count + self.completed = completed + self.completed_at = completed_at + self.created_at = created_at + self.updated_at = updated_at + + + + + def __str__(self): + return "AchievementProgression(id={}, achievement_id={}, task_id={}, world_address={}, namespace={}, player_id={}, count={}, completed={}, completed_at={}, created_at={}, updated_at={})".format(self.id, self.achievement_id, self.task_id, self.world_address, self.namespace, self.player_id, self.count, self.completed, self.completed_at, self.created_at, self.updated_at) + def __eq__(self, other): + if self.id != other.id: + return False + if self.achievement_id != other.achievement_id: + return False + if self.task_id != other.task_id: + return False + if self.world_address != other.world_address: + return False + if self.namespace != other.namespace: + return False + if self.player_id != other.player_id: + return False + if self.count != other.count: + return False + if self.completed != other.completed: + return False + if self.completed_at != other.completed_at: + return False + if self.created_at != other.created_at: + return False + if self.updated_at != other.updated_at: + return False + return True + +class _UniffiFfiConverterTypeAchievementProgression(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return AchievementProgression( + id=_UniffiFfiConverterString.read(buf), + achievement_id=_UniffiFfiConverterString.read(buf), + task_id=_UniffiFfiConverterString.read(buf), + world_address=_UniffiFfiConverterTypeFieldElement.read(buf), + namespace=_UniffiFfiConverterString.read(buf), + player_id=_UniffiFfiConverterTypeFieldElement.read(buf), + count=_UniffiFfiConverterUInt32.read(buf), + completed=_UniffiFfiConverterBoolean.read(buf), + completed_at=_UniffiFfiConverterOptionalUInt64.read(buf), + created_at=_UniffiFfiConverterUInt64.read(buf), + updated_at=_UniffiFfiConverterUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.id) + _UniffiFfiConverterString.check_lower(value.achievement_id) + _UniffiFfiConverterString.check_lower(value.task_id) + _UniffiFfiConverterTypeFieldElement.check_lower(value.world_address) + _UniffiFfiConverterString.check_lower(value.namespace) + _UniffiFfiConverterTypeFieldElement.check_lower(value.player_id) + _UniffiFfiConverterUInt32.check_lower(value.count) + _UniffiFfiConverterBoolean.check_lower(value.completed) + _UniffiFfiConverterOptionalUInt64.check_lower(value.completed_at) + _UniffiFfiConverterUInt64.check_lower(value.created_at) + _UniffiFfiConverterUInt64.check_lower(value.updated_at) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.id, buf) + _UniffiFfiConverterString.write(value.achievement_id, buf) + _UniffiFfiConverterString.write(value.task_id, buf) + _UniffiFfiConverterTypeFieldElement.write(value.world_address, buf) + _UniffiFfiConverterString.write(value.namespace, buf) + _UniffiFfiConverterTypeFieldElement.write(value.player_id, buf) + _UniffiFfiConverterUInt32.write(value.count, buf) + _UniffiFfiConverterBoolean.write(value.completed, buf) + _UniffiFfiConverterOptionalUInt64.write(value.completed_at, buf) + _UniffiFfiConverterUInt64.write(value.created_at, buf) + _UniffiFfiConverterUInt64.write(value.updated_at, buf) + +class _UniffiFfiConverterSequenceTypeFieldElement(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeFieldElement.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeFieldElement.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeFieldElement.read(buf) for i in range(count) + ] + +class _UniffiFfiConverterSequenceString(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterString.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterString.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterString.read(buf) for i in range(count) + ] + +class _UniffiFfiConverterOptionalBoolean(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiFfiConverterBoolean.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiFfiConverterBoolean.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiFfiConverterBoolean.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + +class _UniffiFfiConverterOptionalUInt32(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiFfiConverterUInt32.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiFfiConverterUInt32.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiFfiConverterUInt32.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + + + + + + +class PaginationDirection(enum.Enum): + + FORWARD = 0 + + BACKWARD = 1 + + + +class _UniffiFfiConverterTypePaginationDirection(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return PaginationDirection.FORWARD + if variant == 2: + return PaginationDirection.BACKWARD + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == PaginationDirection.FORWARD: + return + if value == PaginationDirection.BACKWARD: + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value == PaginationDirection.FORWARD: + buf.write_i32(1) + if value == PaginationDirection.BACKWARD: + buf.write_i32(2) + + + + + + + + +class OrderDirection(enum.Enum): + + ASC = 0 + + DESC = 1 + + + +class _UniffiFfiConverterTypeOrderDirection(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return OrderDirection.ASC + if variant == 2: + return OrderDirection.DESC + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == OrderDirection.ASC: + return + if value == OrderDirection.DESC: + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value == OrderDirection.ASC: + buf.write_i32(1) + if value == OrderDirection.DESC: + buf.write_i32(2) + + + +@dataclass +class OrderBy: + def __init__(self, *, field:str, direction:OrderDirection): + self.field = field + self.direction = direction + + + + + def __str__(self): + return "OrderBy(field={}, direction={})".format(self.field, self.direction) + def __eq__(self, other): + if self.field != other.field: + return False + if self.direction != other.direction: + return False + return True + +class _UniffiFfiConverterTypeOrderBy(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return OrderBy( + field=_UniffiFfiConverterString.read(buf), + direction=_UniffiFfiConverterTypeOrderDirection.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.field) + _UniffiFfiConverterTypeOrderDirection.check_lower(value.direction) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.field, buf) + _UniffiFfiConverterTypeOrderDirection.write(value.direction, buf) + +class _UniffiFfiConverterSequenceTypeOrderBy(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeOrderBy.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeOrderBy.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeOrderBy.read(buf) for i in range(count) + ] + +@dataclass +class Pagination: + def __init__(self, *, cursor:typing.Optional[str], limit:typing.Optional[int], direction:PaginationDirection, order_by:typing.List[OrderBy]): + self.cursor = cursor + self.limit = limit + self.direction = direction + self.order_by = order_by + + + + + def __str__(self): + return "Pagination(cursor={}, limit={}, direction={}, order_by={})".format(self.cursor, self.limit, self.direction, self.order_by) + def __eq__(self, other): + if self.cursor != other.cursor: + return False + if self.limit != other.limit: + return False + if self.direction != other.direction: + return False + if self.order_by != other.order_by: + return False + return True + +class _UniffiFfiConverterTypePagination(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Pagination( + cursor=_UniffiFfiConverterOptionalString.read(buf), + limit=_UniffiFfiConverterOptionalUInt32.read(buf), + direction=_UniffiFfiConverterTypePaginationDirection.read(buf), + order_by=_UniffiFfiConverterSequenceTypeOrderBy.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterOptionalString.check_lower(value.cursor) + _UniffiFfiConverterOptionalUInt32.check_lower(value.limit) + _UniffiFfiConverterTypePaginationDirection.check_lower(value.direction) + _UniffiFfiConverterSequenceTypeOrderBy.check_lower(value.order_by) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterOptionalString.write(value.cursor, buf) + _UniffiFfiConverterOptionalUInt32.write(value.limit, buf) + _UniffiFfiConverterTypePaginationDirection.write(value.direction, buf) + _UniffiFfiConverterSequenceTypeOrderBy.write(value.order_by, buf) + +@dataclass +class AchievementQuery: + def __init__(self, *, world_addresses:typing.List[FieldElement], namespaces:typing.List[str], hidden:typing.Optional[bool], pagination:Pagination): + self.world_addresses = world_addresses + self.namespaces = namespaces + self.hidden = hidden + self.pagination = pagination + + + + + def __str__(self): + return "AchievementQuery(world_addresses={}, namespaces={}, hidden={}, pagination={})".format(self.world_addresses, self.namespaces, self.hidden, self.pagination) + def __eq__(self, other): + if self.world_addresses != other.world_addresses: + return False + if self.namespaces != other.namespaces: + return False + if self.hidden != other.hidden: + return False + if self.pagination != other.pagination: + return False + return True + +class _UniffiFfiConverterTypeAchievementQuery(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return AchievementQuery( + world_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + namespaces=_UniffiFfiConverterSequenceString.read(buf), + hidden=_UniffiFfiConverterOptionalBoolean.read(buf), + pagination=_UniffiFfiConverterTypePagination.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.world_addresses) + _UniffiFfiConverterSequenceString.check_lower(value.namespaces) + _UniffiFfiConverterOptionalBoolean.check_lower(value.hidden) + _UniffiFfiConverterTypePagination.check_lower(value.pagination) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeFieldElement.write(value.world_addresses, buf) + _UniffiFfiConverterSequenceString.write(value.namespaces, buf) + _UniffiFfiConverterOptionalBoolean.write(value.hidden, buf) + _UniffiFfiConverterTypePagination.write(value.pagination, buf) + +@dataclass +class ActionCount: + def __init__(self, *, action_name:str, count:int): + self.action_name = action_name + self.count = count + + + + + def __str__(self): + return "ActionCount(action_name={}, count={})".format(self.action_name, self.count) + def __eq__(self, other): + if self.action_name != other.action_name: + return False + if self.count != other.count: + return False + return True + +class _UniffiFfiConverterTypeActionCount(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return ActionCount( + action_name=_UniffiFfiConverterString.read(buf), + count=_UniffiFfiConverterUInt32.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.action_name) + _UniffiFfiConverterUInt32.check_lower(value.count) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.action_name, buf) + _UniffiFfiConverterUInt32.write(value.count, buf) + +class _UniffiFfiConverterSequenceTypeActionCount(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeActionCount.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeActionCount.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeActionCount.read(buf) for i in range(count) + ] + +@dataclass +class Activity: + def __init__(self, *, id:str, world_address:FieldElement, namespace:str, caller_address:FieldElement, session_start:int, session_end:int, action_count:int, actions:typing.List[ActionCount], updated_at:int): + self.id = id + self.world_address = world_address + self.namespace = namespace + self.caller_address = caller_address + self.session_start = session_start + self.session_end = session_end + self.action_count = action_count + self.actions = actions + self.updated_at = updated_at + + + + + def __str__(self): + return "Activity(id={}, world_address={}, namespace={}, caller_address={}, session_start={}, session_end={}, action_count={}, actions={}, updated_at={})".format(self.id, self.world_address, self.namespace, self.caller_address, self.session_start, self.session_end, self.action_count, self.actions, self.updated_at) + def __eq__(self, other): + if self.id != other.id: + return False + if self.world_address != other.world_address: + return False + if self.namespace != other.namespace: + return False + if self.caller_address != other.caller_address: + return False + if self.session_start != other.session_start: + return False + if self.session_end != other.session_end: + return False + if self.action_count != other.action_count: + return False + if self.actions != other.actions: + return False + if self.updated_at != other.updated_at: + return False + return True + +class _UniffiFfiConverterTypeActivity(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Activity( + id=_UniffiFfiConverterString.read(buf), + world_address=_UniffiFfiConverterTypeFieldElement.read(buf), + namespace=_UniffiFfiConverterString.read(buf), + caller_address=_UniffiFfiConverterTypeFieldElement.read(buf), + session_start=_UniffiFfiConverterUInt64.read(buf), + session_end=_UniffiFfiConverterUInt64.read(buf), + action_count=_UniffiFfiConverterUInt32.read(buf), + actions=_UniffiFfiConverterSequenceTypeActionCount.read(buf), + updated_at=_UniffiFfiConverterUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.id) + _UniffiFfiConverterTypeFieldElement.check_lower(value.world_address) + _UniffiFfiConverterString.check_lower(value.namespace) + _UniffiFfiConverterTypeFieldElement.check_lower(value.caller_address) + _UniffiFfiConverterUInt64.check_lower(value.session_start) + _UniffiFfiConverterUInt64.check_lower(value.session_end) + _UniffiFfiConverterUInt32.check_lower(value.action_count) + _UniffiFfiConverterSequenceTypeActionCount.check_lower(value.actions) + _UniffiFfiConverterUInt64.check_lower(value.updated_at) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.id, buf) + _UniffiFfiConverterTypeFieldElement.write(value.world_address, buf) + _UniffiFfiConverterString.write(value.namespace, buf) + _UniffiFfiConverterTypeFieldElement.write(value.caller_address, buf) + _UniffiFfiConverterUInt64.write(value.session_start, buf) + _UniffiFfiConverterUInt64.write(value.session_end, buf) + _UniffiFfiConverterUInt32.write(value.action_count, buf) + _UniffiFfiConverterSequenceTypeActionCount.write(value.actions, buf) + _UniffiFfiConverterUInt64.write(value.updated_at, buf) + +@dataclass +class ActivityQuery: + def __init__(self, *, world_addresses:typing.List[FieldElement], namespaces:typing.List[str], caller_addresses:typing.List[FieldElement], from_time:typing.Optional[int], to_time:typing.Optional[int], pagination:Pagination): + self.world_addresses = world_addresses + self.namespaces = namespaces + self.caller_addresses = caller_addresses + self.from_time = from_time + self.to_time = to_time + self.pagination = pagination + + + + + def __str__(self): + return "ActivityQuery(world_addresses={}, namespaces={}, caller_addresses={}, from_time={}, to_time={}, pagination={})".format(self.world_addresses, self.namespaces, self.caller_addresses, self.from_time, self.to_time, self.pagination) + def __eq__(self, other): + if self.world_addresses != other.world_addresses: + return False + if self.namespaces != other.namespaces: + return False + if self.caller_addresses != other.caller_addresses: + return False + if self.from_time != other.from_time: + return False + if self.to_time != other.to_time: + return False + if self.pagination != other.pagination: + return False + return True + +class _UniffiFfiConverterTypeActivityQuery(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return ActivityQuery( + world_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + namespaces=_UniffiFfiConverterSequenceString.read(buf), + caller_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + from_time=_UniffiFfiConverterOptionalUInt64.read(buf), + to_time=_UniffiFfiConverterOptionalUInt64.read(buf), + pagination=_UniffiFfiConverterTypePagination.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.world_addresses) + _UniffiFfiConverterSequenceString.check_lower(value.namespaces) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.caller_addresses) + _UniffiFfiConverterOptionalUInt64.check_lower(value.from_time) + _UniffiFfiConverterOptionalUInt64.check_lower(value.to_time) + _UniffiFfiConverterTypePagination.check_lower(value.pagination) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeFieldElement.write(value.world_addresses, buf) + _UniffiFfiConverterSequenceString.write(value.namespaces, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.caller_addresses, buf) + _UniffiFfiConverterOptionalUInt64.write(value.from_time, buf) + _UniffiFfiConverterOptionalUInt64.write(value.to_time, buf) + _UniffiFfiConverterTypePagination.write(value.pagination, buf) + + +class _UniffiFfiConverterTypeU256: + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value, buf) + + @staticmethod + def read(buf): + return _UniffiFfiConverterString.read(buf) + + @staticmethod + def lift(value): + return _UniffiFfiConverterString.lift(value) + + @staticmethod + def check_lower(value): + return _UniffiFfiConverterString.check_lower(value) + + @staticmethod + def lower(value): + return _UniffiFfiConverterString.lower(value) + + +U256 = str + +@dataclass +class AggregationEntry: + def __init__(self, *, id:str, aggregator_id:str, entity_id:str, value:U256, display_value:str, position:int, model_id:str, created_at:int, updated_at:int): + self.id = id + self.aggregator_id = aggregator_id + self.entity_id = entity_id + self.value = value + self.display_value = display_value + self.position = position + self.model_id = model_id + self.created_at = created_at + self.updated_at = updated_at + + + + + def __str__(self): + return "AggregationEntry(id={}, aggregator_id={}, entity_id={}, value={}, display_value={}, position={}, model_id={}, created_at={}, updated_at={})".format(self.id, self.aggregator_id, self.entity_id, self.value, self.display_value, self.position, self.model_id, self.created_at, self.updated_at) + def __eq__(self, other): + if self.id != other.id: + return False + if self.aggregator_id != other.aggregator_id: + return False + if self.entity_id != other.entity_id: + return False + if self.value != other.value: + return False + if self.display_value != other.display_value: + return False + if self.position != other.position: + return False + if self.model_id != other.model_id: + return False + if self.created_at != other.created_at: + return False + if self.updated_at != other.updated_at: + return False + return True + +class _UniffiFfiConverterTypeAggregationEntry(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return AggregationEntry( + id=_UniffiFfiConverterString.read(buf), + aggregator_id=_UniffiFfiConverterString.read(buf), + entity_id=_UniffiFfiConverterString.read(buf), + value=_UniffiFfiConverterTypeU256.read(buf), + display_value=_UniffiFfiConverterString.read(buf), + position=_UniffiFfiConverterUInt64.read(buf), + model_id=_UniffiFfiConverterString.read(buf), + created_at=_UniffiFfiConverterUInt64.read(buf), + updated_at=_UniffiFfiConverterUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.id) + _UniffiFfiConverterString.check_lower(value.aggregator_id) + _UniffiFfiConverterString.check_lower(value.entity_id) + _UniffiFfiConverterTypeU256.check_lower(value.value) + _UniffiFfiConverterString.check_lower(value.display_value) + _UniffiFfiConverterUInt64.check_lower(value.position) + _UniffiFfiConverterString.check_lower(value.model_id) + _UniffiFfiConverterUInt64.check_lower(value.created_at) + _UniffiFfiConverterUInt64.check_lower(value.updated_at) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.id, buf) + _UniffiFfiConverterString.write(value.aggregator_id, buf) + _UniffiFfiConverterString.write(value.entity_id, buf) + _UniffiFfiConverterTypeU256.write(value.value, buf) + _UniffiFfiConverterString.write(value.display_value, buf) + _UniffiFfiConverterUInt64.write(value.position, buf) + _UniffiFfiConverterString.write(value.model_id, buf) + _UniffiFfiConverterUInt64.write(value.created_at, buf) + _UniffiFfiConverterUInt64.write(value.updated_at, buf) + +@dataclass +class AggregationQuery: + def __init__(self, *, aggregator_ids:typing.List[str], entity_ids:typing.List[str], pagination:Pagination): + self.aggregator_ids = aggregator_ids + self.entity_ids = entity_ids + self.pagination = pagination + + + + + def __str__(self): + return "AggregationQuery(aggregator_ids={}, entity_ids={}, pagination={})".format(self.aggregator_ids, self.entity_ids, self.pagination) + def __eq__(self, other): + if self.aggregator_ids != other.aggregator_ids: + return False + if self.entity_ids != other.entity_ids: + return False + if self.pagination != other.pagination: + return False + return True + +class _UniffiFfiConverterTypeAggregationQuery(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return AggregationQuery( + aggregator_ids=_UniffiFfiConverterSequenceString.read(buf), + entity_ids=_UniffiFfiConverterSequenceString.read(buf), + pagination=_UniffiFfiConverterTypePagination.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceString.check_lower(value.aggregator_ids) + _UniffiFfiConverterSequenceString.check_lower(value.entity_ids) + _UniffiFfiConverterTypePagination.check_lower(value.pagination) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceString.write(value.aggregator_ids, buf) + _UniffiFfiConverterSequenceString.write(value.entity_ids, buf) + _UniffiFfiConverterTypePagination.write(value.pagination, buf) + +@dataclass +class AttributeFilter: + def __init__(self, *, trait_name:str, trait_value:str): + self.trait_name = trait_name + self.trait_value = trait_value + + + + + def __str__(self): + return "AttributeFilter(trait_name={}, trait_value={})".format(self.trait_name, self.trait_value) + def __eq__(self, other): + if self.trait_name != other.trait_name: + return False + if self.trait_value != other.trait_value: + return False + return True + +class _UniffiFfiConverterTypeAttributeFilter(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return AttributeFilter( + trait_name=_UniffiFfiConverterString.read(buf), + trait_value=_UniffiFfiConverterString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.trait_name) + _UniffiFfiConverterString.check_lower(value.trait_value) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.trait_name, buf) + _UniffiFfiConverterString.write(value.trait_value, buf) + + + + + + +class LogicalOperator(enum.Enum): + + AND = 0 + + OR = 1 + + + +class _UniffiFfiConverterTypeLogicalOperator(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return LogicalOperator.AND + if variant == 2: + return LogicalOperator.OR + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == LogicalOperator.AND: + return + if value == LogicalOperator.OR: + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value == LogicalOperator.AND: + buf.write_i32(1) + if value == LogicalOperator.OR: + buf.write_i32(2) + + + +class _UniffiFfiConverterOptionalTypeFieldElement(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiFfiConverterTypeFieldElement.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiFfiConverterTypeFieldElement.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiFfiConverterTypeFieldElement.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + +class _UniffiFfiConverterSequenceOptionalTypeFieldElement(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterOptionalTypeFieldElement.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterOptionalTypeFieldElement.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterOptionalTypeFieldElement.read(buf) for i in range(count) + ] + + + + + + +class PatternMatching(enum.Enum): + + FIXED_LEN = 0 + + VARIABLE_LEN = 1 + + + +class _UniffiFfiConverterTypePatternMatching(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return PatternMatching.FIXED_LEN + if variant == 2: + return PatternMatching.VARIABLE_LEN + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == PatternMatching.FIXED_LEN: + return + if value == PatternMatching.VARIABLE_LEN: + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value == PatternMatching.FIXED_LEN: + buf.write_i32(1) + if value == PatternMatching.VARIABLE_LEN: + buf.write_i32(2) + + + +@dataclass +class KeysClause: + def __init__(self, *, keys:typing.List[typing.Optional[FieldElement]], pattern_matching:PatternMatching, models:typing.List[str]): + self.keys = keys + self.pattern_matching = pattern_matching + self.models = models + + + + + def __str__(self): + return "KeysClause(keys={}, pattern_matching={}, models={})".format(self.keys, self.pattern_matching, self.models) + def __eq__(self, other): + if self.keys != other.keys: + return False + if self.pattern_matching != other.pattern_matching: + return False + if self.models != other.models: + return False + return True + +class _UniffiFfiConverterTypeKeysClause(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return KeysClause( + keys=_UniffiFfiConverterSequenceOptionalTypeFieldElement.read(buf), + pattern_matching=_UniffiFfiConverterTypePatternMatching.read(buf), + models=_UniffiFfiConverterSequenceString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceOptionalTypeFieldElement.check_lower(value.keys) + _UniffiFfiConverterTypePatternMatching.check_lower(value.pattern_matching) + _UniffiFfiConverterSequenceString.check_lower(value.models) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceOptionalTypeFieldElement.write(value.keys, buf) + _UniffiFfiConverterTypePatternMatching.write(value.pattern_matching, buf) + _UniffiFfiConverterSequenceString.write(value.models, buf) + + + + + + +class ComparisonOperator(enum.Enum): + + EQ = 0 + + NEQ = 1 + + GT = 2 + + GTE = 3 + + LT = 4 + + LTE = 5 + + IN = 6 + + NOT_IN = 7 + + CONTAINS = 8 + + CONTAINS_ALL = 9 + + CONTAINS_ANY = 10 + + ARRAY_LENGTH_EQ = 11 + + ARRAY_LENGTH_GT = 12 + + ARRAY_LENGTH_LT = 13 + + + +class _UniffiFfiConverterTypeComparisonOperator(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return ComparisonOperator.EQ + if variant == 2: + return ComparisonOperator.NEQ + if variant == 3: + return ComparisonOperator.GT + if variant == 4: + return ComparisonOperator.GTE + if variant == 5: + return ComparisonOperator.LT + if variant == 6: + return ComparisonOperator.LTE + if variant == 7: + return ComparisonOperator.IN + if variant == 8: + return ComparisonOperator.NOT_IN + if variant == 9: + return ComparisonOperator.CONTAINS + if variant == 10: + return ComparisonOperator.CONTAINS_ALL + if variant == 11: + return ComparisonOperator.CONTAINS_ANY + if variant == 12: + return ComparisonOperator.ARRAY_LENGTH_EQ + if variant == 13: + return ComparisonOperator.ARRAY_LENGTH_GT + if variant == 14: + return ComparisonOperator.ARRAY_LENGTH_LT + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == ComparisonOperator.EQ: + return + if value == ComparisonOperator.NEQ: + return + if value == ComparisonOperator.GT: + return + if value == ComparisonOperator.GTE: + return + if value == ComparisonOperator.LT: + return + if value == ComparisonOperator.LTE: + return + if value == ComparisonOperator.IN: + return + if value == ComparisonOperator.NOT_IN: + return + if value == ComparisonOperator.CONTAINS: + return + if value == ComparisonOperator.CONTAINS_ALL: + return + if value == ComparisonOperator.CONTAINS_ANY: + return + if value == ComparisonOperator.ARRAY_LENGTH_EQ: + return + if value == ComparisonOperator.ARRAY_LENGTH_GT: + return + if value == ComparisonOperator.ARRAY_LENGTH_LT: + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value == ComparisonOperator.EQ: + buf.write_i32(1) + if value == ComparisonOperator.NEQ: + buf.write_i32(2) + if value == ComparisonOperator.GT: + buf.write_i32(3) + if value == ComparisonOperator.GTE: + buf.write_i32(4) + if value == ComparisonOperator.LT: + buf.write_i32(5) + if value == ComparisonOperator.LTE: + buf.write_i32(6) + if value == ComparisonOperator.IN: + buf.write_i32(7) + if value == ComparisonOperator.NOT_IN: + buf.write_i32(8) + if value == ComparisonOperator.CONTAINS: + buf.write_i32(9) + if value == ComparisonOperator.CONTAINS_ALL: + buf.write_i32(10) + if value == ComparisonOperator.CONTAINS_ANY: + buf.write_i32(11) + if value == ComparisonOperator.ARRAY_LENGTH_EQ: + buf.write_i32(12) + if value == ComparisonOperator.ARRAY_LENGTH_GT: + buf.write_i32(13) + if value == ComparisonOperator.ARRAY_LENGTH_LT: + buf.write_i32(14) + + + +class _UniffiFfiConverterInt8(_UniffiConverterPrimitiveInt): + CLASS_NAME = "i8" + VALUE_MIN = -2**7 + VALUE_MAX = 2**7 + + @staticmethod + def read(buf): + return buf.read_i8() + + @staticmethod + def write(value, buf): + buf.write_i8(value) + +class _UniffiFfiConverterInt16(_UniffiConverterPrimitiveInt): + CLASS_NAME = "i16" + VALUE_MIN = -2**15 + VALUE_MAX = 2**15 + + @staticmethod + def read(buf): + return buf.read_i16() + + @staticmethod + def write(value, buf): + buf.write_i16(value) + +class _UniffiFfiConverterInt32(_UniffiConverterPrimitiveInt): + CLASS_NAME = "i32" + VALUE_MIN = -2**31 + VALUE_MAX = 2**31 + + @staticmethod + def read(buf): + return buf.read_i32() + + @staticmethod + def write(value, buf): + buf.write_i32(value) + +class _UniffiFfiConverterInt64(_UniffiConverterPrimitiveInt): + CLASS_NAME = "i64" + VALUE_MIN = -2**63 + VALUE_MAX = 2**63 + + @staticmethod + def read(buf): + return buf.read_i64() + + @staticmethod + def write(value, buf): + buf.write_i64(value) + +class _UniffiFfiConverterUInt8(_UniffiConverterPrimitiveInt): + CLASS_NAME = "u8" + VALUE_MIN = 0 + VALUE_MAX = 2**8 + + @staticmethod + def read(buf): + return buf.read_u8() + + @staticmethod + def write(value, buf): + buf.write_u8(value) + +class _UniffiFfiConverterSequenceUInt8(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterUInt8.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterUInt8.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterUInt8.read(buf) for i in range(count) + ] + +class _UniffiFfiConverterUInt16(_UniffiConverterPrimitiveInt): + CLASS_NAME = "u16" + VALUE_MIN = 0 + VALUE_MAX = 2**16 + + @staticmethod + def read(buf): + return buf.read_u16() + + @staticmethod + def write(value, buf): + buf.write_u16(value) + + + + + + +class Primitive: + def __init__(self): + raise RuntimeError("Primitive cannot be instantiated directly") + + # Each enum variant is a nested class of the enum itself. + @dataclass + class I8: + + def __init__(self, value:int): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.I8(value={})".format(self.value) + def __eq__(self, other): + if not other.is_I8(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class I16: + + def __init__(self, value:int): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.I16(value={})".format(self.value) + def __eq__(self, other): + if not other.is_I16(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class I32: + + def __init__(self, value:int): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.I32(value={})".format(self.value) + def __eq__(self, other): + if not other.is_I32(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class I64: + + def __init__(self, value:int): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.I64(value={})".format(self.value) + def __eq__(self, other): + if not other.is_I64(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class I128: + + def __init__(self, value:typing.List[int]): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.I128(value={})".format(self.value) + def __eq__(self, other): + if not other.is_I128(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class U8: + + def __init__(self, value:int): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.U8(value={})".format(self.value) + def __eq__(self, other): + if not other.is_U8(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class U16: + + def __init__(self, value:int): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.U16(value={})".format(self.value) + def __eq__(self, other): + if not other.is_U16(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class U32: + + def __init__(self, value:int): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.U32(value={})".format(self.value) + def __eq__(self, other): + if not other.is_U32(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class U64: + + def __init__(self, value:int): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.U64(value={})".format(self.value) + def __eq__(self, other): + if not other.is_U64(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class U128: + + def __init__(self, value:typing.List[int]): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.U128(value={})".format(self.value) + def __eq__(self, other): + if not other.is_U128(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class U256: + + def __init__(self, value:U256): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.U256(value={})".format(self.value) + def __eq__(self, other): + if not other.is_U256(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class BOOL: + + def __init__(self, value:bool): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.BOOL(value={})".format(self.value) + def __eq__(self, other): + if not other.is_BOOL(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class FELT252: + + def __init__(self, value:FieldElement): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.FELT252(value={})".format(self.value) + def __eq__(self, other): + if not other.is_FELT252(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class CLASS_HASH: + + def __init__(self, value:FieldElement): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.CLASS_HASH(value={})".format(self.value) + def __eq__(self, other): + if not other.is_CLASS_HASH(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class CONTRACT_ADDRESS: + + def __init__(self, value:FieldElement): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.CONTRACT_ADDRESS(value={})".format(self.value) + def __eq__(self, other): + if not other.is_CONTRACT_ADDRESS(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class ETH_ADDRESS: + + def __init__(self, value:FieldElement): + self.value = value + + + pass + + + + + + def __str__(self): + return "Primitive.ETH_ADDRESS(value={})".format(self.value) + def __eq__(self, other): + if not other.is_ETH_ADDRESS(): + return False + if self.value != other.value: + return False + return True + + + + # For each variant, we have `is_NAME` and `is_name` methods for easily checking + # whether an instance is that variant. + def is_I8(self) -> bool: + return isinstance(self, Primitive.I8) + def is_i8(self) -> bool: + return isinstance(self, Primitive.I8) + def is_I16(self) -> bool: + return isinstance(self, Primitive.I16) + def is_i16(self) -> bool: + return isinstance(self, Primitive.I16) + def is_I32(self) -> bool: + return isinstance(self, Primitive.I32) + def is_i32(self) -> bool: + return isinstance(self, Primitive.I32) + def is_I64(self) -> bool: + return isinstance(self, Primitive.I64) + def is_i64(self) -> bool: + return isinstance(self, Primitive.I64) + def is_I128(self) -> bool: + return isinstance(self, Primitive.I128) + def is_i128(self) -> bool: + return isinstance(self, Primitive.I128) + def is_U8(self) -> bool: + return isinstance(self, Primitive.U8) + def is_u8(self) -> bool: + return isinstance(self, Primitive.U8) + def is_U16(self) -> bool: + return isinstance(self, Primitive.U16) + def is_u16(self) -> bool: + return isinstance(self, Primitive.U16) + def is_U32(self) -> bool: + return isinstance(self, Primitive.U32) + def is_u32(self) -> bool: + return isinstance(self, Primitive.U32) + def is_U64(self) -> bool: + return isinstance(self, Primitive.U64) + def is_u64(self) -> bool: + return isinstance(self, Primitive.U64) + def is_U128(self) -> bool: + return isinstance(self, Primitive.U128) + def is_u128(self) -> bool: + return isinstance(self, Primitive.U128) + def is_U256(self) -> bool: + return isinstance(self, Primitive.U256) + def is_u256(self) -> bool: + return isinstance(self, Primitive.U256) + def is_BOOL(self) -> bool: + return isinstance(self, Primitive.BOOL) + def is_bool(self) -> bool: + return isinstance(self, Primitive.BOOL) + def is_FELT252(self) -> bool: + return isinstance(self, Primitive.FELT252) + def is_felt252(self) -> bool: + return isinstance(self, Primitive.FELT252) + def is_CLASS_HASH(self) -> bool: + return isinstance(self, Primitive.CLASS_HASH) + def is_class_hash(self) -> bool: + return isinstance(self, Primitive.CLASS_HASH) + def is_CONTRACT_ADDRESS(self) -> bool: + return isinstance(self, Primitive.CONTRACT_ADDRESS) + def is_contract_address(self) -> bool: + return isinstance(self, Primitive.CONTRACT_ADDRESS) + def is_ETH_ADDRESS(self) -> bool: + return isinstance(self, Primitive.ETH_ADDRESS) + def is_eth_address(self) -> bool: + return isinstance(self, Primitive.ETH_ADDRESS) + + +# Now, a little trick - we make each nested variant class be a subclass of the main +# enum class, so that method calls and instance checks etc will work intuitively. +# We might be able to do this a little more neatly with a metaclass, but this'll do. +Primitive.I8 = type("Primitive.I8", (Primitive.I8, Primitive,), {}) # type: ignore +Primitive.I16 = type("Primitive.I16", (Primitive.I16, Primitive,), {}) # type: ignore +Primitive.I32 = type("Primitive.I32", (Primitive.I32, Primitive,), {}) # type: ignore +Primitive.I64 = type("Primitive.I64", (Primitive.I64, Primitive,), {}) # type: ignore +Primitive.I128 = type("Primitive.I128", (Primitive.I128, Primitive,), {}) # type: ignore +Primitive.U8 = type("Primitive.U8", (Primitive.U8, Primitive,), {}) # type: ignore +Primitive.U16 = type("Primitive.U16", (Primitive.U16, Primitive,), {}) # type: ignore +Primitive.U32 = type("Primitive.U32", (Primitive.U32, Primitive,), {}) # type: ignore +Primitive.U64 = type("Primitive.U64", (Primitive.U64, Primitive,), {}) # type: ignore +Primitive.U128 = type("Primitive.U128", (Primitive.U128, Primitive,), {}) # type: ignore +Primitive.U256 = type("Primitive.U256", (Primitive.U256, Primitive,), {}) # type: ignore +Primitive.BOOL = type("Primitive.BOOL", (Primitive.BOOL, Primitive,), {}) # type: ignore +Primitive.FELT252 = type("Primitive.FELT252", (Primitive.FELT252, Primitive,), {}) # type: ignore +Primitive.CLASS_HASH = type("Primitive.CLASS_HASH", (Primitive.CLASS_HASH, Primitive,), {}) # type: ignore +Primitive.CONTRACT_ADDRESS = type("Primitive.CONTRACT_ADDRESS", (Primitive.CONTRACT_ADDRESS, Primitive,), {}) # type: ignore +Primitive.ETH_ADDRESS = type("Primitive.ETH_ADDRESS", (Primitive.ETH_ADDRESS, Primitive,), {}) # type: ignore + + + + +class _UniffiFfiConverterTypePrimitive(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return Primitive.I8( + _UniffiFfiConverterInt8.read(buf), + ) + if variant == 2: + return Primitive.I16( + _UniffiFfiConverterInt16.read(buf), + ) + if variant == 3: + return Primitive.I32( + _UniffiFfiConverterInt32.read(buf), + ) + if variant == 4: + return Primitive.I64( + _UniffiFfiConverterInt64.read(buf), + ) + if variant == 5: + return Primitive.I128( + _UniffiFfiConverterSequenceUInt8.read(buf), + ) + if variant == 6: + return Primitive.U8( + _UniffiFfiConverterUInt8.read(buf), + ) + if variant == 7: + return Primitive.U16( + _UniffiFfiConverterUInt16.read(buf), + ) + if variant == 8: + return Primitive.U32( + _UniffiFfiConverterUInt32.read(buf), + ) + if variant == 9: + return Primitive.U64( + _UniffiFfiConverterUInt64.read(buf), + ) + if variant == 10: + return Primitive.U128( + _UniffiFfiConverterSequenceUInt8.read(buf), + ) + if variant == 11: + return Primitive.U256( + _UniffiFfiConverterTypeU256.read(buf), + ) + if variant == 12: + return Primitive.BOOL( + _UniffiFfiConverterBoolean.read(buf), + ) + if variant == 13: + return Primitive.FELT252( + _UniffiFfiConverterTypeFieldElement.read(buf), + ) + if variant == 14: + return Primitive.CLASS_HASH( + _UniffiFfiConverterTypeFieldElement.read(buf), + ) + if variant == 15: + return Primitive.CONTRACT_ADDRESS( + _UniffiFfiConverterTypeFieldElement.read(buf), + ) + if variant == 16: + return Primitive.ETH_ADDRESS( + _UniffiFfiConverterTypeFieldElement.read(buf), + ) + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value.is_I8(): + _UniffiFfiConverterInt8.check_lower(value.value) + return + if value.is_I16(): + _UniffiFfiConverterInt16.check_lower(value.value) + return + if value.is_I32(): + _UniffiFfiConverterInt32.check_lower(value.value) + return + if value.is_I64(): + _UniffiFfiConverterInt64.check_lower(value.value) + return + if value.is_I128(): + _UniffiFfiConverterSequenceUInt8.check_lower(value.value) + return + if value.is_U8(): + _UniffiFfiConverterUInt8.check_lower(value.value) + return + if value.is_U16(): + _UniffiFfiConverterUInt16.check_lower(value.value) + return + if value.is_U32(): + _UniffiFfiConverterUInt32.check_lower(value.value) + return + if value.is_U64(): + _UniffiFfiConverterUInt64.check_lower(value.value) + return + if value.is_U128(): + _UniffiFfiConverterSequenceUInt8.check_lower(value.value) + return + if value.is_U256(): + _UniffiFfiConverterTypeU256.check_lower(value.value) + return + if value.is_BOOL(): + _UniffiFfiConverterBoolean.check_lower(value.value) + return + if value.is_FELT252(): + _UniffiFfiConverterTypeFieldElement.check_lower(value.value) + return + if value.is_CLASS_HASH(): + _UniffiFfiConverterTypeFieldElement.check_lower(value.value) + return + if value.is_CONTRACT_ADDRESS(): + _UniffiFfiConverterTypeFieldElement.check_lower(value.value) + return + if value.is_ETH_ADDRESS(): + _UniffiFfiConverterTypeFieldElement.check_lower(value.value) + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value.is_I8(): + buf.write_i32(1) + _UniffiFfiConverterInt8.write(value.value, buf) + if value.is_I16(): + buf.write_i32(2) + _UniffiFfiConverterInt16.write(value.value, buf) + if value.is_I32(): + buf.write_i32(3) + _UniffiFfiConverterInt32.write(value.value, buf) + if value.is_I64(): + buf.write_i32(4) + _UniffiFfiConverterInt64.write(value.value, buf) + if value.is_I128(): + buf.write_i32(5) + _UniffiFfiConverterSequenceUInt8.write(value.value, buf) + if value.is_U8(): + buf.write_i32(6) + _UniffiFfiConverterUInt8.write(value.value, buf) + if value.is_U16(): + buf.write_i32(7) + _UniffiFfiConverterUInt16.write(value.value, buf) + if value.is_U32(): + buf.write_i32(8) + _UniffiFfiConverterUInt32.write(value.value, buf) + if value.is_U64(): + buf.write_i32(9) + _UniffiFfiConverterUInt64.write(value.value, buf) + if value.is_U128(): + buf.write_i32(10) + _UniffiFfiConverterSequenceUInt8.write(value.value, buf) + if value.is_U256(): + buf.write_i32(11) + _UniffiFfiConverterTypeU256.write(value.value, buf) + if value.is_BOOL(): + buf.write_i32(12) + _UniffiFfiConverterBoolean.write(value.value, buf) + if value.is_FELT252(): + buf.write_i32(13) + _UniffiFfiConverterTypeFieldElement.write(value.value, buf) + if value.is_CLASS_HASH(): + buf.write_i32(14) + _UniffiFfiConverterTypeFieldElement.write(value.value, buf) + if value.is_CONTRACT_ADDRESS(): + buf.write_i32(15) + _UniffiFfiConverterTypeFieldElement.write(value.value, buf) + if value.is_ETH_ADDRESS(): + buf.write_i32(16) + _UniffiFfiConverterTypeFieldElement.write(value.value, buf) + + + +class _UniffiFfiConverterSequenceTypeMemberValue(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeMemberValue.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeMemberValue.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeMemberValue.read(buf) for i in range(count) + ] + + + + + + +class MemberValue: + def __init__(self): + raise RuntimeError("MemberValue cannot be instantiated directly") + + # Each enum variant is a nested class of the enum itself. + @dataclass + class PRIMITIVE: + + def __init__(self, value:Primitive): + self.value = value + + + pass + + + + + + def __str__(self): + return "MemberValue.PRIMITIVE(value={})".format(self.value) + def __eq__(self, other): + if not other.is_PRIMITIVE(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class STRING: + + def __init__(self, value:str): + self.value = value + + + pass + + + + + + def __str__(self): + return "MemberValue.STRING(value={})".format(self.value) + def __eq__(self, other): + if not other.is_STRING(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class LIST: + + def __init__(self, values:typing.List[MemberValue]): + self.values = values + + + pass + + + + + + def __str__(self): + return "MemberValue.LIST(values={})".format(self.values) + def __eq__(self, other): + if not other.is_LIST(): + return False + if self.values != other.values: + return False + return True + + + + # For each variant, we have `is_NAME` and `is_name` methods for easily checking + # whether an instance is that variant. + def is_PRIMITIVE(self) -> bool: + return isinstance(self, MemberValue.PRIMITIVE) + def is_primitive(self) -> bool: + return isinstance(self, MemberValue.PRIMITIVE) + def is_STRING(self) -> bool: + return isinstance(self, MemberValue.STRING) + def is_string(self) -> bool: + return isinstance(self, MemberValue.STRING) + def is_LIST(self) -> bool: + return isinstance(self, MemberValue.LIST) + def is_list(self) -> bool: + return isinstance(self, MemberValue.LIST) + + +# Now, a little trick - we make each nested variant class be a subclass of the main +# enum class, so that method calls and instance checks etc will work intuitively. +# We might be able to do this a little more neatly with a metaclass, but this'll do. +MemberValue.PRIMITIVE = type("MemberValue.PRIMITIVE", (MemberValue.PRIMITIVE, MemberValue,), {}) # type: ignore +MemberValue.STRING = type("MemberValue.STRING", (MemberValue.STRING, MemberValue,), {}) # type: ignore +MemberValue.LIST = type("MemberValue.LIST", (MemberValue.LIST, MemberValue,), {}) # type: ignore + + + + +class _UniffiFfiConverterTypeMemberValue(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return MemberValue.PRIMITIVE( + _UniffiFfiConverterTypePrimitive.read(buf), + ) + if variant == 2: + return MemberValue.STRING( + _UniffiFfiConverterString.read(buf), + ) + if variant == 3: + return MemberValue.LIST( + _UniffiFfiConverterSequenceTypeMemberValue.read(buf), + ) + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value.is_PRIMITIVE(): + _UniffiFfiConverterTypePrimitive.check_lower(value.value) + return + if value.is_STRING(): + _UniffiFfiConverterString.check_lower(value.value) + return + if value.is_LIST(): + _UniffiFfiConverterSequenceTypeMemberValue.check_lower(value.values) + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value.is_PRIMITIVE(): + buf.write_i32(1) + _UniffiFfiConverterTypePrimitive.write(value.value, buf) + if value.is_STRING(): + buf.write_i32(2) + _UniffiFfiConverterString.write(value.value, buf) + if value.is_LIST(): + buf.write_i32(3) + _UniffiFfiConverterSequenceTypeMemberValue.write(value.values, buf) + + + +@dataclass +class MemberClause: + def __init__(self, *, model:str, member:str, operator:ComparisonOperator, value:MemberValue): + self.model = model + self.member = member + self.operator = operator + self.value = value + + + + + def __str__(self): + return "MemberClause(model={}, member={}, operator={}, value={})".format(self.model, self.member, self.operator, self.value) + def __eq__(self, other): + if self.model != other.model: + return False + if self.member != other.member: + return False + if self.operator != other.operator: + return False + if self.value != other.value: + return False + return True + +class _UniffiFfiConverterTypeMemberClause(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return MemberClause( + model=_UniffiFfiConverterString.read(buf), + member=_UniffiFfiConverterString.read(buf), + operator=_UniffiFfiConverterTypeComparisonOperator.read(buf), + value=_UniffiFfiConverterTypeMemberValue.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.model) + _UniffiFfiConverterString.check_lower(value.member) + _UniffiFfiConverterTypeComparisonOperator.check_lower(value.operator) + _UniffiFfiConverterTypeMemberValue.check_lower(value.value) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.model, buf) + _UniffiFfiConverterString.write(value.member, buf) + _UniffiFfiConverterTypeComparisonOperator.write(value.operator, buf) + _UniffiFfiConverterTypeMemberValue.write(value.value, buf) + + + + + + +class Clause: + def __init__(self): + raise RuntimeError("Clause cannot be instantiated directly") + + # Each enum variant is a nested class of the enum itself. + @dataclass + class HASHED_KEYS: + + def __init__(self, keys:typing.List[FieldElement]): + self.keys = keys + + + pass + + + + + + def __str__(self): + return "Clause.HASHED_KEYS(keys={})".format(self.keys) + def __eq__(self, other): + if not other.is_HASHED_KEYS(): + return False + if self.keys != other.keys: + return False + return True + + @dataclass + class KEYS: + + def __init__(self, clause:KeysClause): + self.clause = clause + + + pass + + + + + + def __str__(self): + return "Clause.KEYS(clause={})".format(self.clause) + def __eq__(self, other): + if not other.is_KEYS(): + return False + if self.clause != other.clause: + return False + return True + + @dataclass + class MEMBER: + + def __init__(self, clause:MemberClause): + self.clause = clause + + + pass + + + + + + def __str__(self): + return "Clause.MEMBER(clause={})".format(self.clause) + def __eq__(self, other): + if not other.is_MEMBER(): + return False + if self.clause != other.clause: + return False + return True + + @dataclass + class COMPOSITE: + + def __init__(self, clause:CompositeClause): + self.clause = clause + + + pass + + + + + + def __str__(self): + return "Clause.COMPOSITE(clause={})".format(self.clause) + def __eq__(self, other): + if not other.is_COMPOSITE(): + return False + if self.clause != other.clause: + return False + return True + + + + # For each variant, we have `is_NAME` and `is_name` methods for easily checking + # whether an instance is that variant. + def is_HASHED_KEYS(self) -> bool: + return isinstance(self, Clause.HASHED_KEYS) + def is_hashed_keys(self) -> bool: + return isinstance(self, Clause.HASHED_KEYS) + def is_KEYS(self) -> bool: + return isinstance(self, Clause.KEYS) + def is_keys(self) -> bool: + return isinstance(self, Clause.KEYS) + def is_MEMBER(self) -> bool: + return isinstance(self, Clause.MEMBER) + def is_member(self) -> bool: + return isinstance(self, Clause.MEMBER) + def is_COMPOSITE(self) -> bool: + return isinstance(self, Clause.COMPOSITE) + def is_composite(self) -> bool: + return isinstance(self, Clause.COMPOSITE) + + +# Now, a little trick - we make each nested variant class be a subclass of the main +# enum class, so that method calls and instance checks etc will work intuitively. +# We might be able to do this a little more neatly with a metaclass, but this'll do. +Clause.HASHED_KEYS = type("Clause.HASHED_KEYS", (Clause.HASHED_KEYS, Clause,), {}) # type: ignore +Clause.KEYS = type("Clause.KEYS", (Clause.KEYS, Clause,), {}) # type: ignore +Clause.MEMBER = type("Clause.MEMBER", (Clause.MEMBER, Clause,), {}) # type: ignore +Clause.COMPOSITE = type("Clause.COMPOSITE", (Clause.COMPOSITE, Clause,), {}) # type: ignore + + + + +class _UniffiFfiConverterTypeClause(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return Clause.HASHED_KEYS( + _UniffiFfiConverterSequenceTypeFieldElement.read(buf), + ) + if variant == 2: + return Clause.KEYS( + _UniffiFfiConverterTypeKeysClause.read(buf), + ) + if variant == 3: + return Clause.MEMBER( + _UniffiFfiConverterTypeMemberClause.read(buf), + ) + if variant == 4: + return Clause.COMPOSITE( + _UniffiFfiConverterTypeCompositeClause.read(buf), + ) + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value.is_HASHED_KEYS(): + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.keys) + return + if value.is_KEYS(): + _UniffiFfiConverterTypeKeysClause.check_lower(value.clause) + return + if value.is_MEMBER(): + _UniffiFfiConverterTypeMemberClause.check_lower(value.clause) + return + if value.is_COMPOSITE(): + _UniffiFfiConverterTypeCompositeClause.check_lower(value.clause) + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value.is_HASHED_KEYS(): + buf.write_i32(1) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.keys, buf) + if value.is_KEYS(): + buf.write_i32(2) + _UniffiFfiConverterTypeKeysClause.write(value.clause, buf) + if value.is_MEMBER(): + buf.write_i32(3) + _UniffiFfiConverterTypeMemberClause.write(value.clause, buf) + if value.is_COMPOSITE(): + buf.write_i32(4) + _UniffiFfiConverterTypeCompositeClause.write(value.clause, buf) + + + +class _UniffiFfiConverterSequenceTypeClause(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeClause.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeClause.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeClause.read(buf) for i in range(count) + ] + +@dataclass +class CompositeClause: + def __init__(self, *, operator:LogicalOperator, clauses:typing.List[Clause]): + self.operator = operator + self.clauses = clauses + + + + + def __str__(self): + return "CompositeClause(operator={}, clauses={})".format(self.operator, self.clauses) + def __eq__(self, other): + if self.operator != other.operator: + return False + if self.clauses != other.clauses: + return False + return True + +class _UniffiFfiConverterTypeCompositeClause(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return CompositeClause( + operator=_UniffiFfiConverterTypeLogicalOperator.read(buf), + clauses=_UniffiFfiConverterSequenceTypeClause.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeLogicalOperator.check_lower(value.operator) + _UniffiFfiConverterSequenceTypeClause.check_lower(value.clauses) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeLogicalOperator.write(value.operator, buf) + _UniffiFfiConverterSequenceTypeClause.write(value.clauses, buf) + + + + + + +class ContractType(enum.Enum): + + WORLD = 0 + + ERC20 = 1 + + ERC721 = 2 + + ERC1155 = 3 + + UDC = 4 + + OTHER = 5 + + + +class _UniffiFfiConverterTypeContractType(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return ContractType.WORLD + if variant == 2: + return ContractType.ERC20 + if variant == 3: + return ContractType.ERC721 + if variant == 4: + return ContractType.ERC1155 + if variant == 5: + return ContractType.UDC + if variant == 6: + return ContractType.OTHER + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == ContractType.WORLD: + return + if value == ContractType.ERC20: + return + if value == ContractType.ERC721: + return + if value == ContractType.ERC1155: + return + if value == ContractType.UDC: + return + if value == ContractType.OTHER: + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value == ContractType.WORLD: + buf.write_i32(1) + if value == ContractType.ERC20: + buf.write_i32(2) + if value == ContractType.ERC721: + buf.write_i32(3) + if value == ContractType.ERC1155: + buf.write_i32(4) + if value == ContractType.UDC: + buf.write_i32(5) + if value == ContractType.OTHER: + buf.write_i32(6) + + + +@dataclass +class Contract: + def __init__(self, *, contract_address:FieldElement, contract_type:ContractType, head:typing.Optional[int], tps:typing.Optional[int], last_block_timestamp:typing.Optional[int], last_pending_block_tx:typing.Optional[FieldElement], updated_at:int, created_at:int): + self.contract_address = contract_address + self.contract_type = contract_type + self.head = head + self.tps = tps + self.last_block_timestamp = last_block_timestamp + self.last_pending_block_tx = last_pending_block_tx + self.updated_at = updated_at + self.created_at = created_at + + + + + def __str__(self): + return "Contract(contract_address={}, contract_type={}, head={}, tps={}, last_block_timestamp={}, last_pending_block_tx={}, updated_at={}, created_at={})".format(self.contract_address, self.contract_type, self.head, self.tps, self.last_block_timestamp, self.last_pending_block_tx, self.updated_at, self.created_at) + def __eq__(self, other): + if self.contract_address != other.contract_address: + return False + if self.contract_type != other.contract_type: + return False + if self.head != other.head: + return False + if self.tps != other.tps: + return False + if self.last_block_timestamp != other.last_block_timestamp: + return False + if self.last_pending_block_tx != other.last_pending_block_tx: + return False + if self.updated_at != other.updated_at: + return False + if self.created_at != other.created_at: + return False + return True + +class _UniffiFfiConverterTypeContract(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Contract( + contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), + contract_type=_UniffiFfiConverterTypeContractType.read(buf), + head=_UniffiFfiConverterOptionalUInt64.read(buf), + tps=_UniffiFfiConverterOptionalUInt64.read(buf), + last_block_timestamp=_UniffiFfiConverterOptionalUInt64.read(buf), + last_pending_block_tx=_UniffiFfiConverterOptionalTypeFieldElement.read(buf), + updated_at=_UniffiFfiConverterUInt64.read(buf), + created_at=_UniffiFfiConverterUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) + _UniffiFfiConverterTypeContractType.check_lower(value.contract_type) + _UniffiFfiConverterOptionalUInt64.check_lower(value.head) + _UniffiFfiConverterOptionalUInt64.check_lower(value.tps) + _UniffiFfiConverterOptionalUInt64.check_lower(value.last_block_timestamp) + _UniffiFfiConverterOptionalTypeFieldElement.check_lower(value.last_pending_block_tx) + _UniffiFfiConverterUInt64.check_lower(value.updated_at) + _UniffiFfiConverterUInt64.check_lower(value.created_at) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) + _UniffiFfiConverterTypeContractType.write(value.contract_type, buf) + _UniffiFfiConverterOptionalUInt64.write(value.head, buf) + _UniffiFfiConverterOptionalUInt64.write(value.tps, buf) + _UniffiFfiConverterOptionalUInt64.write(value.last_block_timestamp, buf) + _UniffiFfiConverterOptionalTypeFieldElement.write(value.last_pending_block_tx, buf) + _UniffiFfiConverterUInt64.write(value.updated_at, buf) + _UniffiFfiConverterUInt64.write(value.created_at, buf) + +class _UniffiFfiConverterSequenceTypeContractType(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeContractType.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeContractType.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeContractType.read(buf) for i in range(count) + ] + +@dataclass +class ContractQuery: + def __init__(self, *, contract_addresses:typing.List[FieldElement], contract_types:typing.List[ContractType]): + self.contract_addresses = contract_addresses + self.contract_types = contract_types + + + + + def __str__(self): + return "ContractQuery(contract_addresses={}, contract_types={})".format(self.contract_addresses, self.contract_types) + def __eq__(self, other): + if self.contract_addresses != other.contract_addresses: + return False + if self.contract_types != other.contract_types: + return False + return True + +class _UniffiFfiConverterTypeContractQuery(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return ContractQuery( + contract_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + contract_types=_UniffiFfiConverterSequenceTypeContractType.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.contract_addresses) + _UniffiFfiConverterSequenceTypeContractType.check_lower(value.contract_types) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeFieldElement.write(value.contract_addresses, buf) + _UniffiFfiConverterSequenceTypeContractType.write(value.contract_types, buf) + +@dataclass +class Controller: + def __init__(self, *, address:FieldElement, username:str, deployed_at_timestamp:int): + self.address = address + self.username = username + self.deployed_at_timestamp = deployed_at_timestamp + + + + + def __str__(self): + return "Controller(address={}, username={}, deployed_at_timestamp={})".format(self.address, self.username, self.deployed_at_timestamp) + def __eq__(self, other): + if self.address != other.address: + return False + if self.username != other.username: + return False + if self.deployed_at_timestamp != other.deployed_at_timestamp: + return False + return True + +class _UniffiFfiConverterTypeController(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Controller( + address=_UniffiFfiConverterTypeFieldElement.read(buf), + username=_UniffiFfiConverterString.read(buf), + deployed_at_timestamp=_UniffiFfiConverterUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeFieldElement.check_lower(value.address) + _UniffiFfiConverterString.check_lower(value.username) + _UniffiFfiConverterUInt64.check_lower(value.deployed_at_timestamp) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeFieldElement.write(value.address, buf) + _UniffiFfiConverterString.write(value.username, buf) + _UniffiFfiConverterUInt64.write(value.deployed_at_timestamp, buf) + +@dataclass +class ControllerQuery: + def __init__(self, *, pagination:Pagination, contract_addresses:typing.List[FieldElement], usernames:typing.List[str]): + self.pagination = pagination + self.contract_addresses = contract_addresses + self.usernames = usernames + + + + + def __str__(self): + return "ControllerQuery(pagination={}, contract_addresses={}, usernames={})".format(self.pagination, self.contract_addresses, self.usernames) + def __eq__(self, other): + if self.pagination != other.pagination: + return False + if self.contract_addresses != other.contract_addresses: + return False + if self.usernames != other.usernames: + return False + return True + +class _UniffiFfiConverterTypeControllerQuery(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return ControllerQuery( + pagination=_UniffiFfiConverterTypePagination.read(buf), + contract_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + usernames=_UniffiFfiConverterSequenceString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypePagination.check_lower(value.pagination) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.contract_addresses) + _UniffiFfiConverterSequenceString.check_lower(value.usernames) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypePagination.write(value.pagination, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.contract_addresses, buf) + _UniffiFfiConverterSequenceString.write(value.usernames, buf) + +@dataclass +class Member: + def __init__(self, *, name:str, ty:Ty, key:bool): + self.name = name + self.ty = ty + self.key = key + + + + + def __str__(self): + return "Member(name={}, ty={}, key={})".format(self.name, self.ty, self.key) + def __eq__(self, other): + if self.name != other.name: + return False + if self.ty != other.ty: + return False + if self.key != other.key: + return False + return True + +class _UniffiFfiConverterTypeMember(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Member( + name=_UniffiFfiConverterString.read(buf), + ty=_UniffiFfiConverterTypeTy.read(buf), + key=_UniffiFfiConverterBoolean.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.name) + _UniffiFfiConverterTypeTy.check_lower(value.ty) + _UniffiFfiConverterBoolean.check_lower(value.key) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.name, buf) + _UniffiFfiConverterTypeTy.write(value.ty, buf) + _UniffiFfiConverterBoolean.write(value.key, buf) + +class _UniffiFfiConverterSequenceTypeMember(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeMember.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeMember.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeMember.read(buf) for i in range(count) + ] + +@dataclass +class Struct: + def __init__(self, *, name:str, children:typing.List[Member]): + self.name = name + self.children = children + + + + + def __str__(self): + return "Struct(name={}, children={})".format(self.name, self.children) + def __eq__(self, other): + if self.name != other.name: + return False + if self.children != other.children: + return False + return True + +class _UniffiFfiConverterTypeStruct(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Struct( + name=_UniffiFfiConverterString.read(buf), + children=_UniffiFfiConverterSequenceTypeMember.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.name) + _UniffiFfiConverterSequenceTypeMember.check_lower(value.children) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.name, buf) + _UniffiFfiConverterSequenceTypeMember.write(value.children, buf) + +class _UniffiFfiConverterSequenceTypeEnumOption(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeEnumOption.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeEnumOption.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeEnumOption.read(buf) for i in range(count) + ] + +@dataclass +class EnumType: + def __init__(self, *, name:str, option:int, options:typing.List[EnumOption]): + self.name = name + self.option = option + self.options = options + + + + + def __str__(self): + return "EnumType(name={}, option={}, options={})".format(self.name, self.option, self.options) + def __eq__(self, other): + if self.name != other.name: + return False + if self.option != other.option: + return False + if self.options != other.options: + return False + return True + +class _UniffiFfiConverterTypeEnumType(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return EnumType( + name=_UniffiFfiConverterString.read(buf), + option=_UniffiFfiConverterUInt8.read(buf), + options=_UniffiFfiConverterSequenceTypeEnumOption.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.name) + _UniffiFfiConverterUInt8.check_lower(value.option) + _UniffiFfiConverterSequenceTypeEnumOption.check_lower(value.options) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.name, buf) + _UniffiFfiConverterUInt8.write(value.option, buf) + _UniffiFfiConverterSequenceTypeEnumOption.write(value.options, buf) + +class _UniffiFfiConverterSequenceTypeTy(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeTy.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeTy.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeTy.read(buf) for i in range(count) + ] + +@dataclass +class FixedSizeArray: + def __init__(self, *, array:typing.List[Ty], size:int): + self.array = array + self.size = size + + + + + def __str__(self): + return "FixedSizeArray(array={}, size={})".format(self.array, self.size) + def __eq__(self, other): + if self.array != other.array: + return False + if self.size != other.size: + return False + return True + +class _UniffiFfiConverterTypeFixedSizeArray(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return FixedSizeArray( + array=_UniffiFfiConverterSequenceTypeTy.read(buf), + size=_UniffiFfiConverterUInt32.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeTy.check_lower(value.array) + _UniffiFfiConverterUInt32.check_lower(value.size) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeTy.write(value.array, buf) + _UniffiFfiConverterUInt32.write(value.size, buf) + + + + + + +class Ty: + def __init__(self): + raise RuntimeError("Ty cannot be instantiated directly") + + # Each enum variant is a nested class of the enum itself. + @dataclass + class PRIMITIVE: + + def __init__(self, value:Primitive): + self.value = value + + + pass + + + + + + def __str__(self): + return "Ty.PRIMITIVE(value={})".format(self.value) + def __eq__(self, other): + if not other.is_PRIMITIVE(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class STRUCT: + + def __init__(self, value:Struct): + self.value = value + + + pass + + + + + + def __str__(self): + return "Ty.STRUCT(value={})".format(self.value) + def __eq__(self, other): + if not other.is_STRUCT(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class ENUM: + + def __init__(self, value:EnumType): + self.value = value + + + pass + + + + + + def __str__(self): + return "Ty.ENUM(value={})".format(self.value) + def __eq__(self, other): + if not other.is_ENUM(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class TUPLE: + + def __init__(self, values:typing.List[Ty]): + self.values = values + + + pass + + + + + + def __str__(self): + return "Ty.TUPLE(values={})".format(self.values) + def __eq__(self, other): + if not other.is_TUPLE(): + return False + if self.values != other.values: + return False + return True + + @dataclass + class ARRAY: + + def __init__(self, values:typing.List[Ty]): + self.values = values + + + pass + + + + + + def __str__(self): + return "Ty.ARRAY(values={})".format(self.values) + def __eq__(self, other): + if not other.is_ARRAY(): + return False + if self.values != other.values: + return False + return True + + @dataclass + class FIXED_SIZE_ARRAY: + + def __init__(self, value:FixedSizeArray): + self.value = value + + + pass + + + + + + def __str__(self): + return "Ty.FIXED_SIZE_ARRAY(value={})".format(self.value) + def __eq__(self, other): + if not other.is_FIXED_SIZE_ARRAY(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class BYTE_ARRAY: + + def __init__(self, value:str): + self.value = value + + + pass + + + + + + def __str__(self): + return "Ty.BYTE_ARRAY(value={})".format(self.value) + def __eq__(self, other): + if not other.is_BYTE_ARRAY(): + return False + if self.value != other.value: + return False + return True + + + + # For each variant, we have `is_NAME` and `is_name` methods for easily checking + # whether an instance is that variant. + def is_PRIMITIVE(self) -> bool: + return isinstance(self, Ty.PRIMITIVE) + def is_primitive(self) -> bool: + return isinstance(self, Ty.PRIMITIVE) + def is_STRUCT(self) -> bool: + return isinstance(self, Ty.STRUCT) + def is_struct(self) -> bool: + return isinstance(self, Ty.STRUCT) + def is_ENUM(self) -> bool: + return isinstance(self, Ty.ENUM) + def is_enum(self) -> bool: + return isinstance(self, Ty.ENUM) + def is_TUPLE(self) -> bool: + return isinstance(self, Ty.TUPLE) + def is_tuple(self) -> bool: + return isinstance(self, Ty.TUPLE) + def is_ARRAY(self) -> bool: + return isinstance(self, Ty.ARRAY) + def is_array(self) -> bool: + return isinstance(self, Ty.ARRAY) + def is_FIXED_SIZE_ARRAY(self) -> bool: + return isinstance(self, Ty.FIXED_SIZE_ARRAY) + def is_fixed_size_array(self) -> bool: + return isinstance(self, Ty.FIXED_SIZE_ARRAY) + def is_BYTE_ARRAY(self) -> bool: + return isinstance(self, Ty.BYTE_ARRAY) + def is_byte_array(self) -> bool: + return isinstance(self, Ty.BYTE_ARRAY) + + +# Now, a little trick - we make each nested variant class be a subclass of the main +# enum class, so that method calls and instance checks etc will work intuitively. +# We might be able to do this a little more neatly with a metaclass, but this'll do. +Ty.PRIMITIVE = type("Ty.PRIMITIVE", (Ty.PRIMITIVE, Ty,), {}) # type: ignore +Ty.STRUCT = type("Ty.STRUCT", (Ty.STRUCT, Ty,), {}) # type: ignore +Ty.ENUM = type("Ty.ENUM", (Ty.ENUM, Ty,), {}) # type: ignore +Ty.TUPLE = type("Ty.TUPLE", (Ty.TUPLE, Ty,), {}) # type: ignore +Ty.ARRAY = type("Ty.ARRAY", (Ty.ARRAY, Ty,), {}) # type: ignore +Ty.FIXED_SIZE_ARRAY = type("Ty.FIXED_SIZE_ARRAY", (Ty.FIXED_SIZE_ARRAY, Ty,), {}) # type: ignore +Ty.BYTE_ARRAY = type("Ty.BYTE_ARRAY", (Ty.BYTE_ARRAY, Ty,), {}) # type: ignore + + + + +class _UniffiFfiConverterTypeTy(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return Ty.PRIMITIVE( + _UniffiFfiConverterTypePrimitive.read(buf), + ) + if variant == 2: + return Ty.STRUCT( + _UniffiFfiConverterTypeStruct.read(buf), + ) + if variant == 3: + return Ty.ENUM( + _UniffiFfiConverterTypeEnumType.read(buf), + ) + if variant == 4: + return Ty.TUPLE( + _UniffiFfiConverterSequenceTypeTy.read(buf), + ) + if variant == 5: + return Ty.ARRAY( + _UniffiFfiConverterSequenceTypeTy.read(buf), + ) + if variant == 6: + return Ty.FIXED_SIZE_ARRAY( + _UniffiFfiConverterTypeFixedSizeArray.read(buf), + ) + if variant == 7: + return Ty.BYTE_ARRAY( + _UniffiFfiConverterString.read(buf), + ) + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value.is_PRIMITIVE(): + _UniffiFfiConverterTypePrimitive.check_lower(value.value) + return + if value.is_STRUCT(): + _UniffiFfiConverterTypeStruct.check_lower(value.value) + return + if value.is_ENUM(): + _UniffiFfiConverterTypeEnumType.check_lower(value.value) + return + if value.is_TUPLE(): + _UniffiFfiConverterSequenceTypeTy.check_lower(value.values) + return + if value.is_ARRAY(): + _UniffiFfiConverterSequenceTypeTy.check_lower(value.values) + return + if value.is_FIXED_SIZE_ARRAY(): + _UniffiFfiConverterTypeFixedSizeArray.check_lower(value.value) + return + if value.is_BYTE_ARRAY(): + _UniffiFfiConverterString.check_lower(value.value) + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value.is_PRIMITIVE(): + buf.write_i32(1) + _UniffiFfiConverterTypePrimitive.write(value.value, buf) + if value.is_STRUCT(): + buf.write_i32(2) + _UniffiFfiConverterTypeStruct.write(value.value, buf) + if value.is_ENUM(): + buf.write_i32(3) + _UniffiFfiConverterTypeEnumType.write(value.value, buf) + if value.is_TUPLE(): + buf.write_i32(4) + _UniffiFfiConverterSequenceTypeTy.write(value.values, buf) + if value.is_ARRAY(): + buf.write_i32(5) + _UniffiFfiConverterSequenceTypeTy.write(value.values, buf) + if value.is_FIXED_SIZE_ARRAY(): + buf.write_i32(6) + _UniffiFfiConverterTypeFixedSizeArray.write(value.value, buf) + if value.is_BYTE_ARRAY(): + buf.write_i32(7) + _UniffiFfiConverterString.write(value.value, buf) + + + +@dataclass +class EnumOption: + def __init__(self, *, name:str, ty:Ty): + self.name = name + self.ty = ty + + + + + def __str__(self): + return "EnumOption(name={}, ty={})".format(self.name, self.ty) + def __eq__(self, other): + if self.name != other.name: + return False + if self.ty != other.ty: + return False + return True + +class _UniffiFfiConverterTypeEnumOption(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return EnumOption( + name=_UniffiFfiConverterString.read(buf), + ty=_UniffiFfiConverterTypeTy.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.name) + _UniffiFfiConverterTypeTy.check_lower(value.ty) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.name, buf) + _UniffiFfiConverterTypeTy.write(value.ty, buf) + +@dataclass +class PlayerAchievementStats: + def __init__(self, *, total_points:int, completed_achievements:int, total_achievements:int, completion_percentage:float, last_achievement_at:typing.Optional[int], created_at:int, updated_at:int): + self.total_points = total_points + self.completed_achievements = completed_achievements + self.total_achievements = total_achievements + self.completion_percentage = completion_percentage + self.last_achievement_at = last_achievement_at + self.created_at = created_at + self.updated_at = updated_at + + + + + def __str__(self): + return "PlayerAchievementStats(total_points={}, completed_achievements={}, total_achievements={}, completion_percentage={}, last_achievement_at={}, created_at={}, updated_at={})".format(self.total_points, self.completed_achievements, self.total_achievements, self.completion_percentage, self.last_achievement_at, self.created_at, self.updated_at) + def __eq__(self, other): + if self.total_points != other.total_points: + return False + if self.completed_achievements != other.completed_achievements: + return False + if self.total_achievements != other.total_achievements: + return False + if self.completion_percentage != other.completion_percentage: + return False + if self.last_achievement_at != other.last_achievement_at: + return False + if self.created_at != other.created_at: + return False + if self.updated_at != other.updated_at: + return False + return True + +class _UniffiFfiConverterTypePlayerAchievementStats(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PlayerAchievementStats( + total_points=_UniffiFfiConverterUInt32.read(buf), + completed_achievements=_UniffiFfiConverterUInt32.read(buf), + total_achievements=_UniffiFfiConverterUInt32.read(buf), + completion_percentage=_UniffiFfiConverterFloat64.read(buf), + last_achievement_at=_UniffiFfiConverterOptionalUInt64.read(buf), + created_at=_UniffiFfiConverterUInt64.read(buf), + updated_at=_UniffiFfiConverterUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterUInt32.check_lower(value.total_points) + _UniffiFfiConverterUInt32.check_lower(value.completed_achievements) + _UniffiFfiConverterUInt32.check_lower(value.total_achievements) + _UniffiFfiConverterFloat64.check_lower(value.completion_percentage) + _UniffiFfiConverterOptionalUInt64.check_lower(value.last_achievement_at) + _UniffiFfiConverterUInt64.check_lower(value.created_at) + _UniffiFfiConverterUInt64.check_lower(value.updated_at) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterUInt32.write(value.total_points, buf) + _UniffiFfiConverterUInt32.write(value.completed_achievements, buf) + _UniffiFfiConverterUInt32.write(value.total_achievements, buf) + _UniffiFfiConverterFloat64.write(value.completion_percentage, buf) + _UniffiFfiConverterOptionalUInt64.write(value.last_achievement_at, buf) + _UniffiFfiConverterUInt64.write(value.created_at, buf) + _UniffiFfiConverterUInt64.write(value.updated_at, buf) + +@dataclass +class TaskProgress: + def __init__(self, *, task_id:str, count:int, completed:bool): + self.task_id = task_id + self.count = count + self.completed = completed + + + + + def __str__(self): + return "TaskProgress(task_id={}, count={}, completed={})".format(self.task_id, self.count, self.completed) + def __eq__(self, other): + if self.task_id != other.task_id: + return False + if self.count != other.count: + return False + if self.completed != other.completed: + return False + return True + +class _UniffiFfiConverterTypeTaskProgress(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TaskProgress( + task_id=_UniffiFfiConverterString.read(buf), + count=_UniffiFfiConverterUInt32.read(buf), + completed=_UniffiFfiConverterBoolean.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.task_id) + _UniffiFfiConverterUInt32.check_lower(value.count) + _UniffiFfiConverterBoolean.check_lower(value.completed) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.task_id, buf) + _UniffiFfiConverterUInt32.write(value.count, buf) + _UniffiFfiConverterBoolean.write(value.completed, buf) + +class _UniffiFfiConverterSequenceTypeTaskProgress(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeTaskProgress.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeTaskProgress.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeTaskProgress.read(buf) for i in range(count) + ] + +@dataclass +class PlayerAchievementProgress: + def __init__(self, *, achievement:Achievement, task_progress:typing.List[TaskProgress], completed:bool, progress_percentage:float): + self.achievement = achievement + self.task_progress = task_progress + self.completed = completed + self.progress_percentage = progress_percentage + + + + + def __str__(self): + return "PlayerAchievementProgress(achievement={}, task_progress={}, completed={}, progress_percentage={})".format(self.achievement, self.task_progress, self.completed, self.progress_percentage) + def __eq__(self, other): + if self.achievement != other.achievement: + return False + if self.task_progress != other.task_progress: + return False + if self.completed != other.completed: + return False + if self.progress_percentage != other.progress_percentage: + return False + return True + +class _UniffiFfiConverterTypePlayerAchievementProgress(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PlayerAchievementProgress( + achievement=_UniffiFfiConverterTypeAchievement.read(buf), + task_progress=_UniffiFfiConverterSequenceTypeTaskProgress.read(buf), + completed=_UniffiFfiConverterBoolean.read(buf), + progress_percentage=_UniffiFfiConverterFloat64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeAchievement.check_lower(value.achievement) + _UniffiFfiConverterSequenceTypeTaskProgress.check_lower(value.task_progress) + _UniffiFfiConverterBoolean.check_lower(value.completed) + _UniffiFfiConverterFloat64.check_lower(value.progress_percentage) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeAchievement.write(value.achievement, buf) + _UniffiFfiConverterSequenceTypeTaskProgress.write(value.task_progress, buf) + _UniffiFfiConverterBoolean.write(value.completed, buf) + _UniffiFfiConverterFloat64.write(value.progress_percentage, buf) + +class _UniffiFfiConverterSequenceTypePlayerAchievementProgress(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypePlayerAchievementProgress.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypePlayerAchievementProgress.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypePlayerAchievementProgress.read(buf) for i in range(count) + ] + +@dataclass +class PlayerAchievementEntry: + def __init__(self, *, player_address:FieldElement, stats:PlayerAchievementStats, achievements:typing.List[PlayerAchievementProgress]): + self.player_address = player_address + self.stats = stats + self.achievements = achievements + + + + + def __str__(self): + return "PlayerAchievementEntry(player_address={}, stats={}, achievements={})".format(self.player_address, self.stats, self.achievements) + def __eq__(self, other): + if self.player_address != other.player_address: + return False + if self.stats != other.stats: + return False + if self.achievements != other.achievements: + return False + return True + +class _UniffiFfiConverterTypePlayerAchievementEntry(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PlayerAchievementEntry( + player_address=_UniffiFfiConverterTypeFieldElement.read(buf), + stats=_UniffiFfiConverterTypePlayerAchievementStats.read(buf), + achievements=_UniffiFfiConverterSequenceTypePlayerAchievementProgress.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeFieldElement.check_lower(value.player_address) + _UniffiFfiConverterTypePlayerAchievementStats.check_lower(value.stats) + _UniffiFfiConverterSequenceTypePlayerAchievementProgress.check_lower(value.achievements) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeFieldElement.write(value.player_address, buf) + _UniffiFfiConverterTypePlayerAchievementStats.write(value.stats, buf) + _UniffiFfiConverterSequenceTypePlayerAchievementProgress.write(value.achievements, buf) + +@dataclass +class PlayerAchievementQuery: + def __init__(self, *, world_addresses:typing.List[FieldElement], namespaces:typing.List[str], player_addresses:typing.List[FieldElement], pagination:Pagination): + self.world_addresses = world_addresses + self.namespaces = namespaces + self.player_addresses = player_addresses + self.pagination = pagination + + + + + def __str__(self): + return "PlayerAchievementQuery(world_addresses={}, namespaces={}, player_addresses={}, pagination={})".format(self.world_addresses, self.namespaces, self.player_addresses, self.pagination) + def __eq__(self, other): + if self.world_addresses != other.world_addresses: + return False + if self.namespaces != other.namespaces: + return False + if self.player_addresses != other.player_addresses: + return False + if self.pagination != other.pagination: + return False + return True + +class _UniffiFfiConverterTypePlayerAchievementQuery(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PlayerAchievementQuery( + world_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + namespaces=_UniffiFfiConverterSequenceString.read(buf), + player_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + pagination=_UniffiFfiConverterTypePagination.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.world_addresses) + _UniffiFfiConverterSequenceString.check_lower(value.namespaces) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.player_addresses) + _UniffiFfiConverterTypePagination.check_lower(value.pagination) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeFieldElement.write(value.world_addresses, buf) + _UniffiFfiConverterSequenceString.write(value.namespaces, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.player_addresses, buf) + _UniffiFfiConverterTypePagination.write(value.pagination, buf) + +@dataclass +class Signature: + def __init__(self, *, r:FieldElement, s:FieldElement): + self.r = r + self.s = s + + + + + def __str__(self): + return "Signature(r={}, s={})".format(self.r, self.s) + def __eq__(self, other): + if self.r != other.r: + return False + if self.s != other.s: + return False + return True + +class _UniffiFfiConverterTypeSignature(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Signature( + r=_UniffiFfiConverterTypeFieldElement.read(buf), + s=_UniffiFfiConverterTypeFieldElement.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeFieldElement.check_lower(value.r) + _UniffiFfiConverterTypeFieldElement.check_lower(value.s) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeFieldElement.write(value.r, buf) + _UniffiFfiConverterTypeFieldElement.write(value.s, buf) + +class _UniffiFfiConverterOptionalTypeU256(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiFfiConverterTypeU256.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiFfiConverterTypeU256.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiFfiConverterTypeU256.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + +@dataclass +class Token: + def __init__(self, *, contract_address:FieldElement, token_id:typing.Optional[U256], name:str, symbol:str, decimals:int, metadata:str, total_supply:typing.Optional[U256]): + self.contract_address = contract_address + self.token_id = token_id + self.name = name + self.symbol = symbol + self.decimals = decimals + self.metadata = metadata + self.total_supply = total_supply + + + + + def __str__(self): + return "Token(contract_address={}, token_id={}, name={}, symbol={}, decimals={}, metadata={}, total_supply={})".format(self.contract_address, self.token_id, self.name, self.symbol, self.decimals, self.metadata, self.total_supply) + def __eq__(self, other): + if self.contract_address != other.contract_address: + return False + if self.token_id != other.token_id: + return False + if self.name != other.name: + return False + if self.symbol != other.symbol: + return False + if self.decimals != other.decimals: + return False + if self.metadata != other.metadata: + return False + if self.total_supply != other.total_supply: + return False + return True + +class _UniffiFfiConverterTypeToken(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Token( + contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), + token_id=_UniffiFfiConverterOptionalTypeU256.read(buf), + name=_UniffiFfiConverterString.read(buf), + symbol=_UniffiFfiConverterString.read(buf), + decimals=_UniffiFfiConverterUInt8.read(buf), + metadata=_UniffiFfiConverterString.read(buf), + total_supply=_UniffiFfiConverterOptionalTypeU256.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) + _UniffiFfiConverterOptionalTypeU256.check_lower(value.token_id) + _UniffiFfiConverterString.check_lower(value.name) + _UniffiFfiConverterString.check_lower(value.symbol) + _UniffiFfiConverterUInt8.check_lower(value.decimals) + _UniffiFfiConverterString.check_lower(value.metadata) + _UniffiFfiConverterOptionalTypeU256.check_lower(value.total_supply) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) + _UniffiFfiConverterOptionalTypeU256.write(value.token_id, buf) + _UniffiFfiConverterString.write(value.name, buf) + _UniffiFfiConverterString.write(value.symbol, buf) + _UniffiFfiConverterUInt8.write(value.decimals, buf) + _UniffiFfiConverterString.write(value.metadata, buf) + _UniffiFfiConverterOptionalTypeU256.write(value.total_supply, buf) + +@dataclass +class TokenBalance: + def __init__(self, *, balance:U256, account_address:FieldElement, contract_address:FieldElement, token_id:typing.Optional[U256]): + self.balance = balance + self.account_address = account_address + self.contract_address = contract_address + self.token_id = token_id + + + + + def __str__(self): + return "TokenBalance(balance={}, account_address={}, contract_address={}, token_id={})".format(self.balance, self.account_address, self.contract_address, self.token_id) + def __eq__(self, other): + if self.balance != other.balance: + return False + if self.account_address != other.account_address: + return False + if self.contract_address != other.contract_address: + return False + if self.token_id != other.token_id: + return False + return True + +class _UniffiFfiConverterTypeTokenBalance(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TokenBalance( + balance=_UniffiFfiConverterTypeU256.read(buf), + account_address=_UniffiFfiConverterTypeFieldElement.read(buf), + contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), + token_id=_UniffiFfiConverterOptionalTypeU256.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeU256.check_lower(value.balance) + _UniffiFfiConverterTypeFieldElement.check_lower(value.account_address) + _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) + _UniffiFfiConverterOptionalTypeU256.check_lower(value.token_id) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeU256.write(value.balance, buf) + _UniffiFfiConverterTypeFieldElement.write(value.account_address, buf) + _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) + _UniffiFfiConverterOptionalTypeU256.write(value.token_id, buf) + +class _UniffiFfiConverterSequenceTypeU256(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeU256.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeU256.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeU256.read(buf) for i in range(count) + ] + +@dataclass +class TokenBalanceQuery: + def __init__(self, *, contract_addresses:typing.List[FieldElement], account_addresses:typing.List[FieldElement], token_ids:typing.List[U256], pagination:Pagination): + self.contract_addresses = contract_addresses + self.account_addresses = account_addresses + self.token_ids = token_ids + self.pagination = pagination + + + + + def __str__(self): + return "TokenBalanceQuery(contract_addresses={}, account_addresses={}, token_ids={}, pagination={})".format(self.contract_addresses, self.account_addresses, self.token_ids, self.pagination) + def __eq__(self, other): + if self.contract_addresses != other.contract_addresses: + return False + if self.account_addresses != other.account_addresses: + return False + if self.token_ids != other.token_ids: + return False + if self.pagination != other.pagination: + return False + return True + +class _UniffiFfiConverterTypeTokenBalanceQuery(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TokenBalanceQuery( + contract_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + account_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + token_ids=_UniffiFfiConverterSequenceTypeU256.read(buf), + pagination=_UniffiFfiConverterTypePagination.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.contract_addresses) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.account_addresses) + _UniffiFfiConverterSequenceTypeU256.check_lower(value.token_ids) + _UniffiFfiConverterTypePagination.check_lower(value.pagination) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeFieldElement.write(value.contract_addresses, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.account_addresses, buf) + _UniffiFfiConverterSequenceTypeU256.write(value.token_ids, buf) + _UniffiFfiConverterTypePagination.write(value.pagination, buf) + +@dataclass +class TokenContract: + def __init__(self, *, contract_address:FieldElement, name:str, symbol:str, decimals:int, metadata:str, token_metadata:str, total_supply:typing.Optional[U256]): + self.contract_address = contract_address + self.name = name + self.symbol = symbol + self.decimals = decimals + self.metadata = metadata + self.token_metadata = token_metadata + self.total_supply = total_supply + + + + + def __str__(self): + return "TokenContract(contract_address={}, name={}, symbol={}, decimals={}, metadata={}, token_metadata={}, total_supply={})".format(self.contract_address, self.name, self.symbol, self.decimals, self.metadata, self.token_metadata, self.total_supply) + def __eq__(self, other): + if self.contract_address != other.contract_address: + return False + if self.name != other.name: + return False + if self.symbol != other.symbol: + return False + if self.decimals != other.decimals: + return False + if self.metadata != other.metadata: + return False + if self.token_metadata != other.token_metadata: + return False + if self.total_supply != other.total_supply: + return False + return True + +class _UniffiFfiConverterTypeTokenContract(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TokenContract( + contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), + name=_UniffiFfiConverterString.read(buf), + symbol=_UniffiFfiConverterString.read(buf), + decimals=_UniffiFfiConverterUInt8.read(buf), + metadata=_UniffiFfiConverterString.read(buf), + token_metadata=_UniffiFfiConverterString.read(buf), + total_supply=_UniffiFfiConverterOptionalTypeU256.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) + _UniffiFfiConverterString.check_lower(value.name) + _UniffiFfiConverterString.check_lower(value.symbol) + _UniffiFfiConverterUInt8.check_lower(value.decimals) + _UniffiFfiConverterString.check_lower(value.metadata) + _UniffiFfiConverterString.check_lower(value.token_metadata) + _UniffiFfiConverterOptionalTypeU256.check_lower(value.total_supply) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) + _UniffiFfiConverterString.write(value.name, buf) + _UniffiFfiConverterString.write(value.symbol, buf) + _UniffiFfiConverterUInt8.write(value.decimals, buf) + _UniffiFfiConverterString.write(value.metadata, buf) + _UniffiFfiConverterString.write(value.token_metadata, buf) + _UniffiFfiConverterOptionalTypeU256.write(value.total_supply, buf) + +@dataclass +class TokenContractQuery: + def __init__(self, *, contract_addresses:typing.List[FieldElement], contract_types:typing.List[ContractType], pagination:Pagination): + self.contract_addresses = contract_addresses + self.contract_types = contract_types + self.pagination = pagination + + + + + def __str__(self): + return "TokenContractQuery(contract_addresses={}, contract_types={}, pagination={})".format(self.contract_addresses, self.contract_types, self.pagination) + def __eq__(self, other): + if self.contract_addresses != other.contract_addresses: + return False + if self.contract_types != other.contract_types: + return False + if self.pagination != other.pagination: + return False + return True + +class _UniffiFfiConverterTypeTokenContractQuery(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TokenContractQuery( + contract_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + contract_types=_UniffiFfiConverterSequenceTypeContractType.read(buf), + pagination=_UniffiFfiConverterTypePagination.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.contract_addresses) + _UniffiFfiConverterSequenceTypeContractType.check_lower(value.contract_types) + _UniffiFfiConverterTypePagination.check_lower(value.pagination) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeFieldElement.write(value.contract_addresses, buf) + _UniffiFfiConverterSequenceTypeContractType.write(value.contract_types, buf) + _UniffiFfiConverterTypePagination.write(value.pagination, buf) + +class _UniffiFfiConverterSequenceTypeAttributeFilter(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeAttributeFilter.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeAttributeFilter.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeAttributeFilter.read(buf) for i in range(count) + ] + +@dataclass +class TokenQuery: + def __init__(self, *, contract_addresses:typing.List[FieldElement], token_ids:typing.List[U256], attribute_filters:typing.List[AttributeFilter], pagination:Pagination): + self.contract_addresses = contract_addresses + self.token_ids = token_ids + self.attribute_filters = attribute_filters + self.pagination = pagination + + + + + def __str__(self): + return "TokenQuery(contract_addresses={}, token_ids={}, attribute_filters={}, pagination={})".format(self.contract_addresses, self.token_ids, self.attribute_filters, self.pagination) + def __eq__(self, other): + if self.contract_addresses != other.contract_addresses: + return False + if self.token_ids != other.token_ids: + return False + if self.attribute_filters != other.attribute_filters: + return False + if self.pagination != other.pagination: + return False + return True + +class _UniffiFfiConverterTypeTokenQuery(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TokenQuery( + contract_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + token_ids=_UniffiFfiConverterSequenceTypeU256.read(buf), + attribute_filters=_UniffiFfiConverterSequenceTypeAttributeFilter.read(buf), + pagination=_UniffiFfiConverterTypePagination.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.contract_addresses) + _UniffiFfiConverterSequenceTypeU256.check_lower(value.token_ids) + _UniffiFfiConverterSequenceTypeAttributeFilter.check_lower(value.attribute_filters) + _UniffiFfiConverterTypePagination.check_lower(value.pagination) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeFieldElement.write(value.contract_addresses, buf) + _UniffiFfiConverterSequenceTypeU256.write(value.token_ids, buf) + _UniffiFfiConverterSequenceTypeAttributeFilter.write(value.attribute_filters, buf) + _UniffiFfiConverterTypePagination.write(value.pagination, buf) + +@dataclass +class TokenTransfer: + def __init__(self, *, id:str, contract_address:FieldElement, from_address:FieldElement, to_address:FieldElement, amount:U256, token_id:typing.Optional[U256], executed_at:int, event_id:typing.Optional[str]): + self.id = id + self.contract_address = contract_address + self.from_address = from_address + self.to_address = to_address + self.amount = amount + self.token_id = token_id + self.executed_at = executed_at + self.event_id = event_id + + + + + def __str__(self): + return "TokenTransfer(id={}, contract_address={}, from_address={}, to_address={}, amount={}, token_id={}, executed_at={}, event_id={})".format(self.id, self.contract_address, self.from_address, self.to_address, self.amount, self.token_id, self.executed_at, self.event_id) + def __eq__(self, other): + if self.id != other.id: + return False + if self.contract_address != other.contract_address: + return False + if self.from_address != other.from_address: + return False + if self.to_address != other.to_address: + return False + if self.amount != other.amount: + return False + if self.token_id != other.token_id: + return False + if self.executed_at != other.executed_at: + return False + if self.event_id != other.event_id: + return False + return True + +class _UniffiFfiConverterTypeTokenTransfer(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TokenTransfer( + id=_UniffiFfiConverterString.read(buf), + contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), + from_address=_UniffiFfiConverterTypeFieldElement.read(buf), + to_address=_UniffiFfiConverterTypeFieldElement.read(buf), + amount=_UniffiFfiConverterTypeU256.read(buf), + token_id=_UniffiFfiConverterOptionalTypeU256.read(buf), + executed_at=_UniffiFfiConverterUInt64.read(buf), + event_id=_UniffiFfiConverterOptionalString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.id) + _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) + _UniffiFfiConverterTypeFieldElement.check_lower(value.from_address) + _UniffiFfiConverterTypeFieldElement.check_lower(value.to_address) + _UniffiFfiConverterTypeU256.check_lower(value.amount) + _UniffiFfiConverterOptionalTypeU256.check_lower(value.token_id) + _UniffiFfiConverterUInt64.check_lower(value.executed_at) + _UniffiFfiConverterOptionalString.check_lower(value.event_id) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.id, buf) + _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) + _UniffiFfiConverterTypeFieldElement.write(value.from_address, buf) + _UniffiFfiConverterTypeFieldElement.write(value.to_address, buf) + _UniffiFfiConverterTypeU256.write(value.amount, buf) + _UniffiFfiConverterOptionalTypeU256.write(value.token_id, buf) + _UniffiFfiConverterUInt64.write(value.executed_at, buf) + _UniffiFfiConverterOptionalString.write(value.event_id, buf) + +@dataclass +class TokenTransferQuery: + def __init__(self, *, contract_addresses:typing.List[FieldElement], account_addresses:typing.List[FieldElement], token_ids:typing.List[U256], pagination:Pagination): + self.contract_addresses = contract_addresses + self.account_addresses = account_addresses + self.token_ids = token_ids + self.pagination = pagination + + + + + def __str__(self): + return "TokenTransferQuery(contract_addresses={}, account_addresses={}, token_ids={}, pagination={})".format(self.contract_addresses, self.account_addresses, self.token_ids, self.pagination) + def __eq__(self, other): + if self.contract_addresses != other.contract_addresses: + return False + if self.account_addresses != other.account_addresses: + return False + if self.token_ids != other.token_ids: + return False + if self.pagination != other.pagination: + return False + return True + +class _UniffiFfiConverterTypeTokenTransferQuery(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TokenTransferQuery( + contract_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + account_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + token_ids=_UniffiFfiConverterSequenceTypeU256.read(buf), + pagination=_UniffiFfiConverterTypePagination.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.contract_addresses) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.account_addresses) + _UniffiFfiConverterSequenceTypeU256.check_lower(value.token_ids) + _UniffiFfiConverterTypePagination.check_lower(value.pagination) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeFieldElement.write(value.contract_addresses, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.account_addresses, buf) + _UniffiFfiConverterSequenceTypeU256.write(value.token_ids, buf) + _UniffiFfiConverterTypePagination.write(value.pagination, buf) + + + + + + +class CallType(enum.Enum): + + EXECUTE = 0 + + EXECUTE_FROM_OUTSIDE = 1 + + + +class _UniffiFfiConverterTypeCallType(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return CallType.EXECUTE + if variant == 2: + return CallType.EXECUTE_FROM_OUTSIDE + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == CallType.EXECUTE: + return + if value == CallType.EXECUTE_FROM_OUTSIDE: + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value == CallType.EXECUTE: + buf.write_i32(1) + if value == CallType.EXECUTE_FROM_OUTSIDE: + buf.write_i32(2) + + + +@dataclass +class TransactionCall: + def __init__(self, *, contract_address:FieldElement, entrypoint:str, calldata:typing.List[FieldElement], call_type:CallType, caller_address:FieldElement): + self.contract_address = contract_address + self.entrypoint = entrypoint + self.calldata = calldata + self.call_type = call_type + self.caller_address = caller_address + + + + + def __str__(self): + return "TransactionCall(contract_address={}, entrypoint={}, calldata={}, call_type={}, caller_address={})".format(self.contract_address, self.entrypoint, self.calldata, self.call_type, self.caller_address) + def __eq__(self, other): + if self.contract_address != other.contract_address: + return False + if self.entrypoint != other.entrypoint: + return False + if self.calldata != other.calldata: + return False + if self.call_type != other.call_type: + return False + if self.caller_address != other.caller_address: + return False + return True + +class _UniffiFfiConverterTypeTransactionCall(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TransactionCall( + contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), + entrypoint=_UniffiFfiConverterString.read(buf), + calldata=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + call_type=_UniffiFfiConverterTypeCallType.read(buf), + caller_address=_UniffiFfiConverterTypeFieldElement.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) + _UniffiFfiConverterString.check_lower(value.entrypoint) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.calldata) + _UniffiFfiConverterTypeCallType.check_lower(value.call_type) + _UniffiFfiConverterTypeFieldElement.check_lower(value.caller_address) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) + _UniffiFfiConverterString.write(value.entrypoint, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.calldata, buf) + _UniffiFfiConverterTypeCallType.write(value.call_type, buf) + _UniffiFfiConverterTypeFieldElement.write(value.caller_address, buf) + +class _UniffiFfiConverterSequenceTypeTransactionCall(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeTransactionCall.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeTransactionCall.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeTransactionCall.read(buf) for i in range(count) + ] + +@dataclass +class Transaction: + def __init__(self, *, transaction_hash:FieldElement, sender_address:FieldElement, calldata:typing.List[FieldElement], max_fee:FieldElement, signature:typing.List[FieldElement], nonce:FieldElement, block_number:int, transaction_type:str, block_timestamp:int, calls:typing.List[TransactionCall], unique_models:typing.List[FieldElement]): + self.transaction_hash = transaction_hash + self.sender_address = sender_address + self.calldata = calldata + self.max_fee = max_fee + self.signature = signature + self.nonce = nonce + self.block_number = block_number + self.transaction_type = transaction_type + self.block_timestamp = block_timestamp + self.calls = calls + self.unique_models = unique_models + + + + + def __str__(self): + return "Transaction(transaction_hash={}, sender_address={}, calldata={}, max_fee={}, signature={}, nonce={}, block_number={}, transaction_type={}, block_timestamp={}, calls={}, unique_models={})".format(self.transaction_hash, self.sender_address, self.calldata, self.max_fee, self.signature, self.nonce, self.block_number, self.transaction_type, self.block_timestamp, self.calls, self.unique_models) + def __eq__(self, other): + if self.transaction_hash != other.transaction_hash: + return False + if self.sender_address != other.sender_address: + return False + if self.calldata != other.calldata: + return False + if self.max_fee != other.max_fee: + return False + if self.signature != other.signature: + return False + if self.nonce != other.nonce: + return False + if self.block_number != other.block_number: + return False + if self.transaction_type != other.transaction_type: + return False + if self.block_timestamp != other.block_timestamp: + return False + if self.calls != other.calls: + return False + if self.unique_models != other.unique_models: + return False + return True + +class _UniffiFfiConverterTypeTransaction(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Transaction( + transaction_hash=_UniffiFfiConverterTypeFieldElement.read(buf), + sender_address=_UniffiFfiConverterTypeFieldElement.read(buf), + calldata=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + max_fee=_UniffiFfiConverterTypeFieldElement.read(buf), + signature=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + nonce=_UniffiFfiConverterTypeFieldElement.read(buf), + block_number=_UniffiFfiConverterUInt64.read(buf), + transaction_type=_UniffiFfiConverterString.read(buf), + block_timestamp=_UniffiFfiConverterUInt64.read(buf), + calls=_UniffiFfiConverterSequenceTypeTransactionCall.read(buf), + unique_models=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeFieldElement.check_lower(value.transaction_hash) + _UniffiFfiConverterTypeFieldElement.check_lower(value.sender_address) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.calldata) + _UniffiFfiConverterTypeFieldElement.check_lower(value.max_fee) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.signature) + _UniffiFfiConverterTypeFieldElement.check_lower(value.nonce) + _UniffiFfiConverterUInt64.check_lower(value.block_number) + _UniffiFfiConverterString.check_lower(value.transaction_type) + _UniffiFfiConverterUInt64.check_lower(value.block_timestamp) + _UniffiFfiConverterSequenceTypeTransactionCall.check_lower(value.calls) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.unique_models) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeFieldElement.write(value.transaction_hash, buf) + _UniffiFfiConverterTypeFieldElement.write(value.sender_address, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.calldata, buf) + _UniffiFfiConverterTypeFieldElement.write(value.max_fee, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.signature, buf) + _UniffiFfiConverterTypeFieldElement.write(value.nonce, buf) + _UniffiFfiConverterUInt64.write(value.block_number, buf) + _UniffiFfiConverterString.write(value.transaction_type, buf) + _UniffiFfiConverterUInt64.write(value.block_timestamp, buf) + _UniffiFfiConverterSequenceTypeTransactionCall.write(value.calls, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.unique_models, buf) + +@dataclass +class TransactionFilter: + def __init__(self, *, transaction_hashes:typing.List[FieldElement], caller_addresses:typing.List[FieldElement], contract_addresses:typing.List[FieldElement], entrypoints:typing.List[str], model_selectors:typing.List[FieldElement], from_block:typing.Optional[int], to_block:typing.Optional[int]): + self.transaction_hashes = transaction_hashes + self.caller_addresses = caller_addresses + self.contract_addresses = contract_addresses + self.entrypoints = entrypoints + self.model_selectors = model_selectors + self.from_block = from_block + self.to_block = to_block + + + + + def __str__(self): + return "TransactionFilter(transaction_hashes={}, caller_addresses={}, contract_addresses={}, entrypoints={}, model_selectors={}, from_block={}, to_block={})".format(self.transaction_hashes, self.caller_addresses, self.contract_addresses, self.entrypoints, self.model_selectors, self.from_block, self.to_block) + def __eq__(self, other): + if self.transaction_hashes != other.transaction_hashes: + return False + if self.caller_addresses != other.caller_addresses: + return False + if self.contract_addresses != other.contract_addresses: + return False + if self.entrypoints != other.entrypoints: + return False + if self.model_selectors != other.model_selectors: + return False + if self.from_block != other.from_block: + return False + if self.to_block != other.to_block: + return False + return True + +class _UniffiFfiConverterTypeTransactionFilter(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TransactionFilter( + transaction_hashes=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + caller_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + contract_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + entrypoints=_UniffiFfiConverterSequenceString.read(buf), + model_selectors=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + from_block=_UniffiFfiConverterOptionalUInt64.read(buf), + to_block=_UniffiFfiConverterOptionalUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.transaction_hashes) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.caller_addresses) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.contract_addresses) + _UniffiFfiConverterSequenceString.check_lower(value.entrypoints) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.model_selectors) + _UniffiFfiConverterOptionalUInt64.check_lower(value.from_block) + _UniffiFfiConverterOptionalUInt64.check_lower(value.to_block) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeFieldElement.write(value.transaction_hashes, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.caller_addresses, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.contract_addresses, buf) + _UniffiFfiConverterSequenceString.write(value.entrypoints, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.model_selectors, buf) + _UniffiFfiConverterOptionalUInt64.write(value.from_block, buf) + _UniffiFfiConverterOptionalUInt64.write(value.to_block, buf) + +class _UniffiFfiConverterOptionalTypeTransactionFilter(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiFfiConverterTypeTransactionFilter.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiFfiConverterTypeTransactionFilter.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiFfiConverterTypeTransactionFilter.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + +@dataclass +class TransactionQuery: + def __init__(self, *, filter:typing.Optional[TransactionFilter], pagination:Pagination): + self.filter = filter + self.pagination = pagination + + + + + def __str__(self): + return "TransactionQuery(filter={}, pagination={})".format(self.filter, self.pagination) + def __eq__(self, other): + if self.filter != other.filter: + return False + if self.pagination != other.pagination: + return False + return True + +class _UniffiFfiConverterTypeTransactionQuery(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TransactionQuery( + filter=_UniffiFfiConverterOptionalTypeTransactionFilter.read(buf), + pagination=_UniffiFfiConverterTypePagination.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterOptionalTypeTransactionFilter.check_lower(value.filter) + _UniffiFfiConverterTypePagination.check_lower(value.pagination) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterOptionalTypeTransactionFilter.write(value.filter, buf) + _UniffiFfiConverterTypePagination.write(value.pagination, buf) + + + +# DojoError +# We want to define each variant as a nested class that's also a subclass, +# which is tricky in Python. To accomplish this we're going to create each +# class separately, then manually add the child classes to the base class's +# __dict__. All of this happens in dummy class to avoid polluting the module +# namespace. +class DojoError(Exception): + pass + +_UniffiTempDojoError = DojoError + +class DojoError: # type: ignore + + class ClientError(_UniffiTempDojoError): + def __repr__(self): + return "DojoError.ClientError({})".format(repr(str(self))) + _UniffiTempDojoError.ClientError = ClientError # type: ignore + class SerializationError(_UniffiTempDojoError): + def __repr__(self): + return "DojoError.SerializationError({})".format(repr(str(self))) + _UniffiTempDojoError.SerializationError = SerializationError # type: ignore + class NetworkError(_UniffiTempDojoError): + def __repr__(self): + return "DojoError.NetworkError({})".format(repr(str(self))) + _UniffiTempDojoError.NetworkError = NetworkError # type: ignore + class InvalidInput(_UniffiTempDojoError): + def __repr__(self): + return "DojoError.InvalidInput({})".format(repr(str(self))) + _UniffiTempDojoError.InvalidInput = InvalidInput # type: ignore + +DojoError = _UniffiTempDojoError # type: ignore +del _UniffiTempDojoError + + +class _UniffiFfiConverterTypeDojoError(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return DojoError.ClientError( + _UniffiFfiConverterString.read(buf), + ) + if variant == 2: + return DojoError.SerializationError( + _UniffiFfiConverterString.read(buf), + ) + if variant == 3: + return DojoError.NetworkError( + _UniffiFfiConverterString.read(buf), + ) + if variant == 4: + return DojoError.InvalidInput( + _UniffiFfiConverterString.read(buf), + ) + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if isinstance(value, DojoError.ClientError): + return + if isinstance(value, DojoError.SerializationError): + return + if isinstance(value, DojoError.NetworkError): + return + if isinstance(value, DojoError.InvalidInput): + return + + @staticmethod + def write(value, buf): + if isinstance(value, DojoError.ClientError): + buf.write_i32(1) + if isinstance(value, DojoError.SerializationError): + buf.write_i32(2) + if isinstance(value, DojoError.NetworkError): + buf.write_i32(3) + if isinstance(value, DojoError.InvalidInput): + buf.write_i32(4) + + + + + + +class ValueType: + def __init__(self): + raise RuntimeError("ValueType cannot be instantiated directly") + + # Each enum variant is a nested class of the enum itself. + @dataclass + class STRING: + + def __init__(self, value:str): + self.value = value + + + pass + + + + + + def __str__(self): + return "ValueType.STRING(value={})".format(self.value) + def __eq__(self, other): + if not other.is_STRING(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class INT: + + def __init__(self, value:int): + self.value = value + + + pass + + + + + + def __str__(self): + return "ValueType.INT(value={})".format(self.value) + def __eq__(self, other): + if not other.is_INT(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class U_INT: + + def __init__(self, value:int): + self.value = value + + + pass + + + + + + def __str__(self): + return "ValueType.U_INT(value={})".format(self.value) + def __eq__(self, other): + if not other.is_U_INT(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class BOOL: + + def __init__(self, value:bool): + self.value = value + + + pass + + + + + + def __str__(self): + return "ValueType.BOOL(value={})".format(self.value) + def __eq__(self, other): + if not other.is_BOOL(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class BYTES: + + def __init__(self, value:typing.List[int]): + self.value = value + + + pass + + + + + + def __str__(self): + return "ValueType.BYTES(value={})".format(self.value) + def __eq__(self, other): + if not other.is_BYTES(): + return False + if self.value != other.value: + return False + return True + + + + # For each variant, we have `is_NAME` and `is_name` methods for easily checking + # whether an instance is that variant. + def is_STRING(self) -> bool: + return isinstance(self, ValueType.STRING) + def is_string(self) -> bool: + return isinstance(self, ValueType.STRING) + def is_INT(self) -> bool: + return isinstance(self, ValueType.INT) + def is_int(self) -> bool: + return isinstance(self, ValueType.INT) + def is_U_INT(self) -> bool: + return isinstance(self, ValueType.U_INT) + def is_u_int(self) -> bool: + return isinstance(self, ValueType.U_INT) + def is_BOOL(self) -> bool: + return isinstance(self, ValueType.BOOL) + def is_bool(self) -> bool: + return isinstance(self, ValueType.BOOL) + def is_BYTES(self) -> bool: + return isinstance(self, ValueType.BYTES) + def is_bytes(self) -> bool: + return isinstance(self, ValueType.BYTES) + + +# Now, a little trick - we make each nested variant class be a subclass of the main +# enum class, so that method calls and instance checks etc will work intuitively. +# We might be able to do this a little more neatly with a metaclass, but this'll do. +ValueType.STRING = type("ValueType.STRING", (ValueType.STRING, ValueType,), {}) # type: ignore +ValueType.INT = type("ValueType.INT", (ValueType.INT, ValueType,), {}) # type: ignore +ValueType.U_INT = type("ValueType.U_INT", (ValueType.U_INT, ValueType,), {}) # type: ignore +ValueType.BOOL = type("ValueType.BOOL", (ValueType.BOOL, ValueType,), {}) # type: ignore +ValueType.BYTES = type("ValueType.BYTES", (ValueType.BYTES, ValueType,), {}) # type: ignore + + + + +class _UniffiFfiConverterTypeValueType(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return ValueType.STRING( + _UniffiFfiConverterString.read(buf), + ) + if variant == 2: + return ValueType.INT( + _UniffiFfiConverterInt64.read(buf), + ) + if variant == 3: + return ValueType.U_INT( + _UniffiFfiConverterUInt64.read(buf), + ) + if variant == 4: + return ValueType.BOOL( + _UniffiFfiConverterBoolean.read(buf), + ) + if variant == 5: + return ValueType.BYTES( + _UniffiFfiConverterSequenceUInt8.read(buf), + ) + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value.is_STRING(): + _UniffiFfiConverterString.check_lower(value.value) + return + if value.is_INT(): + _UniffiFfiConverterInt64.check_lower(value.value) + return + if value.is_U_INT(): + _UniffiFfiConverterUInt64.check_lower(value.value) + return + if value.is_BOOL(): + _UniffiFfiConverterBoolean.check_lower(value.value) + return + if value.is_BYTES(): + _UniffiFfiConverterSequenceUInt8.check_lower(value.value) + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value.is_STRING(): + buf.write_i32(1) + _UniffiFfiConverterString.write(value.value, buf) + if value.is_INT(): + buf.write_i32(2) + _UniffiFfiConverterInt64.write(value.value, buf) + if value.is_U_INT(): + buf.write_i32(3) + _UniffiFfiConverterUInt64.write(value.value, buf) + if value.is_BOOL(): + buf.write_i32(4) + _UniffiFfiConverterBoolean.write(value.value, buf) + if value.is_BYTES(): + buf.write_i32(5) + _UniffiFfiConverterSequenceUInt8.write(value.value, buf) + + + +__all__ = [ + "InternalError", + "PaginationDirection", + "OrderDirection", + "LogicalOperator", + "PatternMatching", + "ComparisonOperator", + "Primitive", + "MemberValue", + "Clause", + "ContractType", + "Ty", + "CallType", + "DojoError", + "ValueType", + "AchievementTask", + "Achievement", + "AchievementProgression", + "OrderBy", + "Pagination", + "AchievementQuery", + "ActionCount", + "Activity", + "ActivityQuery", + "AggregationEntry", + "AggregationQuery", + "AttributeFilter", + "KeysClause", + "MemberClause", + "CompositeClause", + "Contract", + "ContractQuery", + "Controller", + "ControllerQuery", + "Member", + "Struct", + "EnumType", + "FixedSizeArray", + "EnumOption", + "PlayerAchievementStats", + "TaskProgress", + "PlayerAchievementProgress", + "PlayerAchievementEntry", + "PlayerAchievementQuery", + "Signature", + "Token", + "TokenBalance", + "TokenBalanceQuery", + "TokenContract", + "TokenContractQuery", + "TokenQuery", + "TokenTransfer", + "TokenTransferQuery", + "TransactionCall", + "Transaction", + "TransactionFilter", + "TransactionQuery", +] \ No newline at end of file diff --git a/bindings/swift/DojoEngine.swift b/bindings/swift/DojoEngine.swift new file mode 100644 index 0000000..d6b9a57 --- /dev/null +++ b/bindings/swift/DojoEngine.swift @@ -0,0 +1,5294 @@ +// This file was autogenerated by some hot garbage in the `uniffi` crate. +// Trust me, you don't want to mess with it! + +// swiftlint:disable all +import Foundation + +// Depending on the consumer's build setup, the low-level FFI code +// might be in a separate module, or it might be compiled inline into +// this module. This is a bit of light hackery to work with both. +#if canImport(DojoEngineFFI) +import DojoEngineFFI +#endif + +fileprivate extension RustBuffer { + // Allocate a new buffer, copying the contents of a `UInt8` array. + init(bytes: [UInt8]) { + let rbuf = bytes.withUnsafeBufferPointer { ptr in + RustBuffer.from(ptr) + } + self.init(capacity: rbuf.capacity, len: rbuf.len, data: rbuf.data) + } + + static func empty() -> RustBuffer { + RustBuffer(capacity: 0, len:0, data: nil) + } + + static func from(_ ptr: UnsafeBufferPointer) -> RustBuffer { + try! rustCall { ffi_dojo_c_rustbuffer_from_bytes(ForeignBytes(bufferPointer: ptr), $0) } + } + + // Frees the buffer in place. + // The buffer must not be used after this is called. + func deallocate() { + try! rustCall { ffi_dojo_c_rustbuffer_free(self, $0) } + } +} + +fileprivate extension ForeignBytes { + init(bufferPointer: UnsafeBufferPointer) { + self.init(len: Int32(bufferPointer.count), data: bufferPointer.baseAddress) + } +} + +// For every type used in the interface, we provide helper methods for conveniently +// lifting and lowering that type from C-compatible data, and for reading and writing +// values of that type in a buffer. + +// Helper classes/extensions that don't change. +// Someday, this will be in a library of its own. + +fileprivate extension Data { + init(rustBuffer: RustBuffer) { + self.init( + bytesNoCopy: rustBuffer.data!, + count: Int(rustBuffer.len), + deallocator: .none + ) + } +} + +// Define reader functionality. Normally this would be defined in a class or +// struct, but we use standalone functions instead in order to make external +// types work. +// +// With external types, one swift source file needs to be able to call the read +// method on another source file's FfiConverter, but then what visibility +// should Reader have? +// - If Reader is fileprivate, then this means the read() must also +// be fileprivate, which doesn't work with external types. +// - If Reader is internal/public, we'll get compile errors since both source +// files will try define the same type. +// +// Instead, the read() method and these helper functions input a tuple of data + +fileprivate func createReader(data: Data) -> (data: Data, offset: Data.Index) { + (data: data, offset: 0) +} + +// Reads an integer at the current offset, in big-endian order, and advances +// the offset on success. Throws if reading the integer would move the +// offset past the end of the buffer. +fileprivate func readInt(_ reader: inout (data: Data, offset: Data.Index)) throws -> T { + let range = reader.offset...size + guard reader.data.count >= range.upperBound else { + throw UniffiInternalError.bufferOverflow + } + if T.self == UInt8.self { + let value = reader.data[reader.offset] + reader.offset += 1 + return value as! T + } + var value: T = 0 + let _ = withUnsafeMutableBytes(of: &value, { reader.data.copyBytes(to: $0, from: range)}) + reader.offset = range.upperBound + return value.bigEndian +} + +// Reads an arbitrary number of bytes, to be used to read +// raw bytes, this is useful when lifting strings +fileprivate func readBytes(_ reader: inout (data: Data, offset: Data.Index), count: Int) throws -> Array { + let range = reader.offset..<(reader.offset+count) + guard reader.data.count >= range.upperBound else { + throw UniffiInternalError.bufferOverflow + } + var value = [UInt8](repeating: 0, count: count) + value.withUnsafeMutableBufferPointer({ buffer in + reader.data.copyBytes(to: buffer, from: range) + }) + reader.offset = range.upperBound + return value +} + +// Reads a float at the current offset. +fileprivate func readFloat(_ reader: inout (data: Data, offset: Data.Index)) throws -> Float { + return Float(bitPattern: try readInt(&reader)) +} + +// Reads a float at the current offset. +fileprivate func readDouble(_ reader: inout (data: Data, offset: Data.Index)) throws -> Double { + return Double(bitPattern: try readInt(&reader)) +} + +// Indicates if the offset has reached the end of the buffer. +fileprivate func hasRemaining(_ reader: (data: Data, offset: Data.Index)) -> Bool { + return reader.offset < reader.data.count +} + +// Define writer functionality. Normally this would be defined in a class or +// struct, but we use standalone functions instead in order to make external +// types work. See the above discussion on Readers for details. + +fileprivate func createWriter() -> [UInt8] { + return [] +} + +fileprivate func writeBytes(_ writer: inout [UInt8], _ byteArr: S) where S: Sequence, S.Element == UInt8 { + writer.append(contentsOf: byteArr) +} + +// Writes an integer in big-endian order. +// +// Warning: make sure what you are trying to write +// is in the correct type! +fileprivate func writeInt(_ writer: inout [UInt8], _ value: T) { + var value = value.bigEndian + withUnsafeBytes(of: &value) { writer.append(contentsOf: $0) } +} + +fileprivate func writeFloat(_ writer: inout [UInt8], _ value: Float) { + writeInt(&writer, value.bitPattern) +} + +fileprivate func writeDouble(_ writer: inout [UInt8], _ value: Double) { + writeInt(&writer, value.bitPattern) +} + +// Protocol for types that transfer other types across the FFI. This is +// analogous to the Rust trait of the same name. +fileprivate protocol FfiConverter { + associatedtype FfiType + associatedtype SwiftType + + static func lift(_ value: FfiType) throws -> SwiftType + static func lower(_ value: SwiftType) -> FfiType + static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType + static func write(_ value: SwiftType, into buf: inout [UInt8]) +} + +// Types conforming to `Primitive` pass themselves directly over the FFI. +fileprivate protocol FfiConverterPrimitive: FfiConverter where FfiType == SwiftType { } + +extension FfiConverterPrimitive { +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public static func lift(_ value: FfiType) throws -> SwiftType { + return value + } + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public static func lower(_ value: SwiftType) -> FfiType { + return value + } +} + +// Types conforming to `FfiConverterRustBuffer` lift and lower into a `RustBuffer`. +// Used for complex types where it's hard to write a custom lift/lower. +fileprivate protocol FfiConverterRustBuffer: FfiConverter where FfiType == RustBuffer {} + +extension FfiConverterRustBuffer { +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public static func lift(_ buf: RustBuffer) throws -> SwiftType { + var reader = createReader(data: Data(rustBuffer: buf)) + let value = try read(from: &reader) + if hasRemaining(reader) { + throw UniffiInternalError.incompleteData + } + buf.deallocate() + return value + } + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public static func lower(_ value: SwiftType) -> RustBuffer { + var writer = createWriter() + write(value, into: &writer) + return RustBuffer(bytes: writer) + } +} +// An error type for FFI errors. These errors occur at the UniFFI level, not +// the library level. +fileprivate enum UniffiInternalError: LocalizedError { + case bufferOverflow + case incompleteData + case unexpectedOptionalTag + case unexpectedEnumCase + case unexpectedNullPointer + case unexpectedRustCallStatusCode + case unexpectedRustCallError + case unexpectedStaleHandle + case rustPanic(_ message: String) + + public var errorDescription: String? { + switch self { + case .bufferOverflow: return "Reading the requested value would read past the end of the buffer" + case .incompleteData: return "The buffer still has data after lifting its containing value" + case .unexpectedOptionalTag: return "Unexpected optional tag; should be 0 or 1" + case .unexpectedEnumCase: return "Raw enum value doesn't match any cases" + case .unexpectedNullPointer: return "Raw pointer value was null" + case .unexpectedRustCallStatusCode: return "Unexpected RustCallStatus code" + case .unexpectedRustCallError: return "CALL_ERROR but no errorClass specified" + case .unexpectedStaleHandle: return "The object in the handle map has been dropped already" + case let .rustPanic(message): return message + } + } +} + +fileprivate extension NSLock { + func withLock(f: () throws -> T) rethrows -> T { + self.lock() + defer { self.unlock() } + return try f() + } +} + +fileprivate let CALL_SUCCESS: Int8 = 0 +fileprivate let CALL_ERROR: Int8 = 1 +fileprivate let CALL_UNEXPECTED_ERROR: Int8 = 2 +fileprivate let CALL_CANCELLED: Int8 = 3 + +fileprivate extension RustCallStatus { + init() { + self.init( + code: CALL_SUCCESS, + errorBuf: RustBuffer.init( + capacity: 0, + len: 0, + data: nil + ) + ) + } +} + +private func rustCall(_ callback: (UnsafeMutablePointer) -> T) throws -> T { + let neverThrow: ((RustBuffer) throws -> Never)? = nil + return try makeRustCall(callback, errorHandler: neverThrow) +} + +private func rustCallWithError( + _ errorHandler: @escaping (RustBuffer) throws -> E, + _ callback: (UnsafeMutablePointer) -> T) throws -> T { + try makeRustCall(callback, errorHandler: errorHandler) +} + +private func makeRustCall( + _ callback: (UnsafeMutablePointer) -> T, + errorHandler: ((RustBuffer) throws -> E)? +) throws -> T { + uniffiEnsureDojoCInitialized() + var callStatus = RustCallStatus.init() + let returnedVal = callback(&callStatus) + try uniffiCheckCallStatus(callStatus: callStatus, errorHandler: errorHandler) + return returnedVal +} + +private func uniffiCheckCallStatus( + callStatus: RustCallStatus, + errorHandler: ((RustBuffer) throws -> E)? +) throws { + switch callStatus.code { + case CALL_SUCCESS: + return + + case CALL_ERROR: + if let errorHandler = errorHandler { + throw try errorHandler(callStatus.errorBuf) + } else { + callStatus.errorBuf.deallocate() + throw UniffiInternalError.unexpectedRustCallError + } + + case CALL_UNEXPECTED_ERROR: + // When the rust code sees a panic, it tries to construct a RustBuffer + // with the message. But if that code panics, then it just sends back + // an empty buffer. + if callStatus.errorBuf.len > 0 { + throw UniffiInternalError.rustPanic(try FfiConverterString.lift(callStatus.errorBuf)) + } else { + callStatus.errorBuf.deallocate() + throw UniffiInternalError.rustPanic("Rust panic") + } + + case CALL_CANCELLED: + fatalError("Cancellation not supported yet") + + default: + throw UniffiInternalError.unexpectedRustCallStatusCode + } +} + +private func uniffiTraitInterfaceCall( + callStatus: UnsafeMutablePointer, + makeCall: () throws -> T, + writeReturn: (T) -> () +) { + do { + try writeReturn(makeCall()) + } catch let error { + callStatus.pointee.code = CALL_UNEXPECTED_ERROR + callStatus.pointee.errorBuf = FfiConverterString.lower(String(describing: error)) + } +} + +private func uniffiTraitInterfaceCallWithError( + callStatus: UnsafeMutablePointer, + makeCall: () throws -> T, + writeReturn: (T) -> (), + lowerError: (E) -> RustBuffer +) { + do { + try writeReturn(makeCall()) + } catch let error as E { + callStatus.pointee.code = CALL_ERROR + callStatus.pointee.errorBuf = lowerError(error) + } catch { + callStatus.pointee.code = CALL_UNEXPECTED_ERROR + callStatus.pointee.errorBuf = FfiConverterString.lower(String(describing: error)) + } +} +// Initial value and increment amount for handles. +// These ensure that SWIFT handles always have the lowest bit set +fileprivate let UNIFFI_HANDLEMAP_INITIAL: UInt64 = 1 +fileprivate let UNIFFI_HANDLEMAP_DELTA: UInt64 = 2 + +fileprivate final class UniffiHandleMap: @unchecked Sendable { + // All mutation happens with this lock held, which is why we implement @unchecked Sendable. + private let lock = NSLock() + private var map: [UInt64: T] = [:] + private var currentHandle: UInt64 = UNIFFI_HANDLEMAP_INITIAL + + func insert(obj: T) -> UInt64 { + lock.withLock { + return doInsert(obj) + } + } + + // Low-level insert function, this assumes `lock` is held. + private func doInsert(_ obj: T) -> UInt64 { + let handle = currentHandle + currentHandle += UNIFFI_HANDLEMAP_DELTA + map[handle] = obj + return handle + } + + func get(handle: UInt64) throws -> T { + try lock.withLock { + guard let obj = map[handle] else { + throw UniffiInternalError.unexpectedStaleHandle + } + return obj + } + } + + func clone(handle: UInt64) throws -> UInt64 { + try lock.withLock { + guard let obj = map[handle] else { + throw UniffiInternalError.unexpectedStaleHandle + } + return doInsert(obj) + } + } + + @discardableResult + func remove(handle: UInt64) throws -> T { + try lock.withLock { + guard let obj = map.removeValue(forKey: handle) else { + throw UniffiInternalError.unexpectedStaleHandle + } + return obj + } + } + + var count: Int { + get { + map.count + } + } +} + + +// Public interface members begin here. + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterUInt8: FfiConverterPrimitive { + typealias FfiType = UInt8 + typealias SwiftType = UInt8 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt8 { + return try lift(readInt(&buf)) + } + + public static func write(_ value: UInt8, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterInt8: FfiConverterPrimitive { + typealias FfiType = Int8 + typealias SwiftType = Int8 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Int8 { + return try lift(readInt(&buf)) + } + + public static func write(_ value: Int8, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterUInt16: FfiConverterPrimitive { + typealias FfiType = UInt16 + typealias SwiftType = UInt16 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt16 { + return try lift(readInt(&buf)) + } + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterInt16: FfiConverterPrimitive { + typealias FfiType = Int16 + typealias SwiftType = Int16 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Int16 { + return try lift(readInt(&buf)) + } + + public static func write(_ value: Int16, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterUInt32: FfiConverterPrimitive { + typealias FfiType = UInt32 + typealias SwiftType = UInt32 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt32 { + return try lift(readInt(&buf)) + } + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterInt32: FfiConverterPrimitive { + typealias FfiType = Int32 + typealias SwiftType = Int32 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Int32 { + return try lift(readInt(&buf)) + } + + public static func write(_ value: Int32, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterUInt64: FfiConverterPrimitive { + typealias FfiType = UInt64 + typealias SwiftType = UInt64 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> UInt64 { + return try lift(readInt(&buf)) + } + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterInt64: FfiConverterPrimitive { + typealias FfiType = Int64 + typealias SwiftType = Int64 + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Int64 { + return try lift(readInt(&buf)) + } + + public static func write(_ value: Int64, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterDouble: FfiConverterPrimitive { + typealias FfiType = Double + typealias SwiftType = Double + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Double { + return try lift(readDouble(&buf)) + } + + public static func write(_ value: Double, into buf: inout [UInt8]) { + writeDouble(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterBool : FfiConverter { + typealias FfiType = Int8 + typealias SwiftType = Bool + + public static func lift(_ value: Int8) throws -> Bool { + return value != 0 + } + + public static func lower(_ value: Bool) -> Int8 { + return value ? 1 : 0 + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Bool { + return try lift(readInt(&buf)) + } + + public static func write(_ value: Bool, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterString: FfiConverter { + typealias SwiftType = String + typealias FfiType = RustBuffer + + public static func lift(_ value: RustBuffer) throws -> String { + defer { + value.deallocate() + } + if value.data == nil { + return String() + } + let bytes = UnsafeBufferPointer(start: value.data!, count: Int(value.len)) + return String(bytes: bytes, encoding: String.Encoding.utf8)! + } + + public static func lower(_ value: String) -> RustBuffer { + return value.utf8CString.withUnsafeBufferPointer { ptr in + // The swift string gives us int8_t, we want uint8_t. + ptr.withMemoryRebound(to: UInt8.self) { ptr in + // The swift string gives us a trailing null byte, we don't want it. + let buf = UnsafeBufferPointer(rebasing: ptr.prefix(upTo: ptr.count - 1)) + return RustBuffer.from(buf) + } + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> String { + let len: Int32 = try readInt(&buf) + return String(bytes: try readBytes(&buf, count: Int(len)), encoding: String.Encoding.utf8)! + } + + public static func write(_ value: String, into buf: inout [UInt8]) { + let len = Int32(value.utf8.count) + writeInt(&buf, len) + writeBytes(&buf, value.utf8) + } +} + + +public struct Achievement: Equatable, Hashable { + public let id: String + public let worldAddress: FieldElement + public let namespace: String + public let entityId: String + public let hidden: Bool + public let index: UInt32 + public let points: UInt32 + public let start: String + public let end: String + public let group: String + public let icon: String + public let title: String + public let description: String + public let tasks: [AchievementTask] + public let data: String? + public let totalCompletions: UInt32 + public let completionRate: Double + public let createdAt: UInt64 + public let updatedAt: UInt64 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(id: String, worldAddress: FieldElement, namespace: String, entityId: String, hidden: Bool, index: UInt32, points: UInt32, start: String, end: String, group: String, icon: String, title: String, description: String, tasks: [AchievementTask], data: String?, totalCompletions: UInt32, completionRate: Double, createdAt: UInt64, updatedAt: UInt64) { + self.id = id + self.worldAddress = worldAddress + self.namespace = namespace + self.entityId = entityId + self.hidden = hidden + self.index = index + self.points = points + self.start = start + self.end = end + self.group = group + self.icon = icon + self.title = title + self.description = description + self.tasks = tasks + self.data = data + self.totalCompletions = totalCompletions + self.completionRate = completionRate + self.createdAt = createdAt + self.updatedAt = updatedAt + } + + +} + +#if compiler(>=6) +extension Achievement: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeAchievement: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Achievement { + return + try Achievement( + id: FfiConverterString.read(from: &buf), + worldAddress: FfiConverterTypeFieldElement.read(from: &buf), + namespace: FfiConverterString.read(from: &buf), + entityId: FfiConverterString.read(from: &buf), + hidden: FfiConverterBool.read(from: &buf), + index: FfiConverterUInt32.read(from: &buf), + points: FfiConverterUInt32.read(from: &buf), + start: FfiConverterString.read(from: &buf), + end: FfiConverterString.read(from: &buf), + group: FfiConverterString.read(from: &buf), + icon: FfiConverterString.read(from: &buf), + title: FfiConverterString.read(from: &buf), + description: FfiConverterString.read(from: &buf), + tasks: FfiConverterSequenceTypeAchievementTask.read(from: &buf), + data: FfiConverterOptionString.read(from: &buf), + totalCompletions: FfiConverterUInt32.read(from: &buf), + completionRate: FfiConverterDouble.read(from: &buf), + createdAt: FfiConverterUInt64.read(from: &buf), + updatedAt: FfiConverterUInt64.read(from: &buf) + ) + } + + public static func write(_ value: Achievement, into buf: inout [UInt8]) { + FfiConverterString.write(value.id, into: &buf) + FfiConverterTypeFieldElement.write(value.worldAddress, into: &buf) + FfiConverterString.write(value.namespace, into: &buf) + FfiConverterString.write(value.entityId, into: &buf) + FfiConverterBool.write(value.hidden, into: &buf) + FfiConverterUInt32.write(value.index, into: &buf) + FfiConverterUInt32.write(value.points, into: &buf) + FfiConverterString.write(value.start, into: &buf) + FfiConverterString.write(value.end, into: &buf) + FfiConverterString.write(value.group, into: &buf) + FfiConverterString.write(value.icon, into: &buf) + FfiConverterString.write(value.title, into: &buf) + FfiConverterString.write(value.description, into: &buf) + FfiConverterSequenceTypeAchievementTask.write(value.tasks, into: &buf) + FfiConverterOptionString.write(value.data, into: &buf) + FfiConverterUInt32.write(value.totalCompletions, into: &buf) + FfiConverterDouble.write(value.completionRate, into: &buf) + FfiConverterUInt64.write(value.createdAt, into: &buf) + FfiConverterUInt64.write(value.updatedAt, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAchievement_lift(_ buf: RustBuffer) throws -> Achievement { + return try FfiConverterTypeAchievement.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAchievement_lower(_ value: Achievement) -> RustBuffer { + return FfiConverterTypeAchievement.lower(value) +} + + +public struct AchievementProgression: Equatable, Hashable { + public let id: String + public let achievementId: String + public let taskId: String + public let worldAddress: FieldElement + public let namespace: String + public let playerId: FieldElement + public let count: UInt32 + public let completed: Bool + public let completedAt: UInt64? + public let createdAt: UInt64 + public let updatedAt: UInt64 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(id: String, achievementId: String, taskId: String, worldAddress: FieldElement, namespace: String, playerId: FieldElement, count: UInt32, completed: Bool, completedAt: UInt64?, createdAt: UInt64, updatedAt: UInt64) { + self.id = id + self.achievementId = achievementId + self.taskId = taskId + self.worldAddress = worldAddress + self.namespace = namespace + self.playerId = playerId + self.count = count + self.completed = completed + self.completedAt = completedAt + self.createdAt = createdAt + self.updatedAt = updatedAt + } + + +} + +#if compiler(>=6) +extension AchievementProgression: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeAchievementProgression: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AchievementProgression { + return + try AchievementProgression( + id: FfiConverterString.read(from: &buf), + achievementId: FfiConverterString.read(from: &buf), + taskId: FfiConverterString.read(from: &buf), + worldAddress: FfiConverterTypeFieldElement.read(from: &buf), + namespace: FfiConverterString.read(from: &buf), + playerId: FfiConverterTypeFieldElement.read(from: &buf), + count: FfiConverterUInt32.read(from: &buf), + completed: FfiConverterBool.read(from: &buf), + completedAt: FfiConverterOptionUInt64.read(from: &buf), + createdAt: FfiConverterUInt64.read(from: &buf), + updatedAt: FfiConverterUInt64.read(from: &buf) + ) + } + + public static func write(_ value: AchievementProgression, into buf: inout [UInt8]) { + FfiConverterString.write(value.id, into: &buf) + FfiConverterString.write(value.achievementId, into: &buf) + FfiConverterString.write(value.taskId, into: &buf) + FfiConverterTypeFieldElement.write(value.worldAddress, into: &buf) + FfiConverterString.write(value.namespace, into: &buf) + FfiConverterTypeFieldElement.write(value.playerId, into: &buf) + FfiConverterUInt32.write(value.count, into: &buf) + FfiConverterBool.write(value.completed, into: &buf) + FfiConverterOptionUInt64.write(value.completedAt, into: &buf) + FfiConverterUInt64.write(value.createdAt, into: &buf) + FfiConverterUInt64.write(value.updatedAt, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAchievementProgression_lift(_ buf: RustBuffer) throws -> AchievementProgression { + return try FfiConverterTypeAchievementProgression.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAchievementProgression_lower(_ value: AchievementProgression) -> RustBuffer { + return FfiConverterTypeAchievementProgression.lower(value) +} + + +public struct AchievementQuery: Equatable, Hashable { + public let worldAddresses: [FieldElement] + public let namespaces: [String] + public let hidden: Bool? + public let pagination: Pagination + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(worldAddresses: [FieldElement], namespaces: [String], hidden: Bool?, pagination: Pagination) { + self.worldAddresses = worldAddresses + self.namespaces = namespaces + self.hidden = hidden + self.pagination = pagination + } + + +} + +#if compiler(>=6) +extension AchievementQuery: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeAchievementQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AchievementQuery { + return + try AchievementQuery( + worldAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + namespaces: FfiConverterSequenceString.read(from: &buf), + hidden: FfiConverterOptionBool.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) + ) + } + + public static func write(_ value: AchievementQuery, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.worldAddresses, into: &buf) + FfiConverterSequenceString.write(value.namespaces, into: &buf) + FfiConverterOptionBool.write(value.hidden, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAchievementQuery_lift(_ buf: RustBuffer) throws -> AchievementQuery { + return try FfiConverterTypeAchievementQuery.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAchievementQuery_lower(_ value: AchievementQuery) -> RustBuffer { + return FfiConverterTypeAchievementQuery.lower(value) +} + + +public struct AchievementTask: Equatable, Hashable { + public let taskId: String + public let description: String + public let total: UInt32 + public let totalCompletions: UInt32 + public let completionRate: Double + public let createdAt: UInt64 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(taskId: String, description: String, total: UInt32, totalCompletions: UInt32, completionRate: Double, createdAt: UInt64) { + self.taskId = taskId + self.description = description + self.total = total + self.totalCompletions = totalCompletions + self.completionRate = completionRate + self.createdAt = createdAt + } + + +} + +#if compiler(>=6) +extension AchievementTask: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeAchievementTask: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AchievementTask { + return + try AchievementTask( + taskId: FfiConverterString.read(from: &buf), + description: FfiConverterString.read(from: &buf), + total: FfiConverterUInt32.read(from: &buf), + totalCompletions: FfiConverterUInt32.read(from: &buf), + completionRate: FfiConverterDouble.read(from: &buf), + createdAt: FfiConverterUInt64.read(from: &buf) + ) + } + + public static func write(_ value: AchievementTask, into buf: inout [UInt8]) { + FfiConverterString.write(value.taskId, into: &buf) + FfiConverterString.write(value.description, into: &buf) + FfiConverterUInt32.write(value.total, into: &buf) + FfiConverterUInt32.write(value.totalCompletions, into: &buf) + FfiConverterDouble.write(value.completionRate, into: &buf) + FfiConverterUInt64.write(value.createdAt, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAchievementTask_lift(_ buf: RustBuffer) throws -> AchievementTask { + return try FfiConverterTypeAchievementTask.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAchievementTask_lower(_ value: AchievementTask) -> RustBuffer { + return FfiConverterTypeAchievementTask.lower(value) +} + + +public struct ActionCount: Equatable, Hashable { + public let actionName: String + public let count: UInt32 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(actionName: String, count: UInt32) { + self.actionName = actionName + self.count = count + } + + +} + +#if compiler(>=6) +extension ActionCount: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeActionCount: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ActionCount { + return + try ActionCount( + actionName: FfiConverterString.read(from: &buf), + count: FfiConverterUInt32.read(from: &buf) + ) + } + + public static func write(_ value: ActionCount, into buf: inout [UInt8]) { + FfiConverterString.write(value.actionName, into: &buf) + FfiConverterUInt32.write(value.count, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeActionCount_lift(_ buf: RustBuffer) throws -> ActionCount { + return try FfiConverterTypeActionCount.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeActionCount_lower(_ value: ActionCount) -> RustBuffer { + return FfiConverterTypeActionCount.lower(value) +} + + +public struct Activity: Equatable, Hashable { + public let id: String + public let worldAddress: FieldElement + public let namespace: String + public let callerAddress: FieldElement + public let sessionStart: UInt64 + public let sessionEnd: UInt64 + public let actionCount: UInt32 + public let actions: [ActionCount] + public let updatedAt: UInt64 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(id: String, worldAddress: FieldElement, namespace: String, callerAddress: FieldElement, sessionStart: UInt64, sessionEnd: UInt64, actionCount: UInt32, actions: [ActionCount], updatedAt: UInt64) { + self.id = id + self.worldAddress = worldAddress + self.namespace = namespace + self.callerAddress = callerAddress + self.sessionStart = sessionStart + self.sessionEnd = sessionEnd + self.actionCount = actionCount + self.actions = actions + self.updatedAt = updatedAt + } + + +} + +#if compiler(>=6) +extension Activity: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeActivity: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Activity { + return + try Activity( + id: FfiConverterString.read(from: &buf), + worldAddress: FfiConverterTypeFieldElement.read(from: &buf), + namespace: FfiConverterString.read(from: &buf), + callerAddress: FfiConverterTypeFieldElement.read(from: &buf), + sessionStart: FfiConverterUInt64.read(from: &buf), + sessionEnd: FfiConverterUInt64.read(from: &buf), + actionCount: FfiConverterUInt32.read(from: &buf), + actions: FfiConverterSequenceTypeActionCount.read(from: &buf), + updatedAt: FfiConverterUInt64.read(from: &buf) + ) + } + + public static func write(_ value: Activity, into buf: inout [UInt8]) { + FfiConverterString.write(value.id, into: &buf) + FfiConverterTypeFieldElement.write(value.worldAddress, into: &buf) + FfiConverterString.write(value.namespace, into: &buf) + FfiConverterTypeFieldElement.write(value.callerAddress, into: &buf) + FfiConverterUInt64.write(value.sessionStart, into: &buf) + FfiConverterUInt64.write(value.sessionEnd, into: &buf) + FfiConverterUInt32.write(value.actionCount, into: &buf) + FfiConverterSequenceTypeActionCount.write(value.actions, into: &buf) + FfiConverterUInt64.write(value.updatedAt, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeActivity_lift(_ buf: RustBuffer) throws -> Activity { + return try FfiConverterTypeActivity.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeActivity_lower(_ value: Activity) -> RustBuffer { + return FfiConverterTypeActivity.lower(value) +} + + +public struct ActivityQuery: Equatable, Hashable { + public let worldAddresses: [FieldElement] + public let namespaces: [String] + public let callerAddresses: [FieldElement] + public let fromTime: UInt64? + public let toTime: UInt64? + public let pagination: Pagination + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(worldAddresses: [FieldElement], namespaces: [String], callerAddresses: [FieldElement], fromTime: UInt64?, toTime: UInt64?, pagination: Pagination) { + self.worldAddresses = worldAddresses + self.namespaces = namespaces + self.callerAddresses = callerAddresses + self.fromTime = fromTime + self.toTime = toTime + self.pagination = pagination + } + + +} + +#if compiler(>=6) +extension ActivityQuery: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeActivityQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ActivityQuery { + return + try ActivityQuery( + worldAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + namespaces: FfiConverterSequenceString.read(from: &buf), + callerAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + fromTime: FfiConverterOptionUInt64.read(from: &buf), + toTime: FfiConverterOptionUInt64.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) + ) + } + + public static func write(_ value: ActivityQuery, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.worldAddresses, into: &buf) + FfiConverterSequenceString.write(value.namespaces, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.callerAddresses, into: &buf) + FfiConverterOptionUInt64.write(value.fromTime, into: &buf) + FfiConverterOptionUInt64.write(value.toTime, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeActivityQuery_lift(_ buf: RustBuffer) throws -> ActivityQuery { + return try FfiConverterTypeActivityQuery.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeActivityQuery_lower(_ value: ActivityQuery) -> RustBuffer { + return FfiConverterTypeActivityQuery.lower(value) +} + + +public struct AggregationEntry: Equatable, Hashable { + public let id: String + public let aggregatorId: String + public let entityId: String + public let value: U256 + public let displayValue: String + public let position: UInt64 + public let modelId: String + public let createdAt: UInt64 + public let updatedAt: UInt64 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(id: String, aggregatorId: String, entityId: String, value: U256, displayValue: String, position: UInt64, modelId: String, createdAt: UInt64, updatedAt: UInt64) { + self.id = id + self.aggregatorId = aggregatorId + self.entityId = entityId + self.value = value + self.displayValue = displayValue + self.position = position + self.modelId = modelId + self.createdAt = createdAt + self.updatedAt = updatedAt + } + + +} + +#if compiler(>=6) +extension AggregationEntry: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeAggregationEntry: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AggregationEntry { + return + try AggregationEntry( + id: FfiConverterString.read(from: &buf), + aggregatorId: FfiConverterString.read(from: &buf), + entityId: FfiConverterString.read(from: &buf), + value: FfiConverterTypeU256.read(from: &buf), + displayValue: FfiConverterString.read(from: &buf), + position: FfiConverterUInt64.read(from: &buf), + modelId: FfiConverterString.read(from: &buf), + createdAt: FfiConverterUInt64.read(from: &buf), + updatedAt: FfiConverterUInt64.read(from: &buf) + ) + } + + public static func write(_ value: AggregationEntry, into buf: inout [UInt8]) { + FfiConverterString.write(value.id, into: &buf) + FfiConverterString.write(value.aggregatorId, into: &buf) + FfiConverterString.write(value.entityId, into: &buf) + FfiConverterTypeU256.write(value.value, into: &buf) + FfiConverterString.write(value.displayValue, into: &buf) + FfiConverterUInt64.write(value.position, into: &buf) + FfiConverterString.write(value.modelId, into: &buf) + FfiConverterUInt64.write(value.createdAt, into: &buf) + FfiConverterUInt64.write(value.updatedAt, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAggregationEntry_lift(_ buf: RustBuffer) throws -> AggregationEntry { + return try FfiConverterTypeAggregationEntry.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAggregationEntry_lower(_ value: AggregationEntry) -> RustBuffer { + return FfiConverterTypeAggregationEntry.lower(value) +} + + +public struct AggregationQuery: Equatable, Hashable { + public let aggregatorIds: [String] + public let entityIds: [String] + public let pagination: Pagination + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(aggregatorIds: [String], entityIds: [String], pagination: Pagination) { + self.aggregatorIds = aggregatorIds + self.entityIds = entityIds + self.pagination = pagination + } + + +} + +#if compiler(>=6) +extension AggregationQuery: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeAggregationQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AggregationQuery { + return + try AggregationQuery( + aggregatorIds: FfiConverterSequenceString.read(from: &buf), + entityIds: FfiConverterSequenceString.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) + ) + } + + public static func write(_ value: AggregationQuery, into buf: inout [UInt8]) { + FfiConverterSequenceString.write(value.aggregatorIds, into: &buf) + FfiConverterSequenceString.write(value.entityIds, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAggregationQuery_lift(_ buf: RustBuffer) throws -> AggregationQuery { + return try FfiConverterTypeAggregationQuery.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAggregationQuery_lower(_ value: AggregationQuery) -> RustBuffer { + return FfiConverterTypeAggregationQuery.lower(value) +} + + +public struct AttributeFilter: Equatable, Hashable { + public let traitName: String + public let traitValue: String + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(traitName: String, traitValue: String) { + self.traitName = traitName + self.traitValue = traitValue + } + + +} + +#if compiler(>=6) +extension AttributeFilter: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeAttributeFilter: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> AttributeFilter { + return + try AttributeFilter( + traitName: FfiConverterString.read(from: &buf), + traitValue: FfiConverterString.read(from: &buf) + ) + } + + public static func write(_ value: AttributeFilter, into buf: inout [UInt8]) { + FfiConverterString.write(value.traitName, into: &buf) + FfiConverterString.write(value.traitValue, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAttributeFilter_lift(_ buf: RustBuffer) throws -> AttributeFilter { + return try FfiConverterTypeAttributeFilter.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeAttributeFilter_lower(_ value: AttributeFilter) -> RustBuffer { + return FfiConverterTypeAttributeFilter.lower(value) +} + + +public struct CompositeClause: Equatable, Hashable { + public let `operator`: LogicalOperator + public let clauses: [Clause] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(`operator`: LogicalOperator, clauses: [Clause]) { + self.`operator` = `operator` + self.clauses = clauses + } + + +} + +#if compiler(>=6) +extension CompositeClause: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeCompositeClause: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> CompositeClause { + return + try CompositeClause( + operator: FfiConverterTypeLogicalOperator.read(from: &buf), + clauses: FfiConverterSequenceTypeClause.read(from: &buf) + ) + } + + public static func write(_ value: CompositeClause, into buf: inout [UInt8]) { + FfiConverterTypeLogicalOperator.write(value.`operator`, into: &buf) + FfiConverterSequenceTypeClause.write(value.clauses, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeCompositeClause_lift(_ buf: RustBuffer) throws -> CompositeClause { + return try FfiConverterTypeCompositeClause.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeCompositeClause_lower(_ value: CompositeClause) -> RustBuffer { + return FfiConverterTypeCompositeClause.lower(value) +} + + +public struct Contract: Equatable, Hashable { + public let contractAddress: FieldElement + public let contractType: ContractType + public let head: UInt64? + public let tps: UInt64? + public let lastBlockTimestamp: UInt64? + public let lastPendingBlockTx: FieldElement? + public let updatedAt: UInt64 + public let createdAt: UInt64 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddress: FieldElement, contractType: ContractType, head: UInt64?, tps: UInt64?, lastBlockTimestamp: UInt64?, lastPendingBlockTx: FieldElement?, updatedAt: UInt64, createdAt: UInt64) { + self.contractAddress = contractAddress + self.contractType = contractType + self.head = head + self.tps = tps + self.lastBlockTimestamp = lastBlockTimestamp + self.lastPendingBlockTx = lastPendingBlockTx + self.updatedAt = updatedAt + self.createdAt = createdAt + } + + +} + +#if compiler(>=6) +extension Contract: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeContract: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Contract { + return + try Contract( + contractAddress: FfiConverterTypeFieldElement.read(from: &buf), + contractType: FfiConverterTypeContractType.read(from: &buf), + head: FfiConverterOptionUInt64.read(from: &buf), + tps: FfiConverterOptionUInt64.read(from: &buf), + lastBlockTimestamp: FfiConverterOptionUInt64.read(from: &buf), + lastPendingBlockTx: FfiConverterOptionTypeFieldElement.read(from: &buf), + updatedAt: FfiConverterUInt64.read(from: &buf), + createdAt: FfiConverterUInt64.read(from: &buf) + ) + } + + public static func write(_ value: Contract, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) + FfiConverterTypeContractType.write(value.contractType, into: &buf) + FfiConverterOptionUInt64.write(value.head, into: &buf) + FfiConverterOptionUInt64.write(value.tps, into: &buf) + FfiConverterOptionUInt64.write(value.lastBlockTimestamp, into: &buf) + FfiConverterOptionTypeFieldElement.write(value.lastPendingBlockTx, into: &buf) + FfiConverterUInt64.write(value.updatedAt, into: &buf) + FfiConverterUInt64.write(value.createdAt, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeContract_lift(_ buf: RustBuffer) throws -> Contract { + return try FfiConverterTypeContract.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeContract_lower(_ value: Contract) -> RustBuffer { + return FfiConverterTypeContract.lower(value) +} + + +public struct ContractQuery: Equatable, Hashable { + public let contractAddresses: [FieldElement] + public let contractTypes: [ContractType] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddresses: [FieldElement], contractTypes: [ContractType]) { + self.contractAddresses = contractAddresses + self.contractTypes = contractTypes + } + + +} + +#if compiler(>=6) +extension ContractQuery: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeContractQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ContractQuery { + return + try ContractQuery( + contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + contractTypes: FfiConverterSequenceTypeContractType.read(from: &buf) + ) + } + + public static func write(_ value: ContractQuery, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) + FfiConverterSequenceTypeContractType.write(value.contractTypes, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeContractQuery_lift(_ buf: RustBuffer) throws -> ContractQuery { + return try FfiConverterTypeContractQuery.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeContractQuery_lower(_ value: ContractQuery) -> RustBuffer { + return FfiConverterTypeContractQuery.lower(value) +} + + +public struct Controller: Equatable, Hashable { + public let address: FieldElement + public let username: String + public let deployedAtTimestamp: UInt64 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(address: FieldElement, username: String, deployedAtTimestamp: UInt64) { + self.address = address + self.username = username + self.deployedAtTimestamp = deployedAtTimestamp + } + + +} + +#if compiler(>=6) +extension Controller: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeController: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Controller { + return + try Controller( + address: FfiConverterTypeFieldElement.read(from: &buf), + username: FfiConverterString.read(from: &buf), + deployedAtTimestamp: FfiConverterUInt64.read(from: &buf) + ) + } + + public static func write(_ value: Controller, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.address, into: &buf) + FfiConverterString.write(value.username, into: &buf) + FfiConverterUInt64.write(value.deployedAtTimestamp, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeController_lift(_ buf: RustBuffer) throws -> Controller { + return try FfiConverterTypeController.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeController_lower(_ value: Controller) -> RustBuffer { + return FfiConverterTypeController.lower(value) +} + + +public struct ControllerQuery: Equatable, Hashable { + public let pagination: Pagination + public let contractAddresses: [FieldElement] + public let usernames: [String] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(pagination: Pagination, contractAddresses: [FieldElement], usernames: [String]) { + self.pagination = pagination + self.contractAddresses = contractAddresses + self.usernames = usernames + } + + +} + +#if compiler(>=6) +extension ControllerQuery: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeControllerQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ControllerQuery { + return + try ControllerQuery( + pagination: FfiConverterTypePagination.read(from: &buf), + contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + usernames: FfiConverterSequenceString.read(from: &buf) + ) + } + + public static func write(_ value: ControllerQuery, into buf: inout [UInt8]) { + FfiConverterTypePagination.write(value.pagination, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) + FfiConverterSequenceString.write(value.usernames, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeControllerQuery_lift(_ buf: RustBuffer) throws -> ControllerQuery { + return try FfiConverterTypeControllerQuery.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeControllerQuery_lower(_ value: ControllerQuery) -> RustBuffer { + return FfiConverterTypeControllerQuery.lower(value) +} + + +public struct EnumOption: Equatable, Hashable { + public let name: String + public let ty: Ty + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(name: String, ty: Ty) { + self.name = name + self.ty = ty + } + + +} + +#if compiler(>=6) +extension EnumOption: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeEnumOption: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> EnumOption { + return + try EnumOption( + name: FfiConverterString.read(from: &buf), + ty: FfiConverterTypeTy.read(from: &buf) + ) + } + + public static func write(_ value: EnumOption, into buf: inout [UInt8]) { + FfiConverterString.write(value.name, into: &buf) + FfiConverterTypeTy.write(value.ty, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeEnumOption_lift(_ buf: RustBuffer) throws -> EnumOption { + return try FfiConverterTypeEnumOption.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeEnumOption_lower(_ value: EnumOption) -> RustBuffer { + return FfiConverterTypeEnumOption.lower(value) +} + + +public struct EnumType: Equatable, Hashable { + public let name: String + public let option: UInt8 + public let options: [EnumOption] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(name: String, option: UInt8, options: [EnumOption]) { + self.name = name + self.option = option + self.options = options + } + + +} + +#if compiler(>=6) +extension EnumType: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeEnumType: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> EnumType { + return + try EnumType( + name: FfiConverterString.read(from: &buf), + option: FfiConverterUInt8.read(from: &buf), + options: FfiConverterSequenceTypeEnumOption.read(from: &buf) + ) + } + + public static func write(_ value: EnumType, into buf: inout [UInt8]) { + FfiConverterString.write(value.name, into: &buf) + FfiConverterUInt8.write(value.option, into: &buf) + FfiConverterSequenceTypeEnumOption.write(value.options, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeEnumType_lift(_ buf: RustBuffer) throws -> EnumType { + return try FfiConverterTypeEnumType.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeEnumType_lower(_ value: EnumType) -> RustBuffer { + return FfiConverterTypeEnumType.lower(value) +} + + +public struct FixedSizeArray: Equatable, Hashable { + public let array: [Ty] + public let size: UInt32 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(array: [Ty], size: UInt32) { + self.array = array + self.size = size + } + + +} + +#if compiler(>=6) +extension FixedSizeArray: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeFixedSizeArray: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> FixedSizeArray { + return + try FixedSizeArray( + array: FfiConverterSequenceTypeTy.read(from: &buf), + size: FfiConverterUInt32.read(from: &buf) + ) + } + + public static func write(_ value: FixedSizeArray, into buf: inout [UInt8]) { + FfiConverterSequenceTypeTy.write(value.array, into: &buf) + FfiConverterUInt32.write(value.size, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeFixedSizeArray_lift(_ buf: RustBuffer) throws -> FixedSizeArray { + return try FfiConverterTypeFixedSizeArray.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeFixedSizeArray_lower(_ value: FixedSizeArray) -> RustBuffer { + return FfiConverterTypeFixedSizeArray.lower(value) +} + + +public struct KeysClause: Equatable, Hashable { + public let keys: [FieldElement?] + public let patternMatching: PatternMatching + public let models: [String] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(keys: [FieldElement?], patternMatching: PatternMatching, models: [String]) { + self.keys = keys + self.patternMatching = patternMatching + self.models = models + } + + +} + +#if compiler(>=6) +extension KeysClause: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeKeysClause: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> KeysClause { + return + try KeysClause( + keys: FfiConverterSequenceOptionTypeFieldElement.read(from: &buf), + patternMatching: FfiConverterTypePatternMatching.read(from: &buf), + models: FfiConverterSequenceString.read(from: &buf) + ) + } + + public static func write(_ value: KeysClause, into buf: inout [UInt8]) { + FfiConverterSequenceOptionTypeFieldElement.write(value.keys, into: &buf) + FfiConverterTypePatternMatching.write(value.patternMatching, into: &buf) + FfiConverterSequenceString.write(value.models, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeKeysClause_lift(_ buf: RustBuffer) throws -> KeysClause { + return try FfiConverterTypeKeysClause.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeKeysClause_lower(_ value: KeysClause) -> RustBuffer { + return FfiConverterTypeKeysClause.lower(value) +} + + +public struct Member: Equatable, Hashable { + public let name: String + public let ty: Ty + public let key: Bool + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(name: String, ty: Ty, key: Bool) { + self.name = name + self.ty = ty + self.key = key + } + + +} + +#if compiler(>=6) +extension Member: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeMember: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Member { + return + try Member( + name: FfiConverterString.read(from: &buf), + ty: FfiConverterTypeTy.read(from: &buf), + key: FfiConverterBool.read(from: &buf) + ) + } + + public static func write(_ value: Member, into buf: inout [UInt8]) { + FfiConverterString.write(value.name, into: &buf) + FfiConverterTypeTy.write(value.ty, into: &buf) + FfiConverterBool.write(value.key, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeMember_lift(_ buf: RustBuffer) throws -> Member { + return try FfiConverterTypeMember.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeMember_lower(_ value: Member) -> RustBuffer { + return FfiConverterTypeMember.lower(value) +} + + +public struct MemberClause: Equatable, Hashable { + public let model: String + public let member: String + public let `operator`: ComparisonOperator + public let value: MemberValue + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(model: String, member: String, `operator`: ComparisonOperator, value: MemberValue) { + self.model = model + self.member = member + self.`operator` = `operator` + self.value = value + } + + +} + +#if compiler(>=6) +extension MemberClause: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeMemberClause: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> MemberClause { + return + try MemberClause( + model: FfiConverterString.read(from: &buf), + member: FfiConverterString.read(from: &buf), + operator: FfiConverterTypeComparisonOperator.read(from: &buf), + value: FfiConverterTypeMemberValue.read(from: &buf) + ) + } + + public static func write(_ value: MemberClause, into buf: inout [UInt8]) { + FfiConverterString.write(value.model, into: &buf) + FfiConverterString.write(value.member, into: &buf) + FfiConverterTypeComparisonOperator.write(value.`operator`, into: &buf) + FfiConverterTypeMemberValue.write(value.value, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeMemberClause_lift(_ buf: RustBuffer) throws -> MemberClause { + return try FfiConverterTypeMemberClause.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeMemberClause_lower(_ value: MemberClause) -> RustBuffer { + return FfiConverterTypeMemberClause.lower(value) +} + + +public struct OrderBy: Equatable, Hashable { + public let field: String + public let direction: OrderDirection + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(field: String, direction: OrderDirection) { + self.field = field + self.direction = direction + } + + +} + +#if compiler(>=6) +extension OrderBy: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeOrderBy: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OrderBy { + return + try OrderBy( + field: FfiConverterString.read(from: &buf), + direction: FfiConverterTypeOrderDirection.read(from: &buf) + ) + } + + public static func write(_ value: OrderBy, into buf: inout [UInt8]) { + FfiConverterString.write(value.field, into: &buf) + FfiConverterTypeOrderDirection.write(value.direction, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeOrderBy_lift(_ buf: RustBuffer) throws -> OrderBy { + return try FfiConverterTypeOrderBy.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeOrderBy_lower(_ value: OrderBy) -> RustBuffer { + return FfiConverterTypeOrderBy.lower(value) +} + + +public struct Pagination: Equatable, Hashable { + public let cursor: String? + public let limit: UInt32? + public let direction: PaginationDirection + public let orderBy: [OrderBy] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(cursor: String?, limit: UInt32?, direction: PaginationDirection, orderBy: [OrderBy]) { + self.cursor = cursor + self.limit = limit + self.direction = direction + self.orderBy = orderBy + } + + +} + +#if compiler(>=6) +extension Pagination: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePagination: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Pagination { + return + try Pagination( + cursor: FfiConverterOptionString.read(from: &buf), + limit: FfiConverterOptionUInt32.read(from: &buf), + direction: FfiConverterTypePaginationDirection.read(from: &buf), + orderBy: FfiConverterSequenceTypeOrderBy.read(from: &buf) + ) + } + + public static func write(_ value: Pagination, into buf: inout [UInt8]) { + FfiConverterOptionString.write(value.cursor, into: &buf) + FfiConverterOptionUInt32.write(value.limit, into: &buf) + FfiConverterTypePaginationDirection.write(value.direction, into: &buf) + FfiConverterSequenceTypeOrderBy.write(value.orderBy, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePagination_lift(_ buf: RustBuffer) throws -> Pagination { + return try FfiConverterTypePagination.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePagination_lower(_ value: Pagination) -> RustBuffer { + return FfiConverterTypePagination.lower(value) +} + + +public struct PlayerAchievementEntry: Equatable, Hashable { + public let playerAddress: FieldElement + public let stats: PlayerAchievementStats + public let achievements: [PlayerAchievementProgress] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(playerAddress: FieldElement, stats: PlayerAchievementStats, achievements: [PlayerAchievementProgress]) { + self.playerAddress = playerAddress + self.stats = stats + self.achievements = achievements + } + + +} + +#if compiler(>=6) +extension PlayerAchievementEntry: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePlayerAchievementEntry: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PlayerAchievementEntry { + return + try PlayerAchievementEntry( + playerAddress: FfiConverterTypeFieldElement.read(from: &buf), + stats: FfiConverterTypePlayerAchievementStats.read(from: &buf), + achievements: FfiConverterSequenceTypePlayerAchievementProgress.read(from: &buf) + ) + } + + public static func write(_ value: PlayerAchievementEntry, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.playerAddress, into: &buf) + FfiConverterTypePlayerAchievementStats.write(value.stats, into: &buf) + FfiConverterSequenceTypePlayerAchievementProgress.write(value.achievements, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePlayerAchievementEntry_lift(_ buf: RustBuffer) throws -> PlayerAchievementEntry { + return try FfiConverterTypePlayerAchievementEntry.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePlayerAchievementEntry_lower(_ value: PlayerAchievementEntry) -> RustBuffer { + return FfiConverterTypePlayerAchievementEntry.lower(value) +} + + +public struct PlayerAchievementProgress: Equatable, Hashable { + public let achievement: Achievement + public let taskProgress: [TaskProgress] + public let completed: Bool + public let progressPercentage: Double + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(achievement: Achievement, taskProgress: [TaskProgress], completed: Bool, progressPercentage: Double) { + self.achievement = achievement + self.taskProgress = taskProgress + self.completed = completed + self.progressPercentage = progressPercentage + } + + +} + +#if compiler(>=6) +extension PlayerAchievementProgress: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePlayerAchievementProgress: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PlayerAchievementProgress { + return + try PlayerAchievementProgress( + achievement: FfiConverterTypeAchievement.read(from: &buf), + taskProgress: FfiConverterSequenceTypeTaskProgress.read(from: &buf), + completed: FfiConverterBool.read(from: &buf), + progressPercentage: FfiConverterDouble.read(from: &buf) + ) + } + + public static func write(_ value: PlayerAchievementProgress, into buf: inout [UInt8]) { + FfiConverterTypeAchievement.write(value.achievement, into: &buf) + FfiConverterSequenceTypeTaskProgress.write(value.taskProgress, into: &buf) + FfiConverterBool.write(value.completed, into: &buf) + FfiConverterDouble.write(value.progressPercentage, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePlayerAchievementProgress_lift(_ buf: RustBuffer) throws -> PlayerAchievementProgress { + return try FfiConverterTypePlayerAchievementProgress.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePlayerAchievementProgress_lower(_ value: PlayerAchievementProgress) -> RustBuffer { + return FfiConverterTypePlayerAchievementProgress.lower(value) +} + + +public struct PlayerAchievementQuery: Equatable, Hashable { + public let worldAddresses: [FieldElement] + public let namespaces: [String] + public let playerAddresses: [FieldElement] + public let pagination: Pagination + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(worldAddresses: [FieldElement], namespaces: [String], playerAddresses: [FieldElement], pagination: Pagination) { + self.worldAddresses = worldAddresses + self.namespaces = namespaces + self.playerAddresses = playerAddresses + self.pagination = pagination + } + + +} + +#if compiler(>=6) +extension PlayerAchievementQuery: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePlayerAchievementQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PlayerAchievementQuery { + return + try PlayerAchievementQuery( + worldAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + namespaces: FfiConverterSequenceString.read(from: &buf), + playerAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) + ) + } + + public static func write(_ value: PlayerAchievementQuery, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.worldAddresses, into: &buf) + FfiConverterSequenceString.write(value.namespaces, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.playerAddresses, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePlayerAchievementQuery_lift(_ buf: RustBuffer) throws -> PlayerAchievementQuery { + return try FfiConverterTypePlayerAchievementQuery.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePlayerAchievementQuery_lower(_ value: PlayerAchievementQuery) -> RustBuffer { + return FfiConverterTypePlayerAchievementQuery.lower(value) +} + + +public struct PlayerAchievementStats: Equatable, Hashable { + public let totalPoints: UInt32 + public let completedAchievements: UInt32 + public let totalAchievements: UInt32 + public let completionPercentage: Double + public let lastAchievementAt: UInt64? + public let createdAt: UInt64 + public let updatedAt: UInt64 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(totalPoints: UInt32, completedAchievements: UInt32, totalAchievements: UInt32, completionPercentage: Double, lastAchievementAt: UInt64?, createdAt: UInt64, updatedAt: UInt64) { + self.totalPoints = totalPoints + self.completedAchievements = completedAchievements + self.totalAchievements = totalAchievements + self.completionPercentage = completionPercentage + self.lastAchievementAt = lastAchievementAt + self.createdAt = createdAt + self.updatedAt = updatedAt + } + + +} + +#if compiler(>=6) +extension PlayerAchievementStats: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePlayerAchievementStats: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PlayerAchievementStats { + return + try PlayerAchievementStats( + totalPoints: FfiConverterUInt32.read(from: &buf), + completedAchievements: FfiConverterUInt32.read(from: &buf), + totalAchievements: FfiConverterUInt32.read(from: &buf), + completionPercentage: FfiConverterDouble.read(from: &buf), + lastAchievementAt: FfiConverterOptionUInt64.read(from: &buf), + createdAt: FfiConverterUInt64.read(from: &buf), + updatedAt: FfiConverterUInt64.read(from: &buf) + ) + } + + public static func write(_ value: PlayerAchievementStats, into buf: inout [UInt8]) { + FfiConverterUInt32.write(value.totalPoints, into: &buf) + FfiConverterUInt32.write(value.completedAchievements, into: &buf) + FfiConverterUInt32.write(value.totalAchievements, into: &buf) + FfiConverterDouble.write(value.completionPercentage, into: &buf) + FfiConverterOptionUInt64.write(value.lastAchievementAt, into: &buf) + FfiConverterUInt64.write(value.createdAt, into: &buf) + FfiConverterUInt64.write(value.updatedAt, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePlayerAchievementStats_lift(_ buf: RustBuffer) throws -> PlayerAchievementStats { + return try FfiConverterTypePlayerAchievementStats.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePlayerAchievementStats_lower(_ value: PlayerAchievementStats) -> RustBuffer { + return FfiConverterTypePlayerAchievementStats.lower(value) +} + + +public struct Signature: Equatable, Hashable { + public let r: FieldElement + public let s: FieldElement + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(r: FieldElement, s: FieldElement) { + self.r = r + self.s = s + } + + +} + +#if compiler(>=6) +extension Signature: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeSignature: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Signature { + return + try Signature( + r: FfiConverterTypeFieldElement.read(from: &buf), + s: FfiConverterTypeFieldElement.read(from: &buf) + ) + } + + public static func write(_ value: Signature, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.r, into: &buf) + FfiConverterTypeFieldElement.write(value.s, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSignature_lift(_ buf: RustBuffer) throws -> Signature { + return try FfiConverterTypeSignature.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSignature_lower(_ value: Signature) -> RustBuffer { + return FfiConverterTypeSignature.lower(value) +} + + +public struct Struct: Equatable, Hashable { + public let name: String + public let children: [Member] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(name: String, children: [Member]) { + self.name = name + self.children = children + } + + +} + +#if compiler(>=6) +extension Struct: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeStruct: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Struct { + return + try Struct( + name: FfiConverterString.read(from: &buf), + children: FfiConverterSequenceTypeMember.read(from: &buf) + ) + } + + public static func write(_ value: Struct, into buf: inout [UInt8]) { + FfiConverterString.write(value.name, into: &buf) + FfiConverterSequenceTypeMember.write(value.children, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeStruct_lift(_ buf: RustBuffer) throws -> Struct { + return try FfiConverterTypeStruct.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeStruct_lower(_ value: Struct) -> RustBuffer { + return FfiConverterTypeStruct.lower(value) +} + + +public struct TaskProgress: Equatable, Hashable { + public let taskId: String + public let count: UInt32 + public let completed: Bool + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(taskId: String, count: UInt32, completed: Bool) { + self.taskId = taskId + self.count = count + self.completed = completed + } + + +} + +#if compiler(>=6) +extension TaskProgress: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTaskProgress: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TaskProgress { + return + try TaskProgress( + taskId: FfiConverterString.read(from: &buf), + count: FfiConverterUInt32.read(from: &buf), + completed: FfiConverterBool.read(from: &buf) + ) + } + + public static func write(_ value: TaskProgress, into buf: inout [UInt8]) { + FfiConverterString.write(value.taskId, into: &buf) + FfiConverterUInt32.write(value.count, into: &buf) + FfiConverterBool.write(value.completed, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTaskProgress_lift(_ buf: RustBuffer) throws -> TaskProgress { + return try FfiConverterTypeTaskProgress.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTaskProgress_lower(_ value: TaskProgress) -> RustBuffer { + return FfiConverterTypeTaskProgress.lower(value) +} + + +public struct Token: Equatable, Hashable { + public let contractAddress: FieldElement + public let tokenId: U256? + public let name: String + public let symbol: String + public let decimals: UInt8 + public let metadata: String + public let totalSupply: U256? + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddress: FieldElement, tokenId: U256?, name: String, symbol: String, decimals: UInt8, metadata: String, totalSupply: U256?) { + self.contractAddress = contractAddress + self.tokenId = tokenId + self.name = name + self.symbol = symbol + self.decimals = decimals + self.metadata = metadata + self.totalSupply = totalSupply + } + + +} + +#if compiler(>=6) +extension Token: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeToken: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Token { + return + try Token( + contractAddress: FfiConverterTypeFieldElement.read(from: &buf), + tokenId: FfiConverterOptionTypeU256.read(from: &buf), + name: FfiConverterString.read(from: &buf), + symbol: FfiConverterString.read(from: &buf), + decimals: FfiConverterUInt8.read(from: &buf), + metadata: FfiConverterString.read(from: &buf), + totalSupply: FfiConverterOptionTypeU256.read(from: &buf) + ) + } + + public static func write(_ value: Token, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) + FfiConverterOptionTypeU256.write(value.tokenId, into: &buf) + FfiConverterString.write(value.name, into: &buf) + FfiConverterString.write(value.symbol, into: &buf) + FfiConverterUInt8.write(value.decimals, into: &buf) + FfiConverterString.write(value.metadata, into: &buf) + FfiConverterOptionTypeU256.write(value.totalSupply, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeToken_lift(_ buf: RustBuffer) throws -> Token { + return try FfiConverterTypeToken.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeToken_lower(_ value: Token) -> RustBuffer { + return FfiConverterTypeToken.lower(value) +} + + +public struct TokenBalance: Equatable, Hashable { + public let balance: U256 + public let accountAddress: FieldElement + public let contractAddress: FieldElement + public let tokenId: U256? + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(balance: U256, accountAddress: FieldElement, contractAddress: FieldElement, tokenId: U256?) { + self.balance = balance + self.accountAddress = accountAddress + self.contractAddress = contractAddress + self.tokenId = tokenId + } + + +} + +#if compiler(>=6) +extension TokenBalance: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTokenBalance: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenBalance { + return + try TokenBalance( + balance: FfiConverterTypeU256.read(from: &buf), + accountAddress: FfiConverterTypeFieldElement.read(from: &buf), + contractAddress: FfiConverterTypeFieldElement.read(from: &buf), + tokenId: FfiConverterOptionTypeU256.read(from: &buf) + ) + } + + public static func write(_ value: TokenBalance, into buf: inout [UInt8]) { + FfiConverterTypeU256.write(value.balance, into: &buf) + FfiConverterTypeFieldElement.write(value.accountAddress, into: &buf) + FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) + FfiConverterOptionTypeU256.write(value.tokenId, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTokenBalance_lift(_ buf: RustBuffer) throws -> TokenBalance { + return try FfiConverterTypeTokenBalance.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTokenBalance_lower(_ value: TokenBalance) -> RustBuffer { + return FfiConverterTypeTokenBalance.lower(value) +} + + +public struct TokenBalanceQuery: Equatable, Hashable { + public let contractAddresses: [FieldElement] + public let accountAddresses: [FieldElement] + public let tokenIds: [U256] + public let pagination: Pagination + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddresses: [FieldElement], accountAddresses: [FieldElement], tokenIds: [U256], pagination: Pagination) { + self.contractAddresses = contractAddresses + self.accountAddresses = accountAddresses + self.tokenIds = tokenIds + self.pagination = pagination + } + + +} + +#if compiler(>=6) +extension TokenBalanceQuery: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTokenBalanceQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenBalanceQuery { + return + try TokenBalanceQuery( + contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + accountAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + tokenIds: FfiConverterSequenceTypeU256.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) + ) + } + + public static func write(_ value: TokenBalanceQuery, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.accountAddresses, into: &buf) + FfiConverterSequenceTypeU256.write(value.tokenIds, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTokenBalanceQuery_lift(_ buf: RustBuffer) throws -> TokenBalanceQuery { + return try FfiConverterTypeTokenBalanceQuery.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTokenBalanceQuery_lower(_ value: TokenBalanceQuery) -> RustBuffer { + return FfiConverterTypeTokenBalanceQuery.lower(value) +} + + +public struct TokenContract: Equatable, Hashable { + public let contractAddress: FieldElement + public let name: String + public let symbol: String + public let decimals: UInt8 + public let metadata: String + public let tokenMetadata: String + public let totalSupply: U256? + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddress: FieldElement, name: String, symbol: String, decimals: UInt8, metadata: String, tokenMetadata: String, totalSupply: U256?) { + self.contractAddress = contractAddress + self.name = name + self.symbol = symbol + self.decimals = decimals + self.metadata = metadata + self.tokenMetadata = tokenMetadata + self.totalSupply = totalSupply + } + + +} + +#if compiler(>=6) +extension TokenContract: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTokenContract: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenContract { + return + try TokenContract( + contractAddress: FfiConverterTypeFieldElement.read(from: &buf), + name: FfiConverterString.read(from: &buf), + symbol: FfiConverterString.read(from: &buf), + decimals: FfiConverterUInt8.read(from: &buf), + metadata: FfiConverterString.read(from: &buf), + tokenMetadata: FfiConverterString.read(from: &buf), + totalSupply: FfiConverterOptionTypeU256.read(from: &buf) + ) + } + + public static func write(_ value: TokenContract, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) + FfiConverterString.write(value.name, into: &buf) + FfiConverterString.write(value.symbol, into: &buf) + FfiConverterUInt8.write(value.decimals, into: &buf) + FfiConverterString.write(value.metadata, into: &buf) + FfiConverterString.write(value.tokenMetadata, into: &buf) + FfiConverterOptionTypeU256.write(value.totalSupply, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTokenContract_lift(_ buf: RustBuffer) throws -> TokenContract { + return try FfiConverterTypeTokenContract.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTokenContract_lower(_ value: TokenContract) -> RustBuffer { + return FfiConverterTypeTokenContract.lower(value) +} + + +public struct TokenContractQuery: Equatable, Hashable { + public let contractAddresses: [FieldElement] + public let contractTypes: [ContractType] + public let pagination: Pagination + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddresses: [FieldElement], contractTypes: [ContractType], pagination: Pagination) { + self.contractAddresses = contractAddresses + self.contractTypes = contractTypes + self.pagination = pagination + } + + +} + +#if compiler(>=6) +extension TokenContractQuery: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTokenContractQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenContractQuery { + return + try TokenContractQuery( + contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + contractTypes: FfiConverterSequenceTypeContractType.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) + ) + } + + public static func write(_ value: TokenContractQuery, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) + FfiConverterSequenceTypeContractType.write(value.contractTypes, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTokenContractQuery_lift(_ buf: RustBuffer) throws -> TokenContractQuery { + return try FfiConverterTypeTokenContractQuery.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTokenContractQuery_lower(_ value: TokenContractQuery) -> RustBuffer { + return FfiConverterTypeTokenContractQuery.lower(value) +} + + +public struct TokenQuery: Equatable, Hashable { + public let contractAddresses: [FieldElement] + public let tokenIds: [U256] + public let attributeFilters: [AttributeFilter] + public let pagination: Pagination + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddresses: [FieldElement], tokenIds: [U256], attributeFilters: [AttributeFilter], pagination: Pagination) { + self.contractAddresses = contractAddresses + self.tokenIds = tokenIds + self.attributeFilters = attributeFilters + self.pagination = pagination + } + + +} + +#if compiler(>=6) +extension TokenQuery: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTokenQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenQuery { + return + try TokenQuery( + contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + tokenIds: FfiConverterSequenceTypeU256.read(from: &buf), + attributeFilters: FfiConverterSequenceTypeAttributeFilter.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) + ) + } + + public static func write(_ value: TokenQuery, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) + FfiConverterSequenceTypeU256.write(value.tokenIds, into: &buf) + FfiConverterSequenceTypeAttributeFilter.write(value.attributeFilters, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTokenQuery_lift(_ buf: RustBuffer) throws -> TokenQuery { + return try FfiConverterTypeTokenQuery.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTokenQuery_lower(_ value: TokenQuery) -> RustBuffer { + return FfiConverterTypeTokenQuery.lower(value) +} + + +public struct TokenTransfer: Equatable, Hashable { + public let id: String + public let contractAddress: FieldElement + public let fromAddress: FieldElement + public let toAddress: FieldElement + public let amount: U256 + public let tokenId: U256? + public let executedAt: UInt64 + public let eventId: String? + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(id: String, contractAddress: FieldElement, fromAddress: FieldElement, toAddress: FieldElement, amount: U256, tokenId: U256?, executedAt: UInt64, eventId: String?) { + self.id = id + self.contractAddress = contractAddress + self.fromAddress = fromAddress + self.toAddress = toAddress + self.amount = amount + self.tokenId = tokenId + self.executedAt = executedAt + self.eventId = eventId + } + + +} + +#if compiler(>=6) +extension TokenTransfer: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTokenTransfer: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenTransfer { + return + try TokenTransfer( + id: FfiConverterString.read(from: &buf), + contractAddress: FfiConverterTypeFieldElement.read(from: &buf), + fromAddress: FfiConverterTypeFieldElement.read(from: &buf), + toAddress: FfiConverterTypeFieldElement.read(from: &buf), + amount: FfiConverterTypeU256.read(from: &buf), + tokenId: FfiConverterOptionTypeU256.read(from: &buf), + executedAt: FfiConverterUInt64.read(from: &buf), + eventId: FfiConverterOptionString.read(from: &buf) + ) + } + + public static func write(_ value: TokenTransfer, into buf: inout [UInt8]) { + FfiConverterString.write(value.id, into: &buf) + FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) + FfiConverterTypeFieldElement.write(value.fromAddress, into: &buf) + FfiConverterTypeFieldElement.write(value.toAddress, into: &buf) + FfiConverterTypeU256.write(value.amount, into: &buf) + FfiConverterOptionTypeU256.write(value.tokenId, into: &buf) + FfiConverterUInt64.write(value.executedAt, into: &buf) + FfiConverterOptionString.write(value.eventId, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTokenTransfer_lift(_ buf: RustBuffer) throws -> TokenTransfer { + return try FfiConverterTypeTokenTransfer.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTokenTransfer_lower(_ value: TokenTransfer) -> RustBuffer { + return FfiConverterTypeTokenTransfer.lower(value) +} + + +public struct TokenTransferQuery: Equatable, Hashable { + public let contractAddresses: [FieldElement] + public let accountAddresses: [FieldElement] + public let tokenIds: [U256] + public let pagination: Pagination + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddresses: [FieldElement], accountAddresses: [FieldElement], tokenIds: [U256], pagination: Pagination) { + self.contractAddresses = contractAddresses + self.accountAddresses = accountAddresses + self.tokenIds = tokenIds + self.pagination = pagination + } + + +} + +#if compiler(>=6) +extension TokenTransferQuery: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTokenTransferQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenTransferQuery { + return + try TokenTransferQuery( + contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + accountAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + tokenIds: FfiConverterSequenceTypeU256.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) + ) + } + + public static func write(_ value: TokenTransferQuery, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.accountAddresses, into: &buf) + FfiConverterSequenceTypeU256.write(value.tokenIds, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTokenTransferQuery_lift(_ buf: RustBuffer) throws -> TokenTransferQuery { + return try FfiConverterTypeTokenTransferQuery.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTokenTransferQuery_lower(_ value: TokenTransferQuery) -> RustBuffer { + return FfiConverterTypeTokenTransferQuery.lower(value) +} + + +public struct Transaction: Equatable, Hashable { + public let transactionHash: FieldElement + public let senderAddress: FieldElement + public let calldata: [FieldElement] + public let maxFee: FieldElement + public let signature: [FieldElement] + public let nonce: FieldElement + public let blockNumber: UInt64 + public let transactionType: String + public let blockTimestamp: UInt64 + public let calls: [TransactionCall] + public let uniqueModels: [FieldElement] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(transactionHash: FieldElement, senderAddress: FieldElement, calldata: [FieldElement], maxFee: FieldElement, signature: [FieldElement], nonce: FieldElement, blockNumber: UInt64, transactionType: String, blockTimestamp: UInt64, calls: [TransactionCall], uniqueModels: [FieldElement]) { + self.transactionHash = transactionHash + self.senderAddress = senderAddress + self.calldata = calldata + self.maxFee = maxFee + self.signature = signature + self.nonce = nonce + self.blockNumber = blockNumber + self.transactionType = transactionType + self.blockTimestamp = blockTimestamp + self.calls = calls + self.uniqueModels = uniqueModels + } + + +} + +#if compiler(>=6) +extension Transaction: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTransaction: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Transaction { + return + try Transaction( + transactionHash: FfiConverterTypeFieldElement.read(from: &buf), + senderAddress: FfiConverterTypeFieldElement.read(from: &buf), + calldata: FfiConverterSequenceTypeFieldElement.read(from: &buf), + maxFee: FfiConverterTypeFieldElement.read(from: &buf), + signature: FfiConverterSequenceTypeFieldElement.read(from: &buf), + nonce: FfiConverterTypeFieldElement.read(from: &buf), + blockNumber: FfiConverterUInt64.read(from: &buf), + transactionType: FfiConverterString.read(from: &buf), + blockTimestamp: FfiConverterUInt64.read(from: &buf), + calls: FfiConverterSequenceTypeTransactionCall.read(from: &buf), + uniqueModels: FfiConverterSequenceTypeFieldElement.read(from: &buf) + ) + } + + public static func write(_ value: Transaction, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.transactionHash, into: &buf) + FfiConverterTypeFieldElement.write(value.senderAddress, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.calldata, into: &buf) + FfiConverterTypeFieldElement.write(value.maxFee, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.signature, into: &buf) + FfiConverterTypeFieldElement.write(value.nonce, into: &buf) + FfiConverterUInt64.write(value.blockNumber, into: &buf) + FfiConverterString.write(value.transactionType, into: &buf) + FfiConverterUInt64.write(value.blockTimestamp, into: &buf) + FfiConverterSequenceTypeTransactionCall.write(value.calls, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.uniqueModels, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransaction_lift(_ buf: RustBuffer) throws -> Transaction { + return try FfiConverterTypeTransaction.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransaction_lower(_ value: Transaction) -> RustBuffer { + return FfiConverterTypeTransaction.lower(value) +} + + +public struct TransactionCall: Equatable, Hashable { + public let contractAddress: FieldElement + public let entrypoint: String + public let calldata: [FieldElement] + public let callType: CallType + public let callerAddress: FieldElement + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddress: FieldElement, entrypoint: String, calldata: [FieldElement], callType: CallType, callerAddress: FieldElement) { + self.contractAddress = contractAddress + self.entrypoint = entrypoint + self.calldata = calldata + self.callType = callType + self.callerAddress = callerAddress + } + + +} + +#if compiler(>=6) +extension TransactionCall: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTransactionCall: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TransactionCall { + return + try TransactionCall( + contractAddress: FfiConverterTypeFieldElement.read(from: &buf), + entrypoint: FfiConverterString.read(from: &buf), + calldata: FfiConverterSequenceTypeFieldElement.read(from: &buf), + callType: FfiConverterTypeCallType.read(from: &buf), + callerAddress: FfiConverterTypeFieldElement.read(from: &buf) + ) + } + + public static func write(_ value: TransactionCall, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) + FfiConverterString.write(value.entrypoint, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.calldata, into: &buf) + FfiConverterTypeCallType.write(value.callType, into: &buf) + FfiConverterTypeFieldElement.write(value.callerAddress, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransactionCall_lift(_ buf: RustBuffer) throws -> TransactionCall { + return try FfiConverterTypeTransactionCall.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransactionCall_lower(_ value: TransactionCall) -> RustBuffer { + return FfiConverterTypeTransactionCall.lower(value) +} + + +public struct TransactionFilter: Equatable, Hashable { + public let transactionHashes: [FieldElement] + public let callerAddresses: [FieldElement] + public let contractAddresses: [FieldElement] + public let entrypoints: [String] + public let modelSelectors: [FieldElement] + public let fromBlock: UInt64? + public let toBlock: UInt64? + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(transactionHashes: [FieldElement], callerAddresses: [FieldElement], contractAddresses: [FieldElement], entrypoints: [String], modelSelectors: [FieldElement], fromBlock: UInt64?, toBlock: UInt64?) { + self.transactionHashes = transactionHashes + self.callerAddresses = callerAddresses + self.contractAddresses = contractAddresses + self.entrypoints = entrypoints + self.modelSelectors = modelSelectors + self.fromBlock = fromBlock + self.toBlock = toBlock + } + + +} + +#if compiler(>=6) +extension TransactionFilter: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTransactionFilter: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TransactionFilter { + return + try TransactionFilter( + transactionHashes: FfiConverterSequenceTypeFieldElement.read(from: &buf), + callerAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + entrypoints: FfiConverterSequenceString.read(from: &buf), + modelSelectors: FfiConverterSequenceTypeFieldElement.read(from: &buf), + fromBlock: FfiConverterOptionUInt64.read(from: &buf), + toBlock: FfiConverterOptionUInt64.read(from: &buf) + ) + } + + public static func write(_ value: TransactionFilter, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.transactionHashes, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.callerAddresses, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) + FfiConverterSequenceString.write(value.entrypoints, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.modelSelectors, into: &buf) + FfiConverterOptionUInt64.write(value.fromBlock, into: &buf) + FfiConverterOptionUInt64.write(value.toBlock, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransactionFilter_lift(_ buf: RustBuffer) throws -> TransactionFilter { + return try FfiConverterTypeTransactionFilter.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransactionFilter_lower(_ value: TransactionFilter) -> RustBuffer { + return FfiConverterTypeTransactionFilter.lower(value) +} + + +public struct TransactionQuery: Equatable, Hashable { + public let filter: TransactionFilter? + public let pagination: Pagination + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(filter: TransactionFilter?, pagination: Pagination) { + self.filter = filter + self.pagination = pagination + } + + +} + +#if compiler(>=6) +extension TransactionQuery: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTransactionQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TransactionQuery { + return + try TransactionQuery( + filter: FfiConverterOptionTypeTransactionFilter.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) + ) + } + + public static func write(_ value: TransactionQuery, into buf: inout [UInt8]) { + FfiConverterOptionTypeTransactionFilter.write(value.filter, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransactionQuery_lift(_ buf: RustBuffer) throws -> TransactionQuery { + return try FfiConverterTypeTransactionQuery.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransactionQuery_lower(_ value: TransactionQuery) -> RustBuffer { + return FfiConverterTypeTransactionQuery.lower(value) +} + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum CallType: Equatable, Hashable { + + case execute + case executeFromOutside + + + +} + +#if compiler(>=6) +extension CallType: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeCallType: FfiConverterRustBuffer { + typealias SwiftType = CallType + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> CallType { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .execute + + case 2: return .executeFromOutside + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: CallType, into buf: inout [UInt8]) { + switch value { + + + case .execute: + writeInt(&buf, Int32(1)) + + + case .executeFromOutside: + writeInt(&buf, Int32(2)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeCallType_lift(_ buf: RustBuffer) throws -> CallType { + return try FfiConverterTypeCallType.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeCallType_lower(_ value: CallType) -> RustBuffer { + return FfiConverterTypeCallType.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum Clause: Equatable, Hashable { + + case hashedKeys(keys: [FieldElement] + ) + case keys(clause: KeysClause + ) + case member(clause: MemberClause + ) + case composite(clause: CompositeClause + ) + + + +} + +#if compiler(>=6) +extension Clause: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeClause: FfiConverterRustBuffer { + typealias SwiftType = Clause + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Clause { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .hashedKeys(keys: try FfiConverterSequenceTypeFieldElement.read(from: &buf) + ) + + case 2: return .keys(clause: try FfiConverterTypeKeysClause.read(from: &buf) + ) + + case 3: return .member(clause: try FfiConverterTypeMemberClause.read(from: &buf) + ) + + case 4: return .composite(clause: try FfiConverterTypeCompositeClause.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: Clause, into buf: inout [UInt8]) { + switch value { + + + case let .hashedKeys(keys): + writeInt(&buf, Int32(1)) + FfiConverterSequenceTypeFieldElement.write(keys, into: &buf) + + + case let .keys(clause): + writeInt(&buf, Int32(2)) + FfiConverterTypeKeysClause.write(clause, into: &buf) + + + case let .member(clause): + writeInt(&buf, Int32(3)) + FfiConverterTypeMemberClause.write(clause, into: &buf) + + + case let .composite(clause): + writeInt(&buf, Int32(4)) + FfiConverterTypeCompositeClause.write(clause, into: &buf) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeClause_lift(_ buf: RustBuffer) throws -> Clause { + return try FfiConverterTypeClause.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeClause_lower(_ value: Clause) -> RustBuffer { + return FfiConverterTypeClause.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum ComparisonOperator: Equatable, Hashable { + + case eq + case neq + case gt + case gte + case lt + case lte + case `in` + case notIn + case contains + case containsAll + case containsAny + case arrayLengthEq + case arrayLengthGt + case arrayLengthLt + + + +} + +#if compiler(>=6) +extension ComparisonOperator: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeComparisonOperator: FfiConverterRustBuffer { + typealias SwiftType = ComparisonOperator + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ComparisonOperator { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .eq + + case 2: return .neq + + case 3: return .gt + + case 4: return .gte + + case 5: return .lt + + case 6: return .lte + + case 7: return .`in` + + case 8: return .notIn + + case 9: return .contains + + case 10: return .containsAll + + case 11: return .containsAny + + case 12: return .arrayLengthEq + + case 13: return .arrayLengthGt + + case 14: return .arrayLengthLt + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: ComparisonOperator, into buf: inout [UInt8]) { + switch value { + + + case .eq: + writeInt(&buf, Int32(1)) + + + case .neq: + writeInt(&buf, Int32(2)) + + + case .gt: + writeInt(&buf, Int32(3)) + + + case .gte: + writeInt(&buf, Int32(4)) + + + case .lt: + writeInt(&buf, Int32(5)) + + + case .lte: + writeInt(&buf, Int32(6)) + + + case .`in`: + writeInt(&buf, Int32(7)) + + + case .notIn: + writeInt(&buf, Int32(8)) + + + case .contains: + writeInt(&buf, Int32(9)) + + + case .containsAll: + writeInt(&buf, Int32(10)) + + + case .containsAny: + writeInt(&buf, Int32(11)) + + + case .arrayLengthEq: + writeInt(&buf, Int32(12)) + + + case .arrayLengthGt: + writeInt(&buf, Int32(13)) + + + case .arrayLengthLt: + writeInt(&buf, Int32(14)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeComparisonOperator_lift(_ buf: RustBuffer) throws -> ComparisonOperator { + return try FfiConverterTypeComparisonOperator.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeComparisonOperator_lower(_ value: ComparisonOperator) -> RustBuffer { + return FfiConverterTypeComparisonOperator.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum ContractType: Equatable, Hashable { + + case world + case erc20 + case erc721 + case erc1155 + case udc + case other + + + +} + +#if compiler(>=6) +extension ContractType: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeContractType: FfiConverterRustBuffer { + typealias SwiftType = ContractType + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ContractType { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .world + + case 2: return .erc20 + + case 3: return .erc721 + + case 4: return .erc1155 + + case 5: return .udc + + case 6: return .other + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: ContractType, into buf: inout [UInt8]) { + switch value { + + + case .world: + writeInt(&buf, Int32(1)) + + + case .erc20: + writeInt(&buf, Int32(2)) + + + case .erc721: + writeInt(&buf, Int32(3)) + + + case .erc1155: + writeInt(&buf, Int32(4)) + + + case .udc: + writeInt(&buf, Int32(5)) + + + case .other: + writeInt(&buf, Int32(6)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeContractType_lift(_ buf: RustBuffer) throws -> ContractType { + return try FfiConverterTypeContractType.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeContractType_lower(_ value: ContractType) -> RustBuffer { + return FfiConverterTypeContractType.lower(value) +} + + + +public enum DojoError: Swift.Error, Equatable, Hashable, Foundation.LocalizedError { + + + + case ClientError(message: String) + + case SerializationError(message: String) + + case NetworkError(message: String) + + case InvalidInput(message: String) + + + + + + public var errorDescription: String? { + String(reflecting: self) + } + +} + +#if compiler(>=6) +extension DojoError: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeDojoError: FfiConverterRustBuffer { + typealias SwiftType = DojoError + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> DojoError { + let variant: Int32 = try readInt(&buf) + switch variant { + + + + + case 1: return .ClientError( + message: try FfiConverterString.read(from: &buf) + ) + + case 2: return .SerializationError( + message: try FfiConverterString.read(from: &buf) + ) + + case 3: return .NetworkError( + message: try FfiConverterString.read(from: &buf) + ) + + case 4: return .InvalidInput( + message: try FfiConverterString.read(from: &buf) + ) + + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: DojoError, into buf: inout [UInt8]) { + switch value { + + + + + case .ClientError(_ /* message is ignored*/): + writeInt(&buf, Int32(1)) + case .SerializationError(_ /* message is ignored*/): + writeInt(&buf, Int32(2)) + case .NetworkError(_ /* message is ignored*/): + writeInt(&buf, Int32(3)) + case .InvalidInput(_ /* message is ignored*/): + writeInt(&buf, Int32(4)) + + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeDojoError_lift(_ buf: RustBuffer) throws -> DojoError { + return try FfiConverterTypeDojoError.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeDojoError_lower(_ value: DojoError) -> RustBuffer { + return FfiConverterTypeDojoError.lower(value) +} + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum LogicalOperator: Equatable, Hashable { + + case and + case or + + + +} + +#if compiler(>=6) +extension LogicalOperator: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeLogicalOperator: FfiConverterRustBuffer { + typealias SwiftType = LogicalOperator + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LogicalOperator { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .and + + case 2: return .or + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: LogicalOperator, into buf: inout [UInt8]) { + switch value { + + + case .and: + writeInt(&buf, Int32(1)) + + + case .or: + writeInt(&buf, Int32(2)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeLogicalOperator_lift(_ buf: RustBuffer) throws -> LogicalOperator { + return try FfiConverterTypeLogicalOperator.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeLogicalOperator_lower(_ value: LogicalOperator) -> RustBuffer { + return FfiConverterTypeLogicalOperator.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum MemberValue: Equatable, Hashable { + + case primitive(value: Primitive + ) + case string(value: String + ) + case list(values: [MemberValue] + ) + + + +} + +#if compiler(>=6) +extension MemberValue: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeMemberValue: FfiConverterRustBuffer { + typealias SwiftType = MemberValue + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> MemberValue { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .primitive(value: try FfiConverterTypePrimitive.read(from: &buf) + ) + + case 2: return .string(value: try FfiConverterString.read(from: &buf) + ) + + case 3: return .list(values: try FfiConverterSequenceTypeMemberValue.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: MemberValue, into buf: inout [UInt8]) { + switch value { + + + case let .primitive(value): + writeInt(&buf, Int32(1)) + FfiConverterTypePrimitive.write(value, into: &buf) + + + case let .string(value): + writeInt(&buf, Int32(2)) + FfiConverterString.write(value, into: &buf) + + + case let .list(values): + writeInt(&buf, Int32(3)) + FfiConverterSequenceTypeMemberValue.write(values, into: &buf) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeMemberValue_lift(_ buf: RustBuffer) throws -> MemberValue { + return try FfiConverterTypeMemberValue.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeMemberValue_lower(_ value: MemberValue) -> RustBuffer { + return FfiConverterTypeMemberValue.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum OrderDirection: Equatable, Hashable { + + case asc + case desc + + + +} + +#if compiler(>=6) +extension OrderDirection: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeOrderDirection: FfiConverterRustBuffer { + typealias SwiftType = OrderDirection + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OrderDirection { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .asc + + case 2: return .desc + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: OrderDirection, into buf: inout [UInt8]) { + switch value { + + + case .asc: + writeInt(&buf, Int32(1)) + + + case .desc: + writeInt(&buf, Int32(2)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeOrderDirection_lift(_ buf: RustBuffer) throws -> OrderDirection { + return try FfiConverterTypeOrderDirection.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeOrderDirection_lower(_ value: OrderDirection) -> RustBuffer { + return FfiConverterTypeOrderDirection.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum PaginationDirection: Equatable, Hashable { + + case forward + case backward + + + +} + +#if compiler(>=6) +extension PaginationDirection: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePaginationDirection: FfiConverterRustBuffer { + typealias SwiftType = PaginationDirection + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PaginationDirection { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .forward + + case 2: return .backward + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: PaginationDirection, into buf: inout [UInt8]) { + switch value { + + + case .forward: + writeInt(&buf, Int32(1)) + + + case .backward: + writeInt(&buf, Int32(2)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePaginationDirection_lift(_ buf: RustBuffer) throws -> PaginationDirection { + return try FfiConverterTypePaginationDirection.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePaginationDirection_lower(_ value: PaginationDirection) -> RustBuffer { + return FfiConverterTypePaginationDirection.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum PatternMatching: Equatable, Hashable { + + case fixedLen + case variableLen + + + +} + +#if compiler(>=6) +extension PatternMatching: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePatternMatching: FfiConverterRustBuffer { + typealias SwiftType = PatternMatching + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PatternMatching { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .fixedLen + + case 2: return .variableLen + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: PatternMatching, into buf: inout [UInt8]) { + switch value { + + + case .fixedLen: + writeInt(&buf, Int32(1)) + + + case .variableLen: + writeInt(&buf, Int32(2)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePatternMatching_lift(_ buf: RustBuffer) throws -> PatternMatching { + return try FfiConverterTypePatternMatching.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePatternMatching_lower(_ value: PatternMatching) -> RustBuffer { + return FfiConverterTypePatternMatching.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum Primitive: Equatable, Hashable { + + case i8(value: Int8 + ) + case i16(value: Int16 + ) + case i32(value: Int32 + ) + case i64(value: Int64 + ) + case i128(value: [UInt8] + ) + case u8(value: UInt8 + ) + case u16(value: UInt16 + ) + case u32(value: UInt32 + ) + case u64(value: UInt64 + ) + case u128(value: [UInt8] + ) + case u256(value: U256 + ) + case bool(value: Bool + ) + case felt252(value: FieldElement + ) + case classHash(value: FieldElement + ) + case contractAddress(value: FieldElement + ) + case ethAddress(value: FieldElement + ) + + + +} + +#if compiler(>=6) +extension Primitive: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePrimitive: FfiConverterRustBuffer { + typealias SwiftType = Primitive + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Primitive { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .i8(value: try FfiConverterInt8.read(from: &buf) + ) + + case 2: return .i16(value: try FfiConverterInt16.read(from: &buf) + ) + + case 3: return .i32(value: try FfiConverterInt32.read(from: &buf) + ) + + case 4: return .i64(value: try FfiConverterInt64.read(from: &buf) + ) + + case 5: return .i128(value: try FfiConverterSequenceUInt8.read(from: &buf) + ) + + case 6: return .u8(value: try FfiConverterUInt8.read(from: &buf) + ) + + case 7: return .u16(value: try FfiConverterUInt16.read(from: &buf) + ) + + case 8: return .u32(value: try FfiConverterUInt32.read(from: &buf) + ) + + case 9: return .u64(value: try FfiConverterUInt64.read(from: &buf) + ) + + case 10: return .u128(value: try FfiConverterSequenceUInt8.read(from: &buf) + ) + + case 11: return .u256(value: try FfiConverterTypeU256.read(from: &buf) + ) + + case 12: return .bool(value: try FfiConverterBool.read(from: &buf) + ) + + case 13: return .felt252(value: try FfiConverterTypeFieldElement.read(from: &buf) + ) + + case 14: return .classHash(value: try FfiConverterTypeFieldElement.read(from: &buf) + ) + + case 15: return .contractAddress(value: try FfiConverterTypeFieldElement.read(from: &buf) + ) + + case 16: return .ethAddress(value: try FfiConverterTypeFieldElement.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: Primitive, into buf: inout [UInt8]) { + switch value { + + + case let .i8(value): + writeInt(&buf, Int32(1)) + FfiConverterInt8.write(value, into: &buf) + + + case let .i16(value): + writeInt(&buf, Int32(2)) + FfiConverterInt16.write(value, into: &buf) + + + case let .i32(value): + writeInt(&buf, Int32(3)) + FfiConverterInt32.write(value, into: &buf) + + + case let .i64(value): + writeInt(&buf, Int32(4)) + FfiConverterInt64.write(value, into: &buf) + + + case let .i128(value): + writeInt(&buf, Int32(5)) + FfiConverterSequenceUInt8.write(value, into: &buf) + + + case let .u8(value): + writeInt(&buf, Int32(6)) + FfiConverterUInt8.write(value, into: &buf) + + + case let .u16(value): + writeInt(&buf, Int32(7)) + FfiConverterUInt16.write(value, into: &buf) + + + case let .u32(value): + writeInt(&buf, Int32(8)) + FfiConverterUInt32.write(value, into: &buf) + + + case let .u64(value): + writeInt(&buf, Int32(9)) + FfiConverterUInt64.write(value, into: &buf) + + + case let .u128(value): + writeInt(&buf, Int32(10)) + FfiConverterSequenceUInt8.write(value, into: &buf) + + + case let .u256(value): + writeInt(&buf, Int32(11)) + FfiConverterTypeU256.write(value, into: &buf) + + + case let .bool(value): + writeInt(&buf, Int32(12)) + FfiConverterBool.write(value, into: &buf) + + + case let .felt252(value): + writeInt(&buf, Int32(13)) + FfiConverterTypeFieldElement.write(value, into: &buf) + + + case let .classHash(value): + writeInt(&buf, Int32(14)) + FfiConverterTypeFieldElement.write(value, into: &buf) + + + case let .contractAddress(value): + writeInt(&buf, Int32(15)) + FfiConverterTypeFieldElement.write(value, into: &buf) + + + case let .ethAddress(value): + writeInt(&buf, Int32(16)) + FfiConverterTypeFieldElement.write(value, into: &buf) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePrimitive_lift(_ buf: RustBuffer) throws -> Primitive { + return try FfiConverterTypePrimitive.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePrimitive_lower(_ value: Primitive) -> RustBuffer { + return FfiConverterTypePrimitive.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum Ty: Equatable, Hashable { + + case primitive(value: Primitive + ) + case `struct`(value: Struct + ) + case `enum`(value: EnumType + ) + case tuple(values: [Ty] + ) + case array(values: [Ty] + ) + case fixedSizeArray(value: FixedSizeArray + ) + case byteArray(value: String + ) + + + +} + +#if compiler(>=6) +extension Ty: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTy: FfiConverterRustBuffer { + typealias SwiftType = Ty + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Ty { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .primitive(value: try FfiConverterTypePrimitive.read(from: &buf) + ) + + case 2: return .`struct`(value: try FfiConverterTypeStruct.read(from: &buf) + ) + + case 3: return .`enum`(value: try FfiConverterTypeEnumType.read(from: &buf) + ) + + case 4: return .tuple(values: try FfiConverterSequenceTypeTy.read(from: &buf) + ) + + case 5: return .array(values: try FfiConverterSequenceTypeTy.read(from: &buf) + ) + + case 6: return .fixedSizeArray(value: try FfiConverterTypeFixedSizeArray.read(from: &buf) + ) + + case 7: return .byteArray(value: try FfiConverterString.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: Ty, into buf: inout [UInt8]) { + switch value { + + + case let .primitive(value): + writeInt(&buf, Int32(1)) + FfiConverterTypePrimitive.write(value, into: &buf) + + + case let .`struct`(value): + writeInt(&buf, Int32(2)) + FfiConverterTypeStruct.write(value, into: &buf) + + + case let .`enum`(value): + writeInt(&buf, Int32(3)) + FfiConverterTypeEnumType.write(value, into: &buf) + + + case let .tuple(values): + writeInt(&buf, Int32(4)) + FfiConverterSequenceTypeTy.write(values, into: &buf) + + + case let .array(values): + writeInt(&buf, Int32(5)) + FfiConverterSequenceTypeTy.write(values, into: &buf) + + + case let .fixedSizeArray(value): + writeInt(&buf, Int32(6)) + FfiConverterTypeFixedSizeArray.write(value, into: &buf) + + + case let .byteArray(value): + writeInt(&buf, Int32(7)) + FfiConverterString.write(value, into: &buf) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTy_lift(_ buf: RustBuffer) throws -> Ty { + return try FfiConverterTypeTy.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTy_lower(_ value: Ty) -> RustBuffer { + return FfiConverterTypeTy.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum ValueType: Equatable, Hashable { + + case string(value: String + ) + case int(value: Int64 + ) + case uInt(value: UInt64 + ) + case bool(value: Bool + ) + case bytes(value: [UInt8] + ) + + + +} + +#if compiler(>=6) +extension ValueType: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeValueType: FfiConverterRustBuffer { + typealias SwiftType = ValueType + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ValueType { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .string(value: try FfiConverterString.read(from: &buf) + ) + + case 2: return .int(value: try FfiConverterInt64.read(from: &buf) + ) + + case 3: return .uInt(value: try FfiConverterUInt64.read(from: &buf) + ) + + case 4: return .bool(value: try FfiConverterBool.read(from: &buf) + ) + + case 5: return .bytes(value: try FfiConverterSequenceUInt8.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: ValueType, into buf: inout [UInt8]) { + switch value { + + + case let .string(value): + writeInt(&buf, Int32(1)) + FfiConverterString.write(value, into: &buf) + + + case let .int(value): + writeInt(&buf, Int32(2)) + FfiConverterInt64.write(value, into: &buf) + + + case let .uInt(value): + writeInt(&buf, Int32(3)) + FfiConverterUInt64.write(value, into: &buf) + + + case let .bool(value): + writeInt(&buf, Int32(4)) + FfiConverterBool.write(value, into: &buf) + + + case let .bytes(value): + writeInt(&buf, Int32(5)) + FfiConverterSequenceUInt8.write(value, into: &buf) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeValueType_lift(_ buf: RustBuffer) throws -> ValueType { + return try FfiConverterTypeValueType.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeValueType_lower(_ value: ValueType) -> RustBuffer { + return FfiConverterTypeValueType.lower(value) +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionUInt32: FfiConverterRustBuffer { + typealias SwiftType = UInt32? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterUInt32.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterUInt32.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionUInt64: FfiConverterRustBuffer { + typealias SwiftType = UInt64? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterUInt64.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterUInt64.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionBool: FfiConverterRustBuffer { + typealias SwiftType = Bool? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterBool.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterBool.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionString: FfiConverterRustBuffer { + typealias SwiftType = String? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterString.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterString.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeTransactionFilter: FfiConverterRustBuffer { + typealias SwiftType = TransactionFilter? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeTransactionFilter.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeTransactionFilter.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeFieldElement: FfiConverterRustBuffer { + typealias SwiftType = FieldElement? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeFieldElement.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeFieldElement.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeU256: FfiConverterRustBuffer { + typealias SwiftType = U256? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeU256.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeU256.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceUInt8: FfiConverterRustBuffer { + typealias SwiftType = [UInt8] + + public static func write(_ value: [UInt8], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterUInt8.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [UInt8] { + let len: Int32 = try readInt(&buf) + var seq = [UInt8]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterUInt8.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceString: FfiConverterRustBuffer { + typealias SwiftType = [String] + + public static func write(_ value: [String], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterString.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [String] { + let len: Int32 = try readInt(&buf) + var seq = [String]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterString.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeAchievementTask: FfiConverterRustBuffer { + typealias SwiftType = [AchievementTask] + + public static func write(_ value: [AchievementTask], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeAchievementTask.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [AchievementTask] { + let len: Int32 = try readInt(&buf) + var seq = [AchievementTask]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeAchievementTask.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeActionCount: FfiConverterRustBuffer { + typealias SwiftType = [ActionCount] + + public static func write(_ value: [ActionCount], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeActionCount.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [ActionCount] { + let len: Int32 = try readInt(&buf) + var seq = [ActionCount]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeActionCount.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeAttributeFilter: FfiConverterRustBuffer { + typealias SwiftType = [AttributeFilter] + + public static func write(_ value: [AttributeFilter], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeAttributeFilter.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [AttributeFilter] { + let len: Int32 = try readInt(&buf) + var seq = [AttributeFilter]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeAttributeFilter.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeEnumOption: FfiConverterRustBuffer { + typealias SwiftType = [EnumOption] + + public static func write(_ value: [EnumOption], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeEnumOption.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [EnumOption] { + let len: Int32 = try readInt(&buf) + var seq = [EnumOption]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeEnumOption.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeMember: FfiConverterRustBuffer { + typealias SwiftType = [Member] + + public static func write(_ value: [Member], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeMember.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Member] { + let len: Int32 = try readInt(&buf) + var seq = [Member]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeMember.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeOrderBy: FfiConverterRustBuffer { + typealias SwiftType = [OrderBy] + + public static func write(_ value: [OrderBy], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeOrderBy.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [OrderBy] { + let len: Int32 = try readInt(&buf) + var seq = [OrderBy]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeOrderBy.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypePlayerAchievementProgress: FfiConverterRustBuffer { + typealias SwiftType = [PlayerAchievementProgress] + + public static func write(_ value: [PlayerAchievementProgress], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypePlayerAchievementProgress.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [PlayerAchievementProgress] { + let len: Int32 = try readInt(&buf) + var seq = [PlayerAchievementProgress]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypePlayerAchievementProgress.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeTaskProgress: FfiConverterRustBuffer { + typealias SwiftType = [TaskProgress] + + public static func write(_ value: [TaskProgress], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeTaskProgress.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [TaskProgress] { + let len: Int32 = try readInt(&buf) + var seq = [TaskProgress]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeTaskProgress.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeTransactionCall: FfiConverterRustBuffer { + typealias SwiftType = [TransactionCall] + + public static func write(_ value: [TransactionCall], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeTransactionCall.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [TransactionCall] { + let len: Int32 = try readInt(&buf) + var seq = [TransactionCall]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeTransactionCall.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeClause: FfiConverterRustBuffer { + typealias SwiftType = [Clause] + + public static func write(_ value: [Clause], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeClause.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Clause] { + let len: Int32 = try readInt(&buf) + var seq = [Clause]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeClause.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeContractType: FfiConverterRustBuffer { + typealias SwiftType = [ContractType] + + public static func write(_ value: [ContractType], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeContractType.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [ContractType] { + let len: Int32 = try readInt(&buf) + var seq = [ContractType]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeContractType.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeMemberValue: FfiConverterRustBuffer { + typealias SwiftType = [MemberValue] + + public static func write(_ value: [MemberValue], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeMemberValue.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [MemberValue] { + let len: Int32 = try readInt(&buf) + var seq = [MemberValue]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeMemberValue.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeTy: FfiConverterRustBuffer { + typealias SwiftType = [Ty] + + public static func write(_ value: [Ty], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeTy.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Ty] { + let len: Int32 = try readInt(&buf) + var seq = [Ty]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeTy.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceOptionTypeFieldElement: FfiConverterRustBuffer { + typealias SwiftType = [FieldElement?] + + public static func write(_ value: [FieldElement?], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterOptionTypeFieldElement.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [FieldElement?] { + let len: Int32 = try readInt(&buf) + var seq = [FieldElement?]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterOptionTypeFieldElement.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeFieldElement: FfiConverterRustBuffer { + typealias SwiftType = [FieldElement] + + public static func write(_ value: [FieldElement], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeFieldElement.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [FieldElement] { + let len: Int32 = try readInt(&buf) + var seq = [FieldElement]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeFieldElement.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeU256: FfiConverterRustBuffer { + typealias SwiftType = [U256] + + public static func write(_ value: [U256], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeU256.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [U256] { + let len: Int32 = try readInt(&buf) + var seq = [U256]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeU256.read(from: &buf)) + } + return seq + } +} + + +/** + * Typealias from the type name used in the UDL file to the builtin type. This + * is needed because the UDL type name is used in function/method signatures. + */ +public typealias FieldElement = String + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeFieldElement: FfiConverter { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> FieldElement { + return try FfiConverterString.read(from: &buf) + } + + public static func write(_ value: FieldElement, into buf: inout [UInt8]) { + return FfiConverterString.write(value, into: &buf) + } + + public static func lift(_ value: RustBuffer) throws -> FieldElement { + return try FfiConverterString.lift(value) + } + + public static func lower(_ value: FieldElement) -> RustBuffer { + return FfiConverterString.lower(value) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeFieldElement_lift(_ value: RustBuffer) throws -> FieldElement { + return try FfiConverterTypeFieldElement.lift(value) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeFieldElement_lower(_ value: FieldElement) -> RustBuffer { + return FfiConverterTypeFieldElement.lower(value) +} + + + +/** + * Typealias from the type name used in the UDL file to the builtin type. This + * is needed because the UDL type name is used in function/method signatures. + */ +public typealias U256 = String + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeU256: FfiConverter { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> U256 { + return try FfiConverterString.read(from: &buf) + } + + public static func write(_ value: U256, into buf: inout [UInt8]) { + return FfiConverterString.write(value, into: &buf) + } + + public static func lift(_ value: RustBuffer) throws -> U256 { + return try FfiConverterString.lift(value) + } + + public static func lower(_ value: U256) -> RustBuffer { + return FfiConverterString.lower(value) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeU256_lift(_ value: RustBuffer) throws -> U256 { + return try FfiConverterTypeU256.lift(value) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeU256_lower(_ value: U256) -> RustBuffer { + return FfiConverterTypeU256.lower(value) +} + + +private enum InitializationResult { + case ok + case contractVersionMismatch + case apiChecksumMismatch +} +// Use a global variable to perform the versioning checks. Swift ensures that +// the code inside is only computed once. +private let initializationResult: InitializationResult = { + // Get the bindings contract version from our ComponentInterface + let bindings_contract_version = 30 + // Get the scaffolding contract version by calling the into the dylib + let scaffolding_contract_version = ffi_dojo_c_uniffi_contract_version() + if bindings_contract_version != scaffolding_contract_version { + return InitializationResult.contractVersionMismatch + } + + return InitializationResult.ok +}() + +// Make the ensure init function public so that other modules which have external type references to +// our types can call it. +public func uniffiEnsureDojoCInitialized() { + switch initializationResult { + case .ok: + break + case .contractVersionMismatch: + fatalError("UniFFI contract version mismatch: try cleaning and rebuilding your project") + case .apiChecksumMismatch: + fatalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } +} + +// swiftlint:enable all \ No newline at end of file diff --git a/src/bin/uniffi-bindgen-kotlin.rs b/src/bin/uniffi-bindgen-kotlin.rs new file mode 100644 index 0000000..f9a2f4d --- /dev/null +++ b/src/bin/uniffi-bindgen-kotlin.rs @@ -0,0 +1,55 @@ +use std::env; +use std::process; +use uniffi_bindgen::bindings::KotlinBindingGenerator; +use uniffi_bindgen::library_mode::generate_bindings; +use camino::Utf8PathBuf; + +fn main() { + let args: Vec = env::args().collect(); + + if args.len() < 3 { + eprintln!("UniFFI Kotlin Binding Generator"); + eprintln!(); + eprintln!("Usage: {} ", args[0]); + eprintln!(); + eprintln!("Example:"); + eprintln!(" {} target/release/libdojo_c.dylib bindings/kotlin", args[0]); + eprintln!(); + process::exit(1); + } + + let library_path = Utf8PathBuf::from(&args[1]); + let out_dir = Utf8PathBuf::from(&args[2]); + + if !library_path.exists() { + eprintln!("Error: Library file not found: {}", library_path); + eprintln!("Build the library first with: cargo build --release"); + process::exit(1); + } + + println!("Generating Kotlin bindings..."); + println!("Library: {}", library_path); + println!("Output: {}", out_dir); + + // Use library mode with Kotlin binding generator + let config_supplier = uniffi_bindgen::EmptyCrateConfigSupplier; + + match generate_bindings( + &library_path, + None, // crate_name (auto-detect) + &KotlinBindingGenerator, + &config_supplier, + None, // config_file_override + &out_dir, + false, // try_format_code + ) { + Ok(_) => { + println!("✓ Kotlin bindings generated successfully in {}", out_dir); + } + Err(e) => { + eprintln!("Error generating bindings: {}", e); + process::exit(1); + } + } +} + diff --git a/src/bin/uniffi-bindgen-python.rs b/src/bin/uniffi-bindgen-python.rs new file mode 100644 index 0000000..e4f37bb --- /dev/null +++ b/src/bin/uniffi-bindgen-python.rs @@ -0,0 +1,65 @@ +use std::env; +use std::process; +use uniffi_bindgen::bindings::python::run_pipeline; +use uniffi_bindgen::cargo_metadata::CrateConfigSupplier; +use uniffi_bindgen::pipeline::initial::Root; +use camino::Utf8PathBuf; + +fn main() { + let args: Vec = env::args().collect(); + + if args.len() < 3 { + eprintln!("UniFFI Python Binding Generator"); + eprintln!(); + eprintln!("Usage: {} ", args[0]); + eprintln!(); + eprintln!("Example:"); + eprintln!(" {} target/release/libdojo_c.dylib bindings/python", args[0]); + eprintln!(); + process::exit(1); + } + + let library_path = Utf8PathBuf::from(&args[1]); + let out_dir = Utf8PathBuf::from(&args[2]); + + if !library_path.exists() { + eprintln!("Error: Library file not found: {}", library_path); + eprintln!("Build the library first with: cargo build --release"); + process::exit(1); + } + + println!("Generating Python bindings..."); + println!("Library: {}", library_path); + println!("Output: {}", out_dir); + + // Use cargo metadata to get crate configuration + let metadata = match cargo_metadata::MetadataCommand::new().exec() { + Ok(m) => m, + Err(e) => { + eprintln!("Error getting cargo metadata: {}", e); + eprintln!("Make sure you're running this from a cargo project directory"); + process::exit(1); + } + }; + + let config_supplier = CrateConfigSupplier::from(metadata); + + match Root::from_library(config_supplier, &library_path, None) { + Ok(root) => { + match run_pipeline(root, &out_dir) { + Ok(_) => { + println!("✓ Python bindings generated successfully in {}", out_dir); + } + Err(e) => { + eprintln!("Error generating Python bindings: {}", e); + process::exit(1); + } + } + } + Err(e) => { + eprintln!("Error loading library metadata: {}", e); + process::exit(1); + } + } +} + diff --git a/src/bin/uniffi-bindgen-swift.rs b/src/bin/uniffi-bindgen-swift.rs new file mode 100644 index 0000000..5396425 --- /dev/null +++ b/src/bin/uniffi-bindgen-swift.rs @@ -0,0 +1,71 @@ +use std::env; +use std::process; +use uniffi_bindgen::bindings::{generate_swift_bindings, SwiftBindingsOptions}; +use camino::Utf8PathBuf; + +fn main() { + let args: Vec = env::args().collect(); + + if args.len() < 3 { + eprintln!("UniFFI Swift Binding Generator"); + eprintln!(); + eprintln!("Usage: {} [--swift-sources] [--headers] [--modulemap]", args[0]); + eprintln!(); + eprintln!("Options:"); + eprintln!(" --swift-sources Generate .swift source files (default)"); + eprintln!(" --headers Generate .h header files"); + eprintln!(" --modulemap Generate modulemap"); + eprintln!(" --xcframework Generate XCFramework-compatible modulemap"); + eprintln!(); + eprintln!("Examples:"); + eprintln!(" {} target/release/libdojo_c.dylib bindings/swift --swift-sources", args[0]); + eprintln!(" {} target/release/libdojo_c.dylib bindings/swift --headers --modulemap", args[0]); + eprintln!(); + process::exit(1); + } + + let library_path = Utf8PathBuf::from(&args[1]); + let out_dir = Utf8PathBuf::from(&args[2]); + + if !library_path.exists() { + eprintln!("Error: Library file not found: {}", library_path); + eprintln!("Build the library first with: cargo build --release"); + process::exit(1); + } + + // Parse options + let has_swift_sources = args.contains(&"--swift-sources".to_string()); + let has_headers = args.contains(&"--headers".to_string()); + let has_modulemap = args.contains(&"--modulemap".to_string()); + let has_xcframework = args.contains(&"--xcframework".to_string()); + + // Default to generating Swift sources if no specific flags are provided + let generate_swift_sources = has_swift_sources || (!has_headers && !has_modulemap); + + println!("Generating Swift bindings..."); + println!("Library: {}", library_path); + println!("Output: {}", out_dir); + + let options = SwiftBindingsOptions { + generate_swift_sources, + generate_headers: has_headers, + generate_modulemap: has_modulemap, + source: library_path, + out_dir, + xcframework: has_xcframework, + module_name: Some("DojoEngine".to_string()), + modulemap_filename: None, + metadata_no_deps: false, + link_frameworks: vec![], + }; + + match generate_swift_bindings(options) { + Ok(_) => { + println!("✓ Swift bindings generated successfully!"); + } + Err(e) => { + eprintln!("Error generating bindings: {}", e); + process::exit(1); + } + } +} diff --git a/src/bin/uniffi-bindgen.rs b/src/bin/uniffi-bindgen.rs deleted file mode 100644 index a5b7643..0000000 --- a/src/bin/uniffi-bindgen.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - uniffi_bindgen::main() -} - diff --git a/src/dojo_full.udl.bak b/src/dojo_full.udl.bak deleted file mode 100644 index 10d7a3f..0000000 --- a/src/dojo_full.udl.bak +++ /dev/null @@ -1,335 +0,0 @@ -namespace dojo { -}; - -// Core types -[Custom] -typedef string FieldElement; - -[Custom] -typedef string U256; - -// Simple Enums (no associated data) -enum PaginationDirection { - "Forward", - "Backward", -}; - -enum OrderDirection { - "Asc", - "Desc", -}; - -enum ContractType { - "WORLD", - "ERC20", - "ERC721", - "ERC1155", - "UDC", - "OTHER", -}; - -enum CallType { - "Execute", - "ExecuteFromOutside", -}; - -// Basic structures -dictionary Signature { - FieldElement r; - FieldElement s; -}; - -dictionary OrderBy { - string field; - OrderDirection direction; -}; - -dictionary Pagination { - string? cursor; - u32? limit; - PaginationDirection direction; - sequence order_by; -}; - -// Controller -dictionary Controller { - FieldElement address; - string username; - u64 deployed_at_timestamp; -}; - -dictionary ControllerQuery { - Pagination pagination; - sequence contract_addresses; - sequence usernames; -}; - -// Token types -dictionary Token { - FieldElement contract_address; - U256? token_id; - string name; - string symbol; - u8 decimals; - string metadata; - U256? total_supply; -}; - -dictionary TokenBalance { - U256 balance; - FieldElement account_address; - FieldElement contract_address; - U256? token_id; -}; - -dictionary TokenContract { - FieldElement contract_address; - string name; - string symbol; - u8 decimals; - string metadata; - string token_metadata; - U256? total_supply; -}; - -dictionary AttributeFilter { - string trait_name; - string trait_value; -}; - -dictionary TokenQuery { - sequence contract_addresses; - sequence token_ids; - sequence attribute_filters; - Pagination pagination; -}; - -dictionary TokenBalanceQuery { - sequence contract_addresses; - sequence account_addresses; - sequence token_ids; - Pagination pagination; -}; - -dictionary TokenContractQuery { - sequence contract_addresses; - sequence contract_types; - Pagination pagination; -}; - -dictionary TokenTransfer { - string id; - FieldElement contract_address; - FieldElement from_address; - FieldElement to_address; - U256 amount; - U256? token_id; - u64 executed_at; - string? event_id; -}; - -dictionary TokenTransferQuery { - sequence contract_addresses; - sequence account_addresses; - sequence token_ids; - Pagination pagination; -}; - -// Contract -dictionary Contract { - FieldElement contract_address; - ContractType contract_type; - u64? head; - u64? tps; - u64? last_block_timestamp; - FieldElement? last_pending_block_tx; - u64 updated_at; - u64 created_at; -}; - -dictionary ContractQuery { - sequence contract_addresses; - sequence contract_types; -}; - -// Transaction types (simplified - no complex Call type) -dictionary TransactionCall { - FieldElement contract_address; - string entrypoint; - sequence calldata; - CallType call_type; - FieldElement caller_address; -}; - -dictionary Transaction { - FieldElement transaction_hash; - FieldElement sender_address; - sequence calldata; - FieldElement max_fee; - sequence signature; - FieldElement nonce; - u64 block_number; - string transaction_type; - u64 block_timestamp; - sequence calls; - sequence unique_models; -}; - -dictionary TransactionFilter { - sequence transaction_hashes; - sequence caller_addresses; - sequence contract_addresses; - sequence entrypoints; - sequence model_selectors; - u64? from_block; - u64? to_block; -}; - -dictionary TransactionQuery { - TransactionFilter? filter; - Pagination pagination; -}; - -// Aggregation -dictionary AggregationQuery { - sequence aggregator_ids; - sequence entity_ids; - Pagination pagination; -}; - -dictionary AggregationEntry { - string id; - string aggregator_id; - string entity_id; - U256 value; - string display_value; - u64 position; - string model_id; - u64 created_at; - u64 updated_at; -}; - -// Activity -dictionary ActionCount { - string action_name; - u32 count; -}; - -dictionary Activity { - string id; - FieldElement world_address; - string namespace; - FieldElement caller_address; - u64 session_start; - u64 session_end; - u32 action_count; - sequence actions; - u64 updated_at; -}; - -dictionary ActivityQuery { - sequence world_addresses; - sequence namespaces; - sequence caller_addresses; - u64? from_time; - u64? to_time; - Pagination pagination; -}; - -// Achievement -dictionary AchievementTask { - string task_id; - string description; - u32 total; - u32 total_completions; - f64 completion_rate; - u64 created_at; -}; - -dictionary Achievement { - string id; - FieldElement world_address; - string namespace; - string entity_id; - boolean hidden; - u32 index; - u32 points; - string start; - string end; - string group; - string icon; - string title; - string description; - sequence tasks; - string? data; - u32 total_completions; - f64 completion_rate; - u64 created_at; - u64 updated_at; -}; - -dictionary AchievementQuery { - sequence world_addresses; - sequence namespaces; - boolean? hidden; - Pagination pagination; -}; - -dictionary TaskProgress { - string task_id; - u32 count; - boolean completed; -}; - -dictionary PlayerAchievementProgress { - Achievement achievement; - sequence task_progress; - boolean completed; - f64 progress_percentage; -}; - -dictionary PlayerAchievementStats { - u32 total_points; - u32 completed_achievements; - u32 total_achievements; - f64 completion_percentage; - u64? last_achievement_at; - u64 created_at; - u64 updated_at; -}; - -dictionary PlayerAchievementEntry { - FieldElement player_address; - PlayerAchievementStats stats; - sequence achievements; -}; - -dictionary PlayerAchievementQuery { - sequence world_addresses; - sequence namespaces; - sequence player_addresses; - Pagination pagination; -}; - -dictionary AchievementProgression { - string id; - string achievement_id; - string task_id; - FieldElement world_address; - string namespace; - FieldElement player_id; - u32 count; - boolean completed; - u64? completed_at; - u64 created_at; - u64 updated_at; -}; - -// Error type -[Error] -enum DojoError { - "ClientError", - "SerializationError", - "NetworkError", - "InvalidInput", -}; diff --git a/src/uniffi/core.rs b/src/uniffi/core.rs index 0af019e..f2ca4a8 100644 --- a/src/uniffi/core.rs +++ b/src/uniffi/core.rs @@ -9,32 +9,10 @@ pub struct FieldElement(pub String); #[derive(Debug, Clone, PartialEq, Eq)] pub struct U256(pub String); -// Custom type converter implementations for UniFFI -// Note: uniffi::custom_type! is called by the generated scaffolding from the UDL -// The UniffiCustomTypeConverter trait is defined in the generated scaffolding -impl crate::UniffiCustomTypeConverter for FieldElement { - type Builtin = String; - - fn into_custom(val: Self::Builtin) -> uniffi::Result { - Ok(FieldElement(val)) - } - - fn from_custom(obj: Self) -> Self::Builtin { - obj.0 - } -} - -impl crate::UniffiCustomTypeConverter for U256 { - type Builtin = String; - - fn into_custom(val: Self::Builtin) -> uniffi::Result { - Ok(U256(val)) - } - - fn from_custom(obj: Self) -> Self::Builtin { - obj.0 - } -} +// Custom type implementations for UniFFI +// These newtype wrappers will be represented as their inner type (String) in foreign languages +uniffi::custom_newtype!(FieldElement, String); +uniffi::custom_newtype!(U256, String); // Helper functions to convert between internal types and UniFFI types pub fn felt_to_field_element(felt: starknet::core::types::Felt) -> FieldElement { diff --git a/uniffi.toml b/uniffi.toml new file mode 100644 index 0000000..e5b4645 --- /dev/null +++ b/uniffi.toml @@ -0,0 +1,22 @@ +# UniFFI Configuration for Dojo +# This file configures language-specific bindings generation + +[bindings.kotlin] +package_name = "com.dojoengine.dojo" +cdylib_name = "dojo_c" +generate_immutable_records = true + +[bindings.swift] +module_name = "DojoEngine" +cdylib_name = "dojo_c" +generate_immutable_records = true +# Swift-specific naming conventions +omit_argument_labels = false + +[bindings.python] +module_name = "dojo" +cdylib_name = "dojo_c" + +[bindings.ruby] +module_name = "Dojo" +cdylib_name = "dojo_c" From 09c7b811d8f563c4e4d19d7182192fa888c84d64 Mon Sep 17 00:00:00 2001 From: Nasr Date: Wed, 15 Oct 2025 13:27:36 -0500 Subject: [PATCH 03/16] implementations of tori iclient --- Cargo.lock | 1 + Cargo.toml | 1 + bindings/python/dojo.py | 3688 +++++++++++++++---- bindings/swift/DojoEngine.swift | 5861 ++++++++++++++++++++++--------- src/dojo.udl | 276 ++ src/uniffi/README.md | 307 -- src/uniffi/client.rs | 544 +++ src/uniffi/core.rs | 91 + src/uniffi/event.rs | 18 + src/uniffi/mod.rs | 2 + src/uniffi/query.rs | 39 + 11 files changed, 8100 insertions(+), 2728 deletions(-) delete mode 100644 src/uniffi/README.md create mode 100644 src/uniffi/client.rs diff --git a/Cargo.lock b/Cargo.lock index 6b836cf..6338837 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1055,6 +1055,7 @@ dependencies = [ ======= "futures", "futures-channel", + "futures-util", "gloo-timers", "gloo-utils", "hex", diff --git a/Cargo.toml b/Cargo.toml index 981536d..12008a4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,6 +34,7 @@ serde_json = "1.0.115" tokio-stream = "0.1.14" futures = "0.3.30" futures-channel = "0.3.30" +futures-util = "0.3" stream-cancel = "0.8.2" cainome = "0.10.1" lazy_static = "1.5.0" diff --git a/bindings/python/dojo.py b/bindings/python/dojo.py index beaf4a6..085b1b8 100644 --- a/bindings/python/dojo.py +++ b/bindings/python/dojo.py @@ -26,6 +26,7 @@ import itertools import traceback import typing +import asyncio import platform @@ -478,7 +479,46 @@ def _uniffi_check_contract_api_version(lib): raise InternalError("UniFFI contract version mismatch: try cleaning and rebuilding your project") def _uniffi_check_api_checksums(lib): - pass + if lib.uniffi_dojo_c_checksum_constructor_toriiclient_new() != 9333: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_constructor_toriiclient_new_with_config() != 41101: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_achievements() != 25483: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_activities() != 47526: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_aggregations() != 2286: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_contracts() != 19355: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_controllers() != 57439: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_entities() != 58651: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_event_messages() != 13178: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_player_achievements() != 23418: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_publish_message() != 30337: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_publish_message_batch() != 62654: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_sql() != 51092: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_starknet_events() != 47081: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_token_balances() != 31624: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_token_contracts() != 34016: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_token_transfers() != 64003: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_tokens() != 8250: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_transactions() != 39655: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_worlds() != 61633: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") # A ctypes library to expose the extern-C FFI definitions. # This is an implementation detail which will be called internally by the public API. @@ -742,14 +782,245 @@ class _UniffiForeignFutureDroppedCallbackStruct(ctypes.Structure): ctypes.c_uint64, ) _UniffiLib.ffi_dojo_c_rust_future_free_void.restype = None +_UniffiLib.uniffi_dojo_c_fn_clone_toriiclient.argtypes = ( + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_dojo_c_fn_clone_toriiclient.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_free_toriiclient.argtypes = ( + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_dojo_c_fn_free_toriiclient.restype = None +_UniffiLib.uniffi_dojo_c_fn_constructor_toriiclient_new.argtypes = ( + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_constructor_toriiclient_new.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_constructor_toriiclient_new_with_config.argtypes = ( + _UniffiRustBuffer, + ctypes.c_uint64, +) +_UniffiLib.uniffi_dojo_c_fn_constructor_toriiclient_new_with_config.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_achievements.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_achievements.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_activities.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_activities.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_aggregations.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_aggregations.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_contracts.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_contracts.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_controllers.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_controllers.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_entities.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_entities.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_event_messages.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_event_messages.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_player_achievements.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_player_achievements.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_publish_message.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_publish_message.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_publish_message_batch.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_publish_message_batch.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_sql.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_sql.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_starknet_events.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_starknet_events.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_token_balances.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_token_balances.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_token_contracts.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_token_contracts.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_token_transfers.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_token_transfers.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_tokens.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_tokens.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_transactions.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_transactions.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_worlds.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_worlds.restype = ctypes.c_uint64 _UniffiLib.ffi_dojo_c_uniffi_contract_version.argtypes = ( ) _UniffiLib.ffi_dojo_c_uniffi_contract_version.restype = ctypes.c_uint32 +_UniffiLib.uniffi_dojo_c_checksum_constructor_toriiclient_new.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_constructor_toriiclient_new.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_constructor_toriiclient_new_with_config.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_constructor_toriiclient_new_with_config.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_achievements.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_achievements.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_activities.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_activities.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_aggregations.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_aggregations.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_contracts.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_contracts.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_controllers.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_controllers.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_entities.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_entities.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_event_messages.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_event_messages.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_player_achievements.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_player_achievements.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_publish_message.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_publish_message.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_publish_message_batch.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_publish_message_batch.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_sql.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_sql.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_starknet_events.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_starknet_events.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_token_balances.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_token_balances.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_token_contracts.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_token_contracts.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_token_transfers.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_token_transfers.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_tokens.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_tokens.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_transactions.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_transactions.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_worlds.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_worlds.restype = ctypes.c_uint16 _uniffi_check_contract_api_version(_UniffiLib) # _uniffi_check_api_checksums(_UniffiLib) +# RustFuturePoll values +_UNIFFI_RUST_FUTURE_POLL_READY = 0 +_UNIFFI_RUST_FUTURE_POLL_WAKE = 1 + +# Stores futures for _uniffi_continuation_callback +_UniffiContinuationHandleMap = _UniffiHandleMap() + +_UNIFFI_GLOBAL_EVENT_LOOP = None + +""" +Set the event loop to use for async functions + +This is needed if some async functions run outside of the eventloop, for example: + - A non-eventloop thread is spawned, maybe from `EventLoop.run_in_executor` or maybe from the + Rust code spawning its own thread. + - The Rust code calls an async callback method from a sync callback function, using something + like `pollster` to block on the async call. + +In this case, we need an event loop to run the Python async function, but there's no eventloop set +for the thread. Use `uniffi_set_event_loop` to force an eventloop to be used in this case. +""" +def uniffi_set_event_loop(eventloop: asyncio.BaseEventLoop): + global _UNIFFI_GLOBAL_EVENT_LOOP + _UNIFFI_GLOBAL_EVENT_LOOP = eventloop + +def _uniffi_get_event_loop(): + if _UNIFFI_GLOBAL_EVENT_LOOP is not None: + return _UNIFFI_GLOBAL_EVENT_LOOP + else: + return asyncio.get_running_loop() + +# Continuation callback for async functions +# lift the return value or error and resolve the future, causing the async function to resume. +@_UNIFFI_RUST_FUTURE_CONTINUATION_CALLBACK +def _uniffi_continuation_callback(future_ptr, poll_code): + (eventloop, future) = _UniffiContinuationHandleMap.remove(future_ptr) + eventloop.call_soon_threadsafe(_uniffi_set_future_result, future, poll_code) +def _uniffi_set_future_result(future, poll_code): + if not future.cancelled(): + future.set_result(poll_code) + +async def _uniffi_rust_call_async(rust_future, ffi_poll, ffi_complete, ffi_free, lift_func, error_ffi_converter): + try: + eventloop = _uniffi_get_event_loop() + + # Loop and poll until we see a _UNIFFI_RUST_FUTURE_POLL_READY value + while True: + future = eventloop.create_future() + ffi_poll( + rust_future, + _uniffi_continuation_callback, + _UniffiContinuationHandleMap.insert((eventloop, future)), + ) + poll_code = await future + if poll_code == _UNIFFI_RUST_FUTURE_POLL_READY: + break + + return lift_func( + _uniffi_rust_call_with_error(error_ffi_converter, ffi_complete, rust_future) + ) + finally: + ffi_free(rust_future) # Public interface members begin here. @@ -3727,105 +3998,40 @@ def write(value, buf): _UniffiFfiConverterSequenceString.write(value.usernames, buf) @dataclass -class Member: - def __init__(self, *, name:str, ty:Ty, key:bool): +class EnumOption: + def __init__(self, *, name:str, ty:Ty): self.name = name self.ty = ty - self.key = key def __str__(self): - return "Member(name={}, ty={}, key={})".format(self.name, self.ty, self.key) + return "EnumOption(name={}, ty={})".format(self.name, self.ty) def __eq__(self, other): if self.name != other.name: return False if self.ty != other.ty: return False - if self.key != other.key: - return False return True -class _UniffiFfiConverterTypeMember(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypeEnumOption(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return Member( + return EnumOption( name=_UniffiFfiConverterString.read(buf), ty=_UniffiFfiConverterTypeTy.read(buf), - key=_UniffiFfiConverterBoolean.read(buf), ) @staticmethod def check_lower(value): _UniffiFfiConverterString.check_lower(value.name) _UniffiFfiConverterTypeTy.check_lower(value.ty) - _UniffiFfiConverterBoolean.check_lower(value.key) @staticmethod def write(value, buf): _UniffiFfiConverterString.write(value.name, buf) _UniffiFfiConverterTypeTy.write(value.ty, buf) - _UniffiFfiConverterBoolean.write(value.key, buf) - -class _UniffiFfiConverterSequenceTypeMember(_UniffiConverterRustBuffer): - @classmethod - def check_lower(cls, value): - for item in value: - _UniffiFfiConverterTypeMember.check_lower(item) - - @classmethod - def write(cls, value, buf): - items = len(value) - buf.write_i32(items) - for item in value: - _UniffiFfiConverterTypeMember.write(item, buf) - - @classmethod - def read(cls, buf): - count = buf.read_i32() - if count < 0: - raise InternalError("Unexpected negative sequence length") - - return [ - _UniffiFfiConverterTypeMember.read(buf) for i in range(count) - ] - -@dataclass -class Struct: - def __init__(self, *, name:str, children:typing.List[Member]): - self.name = name - self.children = children - - - - - def __str__(self): - return "Struct(name={}, children={})".format(self.name, self.children) - def __eq__(self, other): - if self.name != other.name: - return False - if self.children != other.children: - return False - return True - -class _UniffiFfiConverterTypeStruct(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - return Struct( - name=_UniffiFfiConverterString.read(buf), - children=_UniffiFfiConverterSequenceTypeMember.read(buf), - ) - - @staticmethod - def check_lower(value): - _UniffiFfiConverterString.check_lower(value.name) - _UniffiFfiConverterSequenceTypeMember.check_lower(value.children) - - @staticmethod - def write(value, buf): - _UniffiFfiConverterString.write(value.name, buf) - _UniffiFfiConverterSequenceTypeMember.write(value.children, buf) class _UniffiFfiConverterSequenceTypeEnumOption(_UniffiConverterRustBuffer): @classmethod @@ -4249,161 +4455,118 @@ def write(value, buf): @dataclass -class EnumOption: - def __init__(self, *, name:str, ty:Ty): +class Member: + def __init__(self, *, name:str, ty:Ty, key:bool): self.name = name self.ty = ty + self.key = key def __str__(self): - return "EnumOption(name={}, ty={})".format(self.name, self.ty) + return "Member(name={}, ty={}, key={})".format(self.name, self.ty, self.key) def __eq__(self, other): if self.name != other.name: return False if self.ty != other.ty: return False + if self.key != other.key: + return False return True -class _UniffiFfiConverterTypeEnumOption(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypeMember(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return EnumOption( + return Member( name=_UniffiFfiConverterString.read(buf), ty=_UniffiFfiConverterTypeTy.read(buf), + key=_UniffiFfiConverterBoolean.read(buf), ) @staticmethod def check_lower(value): _UniffiFfiConverterString.check_lower(value.name) _UniffiFfiConverterTypeTy.check_lower(value.ty) + _UniffiFfiConverterBoolean.check_lower(value.key) @staticmethod def write(value, buf): _UniffiFfiConverterString.write(value.name, buf) _UniffiFfiConverterTypeTy.write(value.ty, buf) + _UniffiFfiConverterBoolean.write(value.key, buf) + +class _UniffiFfiConverterSequenceTypeMember(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeMember.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeMember.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeMember.read(buf) for i in range(count) + ] @dataclass -class PlayerAchievementStats: - def __init__(self, *, total_points:int, completed_achievements:int, total_achievements:int, completion_percentage:float, last_achievement_at:typing.Optional[int], created_at:int, updated_at:int): - self.total_points = total_points - self.completed_achievements = completed_achievements - self.total_achievements = total_achievements - self.completion_percentage = completion_percentage - self.last_achievement_at = last_achievement_at - self.created_at = created_at - self.updated_at = updated_at +class Struct: + def __init__(self, *, name:str, children:typing.List[Member]): + self.name = name + self.children = children def __str__(self): - return "PlayerAchievementStats(total_points={}, completed_achievements={}, total_achievements={}, completion_percentage={}, last_achievement_at={}, created_at={}, updated_at={})".format(self.total_points, self.completed_achievements, self.total_achievements, self.completion_percentage, self.last_achievement_at, self.created_at, self.updated_at) + return "Struct(name={}, children={})".format(self.name, self.children) def __eq__(self, other): - if self.total_points != other.total_points: - return False - if self.completed_achievements != other.completed_achievements: - return False - if self.total_achievements != other.total_achievements: - return False - if self.completion_percentage != other.completion_percentage: - return False - if self.last_achievement_at != other.last_achievement_at: - return False - if self.created_at != other.created_at: + if self.name != other.name: return False - if self.updated_at != other.updated_at: + if self.children != other.children: return False return True -class _UniffiFfiConverterTypePlayerAchievementStats(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypeStruct(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return PlayerAchievementStats( - total_points=_UniffiFfiConverterUInt32.read(buf), - completed_achievements=_UniffiFfiConverterUInt32.read(buf), - total_achievements=_UniffiFfiConverterUInt32.read(buf), - completion_percentage=_UniffiFfiConverterFloat64.read(buf), - last_achievement_at=_UniffiFfiConverterOptionalUInt64.read(buf), - created_at=_UniffiFfiConverterUInt64.read(buf), - updated_at=_UniffiFfiConverterUInt64.read(buf), - ) - - @staticmethod - def check_lower(value): - _UniffiFfiConverterUInt32.check_lower(value.total_points) - _UniffiFfiConverterUInt32.check_lower(value.completed_achievements) - _UniffiFfiConverterUInt32.check_lower(value.total_achievements) - _UniffiFfiConverterFloat64.check_lower(value.completion_percentage) - _UniffiFfiConverterOptionalUInt64.check_lower(value.last_achievement_at) - _UniffiFfiConverterUInt64.check_lower(value.created_at) - _UniffiFfiConverterUInt64.check_lower(value.updated_at) - - @staticmethod - def write(value, buf): - _UniffiFfiConverterUInt32.write(value.total_points, buf) - _UniffiFfiConverterUInt32.write(value.completed_achievements, buf) - _UniffiFfiConverterUInt32.write(value.total_achievements, buf) - _UniffiFfiConverterFloat64.write(value.completion_percentage, buf) - _UniffiFfiConverterOptionalUInt64.write(value.last_achievement_at, buf) - _UniffiFfiConverterUInt64.write(value.created_at, buf) - _UniffiFfiConverterUInt64.write(value.updated_at, buf) - -@dataclass -class TaskProgress: - def __init__(self, *, task_id:str, count:int, completed:bool): - self.task_id = task_id - self.count = count - self.completed = completed - - - - - def __str__(self): - return "TaskProgress(task_id={}, count={}, completed={})".format(self.task_id, self.count, self.completed) - def __eq__(self, other): - if self.task_id != other.task_id: - return False - if self.count != other.count: - return False - if self.completed != other.completed: - return False - return True - -class _UniffiFfiConverterTypeTaskProgress(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - return TaskProgress( - task_id=_UniffiFfiConverterString.read(buf), - count=_UniffiFfiConverterUInt32.read(buf), - completed=_UniffiFfiConverterBoolean.read(buf), + return Struct( + name=_UniffiFfiConverterString.read(buf), + children=_UniffiFfiConverterSequenceTypeMember.read(buf), ) @staticmethod def check_lower(value): - _UniffiFfiConverterString.check_lower(value.task_id) - _UniffiFfiConverterUInt32.check_lower(value.count) - _UniffiFfiConverterBoolean.check_lower(value.completed) + _UniffiFfiConverterString.check_lower(value.name) + _UniffiFfiConverterSequenceTypeMember.check_lower(value.children) @staticmethod def write(value, buf): - _UniffiFfiConverterString.write(value.task_id, buf) - _UniffiFfiConverterUInt32.write(value.count, buf) - _UniffiFfiConverterBoolean.write(value.completed, buf) + _UniffiFfiConverterString.write(value.name, buf) + _UniffiFfiConverterSequenceTypeMember.write(value.children, buf) -class _UniffiFfiConverterSequenceTypeTaskProgress(_UniffiConverterRustBuffer): +class _UniffiFfiConverterSequenceTypeStruct(_UniffiConverterRustBuffer): @classmethod def check_lower(cls, value): for item in value: - _UniffiFfiConverterTypeTaskProgress.check_lower(item) + _UniffiFfiConverterTypeStruct.check_lower(item) @classmethod def write(cls, value, buf): items = len(value) buf.write_i32(items) for item in value: - _UniffiFfiConverterTypeTaskProgress.write(item, buf) + _UniffiFfiConverterTypeStruct.write(item, buf) @classmethod def read(cls, buf): @@ -4412,357 +4575,375 @@ def read(cls, buf): raise InternalError("Unexpected negative sequence length") return [ - _UniffiFfiConverterTypeTaskProgress.read(buf) for i in range(count) + _UniffiFfiConverterTypeStruct.read(buf) for i in range(count) ] @dataclass -class PlayerAchievementProgress: - def __init__(self, *, achievement:Achievement, task_progress:typing.List[TaskProgress], completed:bool, progress_percentage:float): - self.achievement = achievement - self.task_progress = task_progress - self.completed = completed - self.progress_percentage = progress_percentage +class Entity: + def __init__(self, *, world_address:FieldElement, hashed_keys:FieldElement, models:typing.List[Struct], created_at:int, updated_at:int, executed_at:int): + self.world_address = world_address + self.hashed_keys = hashed_keys + self.models = models + self.created_at = created_at + self.updated_at = updated_at + self.executed_at = executed_at def __str__(self): - return "PlayerAchievementProgress(achievement={}, task_progress={}, completed={}, progress_percentage={})".format(self.achievement, self.task_progress, self.completed, self.progress_percentage) + return "Entity(world_address={}, hashed_keys={}, models={}, created_at={}, updated_at={}, executed_at={})".format(self.world_address, self.hashed_keys, self.models, self.created_at, self.updated_at, self.executed_at) def __eq__(self, other): - if self.achievement != other.achievement: + if self.world_address != other.world_address: return False - if self.task_progress != other.task_progress: + if self.hashed_keys != other.hashed_keys: return False - if self.completed != other.completed: + if self.models != other.models: return False - if self.progress_percentage != other.progress_percentage: + if self.created_at != other.created_at: + return False + if self.updated_at != other.updated_at: + return False + if self.executed_at != other.executed_at: return False return True -class _UniffiFfiConverterTypePlayerAchievementProgress(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypeEntity(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return PlayerAchievementProgress( - achievement=_UniffiFfiConverterTypeAchievement.read(buf), - task_progress=_UniffiFfiConverterSequenceTypeTaskProgress.read(buf), - completed=_UniffiFfiConverterBoolean.read(buf), - progress_percentage=_UniffiFfiConverterFloat64.read(buf), + return Entity( + world_address=_UniffiFfiConverterTypeFieldElement.read(buf), + hashed_keys=_UniffiFfiConverterTypeFieldElement.read(buf), + models=_UniffiFfiConverterSequenceTypeStruct.read(buf), + created_at=_UniffiFfiConverterUInt64.read(buf), + updated_at=_UniffiFfiConverterUInt64.read(buf), + executed_at=_UniffiFfiConverterUInt64.read(buf), ) @staticmethod def check_lower(value): - _UniffiFfiConverterTypeAchievement.check_lower(value.achievement) - _UniffiFfiConverterSequenceTypeTaskProgress.check_lower(value.task_progress) - _UniffiFfiConverterBoolean.check_lower(value.completed) - _UniffiFfiConverterFloat64.check_lower(value.progress_percentage) + _UniffiFfiConverterTypeFieldElement.check_lower(value.world_address) + _UniffiFfiConverterTypeFieldElement.check_lower(value.hashed_keys) + _UniffiFfiConverterSequenceTypeStruct.check_lower(value.models) + _UniffiFfiConverterUInt64.check_lower(value.created_at) + _UniffiFfiConverterUInt64.check_lower(value.updated_at) + _UniffiFfiConverterUInt64.check_lower(value.executed_at) @staticmethod def write(value, buf): - _UniffiFfiConverterTypeAchievement.write(value.achievement, buf) - _UniffiFfiConverterSequenceTypeTaskProgress.write(value.task_progress, buf) - _UniffiFfiConverterBoolean.write(value.completed, buf) - _UniffiFfiConverterFloat64.write(value.progress_percentage, buf) - -class _UniffiFfiConverterSequenceTypePlayerAchievementProgress(_UniffiConverterRustBuffer): - @classmethod - def check_lower(cls, value): - for item in value: - _UniffiFfiConverterTypePlayerAchievementProgress.check_lower(item) - - @classmethod - def write(cls, value, buf): - items = len(value) - buf.write_i32(items) - for item in value: - _UniffiFfiConverterTypePlayerAchievementProgress.write(item, buf) - - @classmethod - def read(cls, buf): - count = buf.read_i32() - if count < 0: - raise InternalError("Unexpected negative sequence length") - - return [ - _UniffiFfiConverterTypePlayerAchievementProgress.read(buf) for i in range(count) - ] + _UniffiFfiConverterTypeFieldElement.write(value.world_address, buf) + _UniffiFfiConverterTypeFieldElement.write(value.hashed_keys, buf) + _UniffiFfiConverterSequenceTypeStruct.write(value.models, buf) + _UniffiFfiConverterUInt64.write(value.created_at, buf) + _UniffiFfiConverterUInt64.write(value.updated_at, buf) + _UniffiFfiConverterUInt64.write(value.executed_at, buf) @dataclass -class PlayerAchievementEntry: - def __init__(self, *, player_address:FieldElement, stats:PlayerAchievementStats, achievements:typing.List[PlayerAchievementProgress]): - self.player_address = player_address - self.stats = stats - self.achievements = achievements +class Event: + def __init__(self, *, keys:typing.List[FieldElement], data:typing.List[FieldElement], transaction_hash:FieldElement): + self.keys = keys + self.data = data + self.transaction_hash = transaction_hash def __str__(self): - return "PlayerAchievementEntry(player_address={}, stats={}, achievements={})".format(self.player_address, self.stats, self.achievements) + return "Event(keys={}, data={}, transaction_hash={})".format(self.keys, self.data, self.transaction_hash) def __eq__(self, other): - if self.player_address != other.player_address: + if self.keys != other.keys: return False - if self.stats != other.stats: + if self.data != other.data: return False - if self.achievements != other.achievements: + if self.transaction_hash != other.transaction_hash: return False return True -class _UniffiFfiConverterTypePlayerAchievementEntry(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypeEvent(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return PlayerAchievementEntry( - player_address=_UniffiFfiConverterTypeFieldElement.read(buf), - stats=_UniffiFfiConverterTypePlayerAchievementStats.read(buf), - achievements=_UniffiFfiConverterSequenceTypePlayerAchievementProgress.read(buf), + return Event( + keys=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + data=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + transaction_hash=_UniffiFfiConverterTypeFieldElement.read(buf), ) @staticmethod def check_lower(value): - _UniffiFfiConverterTypeFieldElement.check_lower(value.player_address) - _UniffiFfiConverterTypePlayerAchievementStats.check_lower(value.stats) - _UniffiFfiConverterSequenceTypePlayerAchievementProgress.check_lower(value.achievements) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.keys) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.data) + _UniffiFfiConverterTypeFieldElement.check_lower(value.transaction_hash) @staticmethod def write(value, buf): - _UniffiFfiConverterTypeFieldElement.write(value.player_address, buf) - _UniffiFfiConverterTypePlayerAchievementStats.write(value.stats, buf) - _UniffiFfiConverterSequenceTypePlayerAchievementProgress.write(value.achievements, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.keys, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.data, buf) + _UniffiFfiConverterTypeFieldElement.write(value.transaction_hash, buf) + +class _UniffiFfiConverterOptionalTypeKeysClause(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiFfiConverterTypeKeysClause.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiFfiConverterTypeKeysClause.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiFfiConverterTypeKeysClause.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") @dataclass -class PlayerAchievementQuery: - def __init__(self, *, world_addresses:typing.List[FieldElement], namespaces:typing.List[str], player_addresses:typing.List[FieldElement], pagination:Pagination): - self.world_addresses = world_addresses - self.namespaces = namespaces - self.player_addresses = player_addresses +class EventQuery: + def __init__(self, *, keys:typing.Optional[KeysClause], pagination:Pagination): + self.keys = keys self.pagination = pagination def __str__(self): - return "PlayerAchievementQuery(world_addresses={}, namespaces={}, player_addresses={}, pagination={})".format(self.world_addresses, self.namespaces, self.player_addresses, self.pagination) + return "EventQuery(keys={}, pagination={})".format(self.keys, self.pagination) def __eq__(self, other): - if self.world_addresses != other.world_addresses: - return False - if self.namespaces != other.namespaces: - return False - if self.player_addresses != other.player_addresses: + if self.keys != other.keys: return False if self.pagination != other.pagination: return False return True -class _UniffiFfiConverterTypePlayerAchievementQuery(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypeEventQuery(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return PlayerAchievementQuery( - world_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), - namespaces=_UniffiFfiConverterSequenceString.read(buf), - player_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + return EventQuery( + keys=_UniffiFfiConverterOptionalTypeKeysClause.read(buf), pagination=_UniffiFfiConverterTypePagination.read(buf), ) @staticmethod def check_lower(value): - _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.world_addresses) - _UniffiFfiConverterSequenceString.check_lower(value.namespaces) - _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.player_addresses) + _UniffiFfiConverterOptionalTypeKeysClause.check_lower(value.keys) _UniffiFfiConverterTypePagination.check_lower(value.pagination) @staticmethod def write(value, buf): - _UniffiFfiConverterSequenceTypeFieldElement.write(value.world_addresses, buf) - _UniffiFfiConverterSequenceString.write(value.namespaces, buf) - _UniffiFfiConverterSequenceTypeFieldElement.write(value.player_addresses, buf) + _UniffiFfiConverterOptionalTypeKeysClause.write(value.keys, buf) _UniffiFfiConverterTypePagination.write(value.pagination, buf) @dataclass -class Signature: - def __init__(self, *, r:FieldElement, s:FieldElement): - self.r = r - self.s = s +class Message: + def __init__(self, *, message:str, signature:typing.List[FieldElement], world_address:FieldElement): + self.message = message + self.signature = signature + self.world_address = world_address def __str__(self): - return "Signature(r={}, s={})".format(self.r, self.s) + return "Message(message={}, signature={}, world_address={})".format(self.message, self.signature, self.world_address) def __eq__(self, other): - if self.r != other.r: + if self.message != other.message: return False - if self.s != other.s: + if self.signature != other.signature: + return False + if self.world_address != other.world_address: return False return True -class _UniffiFfiConverterTypeSignature(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypeMessage(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return Signature( - r=_UniffiFfiConverterTypeFieldElement.read(buf), - s=_UniffiFfiConverterTypeFieldElement.read(buf), + return Message( + message=_UniffiFfiConverterString.read(buf), + signature=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + world_address=_UniffiFfiConverterTypeFieldElement.read(buf), ) @staticmethod def check_lower(value): - _UniffiFfiConverterTypeFieldElement.check_lower(value.r) - _UniffiFfiConverterTypeFieldElement.check_lower(value.s) + _UniffiFfiConverterString.check_lower(value.message) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.signature) + _UniffiFfiConverterTypeFieldElement.check_lower(value.world_address) @staticmethod def write(value, buf): - _UniffiFfiConverterTypeFieldElement.write(value.r, buf) - _UniffiFfiConverterTypeFieldElement.write(value.s, buf) - -class _UniffiFfiConverterOptionalTypeU256(_UniffiConverterRustBuffer): - @classmethod - def check_lower(cls, value): - if value is not None: - _UniffiFfiConverterTypeU256.check_lower(value) + _UniffiFfiConverterString.write(value.message, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.signature, buf) + _UniffiFfiConverterTypeFieldElement.write(value.world_address, buf) - @classmethod - def write(cls, value, buf): - if value is None: - buf.write_u8(0) - return - - buf.write_u8(1) - _UniffiFfiConverterTypeU256.write(value, buf) - - @classmethod - def read(cls, buf): - flag = buf.read_u8() - if flag == 0: - return None - elif flag == 1: - return _UniffiFfiConverterTypeU256.read(buf) - else: - raise InternalError("Unexpected flag byte for optional type") - -@dataclass -class Token: - def __init__(self, *, contract_address:FieldElement, token_id:typing.Optional[U256], name:str, symbol:str, decimals:int, metadata:str, total_supply:typing.Optional[U256]): - self.contract_address = contract_address - self.token_id = token_id - self.name = name - self.symbol = symbol - self.decimals = decimals - self.metadata = metadata - self.total_supply = total_supply - - +@dataclass +class Model: + def __init__(self, *, world_address:FieldElement, schema:Ty, namespace:str, name:str, selector:FieldElement, packed_size:int, unpacked_size:int, class_hash:FieldElement, contract_address:FieldElement, layout:str, use_legacy_store:bool): + self.world_address = world_address + self.schema = schema + self.namespace = namespace + self.name = name + self.selector = selector + self.packed_size = packed_size + self.unpacked_size = unpacked_size + self.class_hash = class_hash + self.contract_address = contract_address + self.layout = layout + self.use_legacy_store = use_legacy_store + + def __str__(self): - return "Token(contract_address={}, token_id={}, name={}, symbol={}, decimals={}, metadata={}, total_supply={})".format(self.contract_address, self.token_id, self.name, self.symbol, self.decimals, self.metadata, self.total_supply) + return "Model(world_address={}, schema={}, namespace={}, name={}, selector={}, packed_size={}, unpacked_size={}, class_hash={}, contract_address={}, layout={}, use_legacy_store={})".format(self.world_address, self.schema, self.namespace, self.name, self.selector, self.packed_size, self.unpacked_size, self.class_hash, self.contract_address, self.layout, self.use_legacy_store) def __eq__(self, other): - if self.contract_address != other.contract_address: + if self.world_address != other.world_address: return False - if self.token_id != other.token_id: + if self.schema != other.schema: + return False + if self.namespace != other.namespace: return False if self.name != other.name: return False - if self.symbol != other.symbol: + if self.selector != other.selector: return False - if self.decimals != other.decimals: + if self.packed_size != other.packed_size: return False - if self.metadata != other.metadata: + if self.unpacked_size != other.unpacked_size: return False - if self.total_supply != other.total_supply: + if self.class_hash != other.class_hash: + return False + if self.contract_address != other.contract_address: + return False + if self.layout != other.layout: + return False + if self.use_legacy_store != other.use_legacy_store: return False return True -class _UniffiFfiConverterTypeToken(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypeModel(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return Token( - contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), - token_id=_UniffiFfiConverterOptionalTypeU256.read(buf), + return Model( + world_address=_UniffiFfiConverterTypeFieldElement.read(buf), + schema=_UniffiFfiConverterTypeTy.read(buf), + namespace=_UniffiFfiConverterString.read(buf), name=_UniffiFfiConverterString.read(buf), - symbol=_UniffiFfiConverterString.read(buf), - decimals=_UniffiFfiConverterUInt8.read(buf), - metadata=_UniffiFfiConverterString.read(buf), - total_supply=_UniffiFfiConverterOptionalTypeU256.read(buf), + selector=_UniffiFfiConverterTypeFieldElement.read(buf), + packed_size=_UniffiFfiConverterUInt32.read(buf), + unpacked_size=_UniffiFfiConverterUInt32.read(buf), + class_hash=_UniffiFfiConverterTypeFieldElement.read(buf), + contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), + layout=_UniffiFfiConverterString.read(buf), + use_legacy_store=_UniffiFfiConverterBoolean.read(buf), ) @staticmethod def check_lower(value): - _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) - _UniffiFfiConverterOptionalTypeU256.check_lower(value.token_id) + _UniffiFfiConverterTypeFieldElement.check_lower(value.world_address) + _UniffiFfiConverterTypeTy.check_lower(value.schema) + _UniffiFfiConverterString.check_lower(value.namespace) _UniffiFfiConverterString.check_lower(value.name) - _UniffiFfiConverterString.check_lower(value.symbol) - _UniffiFfiConverterUInt8.check_lower(value.decimals) - _UniffiFfiConverterString.check_lower(value.metadata) - _UniffiFfiConverterOptionalTypeU256.check_lower(value.total_supply) + _UniffiFfiConverterTypeFieldElement.check_lower(value.selector) + _UniffiFfiConverterUInt32.check_lower(value.packed_size) + _UniffiFfiConverterUInt32.check_lower(value.unpacked_size) + _UniffiFfiConverterTypeFieldElement.check_lower(value.class_hash) + _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) + _UniffiFfiConverterString.check_lower(value.layout) + _UniffiFfiConverterBoolean.check_lower(value.use_legacy_store) @staticmethod def write(value, buf): - _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) - _UniffiFfiConverterOptionalTypeU256.write(value.token_id, buf) + _UniffiFfiConverterTypeFieldElement.write(value.world_address, buf) + _UniffiFfiConverterTypeTy.write(value.schema, buf) + _UniffiFfiConverterString.write(value.namespace, buf) _UniffiFfiConverterString.write(value.name, buf) - _UniffiFfiConverterString.write(value.symbol, buf) - _UniffiFfiConverterUInt8.write(value.decimals, buf) - _UniffiFfiConverterString.write(value.metadata, buf) - _UniffiFfiConverterOptionalTypeU256.write(value.total_supply, buf) + _UniffiFfiConverterTypeFieldElement.write(value.selector, buf) + _UniffiFfiConverterUInt32.write(value.packed_size, buf) + _UniffiFfiConverterUInt32.write(value.unpacked_size, buf) + _UniffiFfiConverterTypeFieldElement.write(value.class_hash, buf) + _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) + _UniffiFfiConverterString.write(value.layout, buf) + _UniffiFfiConverterBoolean.write(value.use_legacy_store, buf) + +class _UniffiFfiConverterSequenceTypeAchievement(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeAchievement.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeAchievement.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeAchievement.read(buf) for i in range(count) + ] @dataclass -class TokenBalance: - def __init__(self, *, balance:U256, account_address:FieldElement, contract_address:FieldElement, token_id:typing.Optional[U256]): - self.balance = balance - self.account_address = account_address - self.contract_address = contract_address - self.token_id = token_id +class PageAchievement: + def __init__(self, *, items:typing.List[Achievement], next_cursor:typing.Optional[str]): + self.items = items + self.next_cursor = next_cursor def __str__(self): - return "TokenBalance(balance={}, account_address={}, contract_address={}, token_id={})".format(self.balance, self.account_address, self.contract_address, self.token_id) + return "PageAchievement(items={}, next_cursor={})".format(self.items, self.next_cursor) def __eq__(self, other): - if self.balance != other.balance: - return False - if self.account_address != other.account_address: - return False - if self.contract_address != other.contract_address: + if self.items != other.items: return False - if self.token_id != other.token_id: + if self.next_cursor != other.next_cursor: return False return True -class _UniffiFfiConverterTypeTokenBalance(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypePageAchievement(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return TokenBalance( - balance=_UniffiFfiConverterTypeU256.read(buf), - account_address=_UniffiFfiConverterTypeFieldElement.read(buf), - contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), - token_id=_UniffiFfiConverterOptionalTypeU256.read(buf), + return PageAchievement( + items=_UniffiFfiConverterSequenceTypeAchievement.read(buf), + next_cursor=_UniffiFfiConverterOptionalString.read(buf), ) @staticmethod def check_lower(value): - _UniffiFfiConverterTypeU256.check_lower(value.balance) - _UniffiFfiConverterTypeFieldElement.check_lower(value.account_address) - _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) - _UniffiFfiConverterOptionalTypeU256.check_lower(value.token_id) + _UniffiFfiConverterSequenceTypeAchievement.check_lower(value.items) + _UniffiFfiConverterOptionalString.check_lower(value.next_cursor) @staticmethod def write(value, buf): - _UniffiFfiConverterTypeU256.write(value.balance, buf) - _UniffiFfiConverterTypeFieldElement.write(value.account_address, buf) - _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) - _UniffiFfiConverterOptionalTypeU256.write(value.token_id, buf) + _UniffiFfiConverterSequenceTypeAchievement.write(value.items, buf) + _UniffiFfiConverterOptionalString.write(value.next_cursor, buf) -class _UniffiFfiConverterSequenceTypeU256(_UniffiConverterRustBuffer): +class _UniffiFfiConverterSequenceTypeActivity(_UniffiConverterRustBuffer): @classmethod def check_lower(cls, value): for item in value: - _UniffiFfiConverterTypeU256.check_lower(item) + _UniffiFfiConverterTypeActivity.check_lower(item) @classmethod def write(cls, value, buf): items = len(value) buf.write_i32(items) for item in value: - _UniffiFfiConverterTypeU256.write(item, buf) + _UniffiFfiConverterTypeActivity.write(item, buf) @classmethod def read(cls, buf): @@ -4771,177 +4952,175 @@ def read(cls, buf): raise InternalError("Unexpected negative sequence length") return [ - _UniffiFfiConverterTypeU256.read(buf) for i in range(count) + _UniffiFfiConverterTypeActivity.read(buf) for i in range(count) ] @dataclass -class TokenBalanceQuery: - def __init__(self, *, contract_addresses:typing.List[FieldElement], account_addresses:typing.List[FieldElement], token_ids:typing.List[U256], pagination:Pagination): - self.contract_addresses = contract_addresses - self.account_addresses = account_addresses - self.token_ids = token_ids - self.pagination = pagination +class PageActivity: + def __init__(self, *, items:typing.List[Activity], next_cursor:typing.Optional[str]): + self.items = items + self.next_cursor = next_cursor def __str__(self): - return "TokenBalanceQuery(contract_addresses={}, account_addresses={}, token_ids={}, pagination={})".format(self.contract_addresses, self.account_addresses, self.token_ids, self.pagination) + return "PageActivity(items={}, next_cursor={})".format(self.items, self.next_cursor) def __eq__(self, other): - if self.contract_addresses != other.contract_addresses: - return False - if self.account_addresses != other.account_addresses: + if self.items != other.items: return False - if self.token_ids != other.token_ids: - return False - if self.pagination != other.pagination: + if self.next_cursor != other.next_cursor: return False return True -class _UniffiFfiConverterTypeTokenBalanceQuery(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypePageActivity(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return TokenBalanceQuery( - contract_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), - account_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), - token_ids=_UniffiFfiConverterSequenceTypeU256.read(buf), - pagination=_UniffiFfiConverterTypePagination.read(buf), + return PageActivity( + items=_UniffiFfiConverterSequenceTypeActivity.read(buf), + next_cursor=_UniffiFfiConverterOptionalString.read(buf), ) @staticmethod def check_lower(value): - _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.contract_addresses) - _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.account_addresses) - _UniffiFfiConverterSequenceTypeU256.check_lower(value.token_ids) - _UniffiFfiConverterTypePagination.check_lower(value.pagination) + _UniffiFfiConverterSequenceTypeActivity.check_lower(value.items) + _UniffiFfiConverterOptionalString.check_lower(value.next_cursor) @staticmethod def write(value, buf): - _UniffiFfiConverterSequenceTypeFieldElement.write(value.contract_addresses, buf) - _UniffiFfiConverterSequenceTypeFieldElement.write(value.account_addresses, buf) - _UniffiFfiConverterSequenceTypeU256.write(value.token_ids, buf) - _UniffiFfiConverterTypePagination.write(value.pagination, buf) + _UniffiFfiConverterSequenceTypeActivity.write(value.items, buf) + _UniffiFfiConverterOptionalString.write(value.next_cursor, buf) + +class _UniffiFfiConverterSequenceTypeAggregationEntry(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeAggregationEntry.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeAggregationEntry.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeAggregationEntry.read(buf) for i in range(count) + ] @dataclass -class TokenContract: - def __init__(self, *, contract_address:FieldElement, name:str, symbol:str, decimals:int, metadata:str, token_metadata:str, total_supply:typing.Optional[U256]): - self.contract_address = contract_address - self.name = name - self.symbol = symbol - self.decimals = decimals - self.metadata = metadata - self.token_metadata = token_metadata - self.total_supply = total_supply +class PageAggregationEntry: + def __init__(self, *, items:typing.List[AggregationEntry], next_cursor:typing.Optional[str]): + self.items = items + self.next_cursor = next_cursor def __str__(self): - return "TokenContract(contract_address={}, name={}, symbol={}, decimals={}, metadata={}, token_metadata={}, total_supply={})".format(self.contract_address, self.name, self.symbol, self.decimals, self.metadata, self.token_metadata, self.total_supply) + return "PageAggregationEntry(items={}, next_cursor={})".format(self.items, self.next_cursor) def __eq__(self, other): - if self.contract_address != other.contract_address: - return False - if self.name != other.name: - return False - if self.symbol != other.symbol: - return False - if self.decimals != other.decimals: - return False - if self.metadata != other.metadata: - return False - if self.token_metadata != other.token_metadata: + if self.items != other.items: return False - if self.total_supply != other.total_supply: + if self.next_cursor != other.next_cursor: return False return True -class _UniffiFfiConverterTypeTokenContract(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypePageAggregationEntry(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return TokenContract( - contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), - name=_UniffiFfiConverterString.read(buf), - symbol=_UniffiFfiConverterString.read(buf), - decimals=_UniffiFfiConverterUInt8.read(buf), - metadata=_UniffiFfiConverterString.read(buf), - token_metadata=_UniffiFfiConverterString.read(buf), - total_supply=_UniffiFfiConverterOptionalTypeU256.read(buf), + return PageAggregationEntry( + items=_UniffiFfiConverterSequenceTypeAggregationEntry.read(buf), + next_cursor=_UniffiFfiConverterOptionalString.read(buf), ) @staticmethod def check_lower(value): - _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) - _UniffiFfiConverterString.check_lower(value.name) - _UniffiFfiConverterString.check_lower(value.symbol) - _UniffiFfiConverterUInt8.check_lower(value.decimals) - _UniffiFfiConverterString.check_lower(value.metadata) - _UniffiFfiConverterString.check_lower(value.token_metadata) - _UniffiFfiConverterOptionalTypeU256.check_lower(value.total_supply) + _UniffiFfiConverterSequenceTypeAggregationEntry.check_lower(value.items) + _UniffiFfiConverterOptionalString.check_lower(value.next_cursor) @staticmethod def write(value, buf): - _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) - _UniffiFfiConverterString.write(value.name, buf) - _UniffiFfiConverterString.write(value.symbol, buf) - _UniffiFfiConverterUInt8.write(value.decimals, buf) - _UniffiFfiConverterString.write(value.metadata, buf) - _UniffiFfiConverterString.write(value.token_metadata, buf) - _UniffiFfiConverterOptionalTypeU256.write(value.total_supply, buf) + _UniffiFfiConverterSequenceTypeAggregationEntry.write(value.items, buf) + _UniffiFfiConverterOptionalString.write(value.next_cursor, buf) + +class _UniffiFfiConverterSequenceTypeController(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeController.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeController.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeController.read(buf) for i in range(count) + ] @dataclass -class TokenContractQuery: - def __init__(self, *, contract_addresses:typing.List[FieldElement], contract_types:typing.List[ContractType], pagination:Pagination): - self.contract_addresses = contract_addresses - self.contract_types = contract_types - self.pagination = pagination +class PageController: + def __init__(self, *, items:typing.List[Controller], next_cursor:typing.Optional[str]): + self.items = items + self.next_cursor = next_cursor def __str__(self): - return "TokenContractQuery(contract_addresses={}, contract_types={}, pagination={})".format(self.contract_addresses, self.contract_types, self.pagination) + return "PageController(items={}, next_cursor={})".format(self.items, self.next_cursor) def __eq__(self, other): - if self.contract_addresses != other.contract_addresses: - return False - if self.contract_types != other.contract_types: + if self.items != other.items: return False - if self.pagination != other.pagination: + if self.next_cursor != other.next_cursor: return False return True -class _UniffiFfiConverterTypeTokenContractQuery(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypePageController(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return TokenContractQuery( - contract_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), - contract_types=_UniffiFfiConverterSequenceTypeContractType.read(buf), - pagination=_UniffiFfiConverterTypePagination.read(buf), + return PageController( + items=_UniffiFfiConverterSequenceTypeController.read(buf), + next_cursor=_UniffiFfiConverterOptionalString.read(buf), ) @staticmethod def check_lower(value): - _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.contract_addresses) - _UniffiFfiConverterSequenceTypeContractType.check_lower(value.contract_types) - _UniffiFfiConverterTypePagination.check_lower(value.pagination) + _UniffiFfiConverterSequenceTypeController.check_lower(value.items) + _UniffiFfiConverterOptionalString.check_lower(value.next_cursor) @staticmethod def write(value, buf): - _UniffiFfiConverterSequenceTypeFieldElement.write(value.contract_addresses, buf) - _UniffiFfiConverterSequenceTypeContractType.write(value.contract_types, buf) - _UniffiFfiConverterTypePagination.write(value.pagination, buf) + _UniffiFfiConverterSequenceTypeController.write(value.items, buf) + _UniffiFfiConverterOptionalString.write(value.next_cursor, buf) -class _UniffiFfiConverterSequenceTypeAttributeFilter(_UniffiConverterRustBuffer): +class _UniffiFfiConverterSequenceTypeEntity(_UniffiConverterRustBuffer): @classmethod def check_lower(cls, value): for item in value: - _UniffiFfiConverterTypeAttributeFilter.check_lower(item) + _UniffiFfiConverterTypeEntity.check_lower(item) @classmethod def write(cls, value, buf): items = len(value) buf.write_i32(items) for item in value: - _UniffiFfiConverterTypeAttributeFilter.write(item, buf) + _UniffiFfiConverterTypeEntity.write(item, buf) @classmethod def read(cls, buf): @@ -4950,131 +5129,1684 @@ def read(cls, buf): raise InternalError("Unexpected negative sequence length") return [ - _UniffiFfiConverterTypeAttributeFilter.read(buf) for i in range(count) + _UniffiFfiConverterTypeEntity.read(buf) for i in range(count) ] @dataclass -class TokenQuery: - def __init__(self, *, contract_addresses:typing.List[FieldElement], token_ids:typing.List[U256], attribute_filters:typing.List[AttributeFilter], pagination:Pagination): - self.contract_addresses = contract_addresses - self.token_ids = token_ids - self.attribute_filters = attribute_filters - self.pagination = pagination +class PageEntity: + def __init__(self, *, items:typing.List[Entity], next_cursor:typing.Optional[str]): + self.items = items + self.next_cursor = next_cursor def __str__(self): - return "TokenQuery(contract_addresses={}, token_ids={}, attribute_filters={}, pagination={})".format(self.contract_addresses, self.token_ids, self.attribute_filters, self.pagination) + return "PageEntity(items={}, next_cursor={})".format(self.items, self.next_cursor) def __eq__(self, other): - if self.contract_addresses != other.contract_addresses: + if self.items != other.items: return False - if self.token_ids != other.token_ids: + if self.next_cursor != other.next_cursor: return False - if self.attribute_filters != other.attribute_filters: + return True + +class _UniffiFfiConverterTypePageEntity(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PageEntity( + items=_UniffiFfiConverterSequenceTypeEntity.read(buf), + next_cursor=_UniffiFfiConverterOptionalString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeEntity.check_lower(value.items) + _UniffiFfiConverterOptionalString.check_lower(value.next_cursor) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeEntity.write(value.items, buf) + _UniffiFfiConverterOptionalString.write(value.next_cursor, buf) + +class _UniffiFfiConverterSequenceTypeEvent(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeEvent.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeEvent.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeEvent.read(buf) for i in range(count) + ] + +@dataclass +class PageEvent: + def __init__(self, *, items:typing.List[Event], next_cursor:typing.Optional[str]): + self.items = items + self.next_cursor = next_cursor + + + + + def __str__(self): + return "PageEvent(items={}, next_cursor={})".format(self.items, self.next_cursor) + def __eq__(self, other): + if self.items != other.items: return False - if self.pagination != other.pagination: + if self.next_cursor != other.next_cursor: return False return True -class _UniffiFfiConverterTypeTokenQuery(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypePageEvent(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return TokenQuery( - contract_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), - token_ids=_UniffiFfiConverterSequenceTypeU256.read(buf), - attribute_filters=_UniffiFfiConverterSequenceTypeAttributeFilter.read(buf), - pagination=_UniffiFfiConverterTypePagination.read(buf), + return PageEvent( + items=_UniffiFfiConverterSequenceTypeEvent.read(buf), + next_cursor=_UniffiFfiConverterOptionalString.read(buf), ) @staticmethod def check_lower(value): - _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.contract_addresses) - _UniffiFfiConverterSequenceTypeU256.check_lower(value.token_ids) - _UniffiFfiConverterSequenceTypeAttributeFilter.check_lower(value.attribute_filters) - _UniffiFfiConverterTypePagination.check_lower(value.pagination) + _UniffiFfiConverterSequenceTypeEvent.check_lower(value.items) + _UniffiFfiConverterOptionalString.check_lower(value.next_cursor) @staticmethod def write(value, buf): - _UniffiFfiConverterSequenceTypeFieldElement.write(value.contract_addresses, buf) - _UniffiFfiConverterSequenceTypeU256.write(value.token_ids, buf) - _UniffiFfiConverterSequenceTypeAttributeFilter.write(value.attribute_filters, buf) - _UniffiFfiConverterTypePagination.write(value.pagination, buf) + _UniffiFfiConverterSequenceTypeEvent.write(value.items, buf) + _UniffiFfiConverterOptionalString.write(value.next_cursor, buf) @dataclass -class TokenTransfer: - def __init__(self, *, id:str, contract_address:FieldElement, from_address:FieldElement, to_address:FieldElement, amount:U256, token_id:typing.Optional[U256], executed_at:int, event_id:typing.Optional[str]): - self.id = id - self.contract_address = contract_address - self.from_address = from_address - self.to_address = to_address - self.amount = amount - self.token_id = token_id - self.executed_at = executed_at - self.event_id = event_id +class PlayerAchievementStats: + def __init__(self, *, total_points:int, completed_achievements:int, total_achievements:int, completion_percentage:float, last_achievement_at:typing.Optional[int], created_at:int, updated_at:int): + self.total_points = total_points + self.completed_achievements = completed_achievements + self.total_achievements = total_achievements + self.completion_percentage = completion_percentage + self.last_achievement_at = last_achievement_at + self.created_at = created_at + self.updated_at = updated_at def __str__(self): - return "TokenTransfer(id={}, contract_address={}, from_address={}, to_address={}, amount={}, token_id={}, executed_at={}, event_id={})".format(self.id, self.contract_address, self.from_address, self.to_address, self.amount, self.token_id, self.executed_at, self.event_id) + return "PlayerAchievementStats(total_points={}, completed_achievements={}, total_achievements={}, completion_percentage={}, last_achievement_at={}, created_at={}, updated_at={})".format(self.total_points, self.completed_achievements, self.total_achievements, self.completion_percentage, self.last_achievement_at, self.created_at, self.updated_at) def __eq__(self, other): - if self.id != other.id: + if self.total_points != other.total_points: return False - if self.contract_address != other.contract_address: + if self.completed_achievements != other.completed_achievements: return False - if self.from_address != other.from_address: + if self.total_achievements != other.total_achievements: return False - if self.to_address != other.to_address: + if self.completion_percentage != other.completion_percentage: return False - if self.amount != other.amount: + if self.last_achievement_at != other.last_achievement_at: return False - if self.token_id != other.token_id: + if self.created_at != other.created_at: return False - if self.executed_at != other.executed_at: + if self.updated_at != other.updated_at: return False - if self.event_id != other.event_id: + return True + +class _UniffiFfiConverterTypePlayerAchievementStats(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PlayerAchievementStats( + total_points=_UniffiFfiConverterUInt32.read(buf), + completed_achievements=_UniffiFfiConverterUInt32.read(buf), + total_achievements=_UniffiFfiConverterUInt32.read(buf), + completion_percentage=_UniffiFfiConverterFloat64.read(buf), + last_achievement_at=_UniffiFfiConverterOptionalUInt64.read(buf), + created_at=_UniffiFfiConverterUInt64.read(buf), + updated_at=_UniffiFfiConverterUInt64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterUInt32.check_lower(value.total_points) + _UniffiFfiConverterUInt32.check_lower(value.completed_achievements) + _UniffiFfiConverterUInt32.check_lower(value.total_achievements) + _UniffiFfiConverterFloat64.check_lower(value.completion_percentage) + _UniffiFfiConverterOptionalUInt64.check_lower(value.last_achievement_at) + _UniffiFfiConverterUInt64.check_lower(value.created_at) + _UniffiFfiConverterUInt64.check_lower(value.updated_at) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterUInt32.write(value.total_points, buf) + _UniffiFfiConverterUInt32.write(value.completed_achievements, buf) + _UniffiFfiConverterUInt32.write(value.total_achievements, buf) + _UniffiFfiConverterFloat64.write(value.completion_percentage, buf) + _UniffiFfiConverterOptionalUInt64.write(value.last_achievement_at, buf) + _UniffiFfiConverterUInt64.write(value.created_at, buf) + _UniffiFfiConverterUInt64.write(value.updated_at, buf) + +@dataclass +class TaskProgress: + def __init__(self, *, task_id:str, count:int, completed:bool): + self.task_id = task_id + self.count = count + self.completed = completed + + + + + def __str__(self): + return "TaskProgress(task_id={}, count={}, completed={})".format(self.task_id, self.count, self.completed) + def __eq__(self, other): + if self.task_id != other.task_id: + return False + if self.count != other.count: + return False + if self.completed != other.completed: return False return True -class _UniffiFfiConverterTypeTokenTransfer(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypeTaskProgress(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return TokenTransfer( - id=_UniffiFfiConverterString.read(buf), - contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), - from_address=_UniffiFfiConverterTypeFieldElement.read(buf), - to_address=_UniffiFfiConverterTypeFieldElement.read(buf), - amount=_UniffiFfiConverterTypeU256.read(buf), - token_id=_UniffiFfiConverterOptionalTypeU256.read(buf), - executed_at=_UniffiFfiConverterUInt64.read(buf), - event_id=_UniffiFfiConverterOptionalString.read(buf), + return TaskProgress( + task_id=_UniffiFfiConverterString.read(buf), + count=_UniffiFfiConverterUInt32.read(buf), + completed=_UniffiFfiConverterBoolean.read(buf), ) @staticmethod def check_lower(value): - _UniffiFfiConverterString.check_lower(value.id) - _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) - _UniffiFfiConverterTypeFieldElement.check_lower(value.from_address) - _UniffiFfiConverterTypeFieldElement.check_lower(value.to_address) - _UniffiFfiConverterTypeU256.check_lower(value.amount) - _UniffiFfiConverterOptionalTypeU256.check_lower(value.token_id) - _UniffiFfiConverterUInt64.check_lower(value.executed_at) - _UniffiFfiConverterOptionalString.check_lower(value.event_id) + _UniffiFfiConverterString.check_lower(value.task_id) + _UniffiFfiConverterUInt32.check_lower(value.count) + _UniffiFfiConverterBoolean.check_lower(value.completed) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.task_id, buf) + _UniffiFfiConverterUInt32.write(value.count, buf) + _UniffiFfiConverterBoolean.write(value.completed, buf) + +class _UniffiFfiConverterSequenceTypeTaskProgress(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeTaskProgress.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeTaskProgress.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeTaskProgress.read(buf) for i in range(count) + ] + +@dataclass +class PlayerAchievementProgress: + def __init__(self, *, achievement:Achievement, task_progress:typing.List[TaskProgress], completed:bool, progress_percentage:float): + self.achievement = achievement + self.task_progress = task_progress + self.completed = completed + self.progress_percentage = progress_percentage + + + + + def __str__(self): + return "PlayerAchievementProgress(achievement={}, task_progress={}, completed={}, progress_percentage={})".format(self.achievement, self.task_progress, self.completed, self.progress_percentage) + def __eq__(self, other): + if self.achievement != other.achievement: + return False + if self.task_progress != other.task_progress: + return False + if self.completed != other.completed: + return False + if self.progress_percentage != other.progress_percentage: + return False + return True + +class _UniffiFfiConverterTypePlayerAchievementProgress(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PlayerAchievementProgress( + achievement=_UniffiFfiConverterTypeAchievement.read(buf), + task_progress=_UniffiFfiConverterSequenceTypeTaskProgress.read(buf), + completed=_UniffiFfiConverterBoolean.read(buf), + progress_percentage=_UniffiFfiConverterFloat64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeAchievement.check_lower(value.achievement) + _UniffiFfiConverterSequenceTypeTaskProgress.check_lower(value.task_progress) + _UniffiFfiConverterBoolean.check_lower(value.completed) + _UniffiFfiConverterFloat64.check_lower(value.progress_percentage) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeAchievement.write(value.achievement, buf) + _UniffiFfiConverterSequenceTypeTaskProgress.write(value.task_progress, buf) + _UniffiFfiConverterBoolean.write(value.completed, buf) + _UniffiFfiConverterFloat64.write(value.progress_percentage, buf) + +class _UniffiFfiConverterSequenceTypePlayerAchievementProgress(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypePlayerAchievementProgress.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypePlayerAchievementProgress.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypePlayerAchievementProgress.read(buf) for i in range(count) + ] + +@dataclass +class PlayerAchievementEntry: + def __init__(self, *, player_address:FieldElement, stats:PlayerAchievementStats, achievements:typing.List[PlayerAchievementProgress]): + self.player_address = player_address + self.stats = stats + self.achievements = achievements + + + + + def __str__(self): + return "PlayerAchievementEntry(player_address={}, stats={}, achievements={})".format(self.player_address, self.stats, self.achievements) + def __eq__(self, other): + if self.player_address != other.player_address: + return False + if self.stats != other.stats: + return False + if self.achievements != other.achievements: + return False + return True + +class _UniffiFfiConverterTypePlayerAchievementEntry(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PlayerAchievementEntry( + player_address=_UniffiFfiConverterTypeFieldElement.read(buf), + stats=_UniffiFfiConverterTypePlayerAchievementStats.read(buf), + achievements=_UniffiFfiConverterSequenceTypePlayerAchievementProgress.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeFieldElement.check_lower(value.player_address) + _UniffiFfiConverterTypePlayerAchievementStats.check_lower(value.stats) + _UniffiFfiConverterSequenceTypePlayerAchievementProgress.check_lower(value.achievements) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeFieldElement.write(value.player_address, buf) + _UniffiFfiConverterTypePlayerAchievementStats.write(value.stats, buf) + _UniffiFfiConverterSequenceTypePlayerAchievementProgress.write(value.achievements, buf) + +class _UniffiFfiConverterSequenceTypePlayerAchievementEntry(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypePlayerAchievementEntry.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypePlayerAchievementEntry.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypePlayerAchievementEntry.read(buf) for i in range(count) + ] + +@dataclass +class PagePlayerAchievement: + def __init__(self, *, items:typing.List[PlayerAchievementEntry], next_cursor:typing.Optional[str]): + self.items = items + self.next_cursor = next_cursor + + + + + def __str__(self): + return "PagePlayerAchievement(items={}, next_cursor={})".format(self.items, self.next_cursor) + def __eq__(self, other): + if self.items != other.items: + return False + if self.next_cursor != other.next_cursor: + return False + return True + +class _UniffiFfiConverterTypePagePlayerAchievement(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PagePlayerAchievement( + items=_UniffiFfiConverterSequenceTypePlayerAchievementEntry.read(buf), + next_cursor=_UniffiFfiConverterOptionalString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypePlayerAchievementEntry.check_lower(value.items) + _UniffiFfiConverterOptionalString.check_lower(value.next_cursor) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypePlayerAchievementEntry.write(value.items, buf) + _UniffiFfiConverterOptionalString.write(value.next_cursor, buf) + +class _UniffiFfiConverterOptionalTypeU256(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiFfiConverterTypeU256.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiFfiConverterTypeU256.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiFfiConverterTypeU256.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + +@dataclass +class Token: + def __init__(self, *, contract_address:FieldElement, token_id:typing.Optional[U256], name:str, symbol:str, decimals:int, metadata:str, total_supply:typing.Optional[U256]): + self.contract_address = contract_address + self.token_id = token_id + self.name = name + self.symbol = symbol + self.decimals = decimals + self.metadata = metadata + self.total_supply = total_supply + + + + + def __str__(self): + return "Token(contract_address={}, token_id={}, name={}, symbol={}, decimals={}, metadata={}, total_supply={})".format(self.contract_address, self.token_id, self.name, self.symbol, self.decimals, self.metadata, self.total_supply) + def __eq__(self, other): + if self.contract_address != other.contract_address: + return False + if self.token_id != other.token_id: + return False + if self.name != other.name: + return False + if self.symbol != other.symbol: + return False + if self.decimals != other.decimals: + return False + if self.metadata != other.metadata: + return False + if self.total_supply != other.total_supply: + return False + return True + +class _UniffiFfiConverterTypeToken(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Token( + contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), + token_id=_UniffiFfiConverterOptionalTypeU256.read(buf), + name=_UniffiFfiConverterString.read(buf), + symbol=_UniffiFfiConverterString.read(buf), + decimals=_UniffiFfiConverterUInt8.read(buf), + metadata=_UniffiFfiConverterString.read(buf), + total_supply=_UniffiFfiConverterOptionalTypeU256.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) + _UniffiFfiConverterOptionalTypeU256.check_lower(value.token_id) + _UniffiFfiConverterString.check_lower(value.name) + _UniffiFfiConverterString.check_lower(value.symbol) + _UniffiFfiConverterUInt8.check_lower(value.decimals) + _UniffiFfiConverterString.check_lower(value.metadata) + _UniffiFfiConverterOptionalTypeU256.check_lower(value.total_supply) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) + _UniffiFfiConverterOptionalTypeU256.write(value.token_id, buf) + _UniffiFfiConverterString.write(value.name, buf) + _UniffiFfiConverterString.write(value.symbol, buf) + _UniffiFfiConverterUInt8.write(value.decimals, buf) + _UniffiFfiConverterString.write(value.metadata, buf) + _UniffiFfiConverterOptionalTypeU256.write(value.total_supply, buf) + +class _UniffiFfiConverterSequenceTypeToken(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeToken.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeToken.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeToken.read(buf) for i in range(count) + ] + +@dataclass +class PageToken: + def __init__(self, *, items:typing.List[Token], next_cursor:typing.Optional[str]): + self.items = items + self.next_cursor = next_cursor + + + + + def __str__(self): + return "PageToken(items={}, next_cursor={})".format(self.items, self.next_cursor) + def __eq__(self, other): + if self.items != other.items: + return False + if self.next_cursor != other.next_cursor: + return False + return True + +class _UniffiFfiConverterTypePageToken(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PageToken( + items=_UniffiFfiConverterSequenceTypeToken.read(buf), + next_cursor=_UniffiFfiConverterOptionalString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeToken.check_lower(value.items) + _UniffiFfiConverterOptionalString.check_lower(value.next_cursor) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeToken.write(value.items, buf) + _UniffiFfiConverterOptionalString.write(value.next_cursor, buf) + +@dataclass +class TokenBalance: + def __init__(self, *, balance:U256, account_address:FieldElement, contract_address:FieldElement, token_id:typing.Optional[U256]): + self.balance = balance + self.account_address = account_address + self.contract_address = contract_address + self.token_id = token_id + + + + + def __str__(self): + return "TokenBalance(balance={}, account_address={}, contract_address={}, token_id={})".format(self.balance, self.account_address, self.contract_address, self.token_id) + def __eq__(self, other): + if self.balance != other.balance: + return False + if self.account_address != other.account_address: + return False + if self.contract_address != other.contract_address: + return False + if self.token_id != other.token_id: + return False + return True + +class _UniffiFfiConverterTypeTokenBalance(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TokenBalance( + balance=_UniffiFfiConverterTypeU256.read(buf), + account_address=_UniffiFfiConverterTypeFieldElement.read(buf), + contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), + token_id=_UniffiFfiConverterOptionalTypeU256.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeU256.check_lower(value.balance) + _UniffiFfiConverterTypeFieldElement.check_lower(value.account_address) + _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) + _UniffiFfiConverterOptionalTypeU256.check_lower(value.token_id) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeU256.write(value.balance, buf) + _UniffiFfiConverterTypeFieldElement.write(value.account_address, buf) + _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) + _UniffiFfiConverterOptionalTypeU256.write(value.token_id, buf) + +class _UniffiFfiConverterSequenceTypeTokenBalance(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeTokenBalance.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeTokenBalance.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeTokenBalance.read(buf) for i in range(count) + ] + +@dataclass +class PageTokenBalance: + def __init__(self, *, items:typing.List[TokenBalance], next_cursor:typing.Optional[str]): + self.items = items + self.next_cursor = next_cursor + + + + + def __str__(self): + return "PageTokenBalance(items={}, next_cursor={})".format(self.items, self.next_cursor) + def __eq__(self, other): + if self.items != other.items: + return False + if self.next_cursor != other.next_cursor: + return False + return True + +class _UniffiFfiConverterTypePageTokenBalance(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PageTokenBalance( + items=_UniffiFfiConverterSequenceTypeTokenBalance.read(buf), + next_cursor=_UniffiFfiConverterOptionalString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeTokenBalance.check_lower(value.items) + _UniffiFfiConverterOptionalString.check_lower(value.next_cursor) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeTokenBalance.write(value.items, buf) + _UniffiFfiConverterOptionalString.write(value.next_cursor, buf) + +@dataclass +class TokenContract: + def __init__(self, *, contract_address:FieldElement, name:str, symbol:str, decimals:int, metadata:str, token_metadata:str, total_supply:typing.Optional[U256]): + self.contract_address = contract_address + self.name = name + self.symbol = symbol + self.decimals = decimals + self.metadata = metadata + self.token_metadata = token_metadata + self.total_supply = total_supply + + + + + def __str__(self): + return "TokenContract(contract_address={}, name={}, symbol={}, decimals={}, metadata={}, token_metadata={}, total_supply={})".format(self.contract_address, self.name, self.symbol, self.decimals, self.metadata, self.token_metadata, self.total_supply) + def __eq__(self, other): + if self.contract_address != other.contract_address: + return False + if self.name != other.name: + return False + if self.symbol != other.symbol: + return False + if self.decimals != other.decimals: + return False + if self.metadata != other.metadata: + return False + if self.token_metadata != other.token_metadata: + return False + if self.total_supply != other.total_supply: + return False + return True + +class _UniffiFfiConverterTypeTokenContract(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TokenContract( + contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), + name=_UniffiFfiConverterString.read(buf), + symbol=_UniffiFfiConverterString.read(buf), + decimals=_UniffiFfiConverterUInt8.read(buf), + metadata=_UniffiFfiConverterString.read(buf), + token_metadata=_UniffiFfiConverterString.read(buf), + total_supply=_UniffiFfiConverterOptionalTypeU256.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) + _UniffiFfiConverterString.check_lower(value.name) + _UniffiFfiConverterString.check_lower(value.symbol) + _UniffiFfiConverterUInt8.check_lower(value.decimals) + _UniffiFfiConverterString.check_lower(value.metadata) + _UniffiFfiConverterString.check_lower(value.token_metadata) + _UniffiFfiConverterOptionalTypeU256.check_lower(value.total_supply) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) + _UniffiFfiConverterString.write(value.name, buf) + _UniffiFfiConverterString.write(value.symbol, buf) + _UniffiFfiConverterUInt8.write(value.decimals, buf) + _UniffiFfiConverterString.write(value.metadata, buf) + _UniffiFfiConverterString.write(value.token_metadata, buf) + _UniffiFfiConverterOptionalTypeU256.write(value.total_supply, buf) + +class _UniffiFfiConverterSequenceTypeTokenContract(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeTokenContract.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeTokenContract.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeTokenContract.read(buf) for i in range(count) + ] + +@dataclass +class PageTokenContract: + def __init__(self, *, items:typing.List[TokenContract], next_cursor:typing.Optional[str]): + self.items = items + self.next_cursor = next_cursor + + + + + def __str__(self): + return "PageTokenContract(items={}, next_cursor={})".format(self.items, self.next_cursor) + def __eq__(self, other): + if self.items != other.items: + return False + if self.next_cursor != other.next_cursor: + return False + return True + +class _UniffiFfiConverterTypePageTokenContract(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PageTokenContract( + items=_UniffiFfiConverterSequenceTypeTokenContract.read(buf), + next_cursor=_UniffiFfiConverterOptionalString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeTokenContract.check_lower(value.items) + _UniffiFfiConverterOptionalString.check_lower(value.next_cursor) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeTokenContract.write(value.items, buf) + _UniffiFfiConverterOptionalString.write(value.next_cursor, buf) + +@dataclass +class TokenTransfer: + def __init__(self, *, id:str, contract_address:FieldElement, from_address:FieldElement, to_address:FieldElement, amount:U256, token_id:typing.Optional[U256], executed_at:int, event_id:typing.Optional[str]): + self.id = id + self.contract_address = contract_address + self.from_address = from_address + self.to_address = to_address + self.amount = amount + self.token_id = token_id + self.executed_at = executed_at + self.event_id = event_id + + + + + def __str__(self): + return "TokenTransfer(id={}, contract_address={}, from_address={}, to_address={}, amount={}, token_id={}, executed_at={}, event_id={})".format(self.id, self.contract_address, self.from_address, self.to_address, self.amount, self.token_id, self.executed_at, self.event_id) + def __eq__(self, other): + if self.id != other.id: + return False + if self.contract_address != other.contract_address: + return False + if self.from_address != other.from_address: + return False + if self.to_address != other.to_address: + return False + if self.amount != other.amount: + return False + if self.token_id != other.token_id: + return False + if self.executed_at != other.executed_at: + return False + if self.event_id != other.event_id: + return False + return True + +class _UniffiFfiConverterTypeTokenTransfer(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TokenTransfer( + id=_UniffiFfiConverterString.read(buf), + contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), + from_address=_UniffiFfiConverterTypeFieldElement.read(buf), + to_address=_UniffiFfiConverterTypeFieldElement.read(buf), + amount=_UniffiFfiConverterTypeU256.read(buf), + token_id=_UniffiFfiConverterOptionalTypeU256.read(buf), + executed_at=_UniffiFfiConverterUInt64.read(buf), + event_id=_UniffiFfiConverterOptionalString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.id) + _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) + _UniffiFfiConverterTypeFieldElement.check_lower(value.from_address) + _UniffiFfiConverterTypeFieldElement.check_lower(value.to_address) + _UniffiFfiConverterTypeU256.check_lower(value.amount) + _UniffiFfiConverterOptionalTypeU256.check_lower(value.token_id) + _UniffiFfiConverterUInt64.check_lower(value.executed_at) + _UniffiFfiConverterOptionalString.check_lower(value.event_id) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.id, buf) + _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) + _UniffiFfiConverterTypeFieldElement.write(value.from_address, buf) + _UniffiFfiConverterTypeFieldElement.write(value.to_address, buf) + _UniffiFfiConverterTypeU256.write(value.amount, buf) + _UniffiFfiConverterOptionalTypeU256.write(value.token_id, buf) + _UniffiFfiConverterUInt64.write(value.executed_at, buf) + _UniffiFfiConverterOptionalString.write(value.event_id, buf) + +class _UniffiFfiConverterSequenceTypeTokenTransfer(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeTokenTransfer.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeTokenTransfer.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeTokenTransfer.read(buf) for i in range(count) + ] + +@dataclass +class PageTokenTransfer: + def __init__(self, *, items:typing.List[TokenTransfer], next_cursor:typing.Optional[str]): + self.items = items + self.next_cursor = next_cursor + + + + + def __str__(self): + return "PageTokenTransfer(items={}, next_cursor={})".format(self.items, self.next_cursor) + def __eq__(self, other): + if self.items != other.items: + return False + if self.next_cursor != other.next_cursor: + return False + return True + +class _UniffiFfiConverterTypePageTokenTransfer(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PageTokenTransfer( + items=_UniffiFfiConverterSequenceTypeTokenTransfer.read(buf), + next_cursor=_UniffiFfiConverterOptionalString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeTokenTransfer.check_lower(value.items) + _UniffiFfiConverterOptionalString.check_lower(value.next_cursor) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeTokenTransfer.write(value.items, buf) + _UniffiFfiConverterOptionalString.write(value.next_cursor, buf) + + + + + + +class CallType(enum.Enum): + + EXECUTE = 0 + + EXECUTE_FROM_OUTSIDE = 1 + + + +class _UniffiFfiConverterTypeCallType(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return CallType.EXECUTE + if variant == 2: + return CallType.EXECUTE_FROM_OUTSIDE + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value == CallType.EXECUTE: + return + if value == CallType.EXECUTE_FROM_OUTSIDE: + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value == CallType.EXECUTE: + buf.write_i32(1) + if value == CallType.EXECUTE_FROM_OUTSIDE: + buf.write_i32(2) + + + +@dataclass +class TransactionCall: + def __init__(self, *, contract_address:FieldElement, entrypoint:str, calldata:typing.List[FieldElement], call_type:CallType, caller_address:FieldElement): + self.contract_address = contract_address + self.entrypoint = entrypoint + self.calldata = calldata + self.call_type = call_type + self.caller_address = caller_address + + + + + def __str__(self): + return "TransactionCall(contract_address={}, entrypoint={}, calldata={}, call_type={}, caller_address={})".format(self.contract_address, self.entrypoint, self.calldata, self.call_type, self.caller_address) + def __eq__(self, other): + if self.contract_address != other.contract_address: + return False + if self.entrypoint != other.entrypoint: + return False + if self.calldata != other.calldata: + return False + if self.call_type != other.call_type: + return False + if self.caller_address != other.caller_address: + return False + return True + +class _UniffiFfiConverterTypeTransactionCall(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TransactionCall( + contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), + entrypoint=_UniffiFfiConverterString.read(buf), + calldata=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + call_type=_UniffiFfiConverterTypeCallType.read(buf), + caller_address=_UniffiFfiConverterTypeFieldElement.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) + _UniffiFfiConverterString.check_lower(value.entrypoint) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.calldata) + _UniffiFfiConverterTypeCallType.check_lower(value.call_type) + _UniffiFfiConverterTypeFieldElement.check_lower(value.caller_address) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) + _UniffiFfiConverterString.write(value.entrypoint, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.calldata, buf) + _UniffiFfiConverterTypeCallType.write(value.call_type, buf) + _UniffiFfiConverterTypeFieldElement.write(value.caller_address, buf) + +class _UniffiFfiConverterSequenceTypeTransactionCall(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeTransactionCall.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeTransactionCall.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeTransactionCall.read(buf) for i in range(count) + ] + +@dataclass +class Transaction: + def __init__(self, *, transaction_hash:FieldElement, sender_address:FieldElement, calldata:typing.List[FieldElement], max_fee:FieldElement, signature:typing.List[FieldElement], nonce:FieldElement, block_number:int, transaction_type:str, block_timestamp:int, calls:typing.List[TransactionCall], unique_models:typing.List[FieldElement]): + self.transaction_hash = transaction_hash + self.sender_address = sender_address + self.calldata = calldata + self.max_fee = max_fee + self.signature = signature + self.nonce = nonce + self.block_number = block_number + self.transaction_type = transaction_type + self.block_timestamp = block_timestamp + self.calls = calls + self.unique_models = unique_models + + + + + def __str__(self): + return "Transaction(transaction_hash={}, sender_address={}, calldata={}, max_fee={}, signature={}, nonce={}, block_number={}, transaction_type={}, block_timestamp={}, calls={}, unique_models={})".format(self.transaction_hash, self.sender_address, self.calldata, self.max_fee, self.signature, self.nonce, self.block_number, self.transaction_type, self.block_timestamp, self.calls, self.unique_models) + def __eq__(self, other): + if self.transaction_hash != other.transaction_hash: + return False + if self.sender_address != other.sender_address: + return False + if self.calldata != other.calldata: + return False + if self.max_fee != other.max_fee: + return False + if self.signature != other.signature: + return False + if self.nonce != other.nonce: + return False + if self.block_number != other.block_number: + return False + if self.transaction_type != other.transaction_type: + return False + if self.block_timestamp != other.block_timestamp: + return False + if self.calls != other.calls: + return False + if self.unique_models != other.unique_models: + return False + return True + +class _UniffiFfiConverterTypeTransaction(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Transaction( + transaction_hash=_UniffiFfiConverterTypeFieldElement.read(buf), + sender_address=_UniffiFfiConverterTypeFieldElement.read(buf), + calldata=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + max_fee=_UniffiFfiConverterTypeFieldElement.read(buf), + signature=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + nonce=_UniffiFfiConverterTypeFieldElement.read(buf), + block_number=_UniffiFfiConverterUInt64.read(buf), + transaction_type=_UniffiFfiConverterString.read(buf), + block_timestamp=_UniffiFfiConverterUInt64.read(buf), + calls=_UniffiFfiConverterSequenceTypeTransactionCall.read(buf), + unique_models=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeFieldElement.check_lower(value.transaction_hash) + _UniffiFfiConverterTypeFieldElement.check_lower(value.sender_address) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.calldata) + _UniffiFfiConverterTypeFieldElement.check_lower(value.max_fee) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.signature) + _UniffiFfiConverterTypeFieldElement.check_lower(value.nonce) + _UniffiFfiConverterUInt64.check_lower(value.block_number) + _UniffiFfiConverterString.check_lower(value.transaction_type) + _UniffiFfiConverterUInt64.check_lower(value.block_timestamp) + _UniffiFfiConverterSequenceTypeTransactionCall.check_lower(value.calls) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.unique_models) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeFieldElement.write(value.transaction_hash, buf) + _UniffiFfiConverterTypeFieldElement.write(value.sender_address, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.calldata, buf) + _UniffiFfiConverterTypeFieldElement.write(value.max_fee, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.signature, buf) + _UniffiFfiConverterTypeFieldElement.write(value.nonce, buf) + _UniffiFfiConverterUInt64.write(value.block_number, buf) + _UniffiFfiConverterString.write(value.transaction_type, buf) + _UniffiFfiConverterUInt64.write(value.block_timestamp, buf) + _UniffiFfiConverterSequenceTypeTransactionCall.write(value.calls, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.unique_models, buf) + +class _UniffiFfiConverterSequenceTypeTransaction(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeTransaction.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeTransaction.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeTransaction.read(buf) for i in range(count) + ] + +@dataclass +class PageTransaction: + def __init__(self, *, items:typing.List[Transaction], next_cursor:typing.Optional[str]): + self.items = items + self.next_cursor = next_cursor + + + + + def __str__(self): + return "PageTransaction(items={}, next_cursor={})".format(self.items, self.next_cursor) + def __eq__(self, other): + if self.items != other.items: + return False + if self.next_cursor != other.next_cursor: + return False + return True + +class _UniffiFfiConverterTypePageTransaction(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PageTransaction( + items=_UniffiFfiConverterSequenceTypeTransaction.read(buf), + next_cursor=_UniffiFfiConverterOptionalString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeTransaction.check_lower(value.items) + _UniffiFfiConverterOptionalString.check_lower(value.next_cursor) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeTransaction.write(value.items, buf) + _UniffiFfiConverterOptionalString.write(value.next_cursor, buf) + +@dataclass +class PlayerAchievementQuery: + def __init__(self, *, world_addresses:typing.List[FieldElement], namespaces:typing.List[str], player_addresses:typing.List[FieldElement], pagination:Pagination): + self.world_addresses = world_addresses + self.namespaces = namespaces + self.player_addresses = player_addresses + self.pagination = pagination + + + + + def __str__(self): + return "PlayerAchievementQuery(world_addresses={}, namespaces={}, player_addresses={}, pagination={})".format(self.world_addresses, self.namespaces, self.player_addresses, self.pagination) + def __eq__(self, other): + if self.world_addresses != other.world_addresses: + return False + if self.namespaces != other.namespaces: + return False + if self.player_addresses != other.player_addresses: + return False + if self.pagination != other.pagination: + return False + return True + +class _UniffiFfiConverterTypePlayerAchievementQuery(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return PlayerAchievementQuery( + world_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + namespaces=_UniffiFfiConverterSequenceString.read(buf), + player_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + pagination=_UniffiFfiConverterTypePagination.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.world_addresses) + _UniffiFfiConverterSequenceString.check_lower(value.namespaces) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.player_addresses) + _UniffiFfiConverterTypePagination.check_lower(value.pagination) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeFieldElement.write(value.world_addresses, buf) + _UniffiFfiConverterSequenceString.write(value.namespaces, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.player_addresses, buf) + _UniffiFfiConverterTypePagination.write(value.pagination, buf) + +class _UniffiFfiConverterOptionalTypeClause(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiFfiConverterTypeClause.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiFfiConverterTypeClause.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiFfiConverterTypeClause.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + +@dataclass +class Query: + def __init__(self, *, world_addresses:typing.List[FieldElement], pagination:Pagination, clause:typing.Optional[Clause], no_hashed_keys:bool, models:typing.List[str], historical:bool): + self.world_addresses = world_addresses + self.pagination = pagination + self.clause = clause + self.no_hashed_keys = no_hashed_keys + self.models = models + self.historical = historical + + + + + def __str__(self): + return "Query(world_addresses={}, pagination={}, clause={}, no_hashed_keys={}, models={}, historical={})".format(self.world_addresses, self.pagination, self.clause, self.no_hashed_keys, self.models, self.historical) + def __eq__(self, other): + if self.world_addresses != other.world_addresses: + return False + if self.pagination != other.pagination: + return False + if self.clause != other.clause: + return False + if self.no_hashed_keys != other.no_hashed_keys: + return False + if self.models != other.models: + return False + if self.historical != other.historical: + return False + return True + +class _UniffiFfiConverterTypeQuery(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Query( + world_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + pagination=_UniffiFfiConverterTypePagination.read(buf), + clause=_UniffiFfiConverterOptionalTypeClause.read(buf), + no_hashed_keys=_UniffiFfiConverterBoolean.read(buf), + models=_UniffiFfiConverterSequenceString.read(buf), + historical=_UniffiFfiConverterBoolean.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.world_addresses) + _UniffiFfiConverterTypePagination.check_lower(value.pagination) + _UniffiFfiConverterOptionalTypeClause.check_lower(value.clause) + _UniffiFfiConverterBoolean.check_lower(value.no_hashed_keys) + _UniffiFfiConverterSequenceString.check_lower(value.models) + _UniffiFfiConverterBoolean.check_lower(value.historical) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeFieldElement.write(value.world_addresses, buf) + _UniffiFfiConverterTypePagination.write(value.pagination, buf) + _UniffiFfiConverterOptionalTypeClause.write(value.clause, buf) + _UniffiFfiConverterBoolean.write(value.no_hashed_keys, buf) + _UniffiFfiConverterSequenceString.write(value.models, buf) + _UniffiFfiConverterBoolean.write(value.historical, buf) + +@dataclass +class Signature: + def __init__(self, *, r:FieldElement, s:FieldElement): + self.r = r + self.s = s + + + + + def __str__(self): + return "Signature(r={}, s={})".format(self.r, self.s) + def __eq__(self, other): + if self.r != other.r: + return False + if self.s != other.s: + return False + return True + +class _UniffiFfiConverterTypeSignature(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return Signature( + r=_UniffiFfiConverterTypeFieldElement.read(buf), + s=_UniffiFfiConverterTypeFieldElement.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeFieldElement.check_lower(value.r) + _UniffiFfiConverterTypeFieldElement.check_lower(value.s) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeFieldElement.write(value.r, buf) + _UniffiFfiConverterTypeFieldElement.write(value.s, buf) + + + + + + +class SqlValue: + def __init__(self): + raise RuntimeError("SqlValue cannot be instantiated directly") + + # Each enum variant is a nested class of the enum itself. + @dataclass + class TEXT: + + def __init__(self, value:str): + self.value = value + + + pass + + + + + + def __str__(self): + return "SqlValue.TEXT(value={})".format(self.value) + def __eq__(self, other): + if not other.is_TEXT(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class INTEGER: + + def __init__(self, value:int): + self.value = value + + + pass + + + + + + def __str__(self): + return "SqlValue.INTEGER(value={})".format(self.value) + def __eq__(self, other): + if not other.is_INTEGER(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class REAL: + + def __init__(self, value:float): + self.value = value + + + pass + + + + + + def __str__(self): + return "SqlValue.REAL(value={})".format(self.value) + def __eq__(self, other): + if not other.is_REAL(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class BLOB: + + def __init__(self, value:typing.List[int]): + self.value = value + + + pass + + + + + + def __str__(self): + return "SqlValue.BLOB(value={})".format(self.value) + def __eq__(self, other): + if not other.is_BLOB(): + return False + if self.value != other.value: + return False + return True + + @dataclass + class NULL: + + def __init__(self, ): + pass + + + + + + def __str__(self): + return "SqlValue.NULL()".format() + def __eq__(self, other): + if not other.is_NULL(): + return False + return True + + + + # For each variant, we have `is_NAME` and `is_name` methods for easily checking + # whether an instance is that variant. + def is_TEXT(self) -> bool: + return isinstance(self, SqlValue.TEXT) + def is_text(self) -> bool: + return isinstance(self, SqlValue.TEXT) + def is_INTEGER(self) -> bool: + return isinstance(self, SqlValue.INTEGER) + def is_integer(self) -> bool: + return isinstance(self, SqlValue.INTEGER) + def is_REAL(self) -> bool: + return isinstance(self, SqlValue.REAL) + def is_real(self) -> bool: + return isinstance(self, SqlValue.REAL) + def is_BLOB(self) -> bool: + return isinstance(self, SqlValue.BLOB) + def is_blob(self) -> bool: + return isinstance(self, SqlValue.BLOB) + def is_NULL(self) -> bool: + return isinstance(self, SqlValue.NULL) + def is_null(self) -> bool: + return isinstance(self, SqlValue.NULL) + + +# Now, a little trick - we make each nested variant class be a subclass of the main +# enum class, so that method calls and instance checks etc will work intuitively. +# We might be able to do this a little more neatly with a metaclass, but this'll do. +SqlValue.TEXT = type("SqlValue.TEXT", (SqlValue.TEXT, SqlValue,), {}) # type: ignore +SqlValue.INTEGER = type("SqlValue.INTEGER", (SqlValue.INTEGER, SqlValue,), {}) # type: ignore +SqlValue.REAL = type("SqlValue.REAL", (SqlValue.REAL, SqlValue,), {}) # type: ignore +SqlValue.BLOB = type("SqlValue.BLOB", (SqlValue.BLOB, SqlValue,), {}) # type: ignore +SqlValue.NULL = type("SqlValue.NULL", (SqlValue.NULL, SqlValue,), {}) # type: ignore + + + + +class _UniffiFfiConverterTypeSqlValue(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + variant = buf.read_i32() + if variant == 1: + return SqlValue.TEXT( + _UniffiFfiConverterString.read(buf), + ) + if variant == 2: + return SqlValue.INTEGER( + _UniffiFfiConverterInt64.read(buf), + ) + if variant == 3: + return SqlValue.REAL( + _UniffiFfiConverterFloat64.read(buf), + ) + if variant == 4: + return SqlValue.BLOB( + _UniffiFfiConverterSequenceUInt8.read(buf), + ) + if variant == 5: + return SqlValue.NULL( + ) + raise InternalError("Raw enum value doesn't match any cases") + + @staticmethod + def check_lower(value): + if value.is_TEXT(): + _UniffiFfiConverterString.check_lower(value.value) + return + if value.is_INTEGER(): + _UniffiFfiConverterInt64.check_lower(value.value) + return + if value.is_REAL(): + _UniffiFfiConverterFloat64.check_lower(value.value) + return + if value.is_BLOB(): + _UniffiFfiConverterSequenceUInt8.check_lower(value.value) + return + if value.is_NULL(): + return + raise ValueError(value) + + @staticmethod + def write(value, buf): + if value.is_TEXT(): + buf.write_i32(1) + _UniffiFfiConverterString.write(value.value, buf) + if value.is_INTEGER(): + buf.write_i32(2) + _UniffiFfiConverterInt64.write(value.value, buf) + if value.is_REAL(): + buf.write_i32(3) + _UniffiFfiConverterFloat64.write(value.value, buf) + if value.is_BLOB(): + buf.write_i32(4) + _UniffiFfiConverterSequenceUInt8.write(value.value, buf) + if value.is_NULL(): + buf.write_i32(5) + + + +@dataclass +class SqlField: + def __init__(self, *, name:str, value:SqlValue): + self.name = name + self.value = value + + + + + def __str__(self): + return "SqlField(name={}, value={})".format(self.name, self.value) + def __eq__(self, other): + if self.name != other.name: + return False + if self.value != other.value: + return False + return True + +class _UniffiFfiConverterTypeSqlField(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return SqlField( + name=_UniffiFfiConverterString.read(buf), + value=_UniffiFfiConverterTypeSqlValue.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.name) + _UniffiFfiConverterTypeSqlValue.check_lower(value.value) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.name, buf) + _UniffiFfiConverterTypeSqlValue.write(value.value, buf) + +class _UniffiFfiConverterSequenceTypeSqlField(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeSqlField.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeSqlField.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeSqlField.read(buf) for i in range(count) + ] + +@dataclass +class SqlRow: + def __init__(self, *, fields:typing.List[SqlField]): + self.fields = fields + + + + + def __str__(self): + return "SqlRow(fields={})".format(self.fields) + def __eq__(self, other): + if self.fields != other.fields: + return False + return True + +class _UniffiFfiConverterTypeSqlRow(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return SqlRow( + fields=_UniffiFfiConverterSequenceTypeSqlField.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeSqlField.check_lower(value.fields) @staticmethod def write(value, buf): - _UniffiFfiConverterString.write(value.id, buf) - _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) - _UniffiFfiConverterTypeFieldElement.write(value.from_address, buf) - _UniffiFfiConverterTypeFieldElement.write(value.to_address, buf) - _UniffiFfiConverterTypeU256.write(value.amount, buf) - _UniffiFfiConverterOptionalTypeU256.write(value.token_id, buf) - _UniffiFfiConverterUInt64.write(value.executed_at, buf) - _UniffiFfiConverterOptionalString.write(value.event_id, buf) + _UniffiFfiConverterSequenceTypeSqlField.write(value.fields, buf) + +class _UniffiFfiConverterSequenceTypeU256(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeU256.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeU256.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeU256.read(buf) for i in range(count) + ] @dataclass -class TokenTransferQuery: +class TokenBalanceQuery: def __init__(self, *, contract_addresses:typing.List[FieldElement], account_addresses:typing.List[FieldElement], token_ids:typing.List[U256], pagination:Pagination): self.contract_addresses = contract_addresses self.account_addresses = account_addresses @@ -5085,7 +6817,7 @@ def __init__(self, *, contract_addresses:typing.List[FieldElement], account_addr def __str__(self): - return "TokenTransferQuery(contract_addresses={}, account_addresses={}, token_ids={}, pagination={})".format(self.contract_addresses, self.account_addresses, self.token_ids, self.pagination) + return "TokenBalanceQuery(contract_addresses={}, account_addresses={}, token_ids={}, pagination={})".format(self.contract_addresses, self.account_addresses, self.token_ids, self.pagination) def __eq__(self, other): if self.contract_addresses != other.contract_addresses: return False @@ -5097,10 +6829,10 @@ def __eq__(self, other): return False return True -class _UniffiFfiConverterTypeTokenTransferQuery(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypeTokenBalanceQuery(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return TokenTransferQuery( + return TokenBalanceQuery( contract_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), account_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), token_ids=_UniffiFfiConverterSequenceTypeU256.read(buf), @@ -5121,112 +6853,60 @@ def write(value, buf): _UniffiFfiConverterSequenceTypeU256.write(value.token_ids, buf) _UniffiFfiConverterTypePagination.write(value.pagination, buf) - - - - - -class CallType(enum.Enum): - - EXECUTE = 0 - - EXECUTE_FROM_OUTSIDE = 1 - - - -class _UniffiFfiConverterTypeCallType(_UniffiConverterRustBuffer): - @staticmethod - def read(buf): - variant = buf.read_i32() - if variant == 1: - return CallType.EXECUTE - if variant == 2: - return CallType.EXECUTE_FROM_OUTSIDE - raise InternalError("Raw enum value doesn't match any cases") - - @staticmethod - def check_lower(value): - if value == CallType.EXECUTE: - return - if value == CallType.EXECUTE_FROM_OUTSIDE: - return - raise ValueError(value) - - @staticmethod - def write(value, buf): - if value == CallType.EXECUTE: - buf.write_i32(1) - if value == CallType.EXECUTE_FROM_OUTSIDE: - buf.write_i32(2) - - - @dataclass -class TransactionCall: - def __init__(self, *, contract_address:FieldElement, entrypoint:str, calldata:typing.List[FieldElement], call_type:CallType, caller_address:FieldElement): - self.contract_address = contract_address - self.entrypoint = entrypoint - self.calldata = calldata - self.call_type = call_type - self.caller_address = caller_address +class TokenContractQuery: + def __init__(self, *, contract_addresses:typing.List[FieldElement], contract_types:typing.List[ContractType], pagination:Pagination): + self.contract_addresses = contract_addresses + self.contract_types = contract_types + self.pagination = pagination def __str__(self): - return "TransactionCall(contract_address={}, entrypoint={}, calldata={}, call_type={}, caller_address={})".format(self.contract_address, self.entrypoint, self.calldata, self.call_type, self.caller_address) + return "TokenContractQuery(contract_addresses={}, contract_types={}, pagination={})".format(self.contract_addresses, self.contract_types, self.pagination) def __eq__(self, other): - if self.contract_address != other.contract_address: - return False - if self.entrypoint != other.entrypoint: - return False - if self.calldata != other.calldata: + if self.contract_addresses != other.contract_addresses: return False - if self.call_type != other.call_type: + if self.contract_types != other.contract_types: return False - if self.caller_address != other.caller_address: + if self.pagination != other.pagination: return False return True -class _UniffiFfiConverterTypeTransactionCall(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypeTokenContractQuery(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return TransactionCall( - contract_address=_UniffiFfiConverterTypeFieldElement.read(buf), - entrypoint=_UniffiFfiConverterString.read(buf), - calldata=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), - call_type=_UniffiFfiConverterTypeCallType.read(buf), - caller_address=_UniffiFfiConverterTypeFieldElement.read(buf), + return TokenContractQuery( + contract_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + contract_types=_UniffiFfiConverterSequenceTypeContractType.read(buf), + pagination=_UniffiFfiConverterTypePagination.read(buf), ) @staticmethod def check_lower(value): - _UniffiFfiConverterTypeFieldElement.check_lower(value.contract_address) - _UniffiFfiConverterString.check_lower(value.entrypoint) - _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.calldata) - _UniffiFfiConverterTypeCallType.check_lower(value.call_type) - _UniffiFfiConverterTypeFieldElement.check_lower(value.caller_address) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.contract_addresses) + _UniffiFfiConverterSequenceTypeContractType.check_lower(value.contract_types) + _UniffiFfiConverterTypePagination.check_lower(value.pagination) @staticmethod def write(value, buf): - _UniffiFfiConverterTypeFieldElement.write(value.contract_address, buf) - _UniffiFfiConverterString.write(value.entrypoint, buf) - _UniffiFfiConverterSequenceTypeFieldElement.write(value.calldata, buf) - _UniffiFfiConverterTypeCallType.write(value.call_type, buf) - _UniffiFfiConverterTypeFieldElement.write(value.caller_address, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.contract_addresses, buf) + _UniffiFfiConverterSequenceTypeContractType.write(value.contract_types, buf) + _UniffiFfiConverterTypePagination.write(value.pagination, buf) -class _UniffiFfiConverterSequenceTypeTransactionCall(_UniffiConverterRustBuffer): +class _UniffiFfiConverterSequenceTypeAttributeFilter(_UniffiConverterRustBuffer): @classmethod def check_lower(cls, value): for item in value: - _UniffiFfiConverterTypeTransactionCall.check_lower(item) + _UniffiFfiConverterTypeAttributeFilter.check_lower(item) @classmethod def write(cls, value, buf): items = len(value) buf.write_i32(items) for item in value: - _UniffiFfiConverterTypeTransactionCall.write(item, buf) + _UniffiFfiConverterTypeAttributeFilter.write(item, buf) @classmethod def read(cls, buf): @@ -5235,98 +6915,104 @@ def read(cls, buf): raise InternalError("Unexpected negative sequence length") return [ - _UniffiFfiConverterTypeTransactionCall.read(buf) for i in range(count) + _UniffiFfiConverterTypeAttributeFilter.read(buf) for i in range(count) ] @dataclass -class Transaction: - def __init__(self, *, transaction_hash:FieldElement, sender_address:FieldElement, calldata:typing.List[FieldElement], max_fee:FieldElement, signature:typing.List[FieldElement], nonce:FieldElement, block_number:int, transaction_type:str, block_timestamp:int, calls:typing.List[TransactionCall], unique_models:typing.List[FieldElement]): - self.transaction_hash = transaction_hash - self.sender_address = sender_address - self.calldata = calldata - self.max_fee = max_fee - self.signature = signature - self.nonce = nonce - self.block_number = block_number - self.transaction_type = transaction_type - self.block_timestamp = block_timestamp - self.calls = calls - self.unique_models = unique_models +class TokenQuery: + def __init__(self, *, contract_addresses:typing.List[FieldElement], token_ids:typing.List[U256], attribute_filters:typing.List[AttributeFilter], pagination:Pagination): + self.contract_addresses = contract_addresses + self.token_ids = token_ids + self.attribute_filters = attribute_filters + self.pagination = pagination def __str__(self): - return "Transaction(transaction_hash={}, sender_address={}, calldata={}, max_fee={}, signature={}, nonce={}, block_number={}, transaction_type={}, block_timestamp={}, calls={}, unique_models={})".format(self.transaction_hash, self.sender_address, self.calldata, self.max_fee, self.signature, self.nonce, self.block_number, self.transaction_type, self.block_timestamp, self.calls, self.unique_models) + return "TokenQuery(contract_addresses={}, token_ids={}, attribute_filters={}, pagination={})".format(self.contract_addresses, self.token_ids, self.attribute_filters, self.pagination) def __eq__(self, other): - if self.transaction_hash != other.transaction_hash: - return False - if self.sender_address != other.sender_address: - return False - if self.calldata != other.calldata: - return False - if self.max_fee != other.max_fee: + if self.contract_addresses != other.contract_addresses: return False - if self.signature != other.signature: + if self.token_ids != other.token_ids: return False - if self.nonce != other.nonce: + if self.attribute_filters != other.attribute_filters: return False - if self.block_number != other.block_number: + if self.pagination != other.pagination: return False - if self.transaction_type != other.transaction_type: + return True + +class _UniffiFfiConverterTypeTokenQuery(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TokenQuery( + contract_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + token_ids=_UniffiFfiConverterSequenceTypeU256.read(buf), + attribute_filters=_UniffiFfiConverterSequenceTypeAttributeFilter.read(buf), + pagination=_UniffiFfiConverterTypePagination.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.contract_addresses) + _UniffiFfiConverterSequenceTypeU256.check_lower(value.token_ids) + _UniffiFfiConverterSequenceTypeAttributeFilter.check_lower(value.attribute_filters) + _UniffiFfiConverterTypePagination.check_lower(value.pagination) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterSequenceTypeFieldElement.write(value.contract_addresses, buf) + _UniffiFfiConverterSequenceTypeU256.write(value.token_ids, buf) + _UniffiFfiConverterSequenceTypeAttributeFilter.write(value.attribute_filters, buf) + _UniffiFfiConverterTypePagination.write(value.pagination, buf) + +@dataclass +class TokenTransferQuery: + def __init__(self, *, contract_addresses:typing.List[FieldElement], account_addresses:typing.List[FieldElement], token_ids:typing.List[U256], pagination:Pagination): + self.contract_addresses = contract_addresses + self.account_addresses = account_addresses + self.token_ids = token_ids + self.pagination = pagination + + + + + def __str__(self): + return "TokenTransferQuery(contract_addresses={}, account_addresses={}, token_ids={}, pagination={})".format(self.contract_addresses, self.account_addresses, self.token_ids, self.pagination) + def __eq__(self, other): + if self.contract_addresses != other.contract_addresses: return False - if self.block_timestamp != other.block_timestamp: + if self.account_addresses != other.account_addresses: return False - if self.calls != other.calls: + if self.token_ids != other.token_ids: return False - if self.unique_models != other.unique_models: + if self.pagination != other.pagination: return False return True -class _UniffiFfiConverterTypeTransaction(_UniffiConverterRustBuffer): +class _UniffiFfiConverterTypeTokenTransferQuery(_UniffiConverterRustBuffer): @staticmethod def read(buf): - return Transaction( - transaction_hash=_UniffiFfiConverterTypeFieldElement.read(buf), - sender_address=_UniffiFfiConverterTypeFieldElement.read(buf), - calldata=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), - max_fee=_UniffiFfiConverterTypeFieldElement.read(buf), - signature=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), - nonce=_UniffiFfiConverterTypeFieldElement.read(buf), - block_number=_UniffiFfiConverterUInt64.read(buf), - transaction_type=_UniffiFfiConverterString.read(buf), - block_timestamp=_UniffiFfiConverterUInt64.read(buf), - calls=_UniffiFfiConverterSequenceTypeTransactionCall.read(buf), - unique_models=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + return TokenTransferQuery( + contract_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + account_addresses=_UniffiFfiConverterSequenceTypeFieldElement.read(buf), + token_ids=_UniffiFfiConverterSequenceTypeU256.read(buf), + pagination=_UniffiFfiConverterTypePagination.read(buf), ) @staticmethod def check_lower(value): - _UniffiFfiConverterTypeFieldElement.check_lower(value.transaction_hash) - _UniffiFfiConverterTypeFieldElement.check_lower(value.sender_address) - _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.calldata) - _UniffiFfiConverterTypeFieldElement.check_lower(value.max_fee) - _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.signature) - _UniffiFfiConverterTypeFieldElement.check_lower(value.nonce) - _UniffiFfiConverterUInt64.check_lower(value.block_number) - _UniffiFfiConverterString.check_lower(value.transaction_type) - _UniffiFfiConverterUInt64.check_lower(value.block_timestamp) - _UniffiFfiConverterSequenceTypeTransactionCall.check_lower(value.calls) - _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.unique_models) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.contract_addresses) + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(value.account_addresses) + _UniffiFfiConverterSequenceTypeU256.check_lower(value.token_ids) + _UniffiFfiConverterTypePagination.check_lower(value.pagination) @staticmethod def write(value, buf): - _UniffiFfiConverterTypeFieldElement.write(value.transaction_hash, buf) - _UniffiFfiConverterTypeFieldElement.write(value.sender_address, buf) - _UniffiFfiConverterSequenceTypeFieldElement.write(value.calldata, buf) - _UniffiFfiConverterTypeFieldElement.write(value.max_fee, buf) - _UniffiFfiConverterSequenceTypeFieldElement.write(value.signature, buf) - _UniffiFfiConverterTypeFieldElement.write(value.nonce, buf) - _UniffiFfiConverterUInt64.write(value.block_number, buf) - _UniffiFfiConverterString.write(value.transaction_type, buf) - _UniffiFfiConverterUInt64.write(value.block_timestamp, buf) - _UniffiFfiConverterSequenceTypeTransactionCall.write(value.calls, buf) - _UniffiFfiConverterSequenceTypeFieldElement.write(value.unique_models, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.contract_addresses, buf) + _UniffiFfiConverterSequenceTypeFieldElement.write(value.account_addresses, buf) + _UniffiFfiConverterSequenceTypeU256.write(value.token_ids, buf) + _UniffiFfiConverterTypePagination.write(value.pagination, buf) @dataclass class TransactionFilter: @@ -5455,6 +7141,65 @@ def write(value, buf): _UniffiFfiConverterOptionalTypeTransactionFilter.write(value.filter, buf) _UniffiFfiConverterTypePagination.write(value.pagination, buf) +class _UniffiFfiConverterSequenceTypeModel(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeModel.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeModel.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeModel.read(buf) for i in range(count) + ] + +@dataclass +class World: + def __init__(self, *, world_address:FieldElement, models:typing.List[Model]): + self.world_address = world_address + self.models = models + + + + + def __str__(self): + return "World(world_address={}, models={})".format(self.world_address, self.models) + def __eq__(self, other): + if self.world_address != other.world_address: + return False + if self.models != other.models: + return False + return True + +class _UniffiFfiConverterTypeWorld(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return World( + world_address=_UniffiFfiConverterTypeFieldElement.read(buf), + models=_UniffiFfiConverterSequenceTypeModel.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterTypeFieldElement.check_lower(value.world_address) + _UniffiFfiConverterSequenceTypeModel.check_lower(value.models) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterTypeFieldElement.write(value.world_address, buf) + _UniffiFfiConverterSequenceTypeModel.write(value.models, buf) + # DojoError @@ -5486,6 +7231,18 @@ class InvalidInput(_UniffiTempDojoError): def __repr__(self): return "DojoError.InvalidInput({})".format(repr(str(self))) _UniffiTempDojoError.InvalidInput = InvalidInput # type: ignore + class ConnectionError(_UniffiTempDojoError): + def __repr__(self): + return "DojoError.ConnectionError({})".format(repr(str(self))) + _UniffiTempDojoError.ConnectionError = ConnectionError # type: ignore + class PublishError(_UniffiTempDojoError): + def __repr__(self): + return "DojoError.PublishError({})".format(repr(str(self))) + _UniffiTempDojoError.PublishError = PublishError # type: ignore + class QueryError(_UniffiTempDojoError): + def __repr__(self): + return "DojoError.QueryError({})".format(repr(str(self))) + _UniffiTempDojoError.QueryError = QueryError # type: ignore DojoError = _UniffiTempDojoError # type: ignore del _UniffiTempDojoError @@ -5511,6 +7268,18 @@ def read(buf): return DojoError.InvalidInput( _UniffiFfiConverterString.read(buf), ) + if variant == 5: + return DojoError.ConnectionError( + _UniffiFfiConverterString.read(buf), + ) + if variant == 6: + return DojoError.PublishError( + _UniffiFfiConverterString.read(buf), + ) + if variant == 7: + return DojoError.QueryError( + _UniffiFfiConverterString.read(buf), + ) raise InternalError("Raw enum value doesn't match any cases") @staticmethod @@ -5523,6 +7292,12 @@ def check_lower(value): return if isinstance(value, DojoError.InvalidInput): return + if isinstance(value, DojoError.ConnectionError): + return + if isinstance(value, DojoError.PublishError): + return + if isinstance(value, DojoError.QueryError): + return @staticmethod def write(value, buf): @@ -5534,6 +7309,12 @@ def write(value, buf): buf.write_i32(3) if isinstance(value, DojoError.InvalidInput): buf.write_i32(4) + if isinstance(value, DojoError.ConnectionError): + buf.write_i32(5) + if isinstance(value, DojoError.PublishError): + buf.write_i32(6) + if isinstance(value, DojoError.QueryError): + buf.write_i32(7) @@ -5758,6 +7539,517 @@ def write(value, buf): +class _UniffiFfiConverterSequenceTypeContract(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeContract.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeContract.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeContract.read(buf) for i in range(count) + ] + +class _UniffiFfiConverterSequenceTypeMessage(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeMessage.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeMessage.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeMessage.read(buf) for i in range(count) + ] + +class _UniffiFfiConverterSequenceTypeSqlRow(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeSqlRow.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeSqlRow.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeSqlRow.read(buf) for i in range(count) + ] + +class _UniffiFfiConverterSequenceTypeWorld(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeWorld.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeWorld.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeWorld.read(buf) for i in range(count) + ] + + +class ToriiClientProtocol(typing.Protocol): + + async def achievements(self, query: AchievementQuery) -> PageAchievement: + raise NotImplementedError + async def activities(self, query: ActivityQuery) -> PageActivity: + raise NotImplementedError + async def aggregations(self, query: AggregationQuery) -> PageAggregationEntry: + raise NotImplementedError + async def contracts(self, query: ContractQuery) -> typing.List[Contract]: + raise NotImplementedError + async def controllers(self, query: ControllerQuery) -> PageController: + raise NotImplementedError + async def entities(self, query: Query) -> PageEntity: + raise NotImplementedError + async def event_messages(self, query: Query) -> PageEntity: + raise NotImplementedError + async def player_achievements(self, query: PlayerAchievementQuery) -> PagePlayerAchievement: + raise NotImplementedError + async def publish_message(self, message: Message) -> str: + raise NotImplementedError + async def publish_message_batch(self, messages: typing.List[Message]) -> typing.List[str]: + raise NotImplementedError + async def sql(self, query: str) -> typing.List[SqlRow]: + raise NotImplementedError + async def starknet_events(self, query: EventQuery) -> PageEvent: + raise NotImplementedError + async def token_balances(self, query: TokenBalanceQuery) -> PageTokenBalance: + raise NotImplementedError + async def token_contracts(self, query: TokenContractQuery) -> PageTokenContract: + raise NotImplementedError + async def token_transfers(self, query: TokenTransferQuery) -> PageTokenTransfer: + raise NotImplementedError + async def tokens(self, query: TokenQuery) -> PageToken: + raise NotImplementedError + async def transactions(self, query: TransactionQuery) -> PageTransaction: + raise NotImplementedError + async def worlds(self, world_addresses: typing.List[FieldElement]) -> typing.List[World]: + raise NotImplementedError + +class ToriiClient(ToriiClientProtocol): + + _handle: ctypes.c_uint64 + def __init__(self, *args, **kw): + raise ValueError("async constructors not supported.") + @classmethod + async def new_with_config(cls, torii_url: str,max_message_size: int) -> ToriiClient: + + _UniffiFfiConverterString.check_lower(torii_url) + + _UniffiFfiConverterUInt64.check_lower(max_message_size) + _uniffi_lowered_args = ( + _UniffiFfiConverterString.lower(torii_url), + _UniffiFfiConverterUInt64.lower(max_message_size), + ) + _uniffi_lift_return = _UniffiFfiConverterTypeToriiClient.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_constructor_toriiclient_new_with_config(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_u64, + _UniffiLib.ffi_dojo_c_rust_future_complete_u64, + _UniffiLib.ffi_dojo_c_rust_future_free_u64, + _uniffi_lift_return, + _uniffi_error_converter, + ) + + def __del__(self): + # In case of partial initialization of instances. + handle = getattr(self, "_handle", None) + if handle is not None: + _uniffi_rust_call(_UniffiLib.uniffi_dojo_c_fn_free_toriiclient, handle) + + def _uniffi_clone_handle(self): + return _uniffi_rust_call(_UniffiLib.uniffi_dojo_c_fn_clone_toriiclient, self._handle) + + # Used by alternative constructors or any methods which return this type. + @classmethod + def _uniffi_make_instance(cls, handle): + # Lightly yucky way to bypass the usual __init__ logic + # and just create a new instance with the required handle. + inst = cls.__new__(cls) + inst._handle = handle + return inst + async def achievements(self, query: AchievementQuery) -> PageAchievement: + + _UniffiFfiConverterTypeAchievementQuery.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypeAchievementQuery.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterTypePageAchievement.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_achievements(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def activities(self, query: ActivityQuery) -> PageActivity: + + _UniffiFfiConverterTypeActivityQuery.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypeActivityQuery.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterTypePageActivity.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_activities(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def aggregations(self, query: AggregationQuery) -> PageAggregationEntry: + + _UniffiFfiConverterTypeAggregationQuery.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypeAggregationQuery.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterTypePageAggregationEntry.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_aggregations(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def contracts(self, query: ContractQuery) -> typing.List[Contract]: + + _UniffiFfiConverterTypeContractQuery.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypeContractQuery.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterSequenceTypeContract.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_contracts(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def controllers(self, query: ControllerQuery) -> PageController: + + _UniffiFfiConverterTypeControllerQuery.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypeControllerQuery.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterTypePageController.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_controllers(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def entities(self, query: Query) -> PageEntity: + + _UniffiFfiConverterTypeQuery.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypeQuery.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterTypePageEntity.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_entities(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def event_messages(self, query: Query) -> PageEntity: + + _UniffiFfiConverterTypeQuery.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypeQuery.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterTypePageEntity.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_event_messages(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def player_achievements(self, query: PlayerAchievementQuery) -> PagePlayerAchievement: + + _UniffiFfiConverterTypePlayerAchievementQuery.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypePlayerAchievementQuery.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterTypePagePlayerAchievement.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_player_achievements(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def publish_message(self, message: Message) -> str: + + _UniffiFfiConverterTypeMessage.check_lower(message) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypeMessage.lower(message), + ) + _uniffi_lift_return = _UniffiFfiConverterString.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_publish_message(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def publish_message_batch(self, messages: typing.List[Message]) -> typing.List[str]: + + _UniffiFfiConverterSequenceTypeMessage.check_lower(messages) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterSequenceTypeMessage.lower(messages), + ) + _uniffi_lift_return = _UniffiFfiConverterSequenceString.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_publish_message_batch(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def sql(self, query: str) -> typing.List[SqlRow]: + + _UniffiFfiConverterString.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterString.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterSequenceTypeSqlRow.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_sql(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def starknet_events(self, query: EventQuery) -> PageEvent: + + _UniffiFfiConverterTypeEventQuery.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypeEventQuery.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterTypePageEvent.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_starknet_events(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def token_balances(self, query: TokenBalanceQuery) -> PageTokenBalance: + + _UniffiFfiConverterTypeTokenBalanceQuery.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypeTokenBalanceQuery.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterTypePageTokenBalance.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_token_balances(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def token_contracts(self, query: TokenContractQuery) -> PageTokenContract: + + _UniffiFfiConverterTypeTokenContractQuery.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypeTokenContractQuery.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterTypePageTokenContract.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_token_contracts(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def token_transfers(self, query: TokenTransferQuery) -> PageTokenTransfer: + + _UniffiFfiConverterTypeTokenTransferQuery.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypeTokenTransferQuery.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterTypePageTokenTransfer.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_token_transfers(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def tokens(self, query: TokenQuery) -> PageToken: + + _UniffiFfiConverterTypeTokenQuery.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypeTokenQuery.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterTypePageToken.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_tokens(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def transactions(self, query: TransactionQuery) -> PageTransaction: + + _UniffiFfiConverterTypeTransactionQuery.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypeTransactionQuery.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterTypePageTransaction.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_transactions(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def worlds(self, world_addresses: typing.List[FieldElement]) -> typing.List[World]: + + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(world_addresses) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterSequenceTypeFieldElement.lower(world_addresses), + ) + _uniffi_lift_return = _UniffiFfiConverterSequenceTypeWorld.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_worlds(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_complete_rust_buffer, + _UniffiLib.ffi_dojo_c_rust_future_free_rust_buffer, + _uniffi_lift_return, + _uniffi_error_converter, + ) + + + + + +class _UniffiFfiConverterTypeToriiClient: + @staticmethod + def lift(value: int) -> ToriiClient: + return ToriiClient._uniffi_make_instance(value) + + @staticmethod + def check_lower(value: ToriiClient): + if not isinstance(value, ToriiClient): + raise TypeError("Expected ToriiClient instance, {} found".format(type(value).__name__)) + + @staticmethod + def lower(value: ToriiClient) -> ctypes.c_uint64: + return value._uniffi_clone_handle() + + @classmethod + def read(cls, buf: _UniffiRustBuffer) -> ToriiClient: + ptr = buf.read_u64() + if ptr == 0: + raise InternalError("Raw handle value was null") + return cls.lift(ptr) + + @classmethod + def write(cls, value: ToriiClient, buf: _UniffiRustBuffer): + buf.write_u64(cls.lower(value)) + __all__ = [ "InternalError", "PaginationDirection", @@ -5771,6 +8063,7 @@ def write(value, buf): "ContractType", "Ty", "CallType", + "SqlValue", "DojoError", "ValueType", "AchievementTask", @@ -5792,27 +8085,50 @@ def write(value, buf): "ContractQuery", "Controller", "ControllerQuery", - "Member", - "Struct", + "EnumOption", "EnumType", "FixedSizeArray", - "EnumOption", + "Member", + "Struct", + "Entity", + "Event", + "EventQuery", + "Message", + "Model", + "PageAchievement", + "PageActivity", + "PageAggregationEntry", + "PageController", + "PageEntity", + "PageEvent", "PlayerAchievementStats", "TaskProgress", "PlayerAchievementProgress", "PlayerAchievementEntry", - "PlayerAchievementQuery", - "Signature", + "PagePlayerAchievement", "Token", + "PageToken", "TokenBalance", - "TokenBalanceQuery", + "PageTokenBalance", "TokenContract", - "TokenContractQuery", - "TokenQuery", + "PageTokenContract", "TokenTransfer", - "TokenTransferQuery", + "PageTokenTransfer", "TransactionCall", "Transaction", + "PageTransaction", + "PlayerAchievementQuery", + "Query", + "Signature", + "SqlField", + "SqlRow", + "TokenBalanceQuery", + "TokenContractQuery", + "TokenQuery", + "TokenTransferQuery", "TransactionFilter", "TransactionQuery", + "World", + "ToriiClient", + "ToriiClientProtocol", ] \ No newline at end of file diff --git a/bindings/swift/DojoEngine.swift b/bindings/swift/DojoEngine.swift index d6b9a57..4d69bf6 100644 --- a/bindings/swift/DojoEngine.swift +++ b/bindings/swift/DojoEngine.swift @@ -626,6 +626,480 @@ fileprivate struct FfiConverterString: FfiConverter { } + + +public protocol ToriiClientProtocol: AnyObject, Sendable { + + func achievements(query: AchievementQuery) async throws -> PageAchievement + + func activities(query: ActivityQuery) async throws -> PageActivity + + func aggregations(query: AggregationQuery) async throws -> PageAggregationEntry + + func contracts(query: ContractQuery) async throws -> [Contract] + + func controllers(query: ControllerQuery) async throws -> PageController + + func entities(query: Query) async throws -> PageEntity + + func eventMessages(query: Query) async throws -> PageEntity + + func playerAchievements(query: PlayerAchievementQuery) async throws -> PagePlayerAchievement + + func publishMessage(message: Message) async throws -> String + + func publishMessageBatch(messages: [Message]) async throws -> [String] + + func sql(query: String) async throws -> [SqlRow] + + func starknetEvents(query: EventQuery) async throws -> PageEvent + + func tokenBalances(query: TokenBalanceQuery) async throws -> PageTokenBalance + + func tokenContracts(query: TokenContractQuery) async throws -> PageTokenContract + + func tokenTransfers(query: TokenTransferQuery) async throws -> PageTokenTransfer + + func tokens(query: TokenQuery) async throws -> PageToken + + func transactions(query: TransactionQuery) async throws -> PageTransaction + + func worlds(worldAddresses: [FieldElement]) async throws -> [World] + +} +open class ToriiClient: ToriiClientProtocol, @unchecked Sendable { + fileprivate let handle: UInt64 + + /// Used to instantiate a [FFIObject] without an actual handle, for fakes in tests, mostly. +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public struct NoHandle { + public init() {} + } + + // TODO: We'd like this to be `private` but for Swifty reasons, + // we can't implement `FfiConverter` without making this `required` and we can't + // make it `required` without making it `public`. +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + required public init(unsafeFromHandle handle: UInt64) { + self.handle = handle + } + + // This constructor can be used to instantiate a fake object. + // - Parameter noHandle: Placeholder value so we can have a constructor separate from the default empty one that may be implemented for classes extending [FFIObject]. + // + // - Warning: + // Any object instantiated with this constructor cannot be passed to an actual Rust-backed object. Since there isn't a backing handle the FFI lower functions will crash. +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public init(noHandle: NoHandle) { + self.handle = 0 + } + +#if swift(>=5.8) + @_documentation(visibility: private) +#endif + public func uniffiCloneHandle() -> UInt64 { + return try! rustCall { uniffi_dojo_c_fn_clone_toriiclient(self.handle, $0) } + } +public convenience init(toriiUrl: String)async throws { + let handle = + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_constructor_toriiclient_new(FfiConverterString.lower(toriiUrl) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_u64, + completeFunc: ffi_dojo_c_rust_future_complete_u64, + freeFunc: ffi_dojo_c_rust_future_free_u64, + liftFunc: FfiConverterTypeToriiClient_lift, + errorHandler: FfiConverterTypeDojoError_lift + ) + + .uniffiCloneHandle() + self.init(unsafeFromHandle: handle) +} + + deinit { + try! rustCall { uniffi_dojo_c_fn_free_toriiclient(handle, $0) } + } + + +public static func newWithConfig(toriiUrl: String, maxMessageSize: UInt64)async throws -> ToriiClient { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_constructor_toriiclient_new_with_config(FfiConverterString.lower(toriiUrl),FfiConverterUInt64.lower(maxMessageSize) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_u64, + completeFunc: ffi_dojo_c_rust_future_complete_u64, + freeFunc: ffi_dojo_c_rust_future_free_u64, + liftFunc: FfiConverterTypeToriiClient_lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + + + +open func achievements(query: AchievementQuery)async throws -> PageAchievement { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_achievements( + self.uniffiCloneHandle(), + FfiConverterTypeAchievementQuery_lower(query) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypePageAchievement_lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func activities(query: ActivityQuery)async throws -> PageActivity { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_activities( + self.uniffiCloneHandle(), + FfiConverterTypeActivityQuery_lower(query) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypePageActivity_lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func aggregations(query: AggregationQuery)async throws -> PageAggregationEntry { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_aggregations( + self.uniffiCloneHandle(), + FfiConverterTypeAggregationQuery_lower(query) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypePageAggregationEntry_lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func contracts(query: ContractQuery)async throws -> [Contract] { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_contracts( + self.uniffiCloneHandle(), + FfiConverterTypeContractQuery_lower(query) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterSequenceTypeContract.lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func controllers(query: ControllerQuery)async throws -> PageController { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_controllers( + self.uniffiCloneHandle(), + FfiConverterTypeControllerQuery_lower(query) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypePageController_lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func entities(query: Query)async throws -> PageEntity { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_entities( + self.uniffiCloneHandle(), + FfiConverterTypeQuery_lower(query) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypePageEntity_lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func eventMessages(query: Query)async throws -> PageEntity { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_event_messages( + self.uniffiCloneHandle(), + FfiConverterTypeQuery_lower(query) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypePageEntity_lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func playerAchievements(query: PlayerAchievementQuery)async throws -> PagePlayerAchievement { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_player_achievements( + self.uniffiCloneHandle(), + FfiConverterTypePlayerAchievementQuery_lower(query) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypePagePlayerAchievement_lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func publishMessage(message: Message)async throws -> String { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_publish_message( + self.uniffiCloneHandle(), + FfiConverterTypeMessage_lower(message) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterString.lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func publishMessageBatch(messages: [Message])async throws -> [String] { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_publish_message_batch( + self.uniffiCloneHandle(), + FfiConverterSequenceTypeMessage.lower(messages) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterSequenceString.lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func sql(query: String)async throws -> [SqlRow] { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_sql( + self.uniffiCloneHandle(), + FfiConverterString.lower(query) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterSequenceTypeSqlRow.lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func starknetEvents(query: EventQuery)async throws -> PageEvent { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_starknet_events( + self.uniffiCloneHandle(), + FfiConverterTypeEventQuery_lower(query) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypePageEvent_lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func tokenBalances(query: TokenBalanceQuery)async throws -> PageTokenBalance { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_token_balances( + self.uniffiCloneHandle(), + FfiConverterTypeTokenBalanceQuery_lower(query) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypePageTokenBalance_lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func tokenContracts(query: TokenContractQuery)async throws -> PageTokenContract { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_token_contracts( + self.uniffiCloneHandle(), + FfiConverterTypeTokenContractQuery_lower(query) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypePageTokenContract_lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func tokenTransfers(query: TokenTransferQuery)async throws -> PageTokenTransfer { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_token_transfers( + self.uniffiCloneHandle(), + FfiConverterTypeTokenTransferQuery_lower(query) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypePageTokenTransfer_lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func tokens(query: TokenQuery)async throws -> PageToken { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_tokens( + self.uniffiCloneHandle(), + FfiConverterTypeTokenQuery_lower(query) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypePageToken_lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func transactions(query: TransactionQuery)async throws -> PageTransaction { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_transactions( + self.uniffiCloneHandle(), + FfiConverterTypeTransactionQuery_lower(query) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterTypePageTransaction_lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + +open func worlds(worldAddresses: [FieldElement])async throws -> [World] { + return + try await uniffiRustCallAsync( + rustFutureFunc: { + uniffi_dojo_c_fn_method_toriiclient_worlds( + self.uniffiCloneHandle(), + FfiConverterSequenceTypeFieldElement.lower(worldAddresses) + ) + }, + pollFunc: ffi_dojo_c_rust_future_poll_rust_buffer, + completeFunc: ffi_dojo_c_rust_future_complete_rust_buffer, + freeFunc: ffi_dojo_c_rust_future_free_rust_buffer, + liftFunc: FfiConverterSequenceTypeWorld.lift, + errorHandler: FfiConverterTypeDojoError_lift + ) +} + + + +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeToriiClient: FfiConverter { + typealias FfiType = UInt64 + typealias SwiftType = ToriiClient + + public static func lift(_ handle: UInt64) throws -> ToriiClient { + return ToriiClient(unsafeFromHandle: handle) + } + + public static func lower(_ value: ToriiClient) -> UInt64 { + return value.uniffiCloneHandle() + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ToriiClient { + let handle: UInt64 = try readInt(&buf) + return try lift(handle) + } + + public static func write(_ value: ToriiClient, into buf: inout [UInt8]) { + writeInt(&buf, lower(value)) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeToriiClient_lift(_ handle: UInt64) throws -> ToriiClient { + return try FfiConverterTypeToriiClient.lift(handle) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeToriiClient_lower(_ value: ToriiClient) -> UInt64 { + return FfiConverterTypeToriiClient.lower(value) +} + + + + public struct Achievement: Equatable, Hashable { public let id: String public let worldAddress: FieldElement @@ -1642,6 +2116,74 @@ public func FfiConverterTypeControllerQuery_lower(_ value: ControllerQuery) -> R } +public struct Entity: Equatable, Hashable { + public let worldAddress: FieldElement + public let hashedKeys: FieldElement + public let models: [Struct] + public let createdAt: UInt64 + public let updatedAt: UInt64 + public let executedAt: UInt64 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(worldAddress: FieldElement, hashedKeys: FieldElement, models: [Struct], createdAt: UInt64, updatedAt: UInt64, executedAt: UInt64) { + self.worldAddress = worldAddress + self.hashedKeys = hashedKeys + self.models = models + self.createdAt = createdAt + self.updatedAt = updatedAt + self.executedAt = executedAt + } + + +} + +#if compiler(>=6) +extension Entity: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeEntity: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Entity { + return + try Entity( + worldAddress: FfiConverterTypeFieldElement.read(from: &buf), + hashedKeys: FfiConverterTypeFieldElement.read(from: &buf), + models: FfiConverterSequenceTypeStruct.read(from: &buf), + createdAt: FfiConverterUInt64.read(from: &buf), + updatedAt: FfiConverterUInt64.read(from: &buf), + executedAt: FfiConverterUInt64.read(from: &buf) + ) + } + + public static func write(_ value: Entity, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.worldAddress, into: &buf) + FfiConverterTypeFieldElement.write(value.hashedKeys, into: &buf) + FfiConverterSequenceTypeStruct.write(value.models, into: &buf) + FfiConverterUInt64.write(value.createdAt, into: &buf) + FfiConverterUInt64.write(value.updatedAt, into: &buf) + FfiConverterUInt64.write(value.executedAt, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeEntity_lift(_ buf: RustBuffer) throws -> Entity { + return try FfiConverterTypeEntity.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeEntity_lower(_ value: Entity) -> RustBuffer { + return FfiConverterTypeEntity.lower(value) +} + + public struct EnumOption: Equatable, Hashable { public let name: String public let ty: Ty @@ -1750,39 +2292,43 @@ public func FfiConverterTypeEnumType_lower(_ value: EnumType) -> RustBuffer { } -public struct FixedSizeArray: Equatable, Hashable { - public let array: [Ty] - public let size: UInt32 +public struct Event: Equatable, Hashable { + public let keys: [FieldElement] + public let data: [FieldElement] + public let transactionHash: FieldElement // Default memberwise initializers are never public by default, so we // declare one manually. - public init(array: [Ty], size: UInt32) { - self.array = array - self.size = size + public init(keys: [FieldElement], data: [FieldElement], transactionHash: FieldElement) { + self.keys = keys + self.data = data + self.transactionHash = transactionHash } } #if compiler(>=6) -extension FixedSizeArray: Sendable {} +extension Event: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeFixedSizeArray: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> FixedSizeArray { +public struct FfiConverterTypeEvent: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Event { return - try FixedSizeArray( - array: FfiConverterSequenceTypeTy.read(from: &buf), - size: FfiConverterUInt32.read(from: &buf) + try Event( + keys: FfiConverterSequenceTypeFieldElement.read(from: &buf), + data: FfiConverterSequenceTypeFieldElement.read(from: &buf), + transactionHash: FfiConverterTypeFieldElement.read(from: &buf) ) } - public static func write(_ value: FixedSizeArray, into buf: inout [UInt8]) { - FfiConverterSequenceTypeTy.write(value.array, into: &buf) - FfiConverterUInt32.write(value.size, into: &buf) + public static func write(_ value: Event, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.keys, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.data, into: &buf) + FfiConverterTypeFieldElement.write(value.transactionHash, into: &buf) } } @@ -1790,55 +2336,51 @@ public struct FfiConverterTypeFixedSizeArray: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeFixedSizeArray_lift(_ buf: RustBuffer) throws -> FixedSizeArray { - return try FfiConverterTypeFixedSizeArray.lift(buf) +public func FfiConverterTypeEvent_lift(_ buf: RustBuffer) throws -> Event { + return try FfiConverterTypeEvent.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeFixedSizeArray_lower(_ value: FixedSizeArray) -> RustBuffer { - return FfiConverterTypeFixedSizeArray.lower(value) +public func FfiConverterTypeEvent_lower(_ value: Event) -> RustBuffer { + return FfiConverterTypeEvent.lower(value) } -public struct KeysClause: Equatable, Hashable { - public let keys: [FieldElement?] - public let patternMatching: PatternMatching - public let models: [String] +public struct EventQuery: Equatable, Hashable { + public let keys: KeysClause? + public let pagination: Pagination // Default memberwise initializers are never public by default, so we // declare one manually. - public init(keys: [FieldElement?], patternMatching: PatternMatching, models: [String]) { + public init(keys: KeysClause?, pagination: Pagination) { self.keys = keys - self.patternMatching = patternMatching - self.models = models + self.pagination = pagination } } #if compiler(>=6) -extension KeysClause: Sendable {} +extension EventQuery: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeKeysClause: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> KeysClause { +public struct FfiConverterTypeEventQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> EventQuery { return - try KeysClause( - keys: FfiConverterSequenceOptionTypeFieldElement.read(from: &buf), - patternMatching: FfiConverterTypePatternMatching.read(from: &buf), - models: FfiConverterSequenceString.read(from: &buf) + try EventQuery( + keys: FfiConverterOptionTypeKeysClause.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) ) } - public static func write(_ value: KeysClause, into buf: inout [UInt8]) { - FfiConverterSequenceOptionTypeFieldElement.write(value.keys, into: &buf) - FfiConverterTypePatternMatching.write(value.patternMatching, into: &buf) - FfiConverterSequenceString.write(value.models, into: &buf) + public static func write(_ value: EventQuery, into buf: inout [UInt8]) { + FfiConverterOptionTypeKeysClause.write(value.keys, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) } } @@ -1846,36 +2388,144 @@ public struct FfiConverterTypeKeysClause: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeKeysClause_lift(_ buf: RustBuffer) throws -> KeysClause { - return try FfiConverterTypeKeysClause.lift(buf) +public func FfiConverterTypeEventQuery_lift(_ buf: RustBuffer) throws -> EventQuery { + return try FfiConverterTypeEventQuery.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeKeysClause_lower(_ value: KeysClause) -> RustBuffer { - return FfiConverterTypeKeysClause.lower(value) +public func FfiConverterTypeEventQuery_lower(_ value: EventQuery) -> RustBuffer { + return FfiConverterTypeEventQuery.lower(value) } -public struct Member: Equatable, Hashable { - public let name: String - public let ty: Ty - public let key: Bool +public struct FixedSizeArray: Equatable, Hashable { + public let array: [Ty] + public let size: UInt32 // Default memberwise initializers are never public by default, so we // declare one manually. - public init(name: String, ty: Ty, key: Bool) { - self.name = name - self.ty = ty - self.key = key + public init(array: [Ty], size: UInt32) { + self.array = array + self.size = size } } #if compiler(>=6) -extension Member: Sendable {} +extension FixedSizeArray: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeFixedSizeArray: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> FixedSizeArray { + return + try FixedSizeArray( + array: FfiConverterSequenceTypeTy.read(from: &buf), + size: FfiConverterUInt32.read(from: &buf) + ) + } + + public static func write(_ value: FixedSizeArray, into buf: inout [UInt8]) { + FfiConverterSequenceTypeTy.write(value.array, into: &buf) + FfiConverterUInt32.write(value.size, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeFixedSizeArray_lift(_ buf: RustBuffer) throws -> FixedSizeArray { + return try FfiConverterTypeFixedSizeArray.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeFixedSizeArray_lower(_ value: FixedSizeArray) -> RustBuffer { + return FfiConverterTypeFixedSizeArray.lower(value) +} + + +public struct KeysClause: Equatable, Hashable { + public let keys: [FieldElement?] + public let patternMatching: PatternMatching + public let models: [String] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(keys: [FieldElement?], patternMatching: PatternMatching, models: [String]) { + self.keys = keys + self.patternMatching = patternMatching + self.models = models + } + + +} + +#if compiler(>=6) +extension KeysClause: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeKeysClause: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> KeysClause { + return + try KeysClause( + keys: FfiConverterSequenceOptionTypeFieldElement.read(from: &buf), + patternMatching: FfiConverterTypePatternMatching.read(from: &buf), + models: FfiConverterSequenceString.read(from: &buf) + ) + } + + public static func write(_ value: KeysClause, into buf: inout [UInt8]) { + FfiConverterSequenceOptionTypeFieldElement.write(value.keys, into: &buf) + FfiConverterTypePatternMatching.write(value.patternMatching, into: &buf) + FfiConverterSequenceString.write(value.models, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeKeysClause_lift(_ buf: RustBuffer) throws -> KeysClause { + return try FfiConverterTypeKeysClause.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeKeysClause_lower(_ value: KeysClause) -> RustBuffer { + return FfiConverterTypeKeysClause.lower(value) +} + + +public struct Member: Equatable, Hashable { + public let name: String + public let ty: Ty + public let key: Bool + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(name: String, ty: Ty, key: Bool) { + self.name = name + self.ty = ty + self.key = key + } + + +} + +#if compiler(>=6) +extension Member: Sendable {} #endif #if swift(>=5.8) @@ -1974,39 +2624,43 @@ public func FfiConverterTypeMemberClause_lower(_ value: MemberClause) -> RustBuf } -public struct OrderBy: Equatable, Hashable { - public let field: String - public let direction: OrderDirection +public struct Message: Equatable, Hashable { + public let message: String + public let signature: [FieldElement] + public let worldAddress: FieldElement // Default memberwise initializers are never public by default, so we // declare one manually. - public init(field: String, direction: OrderDirection) { - self.field = field - self.direction = direction + public init(message: String, signature: [FieldElement], worldAddress: FieldElement) { + self.message = message + self.signature = signature + self.worldAddress = worldAddress } } #if compiler(>=6) -extension OrderBy: Sendable {} +extension Message: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeOrderBy: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OrderBy { +public struct FfiConverterTypeMessage: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Message { return - try OrderBy( - field: FfiConverterString.read(from: &buf), - direction: FfiConverterTypeOrderDirection.read(from: &buf) + try Message( + message: FfiConverterString.read(from: &buf), + signature: FfiConverterSequenceTypeFieldElement.read(from: &buf), + worldAddress: FfiConverterTypeFieldElement.read(from: &buf) ) } - public static func write(_ value: OrderBy, into buf: inout [UInt8]) { - FfiConverterString.write(value.field, into: &buf) - FfiConverterTypeOrderDirection.write(value.direction, into: &buf) + public static func write(_ value: Message, into buf: inout [UInt8]) { + FfiConverterString.write(value.message, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.signature, into: &buf) + FfiConverterTypeFieldElement.write(value.worldAddress, into: &buf) } } @@ -2014,59 +2668,87 @@ public struct FfiConverterTypeOrderBy: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeOrderBy_lift(_ buf: RustBuffer) throws -> OrderBy { - return try FfiConverterTypeOrderBy.lift(buf) +public func FfiConverterTypeMessage_lift(_ buf: RustBuffer) throws -> Message { + return try FfiConverterTypeMessage.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeOrderBy_lower(_ value: OrderBy) -> RustBuffer { - return FfiConverterTypeOrderBy.lower(value) +public func FfiConverterTypeMessage_lower(_ value: Message) -> RustBuffer { + return FfiConverterTypeMessage.lower(value) } -public struct Pagination: Equatable, Hashable { - public let cursor: String? - public let limit: UInt32? - public let direction: PaginationDirection - public let orderBy: [OrderBy] +public struct Model: Equatable, Hashable { + public let worldAddress: FieldElement + public let schema: Ty + public let namespace: String + public let name: String + public let selector: FieldElement + public let packedSize: UInt32 + public let unpackedSize: UInt32 + public let classHash: FieldElement + public let contractAddress: FieldElement + public let layout: String + public let useLegacyStore: Bool // Default memberwise initializers are never public by default, so we // declare one manually. - public init(cursor: String?, limit: UInt32?, direction: PaginationDirection, orderBy: [OrderBy]) { - self.cursor = cursor - self.limit = limit - self.direction = direction - self.orderBy = orderBy + public init(worldAddress: FieldElement, schema: Ty, namespace: String, name: String, selector: FieldElement, packedSize: UInt32, unpackedSize: UInt32, classHash: FieldElement, contractAddress: FieldElement, layout: String, useLegacyStore: Bool) { + self.worldAddress = worldAddress + self.schema = schema + self.namespace = namespace + self.name = name + self.selector = selector + self.packedSize = packedSize + self.unpackedSize = unpackedSize + self.classHash = classHash + self.contractAddress = contractAddress + self.layout = layout + self.useLegacyStore = useLegacyStore } } #if compiler(>=6) -extension Pagination: Sendable {} +extension Model: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypePagination: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Pagination { +public struct FfiConverterTypeModel: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Model { return - try Pagination( - cursor: FfiConverterOptionString.read(from: &buf), - limit: FfiConverterOptionUInt32.read(from: &buf), - direction: FfiConverterTypePaginationDirection.read(from: &buf), - orderBy: FfiConverterSequenceTypeOrderBy.read(from: &buf) + try Model( + worldAddress: FfiConverterTypeFieldElement.read(from: &buf), + schema: FfiConverterTypeTy.read(from: &buf), + namespace: FfiConverterString.read(from: &buf), + name: FfiConverterString.read(from: &buf), + selector: FfiConverterTypeFieldElement.read(from: &buf), + packedSize: FfiConverterUInt32.read(from: &buf), + unpackedSize: FfiConverterUInt32.read(from: &buf), + classHash: FfiConverterTypeFieldElement.read(from: &buf), + contractAddress: FfiConverterTypeFieldElement.read(from: &buf), + layout: FfiConverterString.read(from: &buf), + useLegacyStore: FfiConverterBool.read(from: &buf) ) } - public static func write(_ value: Pagination, into buf: inout [UInt8]) { - FfiConverterOptionString.write(value.cursor, into: &buf) - FfiConverterOptionUInt32.write(value.limit, into: &buf) - FfiConverterTypePaginationDirection.write(value.direction, into: &buf) - FfiConverterSequenceTypeOrderBy.write(value.orderBy, into: &buf) + public static func write(_ value: Model, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.worldAddress, into: &buf) + FfiConverterTypeTy.write(value.schema, into: &buf) + FfiConverterString.write(value.namespace, into: &buf) + FfiConverterString.write(value.name, into: &buf) + FfiConverterTypeFieldElement.write(value.selector, into: &buf) + FfiConverterUInt32.write(value.packedSize, into: &buf) + FfiConverterUInt32.write(value.unpackedSize, into: &buf) + FfiConverterTypeFieldElement.write(value.classHash, into: &buf) + FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) + FfiConverterString.write(value.layout, into: &buf) + FfiConverterBool.write(value.useLegacyStore, into: &buf) } } @@ -2074,55 +2756,51 @@ public struct FfiConverterTypePagination: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePagination_lift(_ buf: RustBuffer) throws -> Pagination { - return try FfiConverterTypePagination.lift(buf) +public func FfiConverterTypeModel_lift(_ buf: RustBuffer) throws -> Model { + return try FfiConverterTypeModel.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePagination_lower(_ value: Pagination) -> RustBuffer { - return FfiConverterTypePagination.lower(value) +public func FfiConverterTypeModel_lower(_ value: Model) -> RustBuffer { + return FfiConverterTypeModel.lower(value) } -public struct PlayerAchievementEntry: Equatable, Hashable { - public let playerAddress: FieldElement - public let stats: PlayerAchievementStats - public let achievements: [PlayerAchievementProgress] +public struct OrderBy: Equatable, Hashable { + public let field: String + public let direction: OrderDirection // Default memberwise initializers are never public by default, so we // declare one manually. - public init(playerAddress: FieldElement, stats: PlayerAchievementStats, achievements: [PlayerAchievementProgress]) { - self.playerAddress = playerAddress - self.stats = stats - self.achievements = achievements + public init(field: String, direction: OrderDirection) { + self.field = field + self.direction = direction } } #if compiler(>=6) -extension PlayerAchievementEntry: Sendable {} +extension OrderBy: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypePlayerAchievementEntry: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PlayerAchievementEntry { +public struct FfiConverterTypeOrderBy: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OrderBy { return - try PlayerAchievementEntry( - playerAddress: FfiConverterTypeFieldElement.read(from: &buf), - stats: FfiConverterTypePlayerAchievementStats.read(from: &buf), - achievements: FfiConverterSequenceTypePlayerAchievementProgress.read(from: &buf) + try OrderBy( + field: FfiConverterString.read(from: &buf), + direction: FfiConverterTypeOrderDirection.read(from: &buf) ) } - public static func write(_ value: PlayerAchievementEntry, into buf: inout [UInt8]) { - FfiConverterTypeFieldElement.write(value.playerAddress, into: &buf) - FfiConverterTypePlayerAchievementStats.write(value.stats, into: &buf) - FfiConverterSequenceTypePlayerAchievementProgress.write(value.achievements, into: &buf) + public static func write(_ value: OrderBy, into buf: inout [UInt8]) { + FfiConverterString.write(value.field, into: &buf) + FfiConverterTypeOrderDirection.write(value.direction, into: &buf) } } @@ -2130,59 +2808,51 @@ public struct FfiConverterTypePlayerAchievementEntry: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePlayerAchievementEntry_lift(_ buf: RustBuffer) throws -> PlayerAchievementEntry { - return try FfiConverterTypePlayerAchievementEntry.lift(buf) +public func FfiConverterTypeOrderBy_lift(_ buf: RustBuffer) throws -> OrderBy { + return try FfiConverterTypeOrderBy.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePlayerAchievementEntry_lower(_ value: PlayerAchievementEntry) -> RustBuffer { - return FfiConverterTypePlayerAchievementEntry.lower(value) +public func FfiConverterTypeOrderBy_lower(_ value: OrderBy) -> RustBuffer { + return FfiConverterTypeOrderBy.lower(value) } -public struct PlayerAchievementProgress: Equatable, Hashable { - public let achievement: Achievement - public let taskProgress: [TaskProgress] - public let completed: Bool - public let progressPercentage: Double +public struct PageAchievement: Equatable, Hashable { + public let items: [Achievement] + public let nextCursor: String? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(achievement: Achievement, taskProgress: [TaskProgress], completed: Bool, progressPercentage: Double) { - self.achievement = achievement - self.taskProgress = taskProgress - self.completed = completed - self.progressPercentage = progressPercentage + public init(items: [Achievement], nextCursor: String?) { + self.items = items + self.nextCursor = nextCursor } } #if compiler(>=6) -extension PlayerAchievementProgress: Sendable {} +extension PageAchievement: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypePlayerAchievementProgress: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PlayerAchievementProgress { +public struct FfiConverterTypePageAchievement: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PageAchievement { return - try PlayerAchievementProgress( - achievement: FfiConverterTypeAchievement.read(from: &buf), - taskProgress: FfiConverterSequenceTypeTaskProgress.read(from: &buf), - completed: FfiConverterBool.read(from: &buf), - progressPercentage: FfiConverterDouble.read(from: &buf) + try PageAchievement( + items: FfiConverterSequenceTypeAchievement.read(from: &buf), + nextCursor: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: PlayerAchievementProgress, into buf: inout [UInt8]) { - FfiConverterTypeAchievement.write(value.achievement, into: &buf) - FfiConverterSequenceTypeTaskProgress.write(value.taskProgress, into: &buf) - FfiConverterBool.write(value.completed, into: &buf) - FfiConverterDouble.write(value.progressPercentage, into: &buf) + public static func write(_ value: PageAchievement, into buf: inout [UInt8]) { + FfiConverterSequenceTypeAchievement.write(value.items, into: &buf) + FfiConverterOptionString.write(value.nextCursor, into: &buf) } } @@ -2190,59 +2860,51 @@ public struct FfiConverterTypePlayerAchievementProgress: FfiConverterRustBuffer #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePlayerAchievementProgress_lift(_ buf: RustBuffer) throws -> PlayerAchievementProgress { - return try FfiConverterTypePlayerAchievementProgress.lift(buf) +public func FfiConverterTypePageAchievement_lift(_ buf: RustBuffer) throws -> PageAchievement { + return try FfiConverterTypePageAchievement.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePlayerAchievementProgress_lower(_ value: PlayerAchievementProgress) -> RustBuffer { - return FfiConverterTypePlayerAchievementProgress.lower(value) +public func FfiConverterTypePageAchievement_lower(_ value: PageAchievement) -> RustBuffer { + return FfiConverterTypePageAchievement.lower(value) } -public struct PlayerAchievementQuery: Equatable, Hashable { - public let worldAddresses: [FieldElement] - public let namespaces: [String] - public let playerAddresses: [FieldElement] - public let pagination: Pagination +public struct PageActivity: Equatable, Hashable { + public let items: [Activity] + public let nextCursor: String? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(worldAddresses: [FieldElement], namespaces: [String], playerAddresses: [FieldElement], pagination: Pagination) { - self.worldAddresses = worldAddresses - self.namespaces = namespaces - self.playerAddresses = playerAddresses - self.pagination = pagination + public init(items: [Activity], nextCursor: String?) { + self.items = items + self.nextCursor = nextCursor } } #if compiler(>=6) -extension PlayerAchievementQuery: Sendable {} +extension PageActivity: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypePlayerAchievementQuery: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PlayerAchievementQuery { +public struct FfiConverterTypePageActivity: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PageActivity { return - try PlayerAchievementQuery( - worldAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), - namespaces: FfiConverterSequenceString.read(from: &buf), - playerAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), - pagination: FfiConverterTypePagination.read(from: &buf) + try PageActivity( + items: FfiConverterSequenceTypeActivity.read(from: &buf), + nextCursor: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: PlayerAchievementQuery, into buf: inout [UInt8]) { - FfiConverterSequenceTypeFieldElement.write(value.worldAddresses, into: &buf) - FfiConverterSequenceString.write(value.namespaces, into: &buf) - FfiConverterSequenceTypeFieldElement.write(value.playerAddresses, into: &buf) - FfiConverterTypePagination.write(value.pagination, into: &buf) + public static func write(_ value: PageActivity, into buf: inout [UInt8]) { + FfiConverterSequenceTypeActivity.write(value.items, into: &buf) + FfiConverterOptionString.write(value.nextCursor, into: &buf) } } @@ -2250,71 +2912,51 @@ public struct FfiConverterTypePlayerAchievementQuery: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePlayerAchievementQuery_lift(_ buf: RustBuffer) throws -> PlayerAchievementQuery { - return try FfiConverterTypePlayerAchievementQuery.lift(buf) +public func FfiConverterTypePageActivity_lift(_ buf: RustBuffer) throws -> PageActivity { + return try FfiConverterTypePageActivity.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePlayerAchievementQuery_lower(_ value: PlayerAchievementQuery) -> RustBuffer { - return FfiConverterTypePlayerAchievementQuery.lower(value) +public func FfiConverterTypePageActivity_lower(_ value: PageActivity) -> RustBuffer { + return FfiConverterTypePageActivity.lower(value) } -public struct PlayerAchievementStats: Equatable, Hashable { - public let totalPoints: UInt32 - public let completedAchievements: UInt32 - public let totalAchievements: UInt32 - public let completionPercentage: Double - public let lastAchievementAt: UInt64? - public let createdAt: UInt64 - public let updatedAt: UInt64 +public struct PageAggregationEntry: Equatable, Hashable { + public let items: [AggregationEntry] + public let nextCursor: String? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(totalPoints: UInt32, completedAchievements: UInt32, totalAchievements: UInt32, completionPercentage: Double, lastAchievementAt: UInt64?, createdAt: UInt64, updatedAt: UInt64) { - self.totalPoints = totalPoints - self.completedAchievements = completedAchievements - self.totalAchievements = totalAchievements - self.completionPercentage = completionPercentage - self.lastAchievementAt = lastAchievementAt - self.createdAt = createdAt - self.updatedAt = updatedAt + public init(items: [AggregationEntry], nextCursor: String?) { + self.items = items + self.nextCursor = nextCursor } } #if compiler(>=6) -extension PlayerAchievementStats: Sendable {} +extension PageAggregationEntry: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypePlayerAchievementStats: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PlayerAchievementStats { +public struct FfiConverterTypePageAggregationEntry: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PageAggregationEntry { return - try PlayerAchievementStats( - totalPoints: FfiConverterUInt32.read(from: &buf), - completedAchievements: FfiConverterUInt32.read(from: &buf), - totalAchievements: FfiConverterUInt32.read(from: &buf), - completionPercentage: FfiConverterDouble.read(from: &buf), - lastAchievementAt: FfiConverterOptionUInt64.read(from: &buf), - createdAt: FfiConverterUInt64.read(from: &buf), - updatedAt: FfiConverterUInt64.read(from: &buf) + try PageAggregationEntry( + items: FfiConverterSequenceTypeAggregationEntry.read(from: &buf), + nextCursor: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: PlayerAchievementStats, into buf: inout [UInt8]) { - FfiConverterUInt32.write(value.totalPoints, into: &buf) - FfiConverterUInt32.write(value.completedAchievements, into: &buf) - FfiConverterUInt32.write(value.totalAchievements, into: &buf) - FfiConverterDouble.write(value.completionPercentage, into: &buf) - FfiConverterOptionUInt64.write(value.lastAchievementAt, into: &buf) - FfiConverterUInt64.write(value.createdAt, into: &buf) - FfiConverterUInt64.write(value.updatedAt, into: &buf) + public static func write(_ value: PageAggregationEntry, into buf: inout [UInt8]) { + FfiConverterSequenceTypeAggregationEntry.write(value.items, into: &buf) + FfiConverterOptionString.write(value.nextCursor, into: &buf) } } @@ -2322,51 +2964,51 @@ public struct FfiConverterTypePlayerAchievementStats: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePlayerAchievementStats_lift(_ buf: RustBuffer) throws -> PlayerAchievementStats { - return try FfiConverterTypePlayerAchievementStats.lift(buf) +public func FfiConverterTypePageAggregationEntry_lift(_ buf: RustBuffer) throws -> PageAggregationEntry { + return try FfiConverterTypePageAggregationEntry.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePlayerAchievementStats_lower(_ value: PlayerAchievementStats) -> RustBuffer { - return FfiConverterTypePlayerAchievementStats.lower(value) +public func FfiConverterTypePageAggregationEntry_lower(_ value: PageAggregationEntry) -> RustBuffer { + return FfiConverterTypePageAggregationEntry.lower(value) } -public struct Signature: Equatable, Hashable { - public let r: FieldElement - public let s: FieldElement +public struct PageController: Equatable, Hashable { + public let items: [Controller] + public let nextCursor: String? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(r: FieldElement, s: FieldElement) { - self.r = r - self.s = s + public init(items: [Controller], nextCursor: String?) { + self.items = items + self.nextCursor = nextCursor } } #if compiler(>=6) -extension Signature: Sendable {} +extension PageController: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeSignature: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Signature { +public struct FfiConverterTypePageController: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PageController { return - try Signature( - r: FfiConverterTypeFieldElement.read(from: &buf), - s: FfiConverterTypeFieldElement.read(from: &buf) + try PageController( + items: FfiConverterSequenceTypeController.read(from: &buf), + nextCursor: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: Signature, into buf: inout [UInt8]) { - FfiConverterTypeFieldElement.write(value.r, into: &buf) - FfiConverterTypeFieldElement.write(value.s, into: &buf) + public static func write(_ value: PageController, into buf: inout [UInt8]) { + FfiConverterSequenceTypeController.write(value.items, into: &buf) + FfiConverterOptionString.write(value.nextCursor, into: &buf) } } @@ -2374,51 +3016,51 @@ public struct FfiConverterTypeSignature: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeSignature_lift(_ buf: RustBuffer) throws -> Signature { - return try FfiConverterTypeSignature.lift(buf) +public func FfiConverterTypePageController_lift(_ buf: RustBuffer) throws -> PageController { + return try FfiConverterTypePageController.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeSignature_lower(_ value: Signature) -> RustBuffer { - return FfiConverterTypeSignature.lower(value) +public func FfiConverterTypePageController_lower(_ value: PageController) -> RustBuffer { + return FfiConverterTypePageController.lower(value) } -public struct Struct: Equatable, Hashable { - public let name: String - public let children: [Member] +public struct PageEntity: Equatable, Hashable { + public let items: [Entity] + public let nextCursor: String? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(name: String, children: [Member]) { - self.name = name - self.children = children + public init(items: [Entity], nextCursor: String?) { + self.items = items + self.nextCursor = nextCursor } } #if compiler(>=6) -extension Struct: Sendable {} +extension PageEntity: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeStruct: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Struct { +public struct FfiConverterTypePageEntity: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PageEntity { return - try Struct( - name: FfiConverterString.read(from: &buf), - children: FfiConverterSequenceTypeMember.read(from: &buf) + try PageEntity( + items: FfiConverterSequenceTypeEntity.read(from: &buf), + nextCursor: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: Struct, into buf: inout [UInt8]) { - FfiConverterString.write(value.name, into: &buf) - FfiConverterSequenceTypeMember.write(value.children, into: &buf) + public static func write(_ value: PageEntity, into buf: inout [UInt8]) { + FfiConverterSequenceTypeEntity.write(value.items, into: &buf) + FfiConverterOptionString.write(value.nextCursor, into: &buf) } } @@ -2426,55 +3068,51 @@ public struct FfiConverterTypeStruct: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeStruct_lift(_ buf: RustBuffer) throws -> Struct { - return try FfiConverterTypeStruct.lift(buf) +public func FfiConverterTypePageEntity_lift(_ buf: RustBuffer) throws -> PageEntity { + return try FfiConverterTypePageEntity.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeStruct_lower(_ value: Struct) -> RustBuffer { - return FfiConverterTypeStruct.lower(value) +public func FfiConverterTypePageEntity_lower(_ value: PageEntity) -> RustBuffer { + return FfiConverterTypePageEntity.lower(value) } -public struct TaskProgress: Equatable, Hashable { - public let taskId: String - public let count: UInt32 - public let completed: Bool +public struct PageEvent: Equatable, Hashable { + public let items: [Event] + public let nextCursor: String? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(taskId: String, count: UInt32, completed: Bool) { - self.taskId = taskId - self.count = count - self.completed = completed + public init(items: [Event], nextCursor: String?) { + self.items = items + self.nextCursor = nextCursor } } #if compiler(>=6) -extension TaskProgress: Sendable {} +extension PageEvent: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTaskProgress: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TaskProgress { +public struct FfiConverterTypePageEvent: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PageEvent { return - try TaskProgress( - taskId: FfiConverterString.read(from: &buf), - count: FfiConverterUInt32.read(from: &buf), - completed: FfiConverterBool.read(from: &buf) + try PageEvent( + items: FfiConverterSequenceTypeEvent.read(from: &buf), + nextCursor: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: TaskProgress, into buf: inout [UInt8]) { - FfiConverterString.write(value.taskId, into: &buf) - FfiConverterUInt32.write(value.count, into: &buf) - FfiConverterBool.write(value.completed, into: &buf) + public static func write(_ value: PageEvent, into buf: inout [UInt8]) { + FfiConverterSequenceTypeEvent.write(value.items, into: &buf) + FfiConverterOptionString.write(value.nextCursor, into: &buf) } } @@ -2482,71 +3120,51 @@ public struct FfiConverterTypeTaskProgress: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTaskProgress_lift(_ buf: RustBuffer) throws -> TaskProgress { - return try FfiConverterTypeTaskProgress.lift(buf) +public func FfiConverterTypePageEvent_lift(_ buf: RustBuffer) throws -> PageEvent { + return try FfiConverterTypePageEvent.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTaskProgress_lower(_ value: TaskProgress) -> RustBuffer { - return FfiConverterTypeTaskProgress.lower(value) +public func FfiConverterTypePageEvent_lower(_ value: PageEvent) -> RustBuffer { + return FfiConverterTypePageEvent.lower(value) } -public struct Token: Equatable, Hashable { - public let contractAddress: FieldElement - public let tokenId: U256? - public let name: String - public let symbol: String - public let decimals: UInt8 - public let metadata: String - public let totalSupply: U256? +public struct PagePlayerAchievement: Equatable, Hashable { + public let items: [PlayerAchievementEntry] + public let nextCursor: String? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(contractAddress: FieldElement, tokenId: U256?, name: String, symbol: String, decimals: UInt8, metadata: String, totalSupply: U256?) { - self.contractAddress = contractAddress - self.tokenId = tokenId - self.name = name - self.symbol = symbol - self.decimals = decimals - self.metadata = metadata - self.totalSupply = totalSupply + public init(items: [PlayerAchievementEntry], nextCursor: String?) { + self.items = items + self.nextCursor = nextCursor } } #if compiler(>=6) -extension Token: Sendable {} +extension PagePlayerAchievement: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeToken: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Token { +public struct FfiConverterTypePagePlayerAchievement: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PagePlayerAchievement { return - try Token( - contractAddress: FfiConverterTypeFieldElement.read(from: &buf), - tokenId: FfiConverterOptionTypeU256.read(from: &buf), - name: FfiConverterString.read(from: &buf), - symbol: FfiConverterString.read(from: &buf), - decimals: FfiConverterUInt8.read(from: &buf), - metadata: FfiConverterString.read(from: &buf), - totalSupply: FfiConverterOptionTypeU256.read(from: &buf) + try PagePlayerAchievement( + items: FfiConverterSequenceTypePlayerAchievementEntry.read(from: &buf), + nextCursor: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: Token, into buf: inout [UInt8]) { - FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) - FfiConverterOptionTypeU256.write(value.tokenId, into: &buf) - FfiConverterString.write(value.name, into: &buf) - FfiConverterString.write(value.symbol, into: &buf) - FfiConverterUInt8.write(value.decimals, into: &buf) - FfiConverterString.write(value.metadata, into: &buf) - FfiConverterOptionTypeU256.write(value.totalSupply, into: &buf) + public static func write(_ value: PagePlayerAchievement, into buf: inout [UInt8]) { + FfiConverterSequenceTypePlayerAchievementEntry.write(value.items, into: &buf) + FfiConverterOptionString.write(value.nextCursor, into: &buf) } } @@ -2554,59 +3172,51 @@ public struct FfiConverterTypeToken: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeToken_lift(_ buf: RustBuffer) throws -> Token { - return try FfiConverterTypeToken.lift(buf) +public func FfiConverterTypePagePlayerAchievement_lift(_ buf: RustBuffer) throws -> PagePlayerAchievement { + return try FfiConverterTypePagePlayerAchievement.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeToken_lower(_ value: Token) -> RustBuffer { - return FfiConverterTypeToken.lower(value) +public func FfiConverterTypePagePlayerAchievement_lower(_ value: PagePlayerAchievement) -> RustBuffer { + return FfiConverterTypePagePlayerAchievement.lower(value) } -public struct TokenBalance: Equatable, Hashable { - public let balance: U256 - public let accountAddress: FieldElement - public let contractAddress: FieldElement - public let tokenId: U256? +public struct PageToken: Equatable, Hashable { + public let items: [Token] + public let nextCursor: String? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(balance: U256, accountAddress: FieldElement, contractAddress: FieldElement, tokenId: U256?) { - self.balance = balance - self.accountAddress = accountAddress - self.contractAddress = contractAddress - self.tokenId = tokenId + public init(items: [Token], nextCursor: String?) { + self.items = items + self.nextCursor = nextCursor } } #if compiler(>=6) -extension TokenBalance: Sendable {} +extension PageToken: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTokenBalance: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenBalance { +public struct FfiConverterTypePageToken: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PageToken { return - try TokenBalance( - balance: FfiConverterTypeU256.read(from: &buf), - accountAddress: FfiConverterTypeFieldElement.read(from: &buf), - contractAddress: FfiConverterTypeFieldElement.read(from: &buf), - tokenId: FfiConverterOptionTypeU256.read(from: &buf) + try PageToken( + items: FfiConverterSequenceTypeToken.read(from: &buf), + nextCursor: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: TokenBalance, into buf: inout [UInt8]) { - FfiConverterTypeU256.write(value.balance, into: &buf) - FfiConverterTypeFieldElement.write(value.accountAddress, into: &buf) - FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) - FfiConverterOptionTypeU256.write(value.tokenId, into: &buf) + public static func write(_ value: PageToken, into buf: inout [UInt8]) { + FfiConverterSequenceTypeToken.write(value.items, into: &buf) + FfiConverterOptionString.write(value.nextCursor, into: &buf) } } @@ -2614,59 +3224,51 @@ public struct FfiConverterTypeTokenBalance: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTokenBalance_lift(_ buf: RustBuffer) throws -> TokenBalance { - return try FfiConverterTypeTokenBalance.lift(buf) +public func FfiConverterTypePageToken_lift(_ buf: RustBuffer) throws -> PageToken { + return try FfiConverterTypePageToken.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTokenBalance_lower(_ value: TokenBalance) -> RustBuffer { - return FfiConverterTypeTokenBalance.lower(value) +public func FfiConverterTypePageToken_lower(_ value: PageToken) -> RustBuffer { + return FfiConverterTypePageToken.lower(value) } -public struct TokenBalanceQuery: Equatable, Hashable { - public let contractAddresses: [FieldElement] - public let accountAddresses: [FieldElement] - public let tokenIds: [U256] - public let pagination: Pagination +public struct PageTokenBalance: Equatable, Hashable { + public let items: [TokenBalance] + public let nextCursor: String? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(contractAddresses: [FieldElement], accountAddresses: [FieldElement], tokenIds: [U256], pagination: Pagination) { - self.contractAddresses = contractAddresses - self.accountAddresses = accountAddresses - self.tokenIds = tokenIds - self.pagination = pagination + public init(items: [TokenBalance], nextCursor: String?) { + self.items = items + self.nextCursor = nextCursor } } #if compiler(>=6) -extension TokenBalanceQuery: Sendable {} +extension PageTokenBalance: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTokenBalanceQuery: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenBalanceQuery { +public struct FfiConverterTypePageTokenBalance: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PageTokenBalance { return - try TokenBalanceQuery( - contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), - accountAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), - tokenIds: FfiConverterSequenceTypeU256.read(from: &buf), - pagination: FfiConverterTypePagination.read(from: &buf) + try PageTokenBalance( + items: FfiConverterSequenceTypeTokenBalance.read(from: &buf), + nextCursor: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: TokenBalanceQuery, into buf: inout [UInt8]) { - FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) - FfiConverterSequenceTypeFieldElement.write(value.accountAddresses, into: &buf) - FfiConverterSequenceTypeU256.write(value.tokenIds, into: &buf) - FfiConverterTypePagination.write(value.pagination, into: &buf) + public static func write(_ value: PageTokenBalance, into buf: inout [UInt8]) { + FfiConverterSequenceTypeTokenBalance.write(value.items, into: &buf) + FfiConverterOptionString.write(value.nextCursor, into: &buf) } } @@ -2674,71 +3276,51 @@ public struct FfiConverterTypeTokenBalanceQuery: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTokenBalanceQuery_lift(_ buf: RustBuffer) throws -> TokenBalanceQuery { - return try FfiConverterTypeTokenBalanceQuery.lift(buf) +public func FfiConverterTypePageTokenBalance_lift(_ buf: RustBuffer) throws -> PageTokenBalance { + return try FfiConverterTypePageTokenBalance.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTokenBalanceQuery_lower(_ value: TokenBalanceQuery) -> RustBuffer { - return FfiConverterTypeTokenBalanceQuery.lower(value) +public func FfiConverterTypePageTokenBalance_lower(_ value: PageTokenBalance) -> RustBuffer { + return FfiConverterTypePageTokenBalance.lower(value) } -public struct TokenContract: Equatable, Hashable { - public let contractAddress: FieldElement - public let name: String - public let symbol: String - public let decimals: UInt8 - public let metadata: String - public let tokenMetadata: String - public let totalSupply: U256? +public struct PageTokenContract: Equatable, Hashable { + public let items: [TokenContract] + public let nextCursor: String? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(contractAddress: FieldElement, name: String, symbol: String, decimals: UInt8, metadata: String, tokenMetadata: String, totalSupply: U256?) { - self.contractAddress = contractAddress - self.name = name - self.symbol = symbol - self.decimals = decimals - self.metadata = metadata - self.tokenMetadata = tokenMetadata - self.totalSupply = totalSupply + public init(items: [TokenContract], nextCursor: String?) { + self.items = items + self.nextCursor = nextCursor } } #if compiler(>=6) -extension TokenContract: Sendable {} +extension PageTokenContract: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTokenContract: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenContract { +public struct FfiConverterTypePageTokenContract: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PageTokenContract { return - try TokenContract( - contractAddress: FfiConverterTypeFieldElement.read(from: &buf), - name: FfiConverterString.read(from: &buf), - symbol: FfiConverterString.read(from: &buf), - decimals: FfiConverterUInt8.read(from: &buf), - metadata: FfiConverterString.read(from: &buf), - tokenMetadata: FfiConverterString.read(from: &buf), - totalSupply: FfiConverterOptionTypeU256.read(from: &buf) + try PageTokenContract( + items: FfiConverterSequenceTypeTokenContract.read(from: &buf), + nextCursor: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: TokenContract, into buf: inout [UInt8]) { - FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) - FfiConverterString.write(value.name, into: &buf) - FfiConverterString.write(value.symbol, into: &buf) - FfiConverterUInt8.write(value.decimals, into: &buf) - FfiConverterString.write(value.metadata, into: &buf) - FfiConverterString.write(value.tokenMetadata, into: &buf) - FfiConverterOptionTypeU256.write(value.totalSupply, into: &buf) + public static func write(_ value: PageTokenContract, into buf: inout [UInt8]) { + FfiConverterSequenceTypeTokenContract.write(value.items, into: &buf) + FfiConverterOptionString.write(value.nextCursor, into: &buf) } } @@ -2746,55 +3328,51 @@ public struct FfiConverterTypeTokenContract: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTokenContract_lift(_ buf: RustBuffer) throws -> TokenContract { - return try FfiConverterTypeTokenContract.lift(buf) +public func FfiConverterTypePageTokenContract_lift(_ buf: RustBuffer) throws -> PageTokenContract { + return try FfiConverterTypePageTokenContract.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTokenContract_lower(_ value: TokenContract) -> RustBuffer { - return FfiConverterTypeTokenContract.lower(value) +public func FfiConverterTypePageTokenContract_lower(_ value: PageTokenContract) -> RustBuffer { + return FfiConverterTypePageTokenContract.lower(value) } -public struct TokenContractQuery: Equatable, Hashable { - public let contractAddresses: [FieldElement] - public let contractTypes: [ContractType] - public let pagination: Pagination +public struct PageTokenTransfer: Equatable, Hashable { + public let items: [TokenTransfer] + public let nextCursor: String? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(contractAddresses: [FieldElement], contractTypes: [ContractType], pagination: Pagination) { - self.contractAddresses = contractAddresses - self.contractTypes = contractTypes - self.pagination = pagination + public init(items: [TokenTransfer], nextCursor: String?) { + self.items = items + self.nextCursor = nextCursor } } #if compiler(>=6) -extension TokenContractQuery: Sendable {} +extension PageTokenTransfer: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTokenContractQuery: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenContractQuery { +public struct FfiConverterTypePageTokenTransfer: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PageTokenTransfer { return - try TokenContractQuery( - contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), - contractTypes: FfiConverterSequenceTypeContractType.read(from: &buf), - pagination: FfiConverterTypePagination.read(from: &buf) + try PageTokenTransfer( + items: FfiConverterSequenceTypeTokenTransfer.read(from: &buf), + nextCursor: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: TokenContractQuery, into buf: inout [UInt8]) { - FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) - FfiConverterSequenceTypeContractType.write(value.contractTypes, into: &buf) - FfiConverterTypePagination.write(value.pagination, into: &buf) + public static func write(_ value: PageTokenTransfer, into buf: inout [UInt8]) { + FfiConverterSequenceTypeTokenTransfer.write(value.items, into: &buf) + FfiConverterOptionString.write(value.nextCursor, into: &buf) } } @@ -2802,59 +3380,51 @@ public struct FfiConverterTypeTokenContractQuery: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTokenContractQuery_lift(_ buf: RustBuffer) throws -> TokenContractQuery { - return try FfiConverterTypeTokenContractQuery.lift(buf) +public func FfiConverterTypePageTokenTransfer_lift(_ buf: RustBuffer) throws -> PageTokenTransfer { + return try FfiConverterTypePageTokenTransfer.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTokenContractQuery_lower(_ value: TokenContractQuery) -> RustBuffer { - return FfiConverterTypeTokenContractQuery.lower(value) +public func FfiConverterTypePageTokenTransfer_lower(_ value: PageTokenTransfer) -> RustBuffer { + return FfiConverterTypePageTokenTransfer.lower(value) } -public struct TokenQuery: Equatable, Hashable { - public let contractAddresses: [FieldElement] - public let tokenIds: [U256] - public let attributeFilters: [AttributeFilter] - public let pagination: Pagination +public struct PageTransaction: Equatable, Hashable { + public let items: [Transaction] + public let nextCursor: String? // Default memberwise initializers are never public by default, so we // declare one manually. - public init(contractAddresses: [FieldElement], tokenIds: [U256], attributeFilters: [AttributeFilter], pagination: Pagination) { - self.contractAddresses = contractAddresses - self.tokenIds = tokenIds - self.attributeFilters = attributeFilters - self.pagination = pagination + public init(items: [Transaction], nextCursor: String?) { + self.items = items + self.nextCursor = nextCursor } } #if compiler(>=6) -extension TokenQuery: Sendable {} +extension PageTransaction: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTokenQuery: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenQuery { +public struct FfiConverterTypePageTransaction: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PageTransaction { return - try TokenQuery( - contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), - tokenIds: FfiConverterSequenceTypeU256.read(from: &buf), - attributeFilters: FfiConverterSequenceTypeAttributeFilter.read(from: &buf), - pagination: FfiConverterTypePagination.read(from: &buf) + try PageTransaction( + items: FfiConverterSequenceTypeTransaction.read(from: &buf), + nextCursor: FfiConverterOptionString.read(from: &buf) ) } - public static func write(_ value: TokenQuery, into buf: inout [UInt8]) { - FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) - FfiConverterSequenceTypeU256.write(value.tokenIds, into: &buf) - FfiConverterSequenceTypeAttributeFilter.write(value.attributeFilters, into: &buf) - FfiConverterTypePagination.write(value.pagination, into: &buf) + public static func write(_ value: PageTransaction, into buf: inout [UInt8]) { + FfiConverterSequenceTypeTransaction.write(value.items, into: &buf) + FfiConverterOptionString.write(value.nextCursor, into: &buf) } } @@ -2862,75 +3432,59 @@ public struct FfiConverterTypeTokenQuery: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTokenQuery_lift(_ buf: RustBuffer) throws -> TokenQuery { - return try FfiConverterTypeTokenQuery.lift(buf) +public func FfiConverterTypePageTransaction_lift(_ buf: RustBuffer) throws -> PageTransaction { + return try FfiConverterTypePageTransaction.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTokenQuery_lower(_ value: TokenQuery) -> RustBuffer { - return FfiConverterTypeTokenQuery.lower(value) +public func FfiConverterTypePageTransaction_lower(_ value: PageTransaction) -> RustBuffer { + return FfiConverterTypePageTransaction.lower(value) } -public struct TokenTransfer: Equatable, Hashable { - public let id: String - public let contractAddress: FieldElement - public let fromAddress: FieldElement - public let toAddress: FieldElement - public let amount: U256 - public let tokenId: U256? - public let executedAt: UInt64 - public let eventId: String? +public struct Pagination: Equatable, Hashable { + public let cursor: String? + public let limit: UInt32? + public let direction: PaginationDirection + public let orderBy: [OrderBy] // Default memberwise initializers are never public by default, so we // declare one manually. - public init(id: String, contractAddress: FieldElement, fromAddress: FieldElement, toAddress: FieldElement, amount: U256, tokenId: U256?, executedAt: UInt64, eventId: String?) { - self.id = id - self.contractAddress = contractAddress - self.fromAddress = fromAddress - self.toAddress = toAddress - self.amount = amount - self.tokenId = tokenId - self.executedAt = executedAt - self.eventId = eventId + public init(cursor: String?, limit: UInt32?, direction: PaginationDirection, orderBy: [OrderBy]) { + self.cursor = cursor + self.limit = limit + self.direction = direction + self.orderBy = orderBy } } #if compiler(>=6) -extension TokenTransfer: Sendable {} +extension Pagination: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTokenTransfer: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenTransfer { +public struct FfiConverterTypePagination: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Pagination { return - try TokenTransfer( - id: FfiConverterString.read(from: &buf), - contractAddress: FfiConverterTypeFieldElement.read(from: &buf), - fromAddress: FfiConverterTypeFieldElement.read(from: &buf), - toAddress: FfiConverterTypeFieldElement.read(from: &buf), - amount: FfiConverterTypeU256.read(from: &buf), - tokenId: FfiConverterOptionTypeU256.read(from: &buf), - executedAt: FfiConverterUInt64.read(from: &buf), - eventId: FfiConverterOptionString.read(from: &buf) + try Pagination( + cursor: FfiConverterOptionString.read(from: &buf), + limit: FfiConverterOptionUInt32.read(from: &buf), + direction: FfiConverterTypePaginationDirection.read(from: &buf), + orderBy: FfiConverterSequenceTypeOrderBy.read(from: &buf) ) } - public static func write(_ value: TokenTransfer, into buf: inout [UInt8]) { - FfiConverterString.write(value.id, into: &buf) - FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) - FfiConverterTypeFieldElement.write(value.fromAddress, into: &buf) - FfiConverterTypeFieldElement.write(value.toAddress, into: &buf) - FfiConverterTypeU256.write(value.amount, into: &buf) - FfiConverterOptionTypeU256.write(value.tokenId, into: &buf) - FfiConverterUInt64.write(value.executedAt, into: &buf) - FfiConverterOptionString.write(value.eventId, into: &buf) + public static func write(_ value: Pagination, into buf: inout [UInt8]) { + FfiConverterOptionString.write(value.cursor, into: &buf) + FfiConverterOptionUInt32.write(value.limit, into: &buf) + FfiConverterTypePaginationDirection.write(value.direction, into: &buf) + FfiConverterSequenceTypeOrderBy.write(value.orderBy, into: &buf) } } @@ -2938,59 +3492,55 @@ public struct FfiConverterTypeTokenTransfer: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTokenTransfer_lift(_ buf: RustBuffer) throws -> TokenTransfer { - return try FfiConverterTypeTokenTransfer.lift(buf) +public func FfiConverterTypePagination_lift(_ buf: RustBuffer) throws -> Pagination { + return try FfiConverterTypePagination.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTokenTransfer_lower(_ value: TokenTransfer) -> RustBuffer { - return FfiConverterTypeTokenTransfer.lower(value) +public func FfiConverterTypePagination_lower(_ value: Pagination) -> RustBuffer { + return FfiConverterTypePagination.lower(value) } -public struct TokenTransferQuery: Equatable, Hashable { - public let contractAddresses: [FieldElement] - public let accountAddresses: [FieldElement] - public let tokenIds: [U256] - public let pagination: Pagination +public struct PlayerAchievementEntry: Equatable, Hashable { + public let playerAddress: FieldElement + public let stats: PlayerAchievementStats + public let achievements: [PlayerAchievementProgress] // Default memberwise initializers are never public by default, so we // declare one manually. - public init(contractAddresses: [FieldElement], accountAddresses: [FieldElement], tokenIds: [U256], pagination: Pagination) { - self.contractAddresses = contractAddresses - self.accountAddresses = accountAddresses - self.tokenIds = tokenIds - self.pagination = pagination + public init(playerAddress: FieldElement, stats: PlayerAchievementStats, achievements: [PlayerAchievementProgress]) { + self.playerAddress = playerAddress + self.stats = stats + self.achievements = achievements } } #if compiler(>=6) -extension TokenTransferQuery: Sendable {} +extension PlayerAchievementEntry: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTokenTransferQuery: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenTransferQuery { +public struct FfiConverterTypePlayerAchievementEntry: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PlayerAchievementEntry { return - try TokenTransferQuery( - contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), - accountAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), - tokenIds: FfiConverterSequenceTypeU256.read(from: &buf), - pagination: FfiConverterTypePagination.read(from: &buf) + try PlayerAchievementEntry( + playerAddress: FfiConverterTypeFieldElement.read(from: &buf), + stats: FfiConverterTypePlayerAchievementStats.read(from: &buf), + achievements: FfiConverterSequenceTypePlayerAchievementProgress.read(from: &buf) ) } - public static func write(_ value: TokenTransferQuery, into buf: inout [UInt8]) { - FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) - FfiConverterSequenceTypeFieldElement.write(value.accountAddresses, into: &buf) - FfiConverterSequenceTypeU256.write(value.tokenIds, into: &buf) - FfiConverterTypePagination.write(value.pagination, into: &buf) + public static func write(_ value: PlayerAchievementEntry, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.playerAddress, into: &buf) + FfiConverterTypePlayerAchievementStats.write(value.stats, into: &buf) + FfiConverterSequenceTypePlayerAchievementProgress.write(value.achievements, into: &buf) } } @@ -2998,87 +3548,59 @@ public struct FfiConverterTypeTokenTransferQuery: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTokenTransferQuery_lift(_ buf: RustBuffer) throws -> TokenTransferQuery { - return try FfiConverterTypeTokenTransferQuery.lift(buf) +public func FfiConverterTypePlayerAchievementEntry_lift(_ buf: RustBuffer) throws -> PlayerAchievementEntry { + return try FfiConverterTypePlayerAchievementEntry.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTokenTransferQuery_lower(_ value: TokenTransferQuery) -> RustBuffer { - return FfiConverterTypeTokenTransferQuery.lower(value) +public func FfiConverterTypePlayerAchievementEntry_lower(_ value: PlayerAchievementEntry) -> RustBuffer { + return FfiConverterTypePlayerAchievementEntry.lower(value) } -public struct Transaction: Equatable, Hashable { - public let transactionHash: FieldElement - public let senderAddress: FieldElement - public let calldata: [FieldElement] - public let maxFee: FieldElement - public let signature: [FieldElement] - public let nonce: FieldElement - public let blockNumber: UInt64 - public let transactionType: String - public let blockTimestamp: UInt64 - public let calls: [TransactionCall] - public let uniqueModels: [FieldElement] +public struct PlayerAchievementProgress: Equatable, Hashable { + public let achievement: Achievement + public let taskProgress: [TaskProgress] + public let completed: Bool + public let progressPercentage: Double // Default memberwise initializers are never public by default, so we // declare one manually. - public init(transactionHash: FieldElement, senderAddress: FieldElement, calldata: [FieldElement], maxFee: FieldElement, signature: [FieldElement], nonce: FieldElement, blockNumber: UInt64, transactionType: String, blockTimestamp: UInt64, calls: [TransactionCall], uniqueModels: [FieldElement]) { - self.transactionHash = transactionHash - self.senderAddress = senderAddress - self.calldata = calldata - self.maxFee = maxFee - self.signature = signature - self.nonce = nonce - self.blockNumber = blockNumber - self.transactionType = transactionType - self.blockTimestamp = blockTimestamp - self.calls = calls - self.uniqueModels = uniqueModels + public init(achievement: Achievement, taskProgress: [TaskProgress], completed: Bool, progressPercentage: Double) { + self.achievement = achievement + self.taskProgress = taskProgress + self.completed = completed + self.progressPercentage = progressPercentage } } #if compiler(>=6) -extension Transaction: Sendable {} +extension PlayerAchievementProgress: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTransaction: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Transaction { +public struct FfiConverterTypePlayerAchievementProgress: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PlayerAchievementProgress { return - try Transaction( - transactionHash: FfiConverterTypeFieldElement.read(from: &buf), - senderAddress: FfiConverterTypeFieldElement.read(from: &buf), - calldata: FfiConverterSequenceTypeFieldElement.read(from: &buf), - maxFee: FfiConverterTypeFieldElement.read(from: &buf), - signature: FfiConverterSequenceTypeFieldElement.read(from: &buf), - nonce: FfiConverterTypeFieldElement.read(from: &buf), - blockNumber: FfiConverterUInt64.read(from: &buf), - transactionType: FfiConverterString.read(from: &buf), - blockTimestamp: FfiConverterUInt64.read(from: &buf), - calls: FfiConverterSequenceTypeTransactionCall.read(from: &buf), - uniqueModels: FfiConverterSequenceTypeFieldElement.read(from: &buf) + try PlayerAchievementProgress( + achievement: FfiConverterTypeAchievement.read(from: &buf), + taskProgress: FfiConverterSequenceTypeTaskProgress.read(from: &buf), + completed: FfiConverterBool.read(from: &buf), + progressPercentage: FfiConverterDouble.read(from: &buf) ) } - public static func write(_ value: Transaction, into buf: inout [UInt8]) { - FfiConverterTypeFieldElement.write(value.transactionHash, into: &buf) - FfiConverterTypeFieldElement.write(value.senderAddress, into: &buf) - FfiConverterSequenceTypeFieldElement.write(value.calldata, into: &buf) - FfiConverterTypeFieldElement.write(value.maxFee, into: &buf) - FfiConverterSequenceTypeFieldElement.write(value.signature, into: &buf) - FfiConverterTypeFieldElement.write(value.nonce, into: &buf) - FfiConverterUInt64.write(value.blockNumber, into: &buf) - FfiConverterString.write(value.transactionType, into: &buf) - FfiConverterUInt64.write(value.blockTimestamp, into: &buf) - FfiConverterSequenceTypeTransactionCall.write(value.calls, into: &buf) - FfiConverterSequenceTypeFieldElement.write(value.uniqueModels, into: &buf) + public static func write(_ value: PlayerAchievementProgress, into buf: inout [UInt8]) { + FfiConverterTypeAchievement.write(value.achievement, into: &buf) + FfiConverterSequenceTypeTaskProgress.write(value.taskProgress, into: &buf) + FfiConverterBool.write(value.completed, into: &buf) + FfiConverterDouble.write(value.progressPercentage, into: &buf) } } @@ -3086,63 +3608,59 @@ public struct FfiConverterTypeTransaction: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTransaction_lift(_ buf: RustBuffer) throws -> Transaction { - return try FfiConverterTypeTransaction.lift(buf) +public func FfiConverterTypePlayerAchievementProgress_lift(_ buf: RustBuffer) throws -> PlayerAchievementProgress { + return try FfiConverterTypePlayerAchievementProgress.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTransaction_lower(_ value: Transaction) -> RustBuffer { - return FfiConverterTypeTransaction.lower(value) +public func FfiConverterTypePlayerAchievementProgress_lower(_ value: PlayerAchievementProgress) -> RustBuffer { + return FfiConverterTypePlayerAchievementProgress.lower(value) } -public struct TransactionCall: Equatable, Hashable { - public let contractAddress: FieldElement - public let entrypoint: String - public let calldata: [FieldElement] - public let callType: CallType - public let callerAddress: FieldElement - - // Default memberwise initializers are never public by default, so we - // declare one manually. - public init(contractAddress: FieldElement, entrypoint: String, calldata: [FieldElement], callType: CallType, callerAddress: FieldElement) { - self.contractAddress = contractAddress - self.entrypoint = entrypoint - self.calldata = calldata - self.callType = callType - self.callerAddress = callerAddress +public struct PlayerAchievementQuery: Equatable, Hashable { + public let worldAddresses: [FieldElement] + public let namespaces: [String] + public let playerAddresses: [FieldElement] + public let pagination: Pagination + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(worldAddresses: [FieldElement], namespaces: [String], playerAddresses: [FieldElement], pagination: Pagination) { + self.worldAddresses = worldAddresses + self.namespaces = namespaces + self.playerAddresses = playerAddresses + self.pagination = pagination } } #if compiler(>=6) -extension TransactionCall: Sendable {} +extension PlayerAchievementQuery: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTransactionCall: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TransactionCall { +public struct FfiConverterTypePlayerAchievementQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PlayerAchievementQuery { return - try TransactionCall( - contractAddress: FfiConverterTypeFieldElement.read(from: &buf), - entrypoint: FfiConverterString.read(from: &buf), - calldata: FfiConverterSequenceTypeFieldElement.read(from: &buf), - callType: FfiConverterTypeCallType.read(from: &buf), - callerAddress: FfiConverterTypeFieldElement.read(from: &buf) + try PlayerAchievementQuery( + worldAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + namespaces: FfiConverterSequenceString.read(from: &buf), + playerAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) ) } - public static func write(_ value: TransactionCall, into buf: inout [UInt8]) { - FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) - FfiConverterString.write(value.entrypoint, into: &buf) - FfiConverterSequenceTypeFieldElement.write(value.calldata, into: &buf) - FfiConverterTypeCallType.write(value.callType, into: &buf) - FfiConverterTypeFieldElement.write(value.callerAddress, into: &buf) + public static func write(_ value: PlayerAchievementQuery, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.worldAddresses, into: &buf) + FfiConverterSequenceString.write(value.namespaces, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.playerAddresses, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) } } @@ -3150,71 +3668,71 @@ public struct FfiConverterTypeTransactionCall: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTransactionCall_lift(_ buf: RustBuffer) throws -> TransactionCall { - return try FfiConverterTypeTransactionCall.lift(buf) +public func FfiConverterTypePlayerAchievementQuery_lift(_ buf: RustBuffer) throws -> PlayerAchievementQuery { + return try FfiConverterTypePlayerAchievementQuery.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTransactionCall_lower(_ value: TransactionCall) -> RustBuffer { - return FfiConverterTypeTransactionCall.lower(value) +public func FfiConverterTypePlayerAchievementQuery_lower(_ value: PlayerAchievementQuery) -> RustBuffer { + return FfiConverterTypePlayerAchievementQuery.lower(value) } -public struct TransactionFilter: Equatable, Hashable { - public let transactionHashes: [FieldElement] - public let callerAddresses: [FieldElement] - public let contractAddresses: [FieldElement] - public let entrypoints: [String] - public let modelSelectors: [FieldElement] - public let fromBlock: UInt64? - public let toBlock: UInt64? +public struct PlayerAchievementStats: Equatable, Hashable { + public let totalPoints: UInt32 + public let completedAchievements: UInt32 + public let totalAchievements: UInt32 + public let completionPercentage: Double + public let lastAchievementAt: UInt64? + public let createdAt: UInt64 + public let updatedAt: UInt64 // Default memberwise initializers are never public by default, so we // declare one manually. - public init(transactionHashes: [FieldElement], callerAddresses: [FieldElement], contractAddresses: [FieldElement], entrypoints: [String], modelSelectors: [FieldElement], fromBlock: UInt64?, toBlock: UInt64?) { - self.transactionHashes = transactionHashes - self.callerAddresses = callerAddresses - self.contractAddresses = contractAddresses - self.entrypoints = entrypoints - self.modelSelectors = modelSelectors - self.fromBlock = fromBlock - self.toBlock = toBlock + public init(totalPoints: UInt32, completedAchievements: UInt32, totalAchievements: UInt32, completionPercentage: Double, lastAchievementAt: UInt64?, createdAt: UInt64, updatedAt: UInt64) { + self.totalPoints = totalPoints + self.completedAchievements = completedAchievements + self.totalAchievements = totalAchievements + self.completionPercentage = completionPercentage + self.lastAchievementAt = lastAchievementAt + self.createdAt = createdAt + self.updatedAt = updatedAt } } #if compiler(>=6) -extension TransactionFilter: Sendable {} +extension PlayerAchievementStats: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTransactionFilter: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TransactionFilter { +public struct FfiConverterTypePlayerAchievementStats: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PlayerAchievementStats { return - try TransactionFilter( - transactionHashes: FfiConverterSequenceTypeFieldElement.read(from: &buf), - callerAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), - contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), - entrypoints: FfiConverterSequenceString.read(from: &buf), - modelSelectors: FfiConverterSequenceTypeFieldElement.read(from: &buf), - fromBlock: FfiConverterOptionUInt64.read(from: &buf), - toBlock: FfiConverterOptionUInt64.read(from: &buf) + try PlayerAchievementStats( + totalPoints: FfiConverterUInt32.read(from: &buf), + completedAchievements: FfiConverterUInt32.read(from: &buf), + totalAchievements: FfiConverterUInt32.read(from: &buf), + completionPercentage: FfiConverterDouble.read(from: &buf), + lastAchievementAt: FfiConverterOptionUInt64.read(from: &buf), + createdAt: FfiConverterUInt64.read(from: &buf), + updatedAt: FfiConverterUInt64.read(from: &buf) ) } - public static func write(_ value: TransactionFilter, into buf: inout [UInt8]) { - FfiConverterSequenceTypeFieldElement.write(value.transactionHashes, into: &buf) - FfiConverterSequenceTypeFieldElement.write(value.callerAddresses, into: &buf) - FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) - FfiConverterSequenceString.write(value.entrypoints, into: &buf) - FfiConverterSequenceTypeFieldElement.write(value.modelSelectors, into: &buf) - FfiConverterOptionUInt64.write(value.fromBlock, into: &buf) - FfiConverterOptionUInt64.write(value.toBlock, into: &buf) + public static func write(_ value: PlayerAchievementStats, into buf: inout [UInt8]) { + FfiConverterUInt32.write(value.totalPoints, into: &buf) + FfiConverterUInt32.write(value.completedAchievements, into: &buf) + FfiConverterUInt32.write(value.totalAchievements, into: &buf) + FfiConverterDouble.write(value.completionPercentage, into: &buf) + FfiConverterOptionUInt64.write(value.lastAchievementAt, into: &buf) + FfiConverterUInt64.write(value.createdAt, into: &buf) + FfiConverterUInt64.write(value.updatedAt, into: &buf) } } @@ -3222,51 +3740,67 @@ public struct FfiConverterTypeTransactionFilter: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTransactionFilter_lift(_ buf: RustBuffer) throws -> TransactionFilter { - return try FfiConverterTypeTransactionFilter.lift(buf) +public func FfiConverterTypePlayerAchievementStats_lift(_ buf: RustBuffer) throws -> PlayerAchievementStats { + return try FfiConverterTypePlayerAchievementStats.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTransactionFilter_lower(_ value: TransactionFilter) -> RustBuffer { - return FfiConverterTypeTransactionFilter.lower(value) +public func FfiConverterTypePlayerAchievementStats_lower(_ value: PlayerAchievementStats) -> RustBuffer { + return FfiConverterTypePlayerAchievementStats.lower(value) } -public struct TransactionQuery: Equatable, Hashable { - public let filter: TransactionFilter? +public struct Query: Equatable, Hashable { + public let worldAddresses: [FieldElement] public let pagination: Pagination + public let clause: Clause? + public let noHashedKeys: Bool + public let models: [String] + public let historical: Bool // Default memberwise initializers are never public by default, so we // declare one manually. - public init(filter: TransactionFilter?, pagination: Pagination) { - self.filter = filter + public init(worldAddresses: [FieldElement], pagination: Pagination, clause: Clause?, noHashedKeys: Bool, models: [String], historical: Bool) { + self.worldAddresses = worldAddresses self.pagination = pagination + self.clause = clause + self.noHashedKeys = noHashedKeys + self.models = models + self.historical = historical } } #if compiler(>=6) -extension TransactionQuery: Sendable {} +extension Query: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTransactionQuery: FfiConverterRustBuffer { - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TransactionQuery { +public struct FfiConverterTypeQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Query { return - try TransactionQuery( - filter: FfiConverterOptionTypeTransactionFilter.read(from: &buf), - pagination: FfiConverterTypePagination.read(from: &buf) + try Query( + worldAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf), + clause: FfiConverterOptionTypeClause.read(from: &buf), + noHashedKeys: FfiConverterBool.read(from: &buf), + models: FfiConverterSequenceString.read(from: &buf), + historical: FfiConverterBool.read(from: &buf) ) } - public static func write(_ value: TransactionQuery, into buf: inout [UInt8]) { - FfiConverterOptionTypeTransactionFilter.write(value.filter, into: &buf) + public static func write(_ value: Query, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.worldAddresses, into: &buf) FfiConverterTypePagination.write(value.pagination, into: &buf) + FfiConverterOptionTypeClause.write(value.clause, into: &buf) + FfiConverterBool.write(value.noHashedKeys, into: &buf) + FfiConverterSequenceString.write(value.models, into: &buf) + FfiConverterBool.write(value.historical, into: &buf) } } @@ -3274,63 +3808,51 @@ public struct FfiConverterTypeTransactionQuery: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTransactionQuery_lift(_ buf: RustBuffer) throws -> TransactionQuery { - return try FfiConverterTypeTransactionQuery.lift(buf) +public func FfiConverterTypeQuery_lift(_ buf: RustBuffer) throws -> Query { + return try FfiConverterTypeQuery.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTransactionQuery_lower(_ value: TransactionQuery) -> RustBuffer { - return FfiConverterTypeTransactionQuery.lower(value) +public func FfiConverterTypeQuery_lower(_ value: Query) -> RustBuffer { + return FfiConverterTypeQuery.lower(value) } -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. - -public enum CallType: Equatable, Hashable { - - case execute - case executeFromOutside +public struct Signature: Equatable, Hashable { + public let r: FieldElement + public let s: FieldElement + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(r: FieldElement, s: FieldElement) { + self.r = r + self.s = s + } + } #if compiler(>=6) -extension CallType: Sendable {} +extension Signature: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeCallType: FfiConverterRustBuffer { - typealias SwiftType = CallType - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> CallType { - let variant: Int32 = try readInt(&buf) - switch variant { - - case 1: return .execute - - case 2: return .executeFromOutside - - default: throw UniffiInternalError.unexpectedEnumCase - } +public struct FfiConverterTypeSignature: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Signature { + return + try Signature( + r: FfiConverterTypeFieldElement.read(from: &buf), + s: FfiConverterTypeFieldElement.read(from: &buf) + ) } - public static func write(_ value: CallType, into buf: inout [UInt8]) { - switch value { - - - case .execute: - writeInt(&buf, Int32(1)) - - - case .executeFromOutside: - writeInt(&buf, Int32(2)) - - } + public static func write(_ value: Signature, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.r, into: &buf) + FfiConverterTypeFieldElement.write(value.s, into: &buf) } } @@ -3338,90 +3860,99 @@ public struct FfiConverterTypeCallType: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeCallType_lift(_ buf: RustBuffer) throws -> CallType { - return try FfiConverterTypeCallType.lift(buf) +public func FfiConverterTypeSignature_lift(_ buf: RustBuffer) throws -> Signature { + return try FfiConverterTypeSignature.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeCallType_lower(_ value: CallType) -> RustBuffer { - return FfiConverterTypeCallType.lower(value) +public func FfiConverterTypeSignature_lower(_ value: Signature) -> RustBuffer { + return FfiConverterTypeSignature.lower(value) } -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +public struct SqlField: Equatable, Hashable { + public let name: String + public let value: SqlValue + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(name: String, value: SqlValue) { + self.name = name + self.value = value + } -public enum Clause: Equatable, Hashable { - case hashedKeys(keys: [FieldElement] - ) - case keys(clause: KeysClause - ) - case member(clause: MemberClause - ) - case composite(clause: CompositeClause - ) +} +#if compiler(>=6) +extension SqlField: Sendable {} +#endif +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeSqlField: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SqlField { + return + try SqlField( + name: FfiConverterString.read(from: &buf), + value: FfiConverterTypeSqlValue.read(from: &buf) + ) + } + public static func write(_ value: SqlField, into buf: inout [UInt8]) { + FfiConverterString.write(value.name, into: &buf) + FfiConverterTypeSqlValue.write(value.value, into: &buf) + } } -#if compiler(>=6) -extension Clause: Sendable {} -#endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeClause: FfiConverterRustBuffer { - typealias SwiftType = Clause +public func FfiConverterTypeSqlField_lift(_ buf: RustBuffer) throws -> SqlField { + return try FfiConverterTypeSqlField.lift(buf) +} - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Clause { - let variant: Int32 = try readInt(&buf) - switch variant { - - case 1: return .hashedKeys(keys: try FfiConverterSequenceTypeFieldElement.read(from: &buf) - ) - - case 2: return .keys(clause: try FfiConverterTypeKeysClause.read(from: &buf) - ) - - case 3: return .member(clause: try FfiConverterTypeMemberClause.read(from: &buf) - ) - - case 4: return .composite(clause: try FfiConverterTypeCompositeClause.read(from: &buf) +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSqlField_lower(_ value: SqlField) -> RustBuffer { + return FfiConverterTypeSqlField.lower(value) +} + + +public struct SqlRow: Equatable, Hashable { + public let fields: [SqlField] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(fields: [SqlField]) { + self.fields = fields + } + + +} + +#if compiler(>=6) +extension SqlRow: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeSqlRow: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SqlRow { + return + try SqlRow( + fields: FfiConverterSequenceTypeSqlField.read(from: &buf) ) - - default: throw UniffiInternalError.unexpectedEnumCase - } } - public static func write(_ value: Clause, into buf: inout [UInt8]) { - switch value { - - - case let .hashedKeys(keys): - writeInt(&buf, Int32(1)) - FfiConverterSequenceTypeFieldElement.write(keys, into: &buf) - - - case let .keys(clause): - writeInt(&buf, Int32(2)) - FfiConverterTypeKeysClause.write(clause, into: &buf) - - - case let .member(clause): - writeInt(&buf, Int32(3)) - FfiConverterTypeMemberClause.write(clause, into: &buf) - - - case let .composite(clause): - writeInt(&buf, Int32(4)) - FfiConverterTypeCompositeClause.write(clause, into: &buf) - - } + public static func write(_ value: SqlRow, into buf: inout [UInt8]) { + FfiConverterSequenceTypeSqlField.write(value.fields, into: &buf) } } @@ -3429,148 +3960,51 @@ public struct FfiConverterTypeClause: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeClause_lift(_ buf: RustBuffer) throws -> Clause { - return try FfiConverterTypeClause.lift(buf) +public func FfiConverterTypeSqlRow_lift(_ buf: RustBuffer) throws -> SqlRow { + return try FfiConverterTypeSqlRow.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeClause_lower(_ value: Clause) -> RustBuffer { - return FfiConverterTypeClause.lower(value) +public func FfiConverterTypeSqlRow_lower(_ value: SqlRow) -> RustBuffer { + return FfiConverterTypeSqlRow.lower(value) } -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. - -public enum ComparisonOperator: Equatable, Hashable { - - case eq - case neq - case gt - case gte - case lt - case lte - case `in` - case notIn - case contains - case containsAll - case containsAny - case arrayLengthEq - case arrayLengthGt - case arrayLengthLt - +public struct Struct: Equatable, Hashable { + public let name: String + public let children: [Member] + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(name: String, children: [Member]) { + self.name = name + self.children = children + } + } #if compiler(>=6) -extension ComparisonOperator: Sendable {} +extension Struct: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeComparisonOperator: FfiConverterRustBuffer { - typealias SwiftType = ComparisonOperator - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ComparisonOperator { - let variant: Int32 = try readInt(&buf) - switch variant { - - case 1: return .eq - - case 2: return .neq - - case 3: return .gt - - case 4: return .gte - - case 5: return .lt - - case 6: return .lte - - case 7: return .`in` - - case 8: return .notIn - - case 9: return .contains - - case 10: return .containsAll - - case 11: return .containsAny - - case 12: return .arrayLengthEq - - case 13: return .arrayLengthGt - - case 14: return .arrayLengthLt - - default: throw UniffiInternalError.unexpectedEnumCase - } +public struct FfiConverterTypeStruct: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Struct { + return + try Struct( + name: FfiConverterString.read(from: &buf), + children: FfiConverterSequenceTypeMember.read(from: &buf) + ) } - public static func write(_ value: ComparisonOperator, into buf: inout [UInt8]) { - switch value { - - - case .eq: - writeInt(&buf, Int32(1)) - - - case .neq: - writeInt(&buf, Int32(2)) - - - case .gt: - writeInt(&buf, Int32(3)) - - - case .gte: - writeInt(&buf, Int32(4)) - - - case .lt: - writeInt(&buf, Int32(5)) - - - case .lte: - writeInt(&buf, Int32(6)) - - - case .`in`: - writeInt(&buf, Int32(7)) - - - case .notIn: - writeInt(&buf, Int32(8)) - - - case .contains: - writeInt(&buf, Int32(9)) - - - case .containsAll: - writeInt(&buf, Int32(10)) - - - case .containsAny: - writeInt(&buf, Int32(11)) - - - case .arrayLengthEq: - writeInt(&buf, Int32(12)) - - - case .arrayLengthGt: - writeInt(&buf, Int32(13)) - - - case .arrayLengthLt: - writeInt(&buf, Int32(14)) - - } + public static func write(_ value: Struct, into buf: inout [UInt8]) { + FfiConverterString.write(value.name, into: &buf) + FfiConverterSequenceTypeMember.write(value.children, into: &buf) } } @@ -3578,92 +4012,55 @@ public struct FfiConverterTypeComparisonOperator: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeComparisonOperator_lift(_ buf: RustBuffer) throws -> ComparisonOperator { - return try FfiConverterTypeComparisonOperator.lift(buf) +public func FfiConverterTypeStruct_lift(_ buf: RustBuffer) throws -> Struct { + return try FfiConverterTypeStruct.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeComparisonOperator_lower(_ value: ComparisonOperator) -> RustBuffer { - return FfiConverterTypeComparisonOperator.lower(value) +public func FfiConverterTypeStruct_lower(_ value: Struct) -> RustBuffer { + return FfiConverterTypeStruct.lower(value) } -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. - -public enum ContractType: Equatable, Hashable { - - case world - case erc20 - case erc721 - case erc1155 - case udc - case other - +public struct TaskProgress: Equatable, Hashable { + public let taskId: String + public let count: UInt32 + public let completed: Bool + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(taskId: String, count: UInt32, completed: Bool) { + self.taskId = taskId + self.count = count + self.completed = completed + } + } #if compiler(>=6) -extension ContractType: Sendable {} +extension TaskProgress: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeContractType: FfiConverterRustBuffer { - typealias SwiftType = ContractType +public struct FfiConverterTypeTaskProgress: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TaskProgress { + return + try TaskProgress( + taskId: FfiConverterString.read(from: &buf), + count: FfiConverterUInt32.read(from: &buf), + completed: FfiConverterBool.read(from: &buf) + ) + } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ContractType { - let variant: Int32 = try readInt(&buf) - switch variant { - - case 1: return .world - - case 2: return .erc20 - - case 3: return .erc721 - - case 4: return .erc1155 - - case 5: return .udc - - case 6: return .other - - default: throw UniffiInternalError.unexpectedEnumCase - } - } - - public static func write(_ value: ContractType, into buf: inout [UInt8]) { - switch value { - - - case .world: - writeInt(&buf, Int32(1)) - - - case .erc20: - writeInt(&buf, Int32(2)) - - - case .erc721: - writeInt(&buf, Int32(3)) - - - case .erc1155: - writeInt(&buf, Int32(4)) - - - case .udc: - writeInt(&buf, Int32(5)) - - - case .other: - writeInt(&buf, Int32(6)) - - } + public static func write(_ value: TaskProgress, into buf: inout [UInt8]) { + FfiConverterString.write(value.taskId, into: &buf) + FfiConverterUInt32.write(value.count, into: &buf) + FfiConverterBool.write(value.completed, into: &buf) } } @@ -3671,96 +4068,71 @@ public struct FfiConverterTypeContractType: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeContractType_lift(_ buf: RustBuffer) throws -> ContractType { - return try FfiConverterTypeContractType.lift(buf) +public func FfiConverterTypeTaskProgress_lift(_ buf: RustBuffer) throws -> TaskProgress { + return try FfiConverterTypeTaskProgress.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeContractType_lower(_ value: ContractType) -> RustBuffer { - return FfiConverterTypeContractType.lower(value) +public func FfiConverterTypeTaskProgress_lower(_ value: TaskProgress) -> RustBuffer { + return FfiConverterTypeTaskProgress.lower(value) } +public struct Token: Equatable, Hashable { + public let contractAddress: FieldElement + public let tokenId: U256? + public let name: String + public let symbol: String + public let decimals: UInt8 + public let metadata: String + public let totalSupply: U256? -public enum DojoError: Swift.Error, Equatable, Hashable, Foundation.LocalizedError { - - - - case ClientError(message: String) - - case SerializationError(message: String) - - case NetworkError(message: String) - - case InvalidInput(message: String) - - - - - - public var errorDescription: String? { - String(reflecting: self) + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddress: FieldElement, tokenId: U256?, name: String, symbol: String, decimals: UInt8, metadata: String, totalSupply: U256?) { + self.contractAddress = contractAddress + self.tokenId = tokenId + self.name = name + self.symbol = symbol + self.decimals = decimals + self.metadata = metadata + self.totalSupply = totalSupply } + } #if compiler(>=6) -extension DojoError: Sendable {} +extension Token: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeDojoError: FfiConverterRustBuffer { - typealias SwiftType = DojoError - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> DojoError { - let variant: Int32 = try readInt(&buf) - switch variant { - - - - - case 1: return .ClientError( - message: try FfiConverterString.read(from: &buf) - ) - - case 2: return .SerializationError( - message: try FfiConverterString.read(from: &buf) - ) - - case 3: return .NetworkError( - message: try FfiConverterString.read(from: &buf) - ) - - case 4: return .InvalidInput( - message: try FfiConverterString.read(from: &buf) +public struct FfiConverterTypeToken: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Token { + return + try Token( + contractAddress: FfiConverterTypeFieldElement.read(from: &buf), + tokenId: FfiConverterOptionTypeU256.read(from: &buf), + name: FfiConverterString.read(from: &buf), + symbol: FfiConverterString.read(from: &buf), + decimals: FfiConverterUInt8.read(from: &buf), + metadata: FfiConverterString.read(from: &buf), + totalSupply: FfiConverterOptionTypeU256.read(from: &buf) ) - - - default: throw UniffiInternalError.unexpectedEnumCase - } } - public static func write(_ value: DojoError, into buf: inout [UInt8]) { - switch value { - - - - - case .ClientError(_ /* message is ignored*/): - writeInt(&buf, Int32(1)) - case .SerializationError(_ /* message is ignored*/): - writeInt(&buf, Int32(2)) - case .NetworkError(_ /* message is ignored*/): - writeInt(&buf, Int32(3)) - case .InvalidInput(_ /* message is ignored*/): - writeInt(&buf, Int32(4)) - - - } + public static func write(_ value: Token, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) + FfiConverterOptionTypeU256.write(value.tokenId, into: &buf) + FfiConverterString.write(value.name, into: &buf) + FfiConverterString.write(value.symbol, into: &buf) + FfiConverterUInt8.write(value.decimals, into: &buf) + FfiConverterString.write(value.metadata, into: &buf) + FfiConverterOptionTypeU256.write(value.totalSupply, into: &buf) } } @@ -3768,63 +4140,59 @@ public struct FfiConverterTypeDojoError: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeDojoError_lift(_ buf: RustBuffer) throws -> DojoError { - return try FfiConverterTypeDojoError.lift(buf) +public func FfiConverterTypeToken_lift(_ buf: RustBuffer) throws -> Token { + return try FfiConverterTypeToken.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeDojoError_lower(_ value: DojoError) -> RustBuffer { - return FfiConverterTypeDojoError.lower(value) +public func FfiConverterTypeToken_lower(_ value: Token) -> RustBuffer { + return FfiConverterTypeToken.lower(value) } -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. - -public enum LogicalOperator: Equatable, Hashable { - - case and - case or +public struct TokenBalance: Equatable, Hashable { + public let balance: U256 + public let accountAddress: FieldElement + public let contractAddress: FieldElement + public let tokenId: U256? + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(balance: U256, accountAddress: FieldElement, contractAddress: FieldElement, tokenId: U256?) { + self.balance = balance + self.accountAddress = accountAddress + self.contractAddress = contractAddress + self.tokenId = tokenId + } + } #if compiler(>=6) -extension LogicalOperator: Sendable {} +extension TokenBalance: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeLogicalOperator: FfiConverterRustBuffer { - typealias SwiftType = LogicalOperator - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LogicalOperator { - let variant: Int32 = try readInt(&buf) - switch variant { - - case 1: return .and - - case 2: return .or - - default: throw UniffiInternalError.unexpectedEnumCase - } +public struct FfiConverterTypeTokenBalance: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenBalance { + return + try TokenBalance( + balance: FfiConverterTypeU256.read(from: &buf), + accountAddress: FfiConverterTypeFieldElement.read(from: &buf), + contractAddress: FfiConverterTypeFieldElement.read(from: &buf), + tokenId: FfiConverterOptionTypeU256.read(from: &buf) + ) } - public static func write(_ value: LogicalOperator, into buf: inout [UInt8]) { - switch value { - - - case .and: - writeInt(&buf, Int32(1)) - - - case .or: - writeInt(&buf, Int32(2)) - - } + public static func write(_ value: TokenBalance, into buf: inout [UInt8]) { + FfiConverterTypeU256.write(value.balance, into: &buf) + FfiConverterTypeFieldElement.write(value.accountAddress, into: &buf) + FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) + FfiConverterOptionTypeU256.write(value.tokenId, into: &buf) } } @@ -3832,80 +4200,59 @@ public struct FfiConverterTypeLogicalOperator: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLogicalOperator_lift(_ buf: RustBuffer) throws -> LogicalOperator { - return try FfiConverterTypeLogicalOperator.lift(buf) +public func FfiConverterTypeTokenBalance_lift(_ buf: RustBuffer) throws -> TokenBalance { + return try FfiConverterTypeTokenBalance.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeLogicalOperator_lower(_ value: LogicalOperator) -> RustBuffer { - return FfiConverterTypeLogicalOperator.lower(value) +public func FfiConverterTypeTokenBalance_lower(_ value: TokenBalance) -> RustBuffer { + return FfiConverterTypeTokenBalance.lower(value) } -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +public struct TokenBalanceQuery: Equatable, Hashable { + public let contractAddresses: [FieldElement] + public let accountAddresses: [FieldElement] + public let tokenIds: [U256] + public let pagination: Pagination + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddresses: [FieldElement], accountAddresses: [FieldElement], tokenIds: [U256], pagination: Pagination) { + self.contractAddresses = contractAddresses + self.accountAddresses = accountAddresses + self.tokenIds = tokenIds + self.pagination = pagination + } -public enum MemberValue: Equatable, Hashable { - case primitive(value: Primitive - ) - case string(value: String - ) - case list(values: [MemberValue] - ) - - - } #if compiler(>=6) -extension MemberValue: Sendable {} +extension TokenBalanceQuery: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeMemberValue: FfiConverterRustBuffer { - typealias SwiftType = MemberValue - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> MemberValue { - let variant: Int32 = try readInt(&buf) - switch variant { - - case 1: return .primitive(value: try FfiConverterTypePrimitive.read(from: &buf) - ) - - case 2: return .string(value: try FfiConverterString.read(from: &buf) - ) - - case 3: return .list(values: try FfiConverterSequenceTypeMemberValue.read(from: &buf) +public struct FfiConverterTypeTokenBalanceQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenBalanceQuery { + return + try TokenBalanceQuery( + contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + accountAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + tokenIds: FfiConverterSequenceTypeU256.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) ) - - default: throw UniffiInternalError.unexpectedEnumCase - } } - public static func write(_ value: MemberValue, into buf: inout [UInt8]) { - switch value { - - - case let .primitive(value): - writeInt(&buf, Int32(1)) - FfiConverterTypePrimitive.write(value, into: &buf) - - - case let .string(value): - writeInt(&buf, Int32(2)) - FfiConverterString.write(value, into: &buf) - - - case let .list(values): - writeInt(&buf, Int32(3)) - FfiConverterSequenceTypeMemberValue.write(values, into: &buf) - - } + public static func write(_ value: TokenBalanceQuery, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.accountAddresses, into: &buf) + FfiConverterSequenceTypeU256.write(value.tokenIds, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) } } @@ -3913,64 +4260,71 @@ public struct FfiConverterTypeMemberValue: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeMemberValue_lift(_ buf: RustBuffer) throws -> MemberValue { - return try FfiConverterTypeMemberValue.lift(buf) +public func FfiConverterTypeTokenBalanceQuery_lift(_ buf: RustBuffer) throws -> TokenBalanceQuery { + return try FfiConverterTypeTokenBalanceQuery.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeMemberValue_lower(_ value: MemberValue) -> RustBuffer { - return FfiConverterTypeMemberValue.lower(value) +public func FfiConverterTypeTokenBalanceQuery_lower(_ value: TokenBalanceQuery) -> RustBuffer { + return FfiConverterTypeTokenBalanceQuery.lower(value) } -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. - -public enum OrderDirection: Equatable, Hashable { - - case asc - case desc - +public struct TokenContract: Equatable, Hashable { + public let contractAddress: FieldElement + public let name: String + public let symbol: String + public let decimals: UInt8 + public let metadata: String + public let tokenMetadata: String + public let totalSupply: U256? + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddress: FieldElement, name: String, symbol: String, decimals: UInt8, metadata: String, tokenMetadata: String, totalSupply: U256?) { + self.contractAddress = contractAddress + self.name = name + self.symbol = symbol + self.decimals = decimals + self.metadata = metadata + self.tokenMetadata = tokenMetadata + self.totalSupply = totalSupply + } + } #if compiler(>=6) -extension OrderDirection: Sendable {} +extension TokenContract: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeOrderDirection: FfiConverterRustBuffer { - typealias SwiftType = OrderDirection - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OrderDirection { - let variant: Int32 = try readInt(&buf) - switch variant { - - case 1: return .asc - - case 2: return .desc - - default: throw UniffiInternalError.unexpectedEnumCase - } +public struct FfiConverterTypeTokenContract: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenContract { + return + try TokenContract( + contractAddress: FfiConverterTypeFieldElement.read(from: &buf), + name: FfiConverterString.read(from: &buf), + symbol: FfiConverterString.read(from: &buf), + decimals: FfiConverterUInt8.read(from: &buf), + metadata: FfiConverterString.read(from: &buf), + tokenMetadata: FfiConverterString.read(from: &buf), + totalSupply: FfiConverterOptionTypeU256.read(from: &buf) + ) } - public static func write(_ value: OrderDirection, into buf: inout [UInt8]) { - switch value { - - - case .asc: - writeInt(&buf, Int32(1)) - - - case .desc: - writeInt(&buf, Int32(2)) - - } + public static func write(_ value: TokenContract, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) + FfiConverterString.write(value.name, into: &buf) + FfiConverterString.write(value.symbol, into: &buf) + FfiConverterUInt8.write(value.decimals, into: &buf) + FfiConverterString.write(value.metadata, into: &buf) + FfiConverterString.write(value.tokenMetadata, into: &buf) + FfiConverterOptionTypeU256.write(value.totalSupply, into: &buf) } } @@ -3978,64 +4332,55 @@ public struct FfiConverterTypeOrderDirection: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeOrderDirection_lift(_ buf: RustBuffer) throws -> OrderDirection { - return try FfiConverterTypeOrderDirection.lift(buf) +public func FfiConverterTypeTokenContract_lift(_ buf: RustBuffer) throws -> TokenContract { + return try FfiConverterTypeTokenContract.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeOrderDirection_lower(_ value: OrderDirection) -> RustBuffer { - return FfiConverterTypeOrderDirection.lower(value) +public func FfiConverterTypeTokenContract_lower(_ value: TokenContract) -> RustBuffer { + return FfiConverterTypeTokenContract.lower(value) } -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. - -public enum PaginationDirection: Equatable, Hashable { - - case forward - case backward - +public struct TokenContractQuery: Equatable, Hashable { + public let contractAddresses: [FieldElement] + public let contractTypes: [ContractType] + public let pagination: Pagination + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddresses: [FieldElement], contractTypes: [ContractType], pagination: Pagination) { + self.contractAddresses = contractAddresses + self.contractTypes = contractTypes + self.pagination = pagination + } + } #if compiler(>=6) -extension PaginationDirection: Sendable {} +extension TokenContractQuery: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypePaginationDirection: FfiConverterRustBuffer { - typealias SwiftType = PaginationDirection - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PaginationDirection { - let variant: Int32 = try readInt(&buf) - switch variant { - - case 1: return .forward - - case 2: return .backward - - default: throw UniffiInternalError.unexpectedEnumCase - } +public struct FfiConverterTypeTokenContractQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenContractQuery { + return + try TokenContractQuery( + contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + contractTypes: FfiConverterSequenceTypeContractType.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) + ) } - public static func write(_ value: PaginationDirection, into buf: inout [UInt8]) { - switch value { - - - case .forward: - writeInt(&buf, Int32(1)) - - - case .backward: - writeInt(&buf, Int32(2)) - - } + public static func write(_ value: TokenContractQuery, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) + FfiConverterSequenceTypeContractType.write(value.contractTypes, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) } } @@ -4043,64 +4388,59 @@ public struct FfiConverterTypePaginationDirection: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePaginationDirection_lift(_ buf: RustBuffer) throws -> PaginationDirection { - return try FfiConverterTypePaginationDirection.lift(buf) +public func FfiConverterTypeTokenContractQuery_lift(_ buf: RustBuffer) throws -> TokenContractQuery { + return try FfiConverterTypeTokenContractQuery.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePaginationDirection_lower(_ value: PaginationDirection) -> RustBuffer { - return FfiConverterTypePaginationDirection.lower(value) +public func FfiConverterTypeTokenContractQuery_lower(_ value: TokenContractQuery) -> RustBuffer { + return FfiConverterTypeTokenContractQuery.lower(value) } -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. - -public enum PatternMatching: Equatable, Hashable { - - case fixedLen - case variableLen - +public struct TokenQuery: Equatable, Hashable { + public let contractAddresses: [FieldElement] + public let tokenIds: [U256] + public let attributeFilters: [AttributeFilter] + public let pagination: Pagination + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddresses: [FieldElement], tokenIds: [U256], attributeFilters: [AttributeFilter], pagination: Pagination) { + self.contractAddresses = contractAddresses + self.tokenIds = tokenIds + self.attributeFilters = attributeFilters + self.pagination = pagination + } + } #if compiler(>=6) -extension PatternMatching: Sendable {} +extension TokenQuery: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypePatternMatching: FfiConverterRustBuffer { - typealias SwiftType = PatternMatching +public struct FfiConverterTypeTokenQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenQuery { + return + try TokenQuery( + contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + tokenIds: FfiConverterSequenceTypeU256.read(from: &buf), + attributeFilters: FfiConverterSequenceTypeAttributeFilter.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) + ) + } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PatternMatching { - let variant: Int32 = try readInt(&buf) - switch variant { - - case 1: return .fixedLen - - case 2: return .variableLen - - default: throw UniffiInternalError.unexpectedEnumCase - } - } - - public static func write(_ value: PatternMatching, into buf: inout [UInt8]) { - switch value { - - - case .fixedLen: - writeInt(&buf, Int32(1)) - - - case .variableLen: - writeInt(&buf, Int32(2)) - - } + public static func write(_ value: TokenQuery, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) + FfiConverterSequenceTypeU256.write(value.tokenIds, into: &buf) + FfiConverterSequenceTypeAttributeFilter.write(value.attributeFilters, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) } } @@ -4108,210 +4448,75 @@ public struct FfiConverterTypePatternMatching: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePatternMatching_lift(_ buf: RustBuffer) throws -> PatternMatching { - return try FfiConverterTypePatternMatching.lift(buf) +public func FfiConverterTypeTokenQuery_lift(_ buf: RustBuffer) throws -> TokenQuery { + return try FfiConverterTypeTokenQuery.lift(buf) } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePatternMatching_lower(_ value: PatternMatching) -> RustBuffer { - return FfiConverterTypePatternMatching.lower(value) +public func FfiConverterTypeTokenQuery_lower(_ value: TokenQuery) -> RustBuffer { + return FfiConverterTypeTokenQuery.lower(value) } -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. - -public enum Primitive: Equatable, Hashable { - - case i8(value: Int8 - ) - case i16(value: Int16 - ) - case i32(value: Int32 - ) - case i64(value: Int64 - ) - case i128(value: [UInt8] - ) - case u8(value: UInt8 - ) - case u16(value: UInt16 - ) - case u32(value: UInt32 - ) - case u64(value: UInt64 - ) - case u128(value: [UInt8] - ) - case u256(value: U256 - ) - case bool(value: Bool - ) - case felt252(value: FieldElement - ) - case classHash(value: FieldElement - ) - case contractAddress(value: FieldElement - ) - case ethAddress(value: FieldElement - ) - +public struct TokenTransfer: Equatable, Hashable { + public let id: String + public let contractAddress: FieldElement + public let fromAddress: FieldElement + public let toAddress: FieldElement + public let amount: U256 + public let tokenId: U256? + public let executedAt: UInt64 + public let eventId: String? + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(id: String, contractAddress: FieldElement, fromAddress: FieldElement, toAddress: FieldElement, amount: U256, tokenId: U256?, executedAt: UInt64, eventId: String?) { + self.id = id + self.contractAddress = contractAddress + self.fromAddress = fromAddress + self.toAddress = toAddress + self.amount = amount + self.tokenId = tokenId + self.executedAt = executedAt + self.eventId = eventId + } + } #if compiler(>=6) -extension Primitive: Sendable {} +extension TokenTransfer: Sendable {} #endif #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypePrimitive: FfiConverterRustBuffer { - typealias SwiftType = Primitive - - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Primitive { - let variant: Int32 = try readInt(&buf) - switch variant { - - case 1: return .i8(value: try FfiConverterInt8.read(from: &buf) - ) - - case 2: return .i16(value: try FfiConverterInt16.read(from: &buf) - ) - - case 3: return .i32(value: try FfiConverterInt32.read(from: &buf) - ) - - case 4: return .i64(value: try FfiConverterInt64.read(from: &buf) - ) - - case 5: return .i128(value: try FfiConverterSequenceUInt8.read(from: &buf) - ) - - case 6: return .u8(value: try FfiConverterUInt8.read(from: &buf) - ) - - case 7: return .u16(value: try FfiConverterUInt16.read(from: &buf) - ) - - case 8: return .u32(value: try FfiConverterUInt32.read(from: &buf) - ) - - case 9: return .u64(value: try FfiConverterUInt64.read(from: &buf) - ) - - case 10: return .u128(value: try FfiConverterSequenceUInt8.read(from: &buf) - ) - - case 11: return .u256(value: try FfiConverterTypeU256.read(from: &buf) - ) - - case 12: return .bool(value: try FfiConverterBool.read(from: &buf) - ) - - case 13: return .felt252(value: try FfiConverterTypeFieldElement.read(from: &buf) - ) - - case 14: return .classHash(value: try FfiConverterTypeFieldElement.read(from: &buf) - ) - - case 15: return .contractAddress(value: try FfiConverterTypeFieldElement.read(from: &buf) - ) - - case 16: return .ethAddress(value: try FfiConverterTypeFieldElement.read(from: &buf) +public struct FfiConverterTypeTokenTransfer: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenTransfer { + return + try TokenTransfer( + id: FfiConverterString.read(from: &buf), + contractAddress: FfiConverterTypeFieldElement.read(from: &buf), + fromAddress: FfiConverterTypeFieldElement.read(from: &buf), + toAddress: FfiConverterTypeFieldElement.read(from: &buf), + amount: FfiConverterTypeU256.read(from: &buf), + tokenId: FfiConverterOptionTypeU256.read(from: &buf), + executedAt: FfiConverterUInt64.read(from: &buf), + eventId: FfiConverterOptionString.read(from: &buf) ) - - default: throw UniffiInternalError.unexpectedEnumCase - } } - public static func write(_ value: Primitive, into buf: inout [UInt8]) { - switch value { - - - case let .i8(value): - writeInt(&buf, Int32(1)) - FfiConverterInt8.write(value, into: &buf) - - - case let .i16(value): - writeInt(&buf, Int32(2)) - FfiConverterInt16.write(value, into: &buf) - - - case let .i32(value): - writeInt(&buf, Int32(3)) - FfiConverterInt32.write(value, into: &buf) - - - case let .i64(value): - writeInt(&buf, Int32(4)) - FfiConverterInt64.write(value, into: &buf) - - - case let .i128(value): - writeInt(&buf, Int32(5)) - FfiConverterSequenceUInt8.write(value, into: &buf) - - - case let .u8(value): - writeInt(&buf, Int32(6)) - FfiConverterUInt8.write(value, into: &buf) - - - case let .u16(value): - writeInt(&buf, Int32(7)) - FfiConverterUInt16.write(value, into: &buf) - - - case let .u32(value): - writeInt(&buf, Int32(8)) - FfiConverterUInt32.write(value, into: &buf) - - - case let .u64(value): - writeInt(&buf, Int32(9)) - FfiConverterUInt64.write(value, into: &buf) - - - case let .u128(value): - writeInt(&buf, Int32(10)) - FfiConverterSequenceUInt8.write(value, into: &buf) - - - case let .u256(value): - writeInt(&buf, Int32(11)) - FfiConverterTypeU256.write(value, into: &buf) - - - case let .bool(value): - writeInt(&buf, Int32(12)) - FfiConverterBool.write(value, into: &buf) - - - case let .felt252(value): - writeInt(&buf, Int32(13)) - FfiConverterTypeFieldElement.write(value, into: &buf) - - - case let .classHash(value): - writeInt(&buf, Int32(14)) - FfiConverterTypeFieldElement.write(value, into: &buf) - - - case let .contractAddress(value): - writeInt(&buf, Int32(15)) - FfiConverterTypeFieldElement.write(value, into: &buf) - - - case let .ethAddress(value): - writeInt(&buf, Int32(16)) - FfiConverterTypeFieldElement.write(value, into: &buf) - - } + public static func write(_ value: TokenTransfer, into buf: inout [UInt8]) { + FfiConverterString.write(value.id, into: &buf) + FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) + FfiConverterTypeFieldElement.write(value.fromAddress, into: &buf) + FfiConverterTypeFieldElement.write(value.toAddress, into: &buf) + FfiConverterTypeU256.write(value.amount, into: &buf) + FfiConverterOptionTypeU256.write(value.tokenId, into: &buf) + FfiConverterUInt64.write(value.executedAt, into: &buf) + FfiConverterOptionString.write(value.eventId, into: &buf) } } @@ -4319,428 +4524,2481 @@ public struct FfiConverterTypePrimitive: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePrimitive_lift(_ buf: RustBuffer) throws -> Primitive { - return try FfiConverterTypePrimitive.lift(buf) -} +public func FfiConverterTypeTokenTransfer_lift(_ buf: RustBuffer) throws -> TokenTransfer { + return try FfiConverterTypeTokenTransfer.lift(buf) +} #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypePrimitive_lower(_ value: Primitive) -> RustBuffer { - return FfiConverterTypePrimitive.lower(value) +public func FfiConverterTypeTokenTransfer_lower(_ value: TokenTransfer) -> RustBuffer { + return FfiConverterTypeTokenTransfer.lower(value) } -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. +public struct TokenTransferQuery: Equatable, Hashable { + public let contractAddresses: [FieldElement] + public let accountAddresses: [FieldElement] + public let tokenIds: [U256] + public let pagination: Pagination + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddresses: [FieldElement], accountAddresses: [FieldElement], tokenIds: [U256], pagination: Pagination) { + self.contractAddresses = contractAddresses + self.accountAddresses = accountAddresses + self.tokenIds = tokenIds + self.pagination = pagination + } -public enum Ty: Equatable, Hashable { - case primitive(value: Primitive - ) - case `struct`(value: Struct - ) - case `enum`(value: EnumType - ) - case tuple(values: [Ty] - ) - case array(values: [Ty] - ) - case fixedSizeArray(value: FixedSizeArray - ) - case byteArray(value: String - ) +} +#if compiler(>=6) +extension TokenTransferQuery: Sendable {} +#endif +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTokenTransferQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TokenTransferQuery { + return + try TokenTransferQuery( + contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + accountAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + tokenIds: FfiConverterSequenceTypeU256.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) + ) + } + public static func write(_ value: TokenTransferQuery, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.accountAddresses, into: &buf) + FfiConverterSequenceTypeU256.write(value.tokenIds, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) + } } -#if compiler(>=6) -extension Ty: Sendable {} + +#if swift(>=5.8) +@_documentation(visibility: private) #endif +public func FfiConverterTypeTokenTransferQuery_lift(_ buf: RustBuffer) throws -> TokenTransferQuery { + return try FfiConverterTypeTokenTransferQuery.lift(buf) +} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeTy: FfiConverterRustBuffer { - typealias SwiftType = Ty +public func FfiConverterTypeTokenTransferQuery_lower(_ value: TokenTransferQuery) -> RustBuffer { + return FfiConverterTypeTokenTransferQuery.lower(value) +} - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Ty { - let variant: Int32 = try readInt(&buf) - switch variant { - - case 1: return .primitive(value: try FfiConverterTypePrimitive.read(from: &buf) - ) - - case 2: return .`struct`(value: try FfiConverterTypeStruct.read(from: &buf) - ) - - case 3: return .`enum`(value: try FfiConverterTypeEnumType.read(from: &buf) - ) - - case 4: return .tuple(values: try FfiConverterSequenceTypeTy.read(from: &buf) - ) - - case 5: return .array(values: try FfiConverterSequenceTypeTy.read(from: &buf) - ) - - case 6: return .fixedSizeArray(value: try FfiConverterTypeFixedSizeArray.read(from: &buf) + +public struct Transaction: Equatable, Hashable { + public let transactionHash: FieldElement + public let senderAddress: FieldElement + public let calldata: [FieldElement] + public let maxFee: FieldElement + public let signature: [FieldElement] + public let nonce: FieldElement + public let blockNumber: UInt64 + public let transactionType: String + public let blockTimestamp: UInt64 + public let calls: [TransactionCall] + public let uniqueModels: [FieldElement] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(transactionHash: FieldElement, senderAddress: FieldElement, calldata: [FieldElement], maxFee: FieldElement, signature: [FieldElement], nonce: FieldElement, blockNumber: UInt64, transactionType: String, blockTimestamp: UInt64, calls: [TransactionCall], uniqueModels: [FieldElement]) { + self.transactionHash = transactionHash + self.senderAddress = senderAddress + self.calldata = calldata + self.maxFee = maxFee + self.signature = signature + self.nonce = nonce + self.blockNumber = blockNumber + self.transactionType = transactionType + self.blockTimestamp = blockTimestamp + self.calls = calls + self.uniqueModels = uniqueModels + } + + +} + +#if compiler(>=6) +extension Transaction: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTransaction: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Transaction { + return + try Transaction( + transactionHash: FfiConverterTypeFieldElement.read(from: &buf), + senderAddress: FfiConverterTypeFieldElement.read(from: &buf), + calldata: FfiConverterSequenceTypeFieldElement.read(from: &buf), + maxFee: FfiConverterTypeFieldElement.read(from: &buf), + signature: FfiConverterSequenceTypeFieldElement.read(from: &buf), + nonce: FfiConverterTypeFieldElement.read(from: &buf), + blockNumber: FfiConverterUInt64.read(from: &buf), + transactionType: FfiConverterString.read(from: &buf), + blockTimestamp: FfiConverterUInt64.read(from: &buf), + calls: FfiConverterSequenceTypeTransactionCall.read(from: &buf), + uniqueModels: FfiConverterSequenceTypeFieldElement.read(from: &buf) ) - - case 7: return .byteArray(value: try FfiConverterString.read(from: &buf) + } + + public static func write(_ value: Transaction, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.transactionHash, into: &buf) + FfiConverterTypeFieldElement.write(value.senderAddress, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.calldata, into: &buf) + FfiConverterTypeFieldElement.write(value.maxFee, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.signature, into: &buf) + FfiConverterTypeFieldElement.write(value.nonce, into: &buf) + FfiConverterUInt64.write(value.blockNumber, into: &buf) + FfiConverterString.write(value.transactionType, into: &buf) + FfiConverterUInt64.write(value.blockTimestamp, into: &buf) + FfiConverterSequenceTypeTransactionCall.write(value.calls, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.uniqueModels, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransaction_lift(_ buf: RustBuffer) throws -> Transaction { + return try FfiConverterTypeTransaction.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransaction_lower(_ value: Transaction) -> RustBuffer { + return FfiConverterTypeTransaction.lower(value) +} + + +public struct TransactionCall: Equatable, Hashable { + public let contractAddress: FieldElement + public let entrypoint: String + public let calldata: [FieldElement] + public let callType: CallType + public let callerAddress: FieldElement + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(contractAddress: FieldElement, entrypoint: String, calldata: [FieldElement], callType: CallType, callerAddress: FieldElement) { + self.contractAddress = contractAddress + self.entrypoint = entrypoint + self.calldata = calldata + self.callType = callType + self.callerAddress = callerAddress + } + + +} + +#if compiler(>=6) +extension TransactionCall: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTransactionCall: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TransactionCall { + return + try TransactionCall( + contractAddress: FfiConverterTypeFieldElement.read(from: &buf), + entrypoint: FfiConverterString.read(from: &buf), + calldata: FfiConverterSequenceTypeFieldElement.read(from: &buf), + callType: FfiConverterTypeCallType.read(from: &buf), + callerAddress: FfiConverterTypeFieldElement.read(from: &buf) ) - - default: throw UniffiInternalError.unexpectedEnumCase - } } - public static func write(_ value: Ty, into buf: inout [UInt8]) { - switch value { - - - case let .primitive(value): - writeInt(&buf, Int32(1)) - FfiConverterTypePrimitive.write(value, into: &buf) - - - case let .`struct`(value): - writeInt(&buf, Int32(2)) - FfiConverterTypeStruct.write(value, into: &buf) - - - case let .`enum`(value): - writeInt(&buf, Int32(3)) - FfiConverterTypeEnumType.write(value, into: &buf) - - - case let .tuple(values): - writeInt(&buf, Int32(4)) - FfiConverterSequenceTypeTy.write(values, into: &buf) - - - case let .array(values): - writeInt(&buf, Int32(5)) - FfiConverterSequenceTypeTy.write(values, into: &buf) - - - case let .fixedSizeArray(value): - writeInt(&buf, Int32(6)) - FfiConverterTypeFixedSizeArray.write(value, into: &buf) - + public static func write(_ value: TransactionCall, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.contractAddress, into: &buf) + FfiConverterString.write(value.entrypoint, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.calldata, into: &buf) + FfiConverterTypeCallType.write(value.callType, into: &buf) + FfiConverterTypeFieldElement.write(value.callerAddress, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransactionCall_lift(_ buf: RustBuffer) throws -> TransactionCall { + return try FfiConverterTypeTransactionCall.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransactionCall_lower(_ value: TransactionCall) -> RustBuffer { + return FfiConverterTypeTransactionCall.lower(value) +} + + +public struct TransactionFilter: Equatable, Hashable { + public let transactionHashes: [FieldElement] + public let callerAddresses: [FieldElement] + public let contractAddresses: [FieldElement] + public let entrypoints: [String] + public let modelSelectors: [FieldElement] + public let fromBlock: UInt64? + public let toBlock: UInt64? + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(transactionHashes: [FieldElement], callerAddresses: [FieldElement], contractAddresses: [FieldElement], entrypoints: [String], modelSelectors: [FieldElement], fromBlock: UInt64?, toBlock: UInt64?) { + self.transactionHashes = transactionHashes + self.callerAddresses = callerAddresses + self.contractAddresses = contractAddresses + self.entrypoints = entrypoints + self.modelSelectors = modelSelectors + self.fromBlock = fromBlock + self.toBlock = toBlock + } + + +} + +#if compiler(>=6) +extension TransactionFilter: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTransactionFilter: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TransactionFilter { + return + try TransactionFilter( + transactionHashes: FfiConverterSequenceTypeFieldElement.read(from: &buf), + callerAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + contractAddresses: FfiConverterSequenceTypeFieldElement.read(from: &buf), + entrypoints: FfiConverterSequenceString.read(from: &buf), + modelSelectors: FfiConverterSequenceTypeFieldElement.read(from: &buf), + fromBlock: FfiConverterOptionUInt64.read(from: &buf), + toBlock: FfiConverterOptionUInt64.read(from: &buf) + ) + } + + public static func write(_ value: TransactionFilter, into buf: inout [UInt8]) { + FfiConverterSequenceTypeFieldElement.write(value.transactionHashes, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.callerAddresses, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.contractAddresses, into: &buf) + FfiConverterSequenceString.write(value.entrypoints, into: &buf) + FfiConverterSequenceTypeFieldElement.write(value.modelSelectors, into: &buf) + FfiConverterOptionUInt64.write(value.fromBlock, into: &buf) + FfiConverterOptionUInt64.write(value.toBlock, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransactionFilter_lift(_ buf: RustBuffer) throws -> TransactionFilter { + return try FfiConverterTypeTransactionFilter.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransactionFilter_lower(_ value: TransactionFilter) -> RustBuffer { + return FfiConverterTypeTransactionFilter.lower(value) +} + + +public struct TransactionQuery: Equatable, Hashable { + public let filter: TransactionFilter? + public let pagination: Pagination + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(filter: TransactionFilter?, pagination: Pagination) { + self.filter = filter + self.pagination = pagination + } + + +} + +#if compiler(>=6) +extension TransactionQuery: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTransactionQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TransactionQuery { + return + try TransactionQuery( + filter: FfiConverterOptionTypeTransactionFilter.read(from: &buf), + pagination: FfiConverterTypePagination.read(from: &buf) + ) + } + + public static func write(_ value: TransactionQuery, into buf: inout [UInt8]) { + FfiConverterOptionTypeTransactionFilter.write(value.filter, into: &buf) + FfiConverterTypePagination.write(value.pagination, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransactionQuery_lift(_ buf: RustBuffer) throws -> TransactionQuery { + return try FfiConverterTypeTransactionQuery.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTransactionQuery_lower(_ value: TransactionQuery) -> RustBuffer { + return FfiConverterTypeTransactionQuery.lower(value) +} + + +public struct World: Equatable, Hashable { + public let worldAddress: FieldElement + public let models: [Model] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(worldAddress: FieldElement, models: [Model]) { + self.worldAddress = worldAddress + self.models = models + } + + +} + +#if compiler(>=6) +extension World: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeWorld: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> World { + return + try World( + worldAddress: FfiConverterTypeFieldElement.read(from: &buf), + models: FfiConverterSequenceTypeModel.read(from: &buf) + ) + } + + public static func write(_ value: World, into buf: inout [UInt8]) { + FfiConverterTypeFieldElement.write(value.worldAddress, into: &buf) + FfiConverterSequenceTypeModel.write(value.models, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeWorld_lift(_ buf: RustBuffer) throws -> World { + return try FfiConverterTypeWorld.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeWorld_lower(_ value: World) -> RustBuffer { + return FfiConverterTypeWorld.lower(value) +} + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum CallType: Equatable, Hashable { + + case execute + case executeFromOutside + + + +} + +#if compiler(>=6) +extension CallType: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeCallType: FfiConverterRustBuffer { + typealias SwiftType = CallType + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> CallType { + let variant: Int32 = try readInt(&buf) + switch variant { - case let .byteArray(value): - writeInt(&buf, Int32(7)) - FfiConverterString.write(value, into: &buf) - + case 1: return .execute + + case 2: return .executeFromOutside + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: CallType, into buf: inout [UInt8]) { + switch value { + + + case .execute: + writeInt(&buf, Int32(1)) + + + case .executeFromOutside: + writeInt(&buf, Int32(2)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeCallType_lift(_ buf: RustBuffer) throws -> CallType { + return try FfiConverterTypeCallType.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeCallType_lower(_ value: CallType) -> RustBuffer { + return FfiConverterTypeCallType.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum Clause: Equatable, Hashable { + + case hashedKeys(keys: [FieldElement] + ) + case keys(clause: KeysClause + ) + case member(clause: MemberClause + ) + case composite(clause: CompositeClause + ) + + + +} + +#if compiler(>=6) +extension Clause: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeClause: FfiConverterRustBuffer { + typealias SwiftType = Clause + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Clause { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .hashedKeys(keys: try FfiConverterSequenceTypeFieldElement.read(from: &buf) + ) + + case 2: return .keys(clause: try FfiConverterTypeKeysClause.read(from: &buf) + ) + + case 3: return .member(clause: try FfiConverterTypeMemberClause.read(from: &buf) + ) + + case 4: return .composite(clause: try FfiConverterTypeCompositeClause.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: Clause, into buf: inout [UInt8]) { + switch value { + + + case let .hashedKeys(keys): + writeInt(&buf, Int32(1)) + FfiConverterSequenceTypeFieldElement.write(keys, into: &buf) + + + case let .keys(clause): + writeInt(&buf, Int32(2)) + FfiConverterTypeKeysClause.write(clause, into: &buf) + + + case let .member(clause): + writeInt(&buf, Int32(3)) + FfiConverterTypeMemberClause.write(clause, into: &buf) + + + case let .composite(clause): + writeInt(&buf, Int32(4)) + FfiConverterTypeCompositeClause.write(clause, into: &buf) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeClause_lift(_ buf: RustBuffer) throws -> Clause { + return try FfiConverterTypeClause.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeClause_lower(_ value: Clause) -> RustBuffer { + return FfiConverterTypeClause.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum ComparisonOperator: Equatable, Hashable { + + case eq + case neq + case gt + case gte + case lt + case lte + case `in` + case notIn + case contains + case containsAll + case containsAny + case arrayLengthEq + case arrayLengthGt + case arrayLengthLt + + + +} + +#if compiler(>=6) +extension ComparisonOperator: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeComparisonOperator: FfiConverterRustBuffer { + typealias SwiftType = ComparisonOperator + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ComparisonOperator { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .eq + + case 2: return .neq + + case 3: return .gt + + case 4: return .gte + + case 5: return .lt + + case 6: return .lte + + case 7: return .`in` + + case 8: return .notIn + + case 9: return .contains + + case 10: return .containsAll + + case 11: return .containsAny + + case 12: return .arrayLengthEq + + case 13: return .arrayLengthGt + + case 14: return .arrayLengthLt + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: ComparisonOperator, into buf: inout [UInt8]) { + switch value { + + + case .eq: + writeInt(&buf, Int32(1)) + + + case .neq: + writeInt(&buf, Int32(2)) + + + case .gt: + writeInt(&buf, Int32(3)) + + + case .gte: + writeInt(&buf, Int32(4)) + + + case .lt: + writeInt(&buf, Int32(5)) + + + case .lte: + writeInt(&buf, Int32(6)) + + + case .`in`: + writeInt(&buf, Int32(7)) + + + case .notIn: + writeInt(&buf, Int32(8)) + + + case .contains: + writeInt(&buf, Int32(9)) + + + case .containsAll: + writeInt(&buf, Int32(10)) + + + case .containsAny: + writeInt(&buf, Int32(11)) + + + case .arrayLengthEq: + writeInt(&buf, Int32(12)) + + + case .arrayLengthGt: + writeInt(&buf, Int32(13)) + + + case .arrayLengthLt: + writeInt(&buf, Int32(14)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeComparisonOperator_lift(_ buf: RustBuffer) throws -> ComparisonOperator { + return try FfiConverterTypeComparisonOperator.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeComparisonOperator_lower(_ value: ComparisonOperator) -> RustBuffer { + return FfiConverterTypeComparisonOperator.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum ContractType: Equatable, Hashable { + + case world + case erc20 + case erc721 + case erc1155 + case udc + case other + + + +} + +#if compiler(>=6) +extension ContractType: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeContractType: FfiConverterRustBuffer { + typealias SwiftType = ContractType + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ContractType { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .world + + case 2: return .erc20 + + case 3: return .erc721 + + case 4: return .erc1155 + + case 5: return .udc + + case 6: return .other + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: ContractType, into buf: inout [UInt8]) { + switch value { + + + case .world: + writeInt(&buf, Int32(1)) + + + case .erc20: + writeInt(&buf, Int32(2)) + + + case .erc721: + writeInt(&buf, Int32(3)) + + + case .erc1155: + writeInt(&buf, Int32(4)) + + + case .udc: + writeInt(&buf, Int32(5)) + + + case .other: + writeInt(&buf, Int32(6)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeContractType_lift(_ buf: RustBuffer) throws -> ContractType { + return try FfiConverterTypeContractType.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeContractType_lower(_ value: ContractType) -> RustBuffer { + return FfiConverterTypeContractType.lower(value) +} + + + +public enum DojoError: Swift.Error, Equatable, Hashable, Foundation.LocalizedError { + + + + case ClientError(message: String) + + case SerializationError(message: String) + + case NetworkError(message: String) + + case InvalidInput(message: String) + + case ConnectionError(message: String) + + case PublishError(message: String) + + case QueryError(message: String) + + + + + + public var errorDescription: String? { + String(reflecting: self) + } + +} + +#if compiler(>=6) +extension DojoError: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeDojoError: FfiConverterRustBuffer { + typealias SwiftType = DojoError + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> DojoError { + let variant: Int32 = try readInt(&buf) + switch variant { + + + + + case 1: return .ClientError( + message: try FfiConverterString.read(from: &buf) + ) + + case 2: return .SerializationError( + message: try FfiConverterString.read(from: &buf) + ) + + case 3: return .NetworkError( + message: try FfiConverterString.read(from: &buf) + ) + + case 4: return .InvalidInput( + message: try FfiConverterString.read(from: &buf) + ) + + case 5: return .ConnectionError( + message: try FfiConverterString.read(from: &buf) + ) + + case 6: return .PublishError( + message: try FfiConverterString.read(from: &buf) + ) + + case 7: return .QueryError( + message: try FfiConverterString.read(from: &buf) + ) + + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: DojoError, into buf: inout [UInt8]) { + switch value { + + + + + case .ClientError(_ /* message is ignored*/): + writeInt(&buf, Int32(1)) + case .SerializationError(_ /* message is ignored*/): + writeInt(&buf, Int32(2)) + case .NetworkError(_ /* message is ignored*/): + writeInt(&buf, Int32(3)) + case .InvalidInput(_ /* message is ignored*/): + writeInt(&buf, Int32(4)) + case .ConnectionError(_ /* message is ignored*/): + writeInt(&buf, Int32(5)) + case .PublishError(_ /* message is ignored*/): + writeInt(&buf, Int32(6)) + case .QueryError(_ /* message is ignored*/): + writeInt(&buf, Int32(7)) + + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeDojoError_lift(_ buf: RustBuffer) throws -> DojoError { + return try FfiConverterTypeDojoError.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeDojoError_lower(_ value: DojoError) -> RustBuffer { + return FfiConverterTypeDojoError.lower(value) +} + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum LogicalOperator: Equatable, Hashable { + + case and + case or + + + +} + +#if compiler(>=6) +extension LogicalOperator: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeLogicalOperator: FfiConverterRustBuffer { + typealias SwiftType = LogicalOperator + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> LogicalOperator { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .and + + case 2: return .or + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: LogicalOperator, into buf: inout [UInt8]) { + switch value { + + + case .and: + writeInt(&buf, Int32(1)) + + + case .or: + writeInt(&buf, Int32(2)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeLogicalOperator_lift(_ buf: RustBuffer) throws -> LogicalOperator { + return try FfiConverterTypeLogicalOperator.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeLogicalOperator_lower(_ value: LogicalOperator) -> RustBuffer { + return FfiConverterTypeLogicalOperator.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum MemberValue: Equatable, Hashable { + + case primitive(value: Primitive + ) + case string(value: String + ) + case list(values: [MemberValue] + ) + + + +} + +#if compiler(>=6) +extension MemberValue: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeMemberValue: FfiConverterRustBuffer { + typealias SwiftType = MemberValue + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> MemberValue { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .primitive(value: try FfiConverterTypePrimitive.read(from: &buf) + ) + + case 2: return .string(value: try FfiConverterString.read(from: &buf) + ) + + case 3: return .list(values: try FfiConverterSequenceTypeMemberValue.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: MemberValue, into buf: inout [UInt8]) { + switch value { + + + case let .primitive(value): + writeInt(&buf, Int32(1)) + FfiConverterTypePrimitive.write(value, into: &buf) + + + case let .string(value): + writeInt(&buf, Int32(2)) + FfiConverterString.write(value, into: &buf) + + + case let .list(values): + writeInt(&buf, Int32(3)) + FfiConverterSequenceTypeMemberValue.write(values, into: &buf) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeMemberValue_lift(_ buf: RustBuffer) throws -> MemberValue { + return try FfiConverterTypeMemberValue.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeMemberValue_lower(_ value: MemberValue) -> RustBuffer { + return FfiConverterTypeMemberValue.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum OrderDirection: Equatable, Hashable { + + case asc + case desc + + + +} + +#if compiler(>=6) +extension OrderDirection: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeOrderDirection: FfiConverterRustBuffer { + typealias SwiftType = OrderDirection + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> OrderDirection { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .asc + + case 2: return .desc + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: OrderDirection, into buf: inout [UInt8]) { + switch value { + + + case .asc: + writeInt(&buf, Int32(1)) + + + case .desc: + writeInt(&buf, Int32(2)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeOrderDirection_lift(_ buf: RustBuffer) throws -> OrderDirection { + return try FfiConverterTypeOrderDirection.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeOrderDirection_lower(_ value: OrderDirection) -> RustBuffer { + return FfiConverterTypeOrderDirection.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum PaginationDirection: Equatable, Hashable { + + case forward + case backward + + + +} + +#if compiler(>=6) +extension PaginationDirection: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePaginationDirection: FfiConverterRustBuffer { + typealias SwiftType = PaginationDirection + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PaginationDirection { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .forward + + case 2: return .backward + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: PaginationDirection, into buf: inout [UInt8]) { + switch value { + + + case .forward: + writeInt(&buf, Int32(1)) + + + case .backward: + writeInt(&buf, Int32(2)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePaginationDirection_lift(_ buf: RustBuffer) throws -> PaginationDirection { + return try FfiConverterTypePaginationDirection.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePaginationDirection_lower(_ value: PaginationDirection) -> RustBuffer { + return FfiConverterTypePaginationDirection.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum PatternMatching: Equatable, Hashable { + + case fixedLen + case variableLen + + + +} + +#if compiler(>=6) +extension PatternMatching: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePatternMatching: FfiConverterRustBuffer { + typealias SwiftType = PatternMatching + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> PatternMatching { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .fixedLen + + case 2: return .variableLen + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: PatternMatching, into buf: inout [UInt8]) { + switch value { + + + case .fixedLen: + writeInt(&buf, Int32(1)) + + + case .variableLen: + writeInt(&buf, Int32(2)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePatternMatching_lift(_ buf: RustBuffer) throws -> PatternMatching { + return try FfiConverterTypePatternMatching.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePatternMatching_lower(_ value: PatternMatching) -> RustBuffer { + return FfiConverterTypePatternMatching.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum Primitive: Equatable, Hashable { + + case i8(value: Int8 + ) + case i16(value: Int16 + ) + case i32(value: Int32 + ) + case i64(value: Int64 + ) + case i128(value: [UInt8] + ) + case u8(value: UInt8 + ) + case u16(value: UInt16 + ) + case u32(value: UInt32 + ) + case u64(value: UInt64 + ) + case u128(value: [UInt8] + ) + case u256(value: U256 + ) + case bool(value: Bool + ) + case felt252(value: FieldElement + ) + case classHash(value: FieldElement + ) + case contractAddress(value: FieldElement + ) + case ethAddress(value: FieldElement + ) + + + +} + +#if compiler(>=6) +extension Primitive: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypePrimitive: FfiConverterRustBuffer { + typealias SwiftType = Primitive + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Primitive { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .i8(value: try FfiConverterInt8.read(from: &buf) + ) + + case 2: return .i16(value: try FfiConverterInt16.read(from: &buf) + ) + + case 3: return .i32(value: try FfiConverterInt32.read(from: &buf) + ) + + case 4: return .i64(value: try FfiConverterInt64.read(from: &buf) + ) + + case 5: return .i128(value: try FfiConverterSequenceUInt8.read(from: &buf) + ) + + case 6: return .u8(value: try FfiConverterUInt8.read(from: &buf) + ) + + case 7: return .u16(value: try FfiConverterUInt16.read(from: &buf) + ) + + case 8: return .u32(value: try FfiConverterUInt32.read(from: &buf) + ) + + case 9: return .u64(value: try FfiConverterUInt64.read(from: &buf) + ) + + case 10: return .u128(value: try FfiConverterSequenceUInt8.read(from: &buf) + ) + + case 11: return .u256(value: try FfiConverterTypeU256.read(from: &buf) + ) + + case 12: return .bool(value: try FfiConverterBool.read(from: &buf) + ) + + case 13: return .felt252(value: try FfiConverterTypeFieldElement.read(from: &buf) + ) + + case 14: return .classHash(value: try FfiConverterTypeFieldElement.read(from: &buf) + ) + + case 15: return .contractAddress(value: try FfiConverterTypeFieldElement.read(from: &buf) + ) + + case 16: return .ethAddress(value: try FfiConverterTypeFieldElement.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: Primitive, into buf: inout [UInt8]) { + switch value { + + + case let .i8(value): + writeInt(&buf, Int32(1)) + FfiConverterInt8.write(value, into: &buf) + + + case let .i16(value): + writeInt(&buf, Int32(2)) + FfiConverterInt16.write(value, into: &buf) + + + case let .i32(value): + writeInt(&buf, Int32(3)) + FfiConverterInt32.write(value, into: &buf) + + + case let .i64(value): + writeInt(&buf, Int32(4)) + FfiConverterInt64.write(value, into: &buf) + + + case let .i128(value): + writeInt(&buf, Int32(5)) + FfiConverterSequenceUInt8.write(value, into: &buf) + + + case let .u8(value): + writeInt(&buf, Int32(6)) + FfiConverterUInt8.write(value, into: &buf) + + + case let .u16(value): + writeInt(&buf, Int32(7)) + FfiConverterUInt16.write(value, into: &buf) + + + case let .u32(value): + writeInt(&buf, Int32(8)) + FfiConverterUInt32.write(value, into: &buf) + + + case let .u64(value): + writeInt(&buf, Int32(9)) + FfiConverterUInt64.write(value, into: &buf) + + + case let .u128(value): + writeInt(&buf, Int32(10)) + FfiConverterSequenceUInt8.write(value, into: &buf) + + + case let .u256(value): + writeInt(&buf, Int32(11)) + FfiConverterTypeU256.write(value, into: &buf) + + + case let .bool(value): + writeInt(&buf, Int32(12)) + FfiConverterBool.write(value, into: &buf) + + + case let .felt252(value): + writeInt(&buf, Int32(13)) + FfiConverterTypeFieldElement.write(value, into: &buf) + + + case let .classHash(value): + writeInt(&buf, Int32(14)) + FfiConverterTypeFieldElement.write(value, into: &buf) + + + case let .contractAddress(value): + writeInt(&buf, Int32(15)) + FfiConverterTypeFieldElement.write(value, into: &buf) + + + case let .ethAddress(value): + writeInt(&buf, Int32(16)) + FfiConverterTypeFieldElement.write(value, into: &buf) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePrimitive_lift(_ buf: RustBuffer) throws -> Primitive { + return try FfiConverterTypePrimitive.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypePrimitive_lower(_ value: Primitive) -> RustBuffer { + return FfiConverterTypePrimitive.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum SqlValue: Equatable, Hashable { + + case text(value: String + ) + case integer(value: Int64 + ) + case real(value: Double + ) + case blob(value: [UInt8] + ) + case null + + + +} + +#if compiler(>=6) +extension SqlValue: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeSqlValue: FfiConverterRustBuffer { + typealias SwiftType = SqlValue + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SqlValue { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .text(value: try FfiConverterString.read(from: &buf) + ) + + case 2: return .integer(value: try FfiConverterInt64.read(from: &buf) + ) + + case 3: return .real(value: try FfiConverterDouble.read(from: &buf) + ) + + case 4: return .blob(value: try FfiConverterSequenceUInt8.read(from: &buf) + ) + + case 5: return .null + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: SqlValue, into buf: inout [UInt8]) { + switch value { + + + case let .text(value): + writeInt(&buf, Int32(1)) + FfiConverterString.write(value, into: &buf) + + + case let .integer(value): + writeInt(&buf, Int32(2)) + FfiConverterInt64.write(value, into: &buf) + + + case let .real(value): + writeInt(&buf, Int32(3)) + FfiConverterDouble.write(value, into: &buf) + + + case let .blob(value): + writeInt(&buf, Int32(4)) + FfiConverterSequenceUInt8.write(value, into: &buf) + + + case .null: + writeInt(&buf, Int32(5)) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSqlValue_lift(_ buf: RustBuffer) throws -> SqlValue { + return try FfiConverterTypeSqlValue.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSqlValue_lower(_ value: SqlValue) -> RustBuffer { + return FfiConverterTypeSqlValue.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum Ty: Equatable, Hashable { + + case primitive(value: Primitive + ) + case `struct`(value: Struct + ) + case `enum`(value: EnumType + ) + case tuple(values: [Ty] + ) + case array(values: [Ty] + ) + case fixedSizeArray(value: FixedSizeArray + ) + case byteArray(value: String + ) + + + +} + +#if compiler(>=6) +extension Ty: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTy: FfiConverterRustBuffer { + typealias SwiftType = Ty + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Ty { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .primitive(value: try FfiConverterTypePrimitive.read(from: &buf) + ) + + case 2: return .`struct`(value: try FfiConverterTypeStruct.read(from: &buf) + ) + + case 3: return .`enum`(value: try FfiConverterTypeEnumType.read(from: &buf) + ) + + case 4: return .tuple(values: try FfiConverterSequenceTypeTy.read(from: &buf) + ) + + case 5: return .array(values: try FfiConverterSequenceTypeTy.read(from: &buf) + ) + + case 6: return .fixedSizeArray(value: try FfiConverterTypeFixedSizeArray.read(from: &buf) + ) + + case 7: return .byteArray(value: try FfiConverterString.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: Ty, into buf: inout [UInt8]) { + switch value { + + + case let .primitive(value): + writeInt(&buf, Int32(1)) + FfiConverterTypePrimitive.write(value, into: &buf) + + + case let .`struct`(value): + writeInt(&buf, Int32(2)) + FfiConverterTypeStruct.write(value, into: &buf) + + + case let .`enum`(value): + writeInt(&buf, Int32(3)) + FfiConverterTypeEnumType.write(value, into: &buf) + + + case let .tuple(values): + writeInt(&buf, Int32(4)) + FfiConverterSequenceTypeTy.write(values, into: &buf) + + + case let .array(values): + writeInt(&buf, Int32(5)) + FfiConverterSequenceTypeTy.write(values, into: &buf) + + + case let .fixedSizeArray(value): + writeInt(&buf, Int32(6)) + FfiConverterTypeFixedSizeArray.write(value, into: &buf) + + + case let .byteArray(value): + writeInt(&buf, Int32(7)) + FfiConverterString.write(value, into: &buf) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTy_lift(_ buf: RustBuffer) throws -> Ty { + return try FfiConverterTypeTy.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTy_lower(_ value: Ty) -> RustBuffer { + return FfiConverterTypeTy.lower(value) +} + + +// Note that we don't yet support `indirect` for enums. +// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + +public enum ValueType: Equatable, Hashable { + + case string(value: String + ) + case int(value: Int64 + ) + case uInt(value: UInt64 + ) + case bool(value: Bool + ) + case bytes(value: [UInt8] + ) + + + +} + +#if compiler(>=6) +extension ValueType: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeValueType: FfiConverterRustBuffer { + typealias SwiftType = ValueType + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ValueType { + let variant: Int32 = try readInt(&buf) + switch variant { + + case 1: return .string(value: try FfiConverterString.read(from: &buf) + ) + + case 2: return .int(value: try FfiConverterInt64.read(from: &buf) + ) + + case 3: return .uInt(value: try FfiConverterUInt64.read(from: &buf) + ) + + case 4: return .bool(value: try FfiConverterBool.read(from: &buf) + ) + + case 5: return .bytes(value: try FfiConverterSequenceUInt8.read(from: &buf) + ) + + default: throw UniffiInternalError.unexpectedEnumCase + } + } + + public static func write(_ value: ValueType, into buf: inout [UInt8]) { + switch value { + + + case let .string(value): + writeInt(&buf, Int32(1)) + FfiConverterString.write(value, into: &buf) + + + case let .int(value): + writeInt(&buf, Int32(2)) + FfiConverterInt64.write(value, into: &buf) + + + case let .uInt(value): + writeInt(&buf, Int32(3)) + FfiConverterUInt64.write(value, into: &buf) + + + case let .bool(value): + writeInt(&buf, Int32(4)) + FfiConverterBool.write(value, into: &buf) + + + case let .bytes(value): + writeInt(&buf, Int32(5)) + FfiConverterSequenceUInt8.write(value, into: &buf) + + } + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeValueType_lift(_ buf: RustBuffer) throws -> ValueType { + return try FfiConverterTypeValueType.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeValueType_lower(_ value: ValueType) -> RustBuffer { + return FfiConverterTypeValueType.lower(value) +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionUInt32: FfiConverterRustBuffer { + typealias SwiftType = UInt32? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterUInt32.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterUInt32.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionUInt64: FfiConverterRustBuffer { + typealias SwiftType = UInt64? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterUInt64.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterUInt64.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionBool: FfiConverterRustBuffer { + typealias SwiftType = Bool? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterBool.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterBool.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionString: FfiConverterRustBuffer { + typealias SwiftType = String? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterString.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterString.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeKeysClause: FfiConverterRustBuffer { + typealias SwiftType = KeysClause? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeKeysClause.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeKeysClause.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeTransactionFilter: FfiConverterRustBuffer { + typealias SwiftType = TransactionFilter? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeTransactionFilter.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeTransactionFilter.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeClause: FfiConverterRustBuffer { + typealias SwiftType = Clause? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeClause.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeClause.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeFieldElement: FfiConverterRustBuffer { + typealias SwiftType = FieldElement? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeFieldElement.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeFieldElement.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionTypeU256: FfiConverterRustBuffer { + typealias SwiftType = U256? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterTypeU256.write(value, into: &buf) + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { + switch try readInt(&buf) as Int8 { + case 0: return nil + case 1: return try FfiConverterTypeU256.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceUInt8: FfiConverterRustBuffer { + typealias SwiftType = [UInt8] + + public static func write(_ value: [UInt8], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterUInt8.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [UInt8] { + let len: Int32 = try readInt(&buf) + var seq = [UInt8]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterUInt8.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceString: FfiConverterRustBuffer { + typealias SwiftType = [String] + + public static func write(_ value: [String], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterString.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [String] { + let len: Int32 = try readInt(&buf) + var seq = [String]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterString.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeAchievement: FfiConverterRustBuffer { + typealias SwiftType = [Achievement] + + public static func write(_ value: [Achievement], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeAchievement.write(item, into: &buf) } } -} + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Achievement] { + let len: Int32 = try readInt(&buf) + var seq = [Achievement]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeAchievement.read(from: &buf)) + } + return seq + } +} #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTy_lift(_ buf: RustBuffer) throws -> Ty { - return try FfiConverterTypeTy.lift(buf) +fileprivate struct FfiConverterSequenceTypeAchievementTask: FfiConverterRustBuffer { + typealias SwiftType = [AchievementTask] + + public static func write(_ value: [AchievementTask], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeAchievementTask.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [AchievementTask] { + let len: Int32 = try readInt(&buf) + var seq = [AchievementTask]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeAchievementTask.read(from: &buf)) + } + return seq + } } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeTy_lower(_ value: Ty) -> RustBuffer { - return FfiConverterTypeTy.lower(value) +fileprivate struct FfiConverterSequenceTypeActionCount: FfiConverterRustBuffer { + typealias SwiftType = [ActionCount] + + public static func write(_ value: [ActionCount], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeActionCount.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [ActionCount] { + let len: Int32 = try readInt(&buf) + var seq = [ActionCount]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeActionCount.read(from: &buf)) + } + return seq + } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeActivity: FfiConverterRustBuffer { + typealias SwiftType = [Activity] -// Note that we don't yet support `indirect` for enums. -// See https://github.com/mozilla/uniffi-rs/issues/396 for further discussion. + public static func write(_ value: [Activity], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeActivity.write(item, into: &buf) + } + } -public enum ValueType: Equatable, Hashable { - - case string(value: String - ) - case int(value: Int64 - ) - case uInt(value: UInt64 - ) - case bool(value: Bool - ) - case bytes(value: [UInt8] - ) + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Activity] { + let len: Int32 = try readInt(&buf) + var seq = [Activity]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeActivity.read(from: &buf)) + } + return seq + } +} +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeAggregationEntry: FfiConverterRustBuffer { + typealias SwiftType = [AggregationEntry] + public static func write(_ value: [AggregationEntry], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeAggregationEntry.write(item, into: &buf) + } + } + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [AggregationEntry] { + let len: Int32 = try readInt(&buf) + var seq = [AggregationEntry]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeAggregationEntry.read(from: &buf)) + } + return seq + } } -#if compiler(>=6) -extension ValueType: Sendable {} +#if swift(>=5.8) +@_documentation(visibility: private) #endif +fileprivate struct FfiConverterSequenceTypeAttributeFilter: FfiConverterRustBuffer { + typealias SwiftType = [AttributeFilter] + + public static func write(_ value: [AttributeFilter], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeAttributeFilter.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [AttributeFilter] { + let len: Int32 = try readInt(&buf) + var seq = [AttributeFilter]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeAttributeFilter.read(from: &buf)) + } + return seq + } +} #if swift(>=5.8) @_documentation(visibility: private) #endif -public struct FfiConverterTypeValueType: FfiConverterRustBuffer { - typealias SwiftType = ValueType +fileprivate struct FfiConverterSequenceTypeContract: FfiConverterRustBuffer { + typealias SwiftType = [Contract] - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> ValueType { - let variant: Int32 = try readInt(&buf) - switch variant { - - case 1: return .string(value: try FfiConverterString.read(from: &buf) - ) - - case 2: return .int(value: try FfiConverterInt64.read(from: &buf) - ) - - case 3: return .uInt(value: try FfiConverterUInt64.read(from: &buf) - ) - - case 4: return .bool(value: try FfiConverterBool.read(from: &buf) - ) - - case 5: return .bytes(value: try FfiConverterSequenceUInt8.read(from: &buf) - ) - - default: throw UniffiInternalError.unexpectedEnumCase + public static func write(_ value: [Contract], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeContract.write(item, into: &buf) } } - public static func write(_ value: ValueType, into buf: inout [UInt8]) { - switch value { - - - case let .string(value): - writeInt(&buf, Int32(1)) - FfiConverterString.write(value, into: &buf) - - - case let .int(value): - writeInt(&buf, Int32(2)) - FfiConverterInt64.write(value, into: &buf) - - - case let .uInt(value): - writeInt(&buf, Int32(3)) - FfiConverterUInt64.write(value, into: &buf) - - - case let .bool(value): - writeInt(&buf, Int32(4)) - FfiConverterBool.write(value, into: &buf) - - - case let .bytes(value): - writeInt(&buf, Int32(5)) - FfiConverterSequenceUInt8.write(value, into: &buf) - + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Contract] { + let len: Int32 = try readInt(&buf) + var seq = [Contract]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeContract.read(from: &buf)) } + return seq } } - #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeValueType_lift(_ buf: RustBuffer) throws -> ValueType { - return try FfiConverterTypeValueType.lift(buf) +fileprivate struct FfiConverterSequenceTypeController: FfiConverterRustBuffer { + typealias SwiftType = [Controller] + + public static func write(_ value: [Controller], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeController.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Controller] { + let len: Int32 = try readInt(&buf) + var seq = [Controller]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeController.read(from: &buf)) + } + return seq + } } #if swift(>=5.8) @_documentation(visibility: private) #endif -public func FfiConverterTypeValueType_lower(_ value: ValueType) -> RustBuffer { - return FfiConverterTypeValueType.lower(value) -} +fileprivate struct FfiConverterSequenceTypeEntity: FfiConverterRustBuffer { + typealias SwiftType = [Entity] + + public static func write(_ value: [Entity], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeEntity.write(item, into: &buf) + } + } + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Entity] { + let len: Int32 = try readInt(&buf) + var seq = [Entity]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeEntity.read(from: &buf)) + } + return seq + } +} #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterOptionUInt32: FfiConverterRustBuffer { - typealias SwiftType = UInt32? +fileprivate struct FfiConverterSequenceTypeEnumOption: FfiConverterRustBuffer { + typealias SwiftType = [EnumOption] - public static func write(_ value: SwiftType, into buf: inout [UInt8]) { - guard let value = value else { - writeInt(&buf, Int8(0)) - return + public static func write(_ value: [EnumOption], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeEnumOption.write(item, into: &buf) } - writeInt(&buf, Int8(1)) - FfiConverterUInt32.write(value, into: &buf) } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { - switch try readInt(&buf) as Int8 { - case 0: return nil - case 1: return try FfiConverterUInt32.read(from: &buf) - default: throw UniffiInternalError.unexpectedOptionalTag + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [EnumOption] { + let len: Int32 = try readInt(&buf) + var seq = [EnumOption]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeEnumOption.read(from: &buf)) } + return seq } } #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterOptionUInt64: FfiConverterRustBuffer { - typealias SwiftType = UInt64? +fileprivate struct FfiConverterSequenceTypeEvent: FfiConverterRustBuffer { + typealias SwiftType = [Event] - public static func write(_ value: SwiftType, into buf: inout [UInt8]) { - guard let value = value else { - writeInt(&buf, Int8(0)) - return - } - writeInt(&buf, Int8(1)) - FfiConverterUInt64.write(value, into: &buf) + public static func write(_ value: [Event], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeEvent.write(item, into: &buf) + } } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { - switch try readInt(&buf) as Int8 { - case 0: return nil - case 1: return try FfiConverterUInt64.read(from: &buf) - default: throw UniffiInternalError.unexpectedOptionalTag + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Event] { + let len: Int32 = try readInt(&buf) + var seq = [Event]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeEvent.read(from: &buf)) } + return seq } } #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterOptionBool: FfiConverterRustBuffer { - typealias SwiftType = Bool? +fileprivate struct FfiConverterSequenceTypeMember: FfiConverterRustBuffer { + typealias SwiftType = [Member] - public static func write(_ value: SwiftType, into buf: inout [UInt8]) { - guard let value = value else { - writeInt(&buf, Int8(0)) - return + public static func write(_ value: [Member], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeMember.write(item, into: &buf) } - writeInt(&buf, Int8(1)) - FfiConverterBool.write(value, into: &buf) } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { - switch try readInt(&buf) as Int8 { - case 0: return nil - case 1: return try FfiConverterBool.read(from: &buf) - default: throw UniffiInternalError.unexpectedOptionalTag + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Member] { + let len: Int32 = try readInt(&buf) + var seq = [Member]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeMember.read(from: &buf)) } + return seq } } #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterOptionString: FfiConverterRustBuffer { - typealias SwiftType = String? +fileprivate struct FfiConverterSequenceTypeMessage: FfiConverterRustBuffer { + typealias SwiftType = [Message] - public static func write(_ value: SwiftType, into buf: inout [UInt8]) { - guard let value = value else { - writeInt(&buf, Int8(0)) - return + public static func write(_ value: [Message], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeMessage.write(item, into: &buf) } - writeInt(&buf, Int8(1)) - FfiConverterString.write(value, into: &buf) } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { - switch try readInt(&buf) as Int8 { - case 0: return nil - case 1: return try FfiConverterString.read(from: &buf) - default: throw UniffiInternalError.unexpectedOptionalTag + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Message] { + let len: Int32 = try readInt(&buf) + var seq = [Message]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeMessage.read(from: &buf)) } + return seq } } #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterOptionTypeTransactionFilter: FfiConverterRustBuffer { - typealias SwiftType = TransactionFilter? +fileprivate struct FfiConverterSequenceTypeModel: FfiConverterRustBuffer { + typealias SwiftType = [Model] - public static func write(_ value: SwiftType, into buf: inout [UInt8]) { - guard let value = value else { - writeInt(&buf, Int8(0)) - return + public static func write(_ value: [Model], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeModel.write(item, into: &buf) } - writeInt(&buf, Int8(1)) - FfiConverterTypeTransactionFilter.write(value, into: &buf) } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { - switch try readInt(&buf) as Int8 { - case 0: return nil - case 1: return try FfiConverterTypeTransactionFilter.read(from: &buf) - default: throw UniffiInternalError.unexpectedOptionalTag + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Model] { + let len: Int32 = try readInt(&buf) + var seq = [Model]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeModel.read(from: &buf)) } + return seq } } #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterOptionTypeFieldElement: FfiConverterRustBuffer { - typealias SwiftType = FieldElement? +fileprivate struct FfiConverterSequenceTypeOrderBy: FfiConverterRustBuffer { + typealias SwiftType = [OrderBy] - public static func write(_ value: SwiftType, into buf: inout [UInt8]) { - guard let value = value else { - writeInt(&buf, Int8(0)) - return + public static func write(_ value: [OrderBy], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeOrderBy.write(item, into: &buf) } - writeInt(&buf, Int8(1)) - FfiConverterTypeFieldElement.write(value, into: &buf) } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { - switch try readInt(&buf) as Int8 { - case 0: return nil - case 1: return try FfiConverterTypeFieldElement.read(from: &buf) - default: throw UniffiInternalError.unexpectedOptionalTag + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [OrderBy] { + let len: Int32 = try readInt(&buf) + var seq = [OrderBy]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeOrderBy.read(from: &buf)) } + return seq } } #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterOptionTypeU256: FfiConverterRustBuffer { - typealias SwiftType = U256? +fileprivate struct FfiConverterSequenceTypePlayerAchievementEntry: FfiConverterRustBuffer { + typealias SwiftType = [PlayerAchievementEntry] - public static func write(_ value: SwiftType, into buf: inout [UInt8]) { - guard let value = value else { - writeInt(&buf, Int8(0)) - return + public static func write(_ value: [PlayerAchievementEntry], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypePlayerAchievementEntry.write(item, into: &buf) } - writeInt(&buf, Int8(1)) - FfiConverterTypeU256.write(value, into: &buf) } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType { - switch try readInt(&buf) as Int8 { - case 0: return nil - case 1: return try FfiConverterTypeU256.read(from: &buf) - default: throw UniffiInternalError.unexpectedOptionalTag + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [PlayerAchievementEntry] { + let len: Int32 = try readInt(&buf) + var seq = [PlayerAchievementEntry]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypePlayerAchievementEntry.read(from: &buf)) } + return seq } } #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterSequenceUInt8: FfiConverterRustBuffer { - typealias SwiftType = [UInt8] +fileprivate struct FfiConverterSequenceTypePlayerAchievementProgress: FfiConverterRustBuffer { + typealias SwiftType = [PlayerAchievementProgress] - public static func write(_ value: [UInt8], into buf: inout [UInt8]) { + public static func write(_ value: [PlayerAchievementProgress], into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) for item in value { - FfiConverterUInt8.write(item, into: &buf) + FfiConverterTypePlayerAchievementProgress.write(item, into: &buf) } } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [UInt8] { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [PlayerAchievementProgress] { let len: Int32 = try readInt(&buf) - var seq = [UInt8]() + var seq = [PlayerAchievementProgress]() seq.reserveCapacity(Int(len)) for _ in 0 ..< len { - seq.append(try FfiConverterUInt8.read(from: &buf)) + seq.append(try FfiConverterTypePlayerAchievementProgress.read(from: &buf)) } return seq } @@ -4749,23 +7007,23 @@ fileprivate struct FfiConverterSequenceUInt8: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterSequenceString: FfiConverterRustBuffer { - typealias SwiftType = [String] +fileprivate struct FfiConverterSequenceTypeSqlField: FfiConverterRustBuffer { + typealias SwiftType = [SqlField] - public static func write(_ value: [String], into buf: inout [UInt8]) { + public static func write(_ value: [SqlField], into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) for item in value { - FfiConverterString.write(item, into: &buf) + FfiConverterTypeSqlField.write(item, into: &buf) } } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [String] { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [SqlField] { let len: Int32 = try readInt(&buf) - var seq = [String]() + var seq = [SqlField]() seq.reserveCapacity(Int(len)) for _ in 0 ..< len { - seq.append(try FfiConverterString.read(from: &buf)) + seq.append(try FfiConverterTypeSqlField.read(from: &buf)) } return seq } @@ -4774,23 +7032,23 @@ fileprivate struct FfiConverterSequenceString: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterSequenceTypeAchievementTask: FfiConverterRustBuffer { - typealias SwiftType = [AchievementTask] +fileprivate struct FfiConverterSequenceTypeSqlRow: FfiConverterRustBuffer { + typealias SwiftType = [SqlRow] - public static func write(_ value: [AchievementTask], into buf: inout [UInt8]) { + public static func write(_ value: [SqlRow], into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) for item in value { - FfiConverterTypeAchievementTask.write(item, into: &buf) + FfiConverterTypeSqlRow.write(item, into: &buf) } } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [AchievementTask] { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [SqlRow] { let len: Int32 = try readInt(&buf) - var seq = [AchievementTask]() + var seq = [SqlRow]() seq.reserveCapacity(Int(len)) for _ in 0 ..< len { - seq.append(try FfiConverterTypeAchievementTask.read(from: &buf)) + seq.append(try FfiConverterTypeSqlRow.read(from: &buf)) } return seq } @@ -4799,23 +7057,23 @@ fileprivate struct FfiConverterSequenceTypeAchievementTask: FfiConverterRustBuff #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterSequenceTypeActionCount: FfiConverterRustBuffer { - typealias SwiftType = [ActionCount] +fileprivate struct FfiConverterSequenceTypeStruct: FfiConverterRustBuffer { + typealias SwiftType = [Struct] - public static func write(_ value: [ActionCount], into buf: inout [UInt8]) { + public static func write(_ value: [Struct], into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) for item in value { - FfiConverterTypeActionCount.write(item, into: &buf) + FfiConverterTypeStruct.write(item, into: &buf) } } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [ActionCount] { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Struct] { let len: Int32 = try readInt(&buf) - var seq = [ActionCount]() + var seq = [Struct]() seq.reserveCapacity(Int(len)) for _ in 0 ..< len { - seq.append(try FfiConverterTypeActionCount.read(from: &buf)) + seq.append(try FfiConverterTypeStruct.read(from: &buf)) } return seq } @@ -4824,23 +7082,23 @@ fileprivate struct FfiConverterSequenceTypeActionCount: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterSequenceTypeAttributeFilter: FfiConverterRustBuffer { - typealias SwiftType = [AttributeFilter] +fileprivate struct FfiConverterSequenceTypeTaskProgress: FfiConverterRustBuffer { + typealias SwiftType = [TaskProgress] - public static func write(_ value: [AttributeFilter], into buf: inout [UInt8]) { + public static func write(_ value: [TaskProgress], into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) for item in value { - FfiConverterTypeAttributeFilter.write(item, into: &buf) + FfiConverterTypeTaskProgress.write(item, into: &buf) } } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [AttributeFilter] { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [TaskProgress] { let len: Int32 = try readInt(&buf) - var seq = [AttributeFilter]() + var seq = [TaskProgress]() seq.reserveCapacity(Int(len)) for _ in 0 ..< len { - seq.append(try FfiConverterTypeAttributeFilter.read(from: &buf)) + seq.append(try FfiConverterTypeTaskProgress.read(from: &buf)) } return seq } @@ -4849,23 +7107,23 @@ fileprivate struct FfiConverterSequenceTypeAttributeFilter: FfiConverterRustBuff #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterSequenceTypeEnumOption: FfiConverterRustBuffer { - typealias SwiftType = [EnumOption] +fileprivate struct FfiConverterSequenceTypeToken: FfiConverterRustBuffer { + typealias SwiftType = [Token] - public static func write(_ value: [EnumOption], into buf: inout [UInt8]) { + public static func write(_ value: [Token], into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) for item in value { - FfiConverterTypeEnumOption.write(item, into: &buf) + FfiConverterTypeToken.write(item, into: &buf) } } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [EnumOption] { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Token] { let len: Int32 = try readInt(&buf) - var seq = [EnumOption]() + var seq = [Token]() seq.reserveCapacity(Int(len)) for _ in 0 ..< len { - seq.append(try FfiConverterTypeEnumOption.read(from: &buf)) + seq.append(try FfiConverterTypeToken.read(from: &buf)) } return seq } @@ -4874,23 +7132,23 @@ fileprivate struct FfiConverterSequenceTypeEnumOption: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterSequenceTypeMember: FfiConverterRustBuffer { - typealias SwiftType = [Member] +fileprivate struct FfiConverterSequenceTypeTokenBalance: FfiConverterRustBuffer { + typealias SwiftType = [TokenBalance] - public static func write(_ value: [Member], into buf: inout [UInt8]) { + public static func write(_ value: [TokenBalance], into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) for item in value { - FfiConverterTypeMember.write(item, into: &buf) + FfiConverterTypeTokenBalance.write(item, into: &buf) } } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Member] { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [TokenBalance] { let len: Int32 = try readInt(&buf) - var seq = [Member]() + var seq = [TokenBalance]() seq.reserveCapacity(Int(len)) for _ in 0 ..< len { - seq.append(try FfiConverterTypeMember.read(from: &buf)) + seq.append(try FfiConverterTypeTokenBalance.read(from: &buf)) } return seq } @@ -4899,23 +7157,23 @@ fileprivate struct FfiConverterSequenceTypeMember: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterSequenceTypeOrderBy: FfiConverterRustBuffer { - typealias SwiftType = [OrderBy] +fileprivate struct FfiConverterSequenceTypeTokenContract: FfiConverterRustBuffer { + typealias SwiftType = [TokenContract] - public static func write(_ value: [OrderBy], into buf: inout [UInt8]) { + public static func write(_ value: [TokenContract], into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) for item in value { - FfiConverterTypeOrderBy.write(item, into: &buf) + FfiConverterTypeTokenContract.write(item, into: &buf) } } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [OrderBy] { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [TokenContract] { let len: Int32 = try readInt(&buf) - var seq = [OrderBy]() + var seq = [TokenContract]() seq.reserveCapacity(Int(len)) for _ in 0 ..< len { - seq.append(try FfiConverterTypeOrderBy.read(from: &buf)) + seq.append(try FfiConverterTypeTokenContract.read(from: &buf)) } return seq } @@ -4924,23 +7182,23 @@ fileprivate struct FfiConverterSequenceTypeOrderBy: FfiConverterRustBuffer { #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterSequenceTypePlayerAchievementProgress: FfiConverterRustBuffer { - typealias SwiftType = [PlayerAchievementProgress] +fileprivate struct FfiConverterSequenceTypeTokenTransfer: FfiConverterRustBuffer { + typealias SwiftType = [TokenTransfer] - public static func write(_ value: [PlayerAchievementProgress], into buf: inout [UInt8]) { + public static func write(_ value: [TokenTransfer], into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) for item in value { - FfiConverterTypePlayerAchievementProgress.write(item, into: &buf) + FfiConverterTypeTokenTransfer.write(item, into: &buf) } } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [PlayerAchievementProgress] { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [TokenTransfer] { let len: Int32 = try readInt(&buf) - var seq = [PlayerAchievementProgress]() + var seq = [TokenTransfer]() seq.reserveCapacity(Int(len)) for _ in 0 ..< len { - seq.append(try FfiConverterTypePlayerAchievementProgress.read(from: &buf)) + seq.append(try FfiConverterTypeTokenTransfer.read(from: &buf)) } return seq } @@ -4949,23 +7207,23 @@ fileprivate struct FfiConverterSequenceTypePlayerAchievementProgress: FfiConvert #if swift(>=5.8) @_documentation(visibility: private) #endif -fileprivate struct FfiConverterSequenceTypeTaskProgress: FfiConverterRustBuffer { - typealias SwiftType = [TaskProgress] +fileprivate struct FfiConverterSequenceTypeTransaction: FfiConverterRustBuffer { + typealias SwiftType = [Transaction] - public static func write(_ value: [TaskProgress], into buf: inout [UInt8]) { + public static func write(_ value: [Transaction], into buf: inout [UInt8]) { let len = Int32(value.count) writeInt(&buf, len) for item in value { - FfiConverterTypeTaskProgress.write(item, into: &buf) + FfiConverterTypeTransaction.write(item, into: &buf) } } - public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [TaskProgress] { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [Transaction] { let len: Int32 = try readInt(&buf) - var seq = [TaskProgress]() + var seq = [Transaction]() seq.reserveCapacity(Int(len)) for _ in 0 ..< len { - seq.append(try FfiConverterTypeTaskProgress.read(from: &buf)) + seq.append(try FfiConverterTypeTransaction.read(from: &buf)) } return seq } @@ -4996,6 +7254,31 @@ fileprivate struct FfiConverterSequenceTypeTransactionCall: FfiConverterRustBuff } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeWorld: FfiConverterRustBuffer { + typealias SwiftType = [World] + + public static func write(_ value: [World], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeWorld.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [World] { + let len: Int32 = try readInt(&buf) + var seq = [World]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeWorld.read(from: &buf)) + } + return seq + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -5258,6 +7541,54 @@ public func FfiConverterTypeU256_lower(_ value: U256) -> RustBuffer { return FfiConverterTypeU256.lower(value) } +private let UNIFFI_RUST_FUTURE_POLL_READY: Int8 = 0 +private let UNIFFI_RUST_FUTURE_POLL_WAKE: Int8 = 1 + +fileprivate let uniffiContinuationHandleMap = UniffiHandleMap>() + +fileprivate func uniffiRustCallAsync( + rustFutureFunc: () -> UInt64, + pollFunc: (UInt64, @escaping UniffiRustFutureContinuationCallback, UInt64) -> (), + completeFunc: (UInt64, UnsafeMutablePointer) -> F, + freeFunc: (UInt64) -> (), + liftFunc: (F) throws -> T, + errorHandler: ((RustBuffer) throws -> Swift.Error)? +) async throws -> T { + // Make sure to call the ensure init function since future creation doesn't have a + // RustCallStatus param, so doesn't use makeRustCall() + uniffiEnsureDojoCInitialized() + let rustFuture = rustFutureFunc() + defer { + freeFunc(rustFuture) + } + var pollResult: Int8; + repeat { + pollResult = await withUnsafeContinuation { + pollFunc( + rustFuture, + { handle, pollResult in + uniffiFutureContinuationCallback(handle: handle, pollResult: pollResult) + }, + uniffiContinuationHandleMap.insert(obj: $0) + ) + } + } while pollResult != UNIFFI_RUST_FUTURE_POLL_READY + + return try liftFunc(makeRustCall( + { completeFunc(rustFuture, $0) }, + errorHandler: errorHandler + )) +} + +// Callback handlers for an async calls. These are invoked by Rust when the future is ready. They +// lift the return value or error and resume the suspended function. +fileprivate func uniffiFutureContinuationCallback(handle: UInt64, pollResult: Int8) { + if let continuation = try? uniffiContinuationHandleMap.remove(handle: handle) { + continuation.resume(returning: pollResult) + } else { + print("uniffiFutureContinuationCallback invalid handle") + } +} private enum InitializationResult { case ok @@ -5274,6 +7605,66 @@ private let initializationResult: InitializationResult = { if bindings_contract_version != scaffolding_contract_version { return InitializationResult.contractVersionMismatch } + if (uniffi_dojo_c_checksum_method_toriiclient_achievements() != 53465) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_activities() != 57395) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_aggregations() != 38469) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_contracts() != 25010) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_controllers() != 20116) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_entities() != 42902) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_event_messages() != 61368) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_player_achievements() != 7710) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_publish_message() != 26581) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_publish_message_batch() != 12967) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_sql() != 47285) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_starknet_events() != 46078) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_token_balances() != 54254) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_token_contracts() != 7124) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_token_transfers() != 52205) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_tokens() != 55378) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_transactions() != 16952) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_method_toriiclient_worlds() != 35445) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_constructor_toriiclient_new() != 9333) { + return InitializationResult.apiChecksumMismatch + } + if (uniffi_dojo_c_checksum_constructor_toriiclient_new_with_config() != 41101) { + return InitializationResult.apiChecksumMismatch + } return InitializationResult.ok }() diff --git a/src/dojo.udl b/src/dojo.udl index e5c7e8d..9f3070f 100644 --- a/src/dojo.udl +++ b/src/dojo.udl @@ -342,6 +342,41 @@ dictionary PlayerAchievementQuery { Pagination pagination; }; +// General entity query +dictionary Query { + sequence world_addresses; + Pagination pagination; + Clause? clause; + boolean no_hashed_keys; + sequence models; + boolean historical; +}; + +// Event query +dictionary EventQuery { + KeysClause? keys; + Pagination pagination; +}; + +// SQL query result types +dictionary SqlField { + string name; + SqlValue value; +}; + +dictionary SqlRow { + sequence fields; +}; + +[Enum] +interface SqlValue { + Text(string value); + Integer(i64 value); + Real(f64 value); + Blob(sequence value); + Null(); +}; + dictionary AchievementProgression { string id; string achievement_id; @@ -460,6 +495,48 @@ interface Clause { Composite(CompositeClause clause); }; +// Event and Message types +dictionary Event { + sequence keys; + sequence data; + FieldElement transaction_hash; +}; + +dictionary Message { + string message; + sequence signature; + FieldElement world_address; +}; + +// Entity, Model, and World types +dictionary Entity { + FieldElement world_address; + FieldElement hashed_keys; + sequence models; + u64 created_at; + u64 updated_at; + u64 executed_at; +}; + +dictionary Model { + FieldElement world_address; + Ty schema; + string namespace; + string name; + FieldElement selector; + u32 packed_size; + u32 unpacked_size; + FieldElement class_hash; + FieldElement contract_address; + string layout; + boolean use_legacy_store; +}; + +dictionary World { + FieldElement world_address; + sequence models; +}; + // Error type [Error] enum DojoError { @@ -467,4 +544,203 @@ enum DojoError { "SerializationError", "NetworkError", "InvalidInput", + "ConnectionError", + "PublishError", + "QueryError", + "SubscriptionError", +}; + +// Callback interfaces for subscriptions +callback interface EntityUpdateCallback { + void on_update(Entity entity); + void on_error(string error); +}; + +callback interface TokenBalanceUpdateCallback { + void on_update(TokenBalance balance); + void on_error(string error); +}; + +callback interface TokenUpdateCallback { + void on_update(Token token); + void on_error(string error); +}; + +callback interface TransactionUpdateCallback { + void on_update(Transaction transaction); + void on_error(string error); +}; + +callback interface EventUpdateCallback { + void on_update(Event event); + void on_error(string error); +}; + +// Pagination wrapper types for different result types +dictionary PageController { + sequence items; + string? next_cursor; +}; + +dictionary PageToken { + sequence items; + string? next_cursor; +}; + +dictionary PageTokenBalance { + sequence items; + string? next_cursor; +}; + +dictionary PageTokenContract { + sequence items; + string? next_cursor; +}; + +dictionary PageTokenTransfer { + sequence items; + string? next_cursor; +}; + +dictionary PageTransaction { + sequence items; + string? next_cursor; +}; + +dictionary PageAggregationEntry { + sequence items; + string? next_cursor; +}; + +dictionary PageActivity { + sequence items; + string? next_cursor; +}; + +dictionary PageAchievement { + sequence items; + string? next_cursor; +}; + +dictionary PagePlayerAchievement { + sequence items; + string? next_cursor; +}; + +dictionary PageEntity { + sequence items; + string? next_cursor; +}; + +dictionary PageEvent { + sequence items; + string? next_cursor; +}; + +// Main Dojo client interface +interface ToriiClient { + // Constructor - create a new client with default config (4MB max message size) + [Async, Throws=DojoError] + constructor(string torii_url); + + // Constructor - create a new client with custom max message size + [Async, Throws=DojoError, Name=new_with_config] + constructor(string torii_url, u64 max_message_size); + + // Publish offchain message + [Async, Throws=DojoError] + string publish_message(Message message); + + // Publish multiple offchain messages + [Async, Throws=DojoError] + sequence publish_message_batch(sequence messages); + + // Get world metadata + [Async, Throws=DojoError] + sequence worlds(sequence world_addresses); + + // Query controllers + [Async, Throws=DojoError] + PageController controllers(ControllerQuery query); + + // Query contracts + [Async, Throws=DojoError] + sequence contracts(ContractQuery query); + + // Query tokens + [Async, Throws=DojoError] + PageToken tokens(TokenQuery query); + + // Query token balances + [Async, Throws=DojoError] + PageTokenBalance token_balances(TokenBalanceQuery query); + + // Query token contracts + [Async, Throws=DojoError] + PageTokenContract token_contracts(TokenContractQuery query); + + // Query token transfers + [Async, Throws=DojoError] + PageTokenTransfer token_transfers(TokenTransferQuery query); + + // Query transactions + [Async, Throws=DojoError] + PageTransaction transactions(TransactionQuery query); + + // Query aggregations (leaderboards, stats, rankings) + [Async, Throws=DojoError] + PageAggregationEntry aggregations(AggregationQuery query); + + // Query activities (user session tracking) + [Async, Throws=DojoError] + PageActivity activities(ActivityQuery query); + + // Query achievements + [Async, Throws=DojoError] + PageAchievement achievements(AchievementQuery query); + + // Query player achievements + [Async, Throws=DojoError] + PagePlayerAchievement player_achievements(PlayerAchievementQuery query); + + // Query entities + [Async, Throws=DojoError] + PageEntity entities(Query query); + + // Query event messages + [Async, Throws=DojoError] + PageEntity event_messages(Query query); + + // Query Starknet events + [Async, Throws=DojoError] + PageEvent starknet_events(EventQuery query); + + // Execute SQL query + [Async, Throws=DojoError] + sequence sql(string query); + + // Subscription methods + // Subscribe to entity updates + [Async, Throws=DojoError] + u64 subscribe_entity_updates(Clause? clause, sequence world_addresses, EntityUpdateCallback callback); + + // Subscribe to token balance updates + [Async, Throws=DojoError] + u64 subscribe_token_balance_updates(sequence contract_addresses, sequence account_addresses, sequence token_ids, TokenBalanceUpdateCallback callback); + + // Subscribe to token updates + [Async, Throws=DojoError] + u64 subscribe_token_updates(sequence contract_addresses, sequence token_ids, TokenUpdateCallback callback); + + // Subscribe to transaction updates + [Async, Throws=DojoError] + u64 subscribe_transaction_updates(TransactionFilter? filter, TransactionUpdateCallback callback); + + // Subscribe to starknet event updates + [Async, Throws=DojoError] + u64 subscribe_event_updates(sequence keys, EventUpdateCallback callback); + + // Cancel a subscription + [Throws=DojoError] + void cancel_subscription(u64 subscription_id); }; diff --git a/src/uniffi/README.md b/src/uniffi/README.md deleted file mode 100644 index 5b17f1e..0000000 --- a/src/uniffi/README.md +++ /dev/null @@ -1,307 +0,0 @@ -# UniFFI Types - Organized by Category - -This directory contains UniFFI-compatible Rust types for Dojo, organized by functional category for better maintainability and discoverability. - -## File Structure - -``` -src/uniffi/ -├── mod.rs # Module definitions and re-exports -├── core.rs # Core types and utilities -├── achievement.rs # Achievement system types -├── activity.rs # Activity tracking types -├── aggregation.rs # Data aggregation types -├── contract.rs # Smart contract types -├── controller.rs # Controller/account types -├── entity.rs # Entity, Model, and World types -├── event.rs # Event and Message types -├── query.rs # Query and filtering types -├── schema.rs # Schema definition types -├── token.rs # Token and NFT types -└── transaction.rs # Transaction types -``` - -## Module Organization - -### `core.rs` - Core Types and Utilities -The foundation module containing: -- **Type Definitions**: `FieldElement`, `U256` (as hex strings) -- **Error Handling**: `DojoError` enum -- **Pagination**: `Pagination`, `PaginationDirection`, `OrderBy`, `OrderDirection` -- **Common Types**: `Signature`, `Call`, `BlockId`, `BlockTag` -- **Helper Functions**: Conversion between internal types and strings - -**Key Types:** -- `FieldElement` - String representation of Starknet field elements -- `U256` - String representation of 256-bit unsigned integers -- `DojoError` - Comprehensive error handling -- `Pagination` - Cursor-based pagination support - -### `controller.rs` - Controller Types -Account and controller management: -- `Controller` - Account controller information -- `ControllerQuery` - Query for controllers - -**Use Cases:** -- Account management -- Username lookups -- Deployment tracking - -### `token.rs` - Token Types -ERC20, ERC721, and ERC1155 token support: -- `Token` - Token information -- `TokenBalance` - Token balance per account -- `TokenContract` - Token contract metadata -- `TokenTransfer` - Transfer event data -- `TokenQuery`, `TokenBalanceQuery`, `TokenContractQuery`, `TokenTransferQuery` -- `AttributeFilter` - NFT attribute filtering - -**Use Cases:** -- Token balance queries -- NFT metadata retrieval -- Transfer history -- Token searches with filters - -### `contract.rs` - Contract Types -Smart contract information and queries: -- `Contract` - Contract metadata -- `ContractType` - Enum for contract types (WORLD, ERC20, ERC721, etc.) -- `ContractQuery` - Query contracts by address or type - -**Use Cases:** -- Contract discovery -- Type-based filtering -- Deployment information - -### `transaction.rs` - Transaction Types -Transaction data and queries: -- `Transaction` - Full transaction information -- `TransactionCall` - Individual contract call -- `TransactionFilter` - Advanced transaction filtering -- `TransactionQuery` - Query transactions -- `CallType` - Execute vs ExecuteFromOutside - -**Use Cases:** -- Transaction history -- Call analysis -- Block explorer functionality - -### `schema.rs` - Schema Types -Type system and schema definitions: -- `Primitive` - Primitive type values (integers, felts, bools, etc.) -- `Ty` - Type definitions (Struct, Enum, Array, Tuple, etc.) -- `Struct` - Struct definition -- `Enum` - Enum definition -- `Member` - Struct/enum member -- `MemberValue` - Runtime value -- `ValueType` - Value type variants - -**Use Cases:** -- Schema introspection -- Dynamic typing -- Model definitions -- Data serialization - -### `query.rs` - Query Types -Powerful querying and filtering: -- `Query` - Main query structure -- `Clause` - Query clauses (HashedKeys, Keys, Member, Composite) -- `KeysClause` - Key-based filtering -- `MemberClause` - Member-based filtering -- `CompositeClause` - Logical composition (AND/OR) -- `PatternMatching` - Key pattern matching -- `ComparisonOperator` - Rich comparison operators -- `LogicalOperator` - AND/OR operators - -**Use Cases:** -- Entity queries -- Complex filtering -- Model data retrieval -- Historical queries - -### `entity.rs` - Entity Types -Core game entity types: -- `Entity` - Game entity with models -- `Model` - Model definition -- `World` - World state - -**Use Cases:** -- Entity management -- Model introspection -- World state queries - -### `event.rs` - Event Types -Blockchain event handling: -- `Event` - Starknet event -- `Message` - Signed message - -**Use Cases:** -- Event listening -- Message verification -- Event history - -### `aggregation.rs` - Aggregation Types -Data aggregation and leaderboards: -- `AggregationEntry` - Aggregated data entry -- `AggregationQuery` - Query aggregations - -**Use Cases:** -- Leaderboards -- Statistics -- Rankings - -### `activity.rs` - Activity Types -Player activity tracking: -- `Activity` - Player activity session -- `ActivityQuery` - Query player activity -- `ActionCount` - Action frequency - -**Use Cases:** -- Player analytics -- Session tracking -- Engagement metrics - -### `achievement.rs` - Achievement Types -Achievement and progression system: -- `Achievement` - Achievement definition -- `AchievementTask` - Individual task -- `PlayerAchievementProgress` - Player's progress -- `PlayerAchievementStats` - Player's achievement stats -- `AchievementProgression` - Detailed progression -- `TaskProgress` - Task completion status -- Corresponding query types - -**Use Cases:** -- Achievement systems -- Progression tracking -- Player rewards -- Gamification - -## Usage Examples - -### Querying Entities -```rust -use uniffi::{Query, Clause, MemberClause, ComparisonOperator, Primitive}; - -let query = Query { - world_addresses: vec!["0x123...".to_string()], - clause: Some(Clause::Member(MemberClause { - model: "Player".to_string(), - member: "level".to_string(), - operator: ComparisonOperator::Gte, - value: MemberValue::Primitive(Primitive::U32(10)), - })), - pagination: Default::default(), - no_hashed_keys: false, - models: vec!["Player".to_string()], - historical: false, -}; -``` - -### Token Balance Query -```rust -use uniffi::{TokenBalanceQuery, Pagination}; - -let query = TokenBalanceQuery { - contract_addresses: vec!["0xabc...".to_string()], - account_addresses: vec!["0xdef...".to_string()], - token_ids: vec![], - pagination: Pagination::default(), -}; -``` - -### Achievement Progress -```rust -use uniffi::{PlayerAchievementQuery, Pagination}; - -let query = PlayerAchievementQuery { - world_addresses: vec!["0x123...".to_string()], - namespaces: vec!["game".to_string()], - player_addresses: vec!["0xplayer...".to_string()], - pagination: Pagination::default(), -}; -``` - -## Design Principles - -### 1. **Category-Based Organization** -Types are grouped by their domain purpose rather than technical structure: -- Easy to find related types -- Clear separation of concerns -- Logical grouping for documentation - -### 2. **Minimal Dependencies** -Each module imports only what it needs: -- `core` has no internal dependencies -- Other modules depend on `core` -- Cross-references are minimal and explicit - -### 3. **Consistent Patterns** -All modules follow the same patterns: -- Types use `FieldElement` and `U256` as strings -- Conversions to/from proto types -- Clear documentation of purpose - -### 4. **Self-Documenting** -File names and organization make the purpose clear: -- `token.rs` - obviously token-related -- `achievement.rs` - clearly achievement system -- No need to read code to understand scope - -## Adding New Types - -When adding new types: - -1. **Determine Category**: Which module does it belong to? -2. **Create/Update Module**: Add to existing or create new category file -3. **Update mod.rs**: Add module declaration and re-exports -4. **Update UDL**: Add type definitions to `src/dojo.udl` -5. **Document**: Update this README - -Example - Adding a new "Quest" system: - -```rust -// src/uniffi/quest.rs -use super::core::*; - -#[derive(Debug, Clone)] -pub struct Quest { - pub id: String, - pub name: String, - // ... -} -``` - -Update `mod.rs`: -```rust -pub mod quest; -pub use quest::*; -``` - -## Benefits of This Organization - -### For Developers -- ✅ Quick discovery of related types -- ✅ Easy navigation -- ✅ Clear module boundaries -- ✅ Reduced cognitive load - -### For Maintenance -- ✅ Easy to add new categories -- ✅ Changes are localized -- ✅ Dependencies are explicit -- ✅ Better IDE support - -### For Documentation -- ✅ Self-organizing -- ✅ Category-based docs -- ✅ Clear examples per category -- ✅ Easy to generate docs - -## See Also - -- [UniFFI Documentation](https://mozilla.github.io/uniffi-rs/) -- [UNIFFI_CONVERSION.md](../../UNIFFI_CONVERSION.md) - Detailed conversion guide -- [CONVERSION_SUMMARY.md](../../CONVERSION_SUMMARY.md) - Complete type mapping -- [dojo.udl](../dojo.udl) - UniFFI interface definition - diff --git a/src/uniffi/client.rs b/src/uniffi/client.rs new file mode 100644 index 0000000..f9c46d2 --- /dev/null +++ b/src/uniffi/client.rs @@ -0,0 +1,544 @@ +// Client wrapper for UniFFI - exposes torii_client functionality + +use super::core::*; +use super::controller::*; +use super::token::*; +use super::contract::*; +use super::transaction::*; +use super::entity::*; +use super::event::*; +use super::aggregation::*; +use super::activity::*; +use super::achievement::*; +use super::query::*; +use std::sync::{Arc, Mutex}; +use std::sync::atomic::{AtomicU64, Ordering}; +use std::collections::HashMap; +use tokio::task::JoinHandle; + +// Callback traits for subscriptions +pub trait EntityUpdateCallback: Send + Sync { + fn on_update(&self, entity: Entity); + fn on_error(&self, error: String); +} + +pub trait TokenBalanceUpdateCallback: Send + Sync { + fn on_update(&self, balance: TokenBalance); + fn on_error(&self, error: String); +} + +pub trait TokenUpdateCallback: Send + Sync { + fn on_update(&self, token: Token); + fn on_error(&self, error: String); +} + +pub trait TransactionUpdateCallback: Send + Sync { + fn on_update(&self, transaction: Transaction); + fn on_error(&self, error: String); +} + +pub trait EventUpdateCallback: Send + Sync { + fn on_update(&self, event: Event); + fn on_error(&self, error: String); +} + +/// Main Dojo client for interacting with the Torii indexer +pub struct ToriiClient { + inner: torii_client::Client, + subscriptions: Arc>>>, + next_sub_id: Arc, +} + +impl ToriiClient { + /// Create a new Torii client with default configuration (4MB max message size) + pub async fn new(torii_url: String) -> Result { + let client = torii_client::Client::new(torii_url) + .await + .map_err(|_e| DojoError::ConnectionError)?; + Ok(Self { + inner: client, + subscriptions: Arc::new(Mutex::new(HashMap::new())), + next_sub_id: Arc::new(AtomicU64::new(0)), + }) + } + + /// Create a new Torii client with custom max message size + pub async fn new_with_config( + torii_url: String, + max_message_size: u64, + ) -> Result { + let client = torii_client::Client::new_with_config(torii_url, max_message_size as usize) + .await + .map_err(|_e| DojoError::ConnectionError)?; + Ok(Self { + inner: client, + subscriptions: Arc::new(Mutex::new(HashMap::new())), + next_sub_id: Arc::new(AtomicU64::new(0)), + }) + } + + /// Publish an offchain message to the world + /// Returns the entity ID of the published message + pub async fn publish_message(&self, message: Message) -> Result { + let msg: torii_proto::Message = message.into(); + self.inner + .publish_message(msg) + .await + .map_err(|_| DojoError::PublishError) + } + + /// Publish multiple offchain messages to the world + /// Returns the entity IDs of the published messages + pub async fn publish_message_batch(&self, messages: Vec) -> Result, DojoError> { + let msgs: Vec = messages + .into_iter() + .map(|m| m.into()) + .collect(); + self.inner + .publish_message_batch(msgs) + .await + .map_err(|_| DojoError::PublishError) + } + + /// Get world metadata for specified world addresses + pub async fn worlds(&self, world_addresses: Vec) -> Result, DojoError> { + let addrs: Result, DojoError> = world_addresses + .iter() + .map(field_element_to_felt) + .collect(); + + let worlds = self.inner + .worlds(addrs?) + .await + .map_err(|_| DojoError::QueryError)?; + + Ok(worlds.into_iter().map(|w| w.into()).collect()) + } + + /// Retrieve controllers matching the query + pub async fn controllers(&self, query: ControllerQuery) -> Result { + let q: torii_proto::ControllerQuery = query.into(); + let page = self.inner + .controllers(q) + .await + .map_err(|_| DojoError::QueryError)?; + + Ok(PageController { + items: page.items.into_iter().map(|c| c.into()).collect(), + next_cursor: page.next_cursor, + }) + } + + /// Retrieve contracts matching the query + pub async fn contracts(&self, query: ContractQuery) -> Result, DojoError> { + let q: torii_proto::ContractQuery = query.into(); + let contracts = self.inner + .contracts(q) + .await + .map_err(|_| DojoError::QueryError)?; + + Ok(contracts.into_iter().map(|c| c.into()).collect()) + } + + /// Retrieve tokens matching the query + pub async fn tokens(&self, query: TokenQuery) -> Result { + let q: torii_proto::TokenQuery = query.into(); + let page = self.inner + .tokens(q) + .await + .map_err(|_| DojoError::QueryError)?; + + Ok(PageToken { + items: page.items.into_iter().map(|t| t.into()).collect(), + next_cursor: page.next_cursor, + }) + } + + /// Retrieve token balances + pub async fn token_balances(&self, query: TokenBalanceQuery) -> Result { + let q: torii_proto::TokenBalanceQuery = query.into(); + let page = self.inner + .token_balances(q) + .await + .map_err(|_| DojoError::QueryError)?; + + Ok(PageTokenBalance { + items: page.items.into_iter().map(|b| b.into()).collect(), + next_cursor: page.next_cursor, + }) + } + + /// Retrieve token contracts + pub async fn token_contracts(&self, query: TokenContractQuery) -> Result { + let q: torii_proto::TokenContractQuery = query.into(); + let page = self.inner + .token_contracts(q) + .await + .map_err(|_| DojoError::QueryError)?; + + Ok(PageTokenContract { + items: page.items.into_iter().map(|tc| tc.into()).collect(), + next_cursor: page.next_cursor, + }) + } + + /// Retrieve token transfers + pub async fn token_transfers(&self, query: TokenTransferQuery) -> Result { + let q: torii_proto::TokenTransferQuery = query.into(); + let page = self.inner + .token_transfers(q) + .await + .map_err(|_| DojoError::QueryError)?; + + Ok(PageTokenTransfer { + items: page.items.into_iter().map(|t| t.into()).collect(), + next_cursor: page.next_cursor, + }) + } + + /// Retrieve transactions + pub async fn transactions(&self, query: TransactionQuery) -> Result { + let q: torii_proto::TransactionQuery = query.into(); + let page = self.inner + .transactions(q) + .await + .map_err(|_| DojoError::QueryError)?; + + Ok(PageTransaction { + items: page.items.into_iter().map(|t| t.into()).collect(), + next_cursor: page.next_cursor, + }) + } + + /// Retrieve aggregations (leaderboards, stats, rankings) + pub async fn aggregations(&self, query: AggregationQuery) -> Result { + let q: torii_proto::AggregationQuery = query.into(); + let page = self.inner + .aggregations(q) + .await + .map_err(|_| DojoError::QueryError)?; + + Ok(PageAggregationEntry { + items: page.items.into_iter().map(|a| a.into()).collect(), + next_cursor: page.next_cursor, + }) + } + + /// Retrieve activities (user session tracking) + pub async fn activities(&self, query: ActivityQuery) -> Result { + let q: torii_proto::ActivityQuery = query.into(); + let page = self.inner + .activities(q) + .await + .map_err(|_| DojoError::QueryError)?; + + Ok(PageActivity { + items: page.items.into_iter().map(|a| a.into()).collect(), + next_cursor: page.next_cursor, + }) + } + + /// Retrieve achievements + pub async fn achievements(&self, query: AchievementQuery) -> Result { + let q: torii_proto::AchievementQuery = query.into(); + let page = self.inner + .achievements(q) + .await + .map_err(|_| DojoError::QueryError)?; + + Ok(PageAchievement { + items: page.items.into_iter().map(|a| a.into()).collect(), + next_cursor: page.next_cursor, + }) + } + + /// Retrieve player achievements + pub async fn player_achievements(&self, query: PlayerAchievementQuery) -> Result { + let q: torii_proto::PlayerAchievementQuery = query.into(); + let page = self.inner + .player_achievements(q) + .await + .map_err(|_| DojoError::QueryError)?; + + Ok(PagePlayerAchievement { + items: page.items.into_iter().map(|p| p.into()).collect(), + next_cursor: page.next_cursor, + }) + } + + /// Retrieve entities matching the query + pub async fn entities(&self, query: Query) -> Result { + let q: torii_proto::Query = query.into(); + let page = self.inner + .entities(q) + .await + .map_err(|_| DojoError::QueryError)?; + + Ok(PageEntity { + items: page.items.into_iter().map(|e| e.into()).collect(), + next_cursor: page.next_cursor, + }) + } + + /// Retrieve event messages matching the query + pub async fn event_messages(&self, query: Query) -> Result { + let q: torii_proto::Query = query.into(); + let page = self.inner + .event_messages(q) + .await + .map_err(|_| DojoError::QueryError)?; + + Ok(PageEntity { + items: page.items.into_iter().map(|e| e.into()).collect(), + next_cursor: page.next_cursor, + }) + } + + /// Retrieve raw Starknet events + pub async fn starknet_events(&self, query: EventQuery) -> Result { + let q: torii_proto::EventQuery = query.try_into()?; + let page = self.inner + .starknet_events(q) + .await + .map_err(|_| DojoError::QueryError)?; + + Ok(PageEvent { + items: page.items.into_iter().map(|e| e.into()).collect(), + next_cursor: page.next_cursor, + }) + } + + /// Execute a SQL query against the Torii database + pub async fn sql(&self, query: String) -> Result, DojoError> { + let rows = self.inner + .sql(query) + .await + .map_err(|_| DojoError::QueryError)?; + + rows.into_iter().map(|r| r.try_into()).collect() + } + + /// Subscribe to entity updates + pub async fn subscribe_entity_updates( + &self, + clause: Option, + world_addresses: Vec, + callback: Box, + ) -> Result { + let sub_id = self.next_sub_id.fetch_add(1, Ordering::SeqCst); + + let addrs: Result, DojoError> = world_addresses + .iter() + .map(field_element_to_felt) + .collect(); + let addrs = addrs?; + + let clause_proto = clause.map(|c| c.into()); + + let mut stream = self.inner + .on_entity_updated(clause_proto, addrs) + .await + .map_err(|_| DojoError::SubscriptionError)?; + + let handle = tokio::spawn(async move { + use futures_util::StreamExt; + // Skip the first message which contains the subscription ID + let _ = stream.next().await; + + while let Some(result) = stream.next().await { + match result { + Ok((_id, entity)) => { + callback.on_update(entity.into()); + } + Err(e) => { + callback.on_error(e.to_string()); + break; + } + } + } + }); + + self.subscriptions.lock().unwrap().insert(sub_id, handle); + Ok(sub_id) + } + + /// Subscribe to token balance updates + pub async fn subscribe_token_balance_updates( + &self, + contract_addresses: Vec, + account_addresses: Vec, + token_ids: Vec, + callback: Box, + ) -> Result { + let sub_id = self.next_sub_id.fetch_add(1, Ordering::SeqCst); + + let contracts: Result, DojoError> = contract_addresses + .iter() + .map(field_element_to_felt) + .collect(); + let accounts: Result, DojoError> = account_addresses + .iter() + .map(field_element_to_felt) + .collect(); + let ids: Result, DojoError> = token_ids + .iter() + .map(uniffi_to_u256) + .collect(); + + let mut stream = self.inner + .on_token_balance_updated(contracts?, accounts?, ids?) + .await + .map_err(|_| DojoError::SubscriptionError)?; + + let handle = tokio::spawn(async move { + use futures_util::StreamExt; + // Skip the first message which contains the subscription ID + let _ = stream.next().await; + + while let Some(result) = stream.next().await { + match result { + Ok((_id, balance)) => { + callback.on_update(balance.into()); + } + Err(e) => { + callback.on_error(e.to_string()); + break; + } + } + } + }); + + self.subscriptions.lock().unwrap().insert(sub_id, handle); + Ok(sub_id) + } + + /// Subscribe to token updates + pub async fn subscribe_token_updates( + &self, + contract_addresses: Vec, + token_ids: Vec, + callback: Box, + ) -> Result { + let sub_id = self.next_sub_id.fetch_add(1, Ordering::SeqCst); + + let contracts: Result, DojoError> = contract_addresses + .iter() + .map(field_element_to_felt) + .collect(); + let ids: Result, DojoError> = token_ids + .iter() + .map(uniffi_to_u256) + .collect(); + + let mut stream = self.inner + .on_token_updated(contracts?, ids?) + .await + .map_err(|_| DojoError::SubscriptionError)?; + + let handle = tokio::spawn(async move { + use futures_util::StreamExt; + // Skip the first message which contains the subscription ID + let _ = stream.next().await; + + while let Some(result) = stream.next().await { + match result { + Ok((_id, token)) => { + callback.on_update(token.into()); + } + Err(e) => { + callback.on_error(e.to_string()); + break; + } + } + } + }); + + self.subscriptions.lock().unwrap().insert(sub_id, handle); + Ok(sub_id) + } + + /// Subscribe to transaction updates + pub async fn subscribe_transaction_updates( + &self, + filter: Option, + callback: Box, + ) -> Result { + let sub_id = self.next_sub_id.fetch_add(1, Ordering::SeqCst); + + let filter_proto = filter.map(|f| f.into()); + + let mut stream = self.inner + .on_transaction(filter_proto) + .await + .map_err(|_| DojoError::SubscriptionError)?; + + let handle = tokio::spawn(async move { + use futures_util::StreamExt; + // Skip the first message which contains the subscription ID + let _ = stream.next().await; + + while let Some(result) = stream.next().await { + match result { + Ok(transaction) => { + callback.on_update(transaction.into()); + } + Err(e) => { + callback.on_error(e.to_string()); + break; + } + } + } + }); + + self.subscriptions.lock().unwrap().insert(sub_id, handle); + Ok(sub_id) + } + + /// Subscribe to Starknet event updates + pub async fn subscribe_event_updates( + &self, + keys: Vec, + callback: Box, + ) -> Result { + let sub_id = self.next_sub_id.fetch_add(1, Ordering::SeqCst); + + let keys_proto: Vec = keys.into_iter().map(|k| k.into()).collect(); + + let mut stream = self.inner + .on_starknet_event(keys_proto) + .await + .map_err(|_| DojoError::SubscriptionError)?; + + let handle = tokio::spawn(async move { + use futures_util::StreamExt; + // Skip the first message which contains the subscription ID + let _ = stream.next().await; + + while let Some(result) = stream.next().await { + match result { + Ok(event) => { + callback.on_update(event.into()); + } + Err(e) => { + callback.on_error(e.to_string()); + break; + } + } + } + }); + + self.subscriptions.lock().unwrap().insert(sub_id, handle); + Ok(sub_id) + } + + /// Cancel a subscription + pub fn cancel_subscription(&self, subscription_id: u64) -> Result<(), DojoError> { + let mut subs = self.subscriptions.lock().unwrap(); + if let Some(handle) = subs.remove(&subscription_id) { + handle.abort(); + Ok(()) + } else { + Err(DojoError::SubscriptionError) + } + } +} diff --git a/src/uniffi/core.rs b/src/uniffi/core.rs index f2ca4a8..3a9b67c 100644 --- a/src/uniffi/core.rs +++ b/src/uniffi/core.rs @@ -44,6 +44,14 @@ pub enum DojoError { NetworkError(String), #[error("Invalid input")] InvalidInput, + #[error("Connection error")] + ConnectionError, + #[error("Publish error")] + PublishError, + #[error("Query error")] + QueryError, + #[error("Subscription error")] + SubscriptionError, } impl From for DojoError { @@ -236,3 +244,86 @@ impl From for starknet::core::types::BlockId { } } +// Pagination wrapper types for different result types +// These are used by the client but defined here for availability + +use super::controller::Controller; +use super::token::{Token, TokenBalance, TokenContract, TokenTransfer}; +use super::transaction::Transaction; +use super::aggregation::AggregationEntry; +use super::activity::Activity; +use super::achievement::{Achievement, PlayerAchievementEntry}; +use super::entity::Entity; +use super::event::Event; + +#[derive(Debug, Clone)] +pub struct PageController { + pub items: Vec, + pub next_cursor: Option, +} + +#[derive(Debug, Clone)] +pub struct PageToken { + pub items: Vec, + pub next_cursor: Option, +} + +#[derive(Debug, Clone)] +pub struct PageTokenBalance { + pub items: Vec, + pub next_cursor: Option, +} + +#[derive(Debug, Clone)] +pub struct PageTokenContract { + pub items: Vec, + pub next_cursor: Option, +} + +#[derive(Debug, Clone)] +pub struct PageTokenTransfer { + pub items: Vec, + pub next_cursor: Option, +} + +#[derive(Debug, Clone)] +pub struct PageTransaction { + pub items: Vec, + pub next_cursor: Option, +} + +#[derive(Debug, Clone)] +pub struct PageAggregationEntry { + pub items: Vec, + pub next_cursor: Option, +} + +#[derive(Debug, Clone)] +pub struct PageActivity { + pub items: Vec, + pub next_cursor: Option, +} + +#[derive(Debug, Clone)] +pub struct PageAchievement { + pub items: Vec, + pub next_cursor: Option, +} + +#[derive(Debug, Clone)] +pub struct PagePlayerAchievement { + pub items: Vec, + pub next_cursor: Option, +} + +#[derive(Debug, Clone)] +pub struct PageEntity { + pub items: Vec, + pub next_cursor: Option, +} + +#[derive(Debug, Clone)] +pub struct PageEvent { + pub items: Vec, + pub next_cursor: Option, +} diff --git a/src/uniffi/event.rs b/src/uniffi/event.rs index 9c57692..96a91f3 100644 --- a/src/uniffi/event.rs +++ b/src/uniffi/event.rs @@ -1,5 +1,6 @@ // Event and Message types use super::core::*; +use super::query::*; #[derive(Debug, Clone)] pub struct Event { @@ -8,6 +9,12 @@ pub struct Event { pub transaction_hash: FieldElement, } +#[derive(Debug, Clone)] +pub struct EventQuery { + pub keys: Option, + pub pagination: Pagination, +} + impl From for torii_proto::Event { fn from(val: Event) -> Self { torii_proto::Event { @@ -45,3 +52,14 @@ impl From for torii_proto::Message { } } +impl TryInto for EventQuery { + type Error = DojoError; + + fn try_into(self) -> Result { + Ok(torii_proto::EventQuery { + keys: self.keys.map(|k| k.into()), + pagination: self.pagination.into(), + }) + } +} + diff --git a/src/uniffi/mod.rs b/src/uniffi/mod.rs index 7abd7b4..8ab2d0a 100644 --- a/src/uniffi/mod.rs +++ b/src/uniffi/mod.rs @@ -8,6 +8,7 @@ pub mod core; pub mod achievement; pub mod activity; pub mod aggregation; +pub mod client; pub mod contract; pub mod controller; pub mod entity; @@ -21,6 +22,7 @@ pub mod transaction; pub use achievement::*; pub use activity::*; pub use aggregation::*; +pub use client::*; pub use contract::*; pub use controller::*; pub use core::*; diff --git a/src/uniffi/query.rs b/src/uniffi/query.rs index 7ca87dd..30a5512 100644 --- a/src/uniffi/query.rs +++ b/src/uniffi/query.rs @@ -2,6 +2,45 @@ use super::core::*; use super::schema::MemberValue; +// SQL query result types +#[derive(Debug, Clone)] +pub struct SqlField { + pub name: String, + pub value: SqlValue, +} + +#[derive(Debug, Clone)] +pub struct SqlRow { + pub fields: Vec, +} + +#[derive(Debug, Clone)] +pub enum SqlValue { + Text { value: String }, + Integer { value: i64 }, + Real { value: f64 }, + Blob { value: Vec }, + Null, +} + +impl TryInto for torii_proto::SqlRow { + type Error = DojoError; + + fn try_into(self) -> Result { + let fields = self.fields.into_iter().map(|(name, v)| { + let value = match v { + torii_proto::SqlValue::Text(s) => SqlValue::Text { value: s }, + torii_proto::SqlValue::Integer(i) => SqlValue::Integer { value: i }, + torii_proto::SqlValue::Real(r) => SqlValue::Real { value: r }, + torii_proto::SqlValue::Blob(b) => SqlValue::Blob { value: b }, + torii_proto::SqlValue::Null => SqlValue::Null, + }; + SqlField { name, value } + }).collect(); + Ok(SqlRow { fields }) + } +} + #[derive(Debug, Clone)] pub enum PatternMatching { FixedLen, From f26176a70edc5e808b2f960034f6e8b51c4e09df Mon Sep 17 00:00:00 2001 From: Nasr Date: Wed, 15 Oct 2025 13:43:42 -0500 Subject: [PATCH 04/16] rename to global types --- README.md | 94 ++- bindings/python/dojo.py | 752 +++++++++++++++++- crates/uniffi/Cargo.toml | 80 ++ crates/uniffi/build.rs | 4 + .../uniffi/src/bin/uniffi-bindgen-kotlin.rs | 55 ++ .../uniffi/src/bin/uniffi-bindgen-python.rs | 65 ++ crates/uniffi/src/bin/uniffi-bindgen-swift.rs | 71 ++ crates/uniffi/src/bin/uniffi-bindgen.rs | 4 + crates/uniffi/src/dojo.udl | 470 +++++++++++ crates/uniffi/src/lib.rs | 11 + crates/uniffi/src/uniffi/README.md | 307 +++++++ .../uniffi/src}/uniffi/achievement.rs | 0 {src => crates/uniffi/src}/uniffi/activity.rs | 0 .../uniffi/src}/uniffi/aggregation.rs | 0 {src => crates/uniffi/src}/uniffi/contract.rs | 0 .../uniffi/src}/uniffi/controller.rs | 0 crates/uniffi/src/uniffi/core.rs | 260 ++++++ {src => crates/uniffi/src}/uniffi/entity.rs | 0 crates/uniffi/src/uniffi/event.rs | 47 ++ crates/uniffi/src/uniffi/mod.rs | 32 + crates/uniffi/src/uniffi/query.rs | 271 +++++++ {src => crates/uniffi/src}/uniffi/schema.rs | 0 {src => crates/uniffi/src}/uniffi/token.rs | 0 .../uniffi/src}/uniffi/transaction.rs | 0 crates/wasm/src/lib.rs | 19 +- dojo.h | 49 +- dojo.hpp | 3 - dojo.pyx | 9 +- src/uniffi/README.md | 93 +++ src/uniffi/client.rs | 12 +- src/uniffi/mod.rs | 38 +- src/uniffi/types/achievement.rs | 239 ++++++ src/uniffi/types/activity.rs | 76 ++ src/uniffi/types/aggregation.rs | 49 ++ src/uniffi/types/contract.rs | 85 ++ src/uniffi/types/controller.rs | 41 + src/uniffi/{ => types}/core.rs | 0 src/uniffi/types/entity.rs | 130 +++ src/uniffi/{ => types}/event.rs | 0 src/uniffi/types/mod.rs | 30 + src/uniffi/{ => types}/query.rs | 0 src/uniffi/types/schema.rs | 331 ++++++++ src/uniffi/types/token.rs | 209 +++++ src/uniffi/types/transaction.rs | 128 +++ 44 files changed, 3970 insertions(+), 94 deletions(-) create mode 100644 crates/uniffi/Cargo.toml create mode 100644 crates/uniffi/build.rs create mode 100644 crates/uniffi/src/bin/uniffi-bindgen-kotlin.rs create mode 100644 crates/uniffi/src/bin/uniffi-bindgen-python.rs create mode 100644 crates/uniffi/src/bin/uniffi-bindgen-swift.rs create mode 100644 crates/uniffi/src/bin/uniffi-bindgen.rs create mode 100644 crates/uniffi/src/dojo.udl create mode 100644 crates/uniffi/src/lib.rs create mode 100644 crates/uniffi/src/uniffi/README.md rename {src => crates/uniffi/src}/uniffi/achievement.rs (100%) rename {src => crates/uniffi/src}/uniffi/activity.rs (100%) rename {src => crates/uniffi/src}/uniffi/aggregation.rs (100%) rename {src => crates/uniffi/src}/uniffi/contract.rs (100%) rename {src => crates/uniffi/src}/uniffi/controller.rs (100%) create mode 100644 crates/uniffi/src/uniffi/core.rs rename {src => crates/uniffi/src}/uniffi/entity.rs (100%) create mode 100644 crates/uniffi/src/uniffi/event.rs create mode 100644 crates/uniffi/src/uniffi/mod.rs create mode 100644 crates/uniffi/src/uniffi/query.rs rename {src => crates/uniffi/src}/uniffi/schema.rs (100%) rename {src => crates/uniffi/src}/uniffi/token.rs (100%) rename {src => crates/uniffi/src}/uniffi/transaction.rs (100%) create mode 100644 src/uniffi/README.md create mode 100644 src/uniffi/types/achievement.rs create mode 100644 src/uniffi/types/activity.rs create mode 100644 src/uniffi/types/aggregation.rs create mode 100644 src/uniffi/types/contract.rs create mode 100644 src/uniffi/types/controller.rs rename src/uniffi/{ => types}/core.rs (100%) create mode 100644 src/uniffi/types/entity.rs rename src/uniffi/{ => types}/event.rs (100%) create mode 100644 src/uniffi/types/mod.rs rename src/uniffi/{ => types}/query.rs (100%) create mode 100644 src/uniffi/types/schema.rs create mode 100644 src/uniffi/types/token.rs create mode 100644 src/uniffi/types/transaction.rs diff --git a/README.md b/README.md index b99ca31..0ba46a4 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,36 @@ # dojo.c -This package provides C and low-level Wasm32 bindings for the Torii Client SDK, as well as for the starknet-rs library. +Multi-language bindings for the Dojo Torii Client SDK, providing seamless integration across multiple platforms and languages. -The approach is to generate a C client using `cbindgen` and a wasm module using `wasm-bindgen` that are interropeable in applications exporting to both native platforms and web browsers. +## Features + +This package provides multiple binding strategies for maximum compatibility: + +- **C/C++ Bindings** - Generated with `cbindgen` for native applications +- **WebAssembly** - Browser and Node.js support via `wasm-bindgen` +- **UniFFI Bindings** - Modern Swift, Kotlin, and Python bindings via Mozilla's UniFFI + +## Project Structure + +``` +dojo.c/ +├── src/ +│ ├── c/ # C FFI implementation +│ ├── wasm/ # WebAssembly implementation +│ ├── uniffi/ # UniFFI implementation +│ │ ├── types/ # Domain types (organized by category) +│ │ ├── client.rs # ToriiClient with queries & subscriptions +│ │ └── README.md # UniFFI-specific documentation +│ ├── dojo.udl # UniFFI interface definition +│ └── lib.rs # Main library entry point +├── src/bin/ # Binding generator binaries +├── scripts/ # Build and generation scripts +├── bindings/ # Generated bindings output +│ ├── swift/ +│ ├── kotlin/ +│ └── python/ +└── example/ # C usage examples +``` ## Building @@ -27,13 +55,67 @@ cargo build --release --target wasm32-unknown-unknown cd pkg && bunx wasm-pack build --release ``` -## Running +## Generating Bindings + +### C/C++ Headers + +Headers are automatically generated during `cargo build`: +- `dojo.h` - C header +- `dojo.hpp` - C++ header +- `dojo.pyx` - Cython definitions + +### UniFFI Bindings (Swift, Kotlin, Python) + +```bash +# Build the library first +cargo build --release + +# Generate Swift bindings (iOS/macOS) +cargo run --bin uniffi-bindgen-swift --release -- \ + target/release/libdojo_c.dylib bindings/swift --swift-sources + +# Generate Kotlin bindings (Android) +cargo run --bin uniffi-bindgen-kotlin --release -- \ + target/release/libdojo_c.dylib bindings/kotlin + +# Generate Python bindings +cargo run --bin uniffi-bindgen-python --release -- \ + target/release/libdojo_c.dylib bindings/python +``` + +See [`src/uniffi/README.md`](src/uniffi/README.md) for detailed UniFFI documentation. + +## Running Examples + +### C Example ```bash -# Building dojo.c +# Build dojo.c cargo build --release -# Linking dojo.c and building example +# Compile and link C example clang example/main.c target/release/libdojo_c.dylib -# Running example +# Run example ./a.out ``` + +### Python Example + +```python +from dojo import ToriiClient + +# Create client +client = await ToriiClient("http://localhost:8080") + +# Subscribe to entity updates +def on_entity_update(entity): + print(f"Entity updated: {entity}") + +def on_error(error): + print(f"Error: {error}") + +sub_id = await client.subscribe_entity_updates( + None, # clause + [], # world_addresses + EntityUpdateCallback(on_entity_update, on_error) +) +``` diff --git a/bindings/python/dojo.py b/bindings/python/dojo.py index 085b1b8..2eda5cd 100644 --- a/bindings/python/dojo.py +++ b/bindings/python/dojo.py @@ -429,7 +429,38 @@ def lift(cls, rbuf): def lower(cls, value): with _UniffiRustBuffer.alloc_with_builder() as builder: cls.write(value, builder) - return builder.finalize() + return builder.finalize()# Magic number for the Rust proxy to call using the same mechanism as every other method, +# to free the callback once it's dropped by Rust. +_UNIFFI_IDX_CALLBACK_FREE = 0 +# Return codes for callback calls +_UNIFFI_CALLBACK_SUCCESS = 0 +_UNIFFI_CALLBACK_ERROR = 1 +_UNIFFI_CALLBACK_UNEXPECTED_ERROR = 2 + +class _UniffiCallbackInterfaceFfiConverter: + _handle_map = _UniffiHandleMap() + + @classmethod + def lift(cls, handle): + return cls._handle_map.get(handle) + + @classmethod + def read(cls, buf): + handle = buf.read_u64() + cls.lift(handle) + + @classmethod + def check_lower(cls, cb): + pass + + @classmethod + def lower(cls, cb): + handle = cls._handle_map.insert(cb) + return handle + + @classmethod + def write(cls, cb, buf): + buf.write_u64(cls.lower(cb)) # Contains loading, initialization code, and the FFI Function declarations. # Define some ctypes FFI types that we use in the library @@ -489,6 +520,8 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_dojo_c_checksum_method_toriiclient_aggregations() != 2286: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_cancel_subscription() != 30979: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_dojo_c_checksum_method_toriiclient_contracts() != 19355: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_dojo_c_checksum_method_toriiclient_controllers() != 57439: @@ -507,6 +540,16 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_dojo_c_checksum_method_toriiclient_starknet_events() != 47081: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_subscribe_entity_updates() != 30649: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_subscribe_event_updates() != 61773: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_subscribe_token_balance_updates() != 32318: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_subscribe_token_updates() != 21031: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_c_checksum_method_toriiclient_subscribe_transaction_updates() != 9579: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_dojo_c_checksum_method_toriiclient_token_balances() != 31624: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_dojo_c_checksum_method_toriiclient_token_contracts() != 34016: @@ -792,6 +835,111 @@ class _UniffiForeignFutureDroppedCallbackStruct(ctypes.Structure): ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_dojo_c_fn_free_toriiclient.restype = None +_UNIFFI_CALLBACK_INTERFACE_DOJO_ENTITY_UPDATE_CALLBACK_METHOD0 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiRustBuffer,ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UNIFFI_CALLBACK_INTERFACE_DOJO_ENTITY_UPDATE_CALLBACK_METHOD1 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiRustBuffer,ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UNIFFI_CALLBACK_INTERFACE_CLONE_DOJO_ENTITY_UPDATE_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_uint64,ctypes.c_uint64, +) +_UNIFFI_CALLBACK_INTERFACE_FREE_DOJO_ENTITY_UPDATE_CALLBACK = ctypes.CFUNCTYPE(None,ctypes.c_uint64, +) +class _UniffiVTableCallbackInterfaceDojoEntityUpdateCallback(ctypes.Structure): + _fields_ = [ + ("uniffi_free", _UNIFFI_CALLBACK_INTERFACE_FREE_DOJO_ENTITY_UPDATE_CALLBACK), + ("uniffi_clone", _UNIFFI_CALLBACK_INTERFACE_CLONE_DOJO_ENTITY_UPDATE_CALLBACK), + ("on_update", _UNIFFI_CALLBACK_INTERFACE_DOJO_ENTITY_UPDATE_CALLBACK_METHOD0), + ("on_error", _UNIFFI_CALLBACK_INTERFACE_DOJO_ENTITY_UPDATE_CALLBACK_METHOD1), + ] +_UniffiLib.uniffi_dojo_c_fn_init_callback_vtable_entityupdatecallback.argtypes = ( + ctypes.POINTER(_UniffiVTableCallbackInterfaceDojoEntityUpdateCallback), +) +_UniffiLib.uniffi_dojo_c_fn_init_callback_vtable_entityupdatecallback.restype = None +_UNIFFI_CALLBACK_INTERFACE_DOJO_EVENT_UPDATE_CALLBACK_METHOD0 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiRustBuffer,ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UNIFFI_CALLBACK_INTERFACE_DOJO_EVENT_UPDATE_CALLBACK_METHOD1 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiRustBuffer,ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UNIFFI_CALLBACK_INTERFACE_CLONE_DOJO_EVENT_UPDATE_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_uint64,ctypes.c_uint64, +) +_UNIFFI_CALLBACK_INTERFACE_FREE_DOJO_EVENT_UPDATE_CALLBACK = ctypes.CFUNCTYPE(None,ctypes.c_uint64, +) +class _UniffiVTableCallbackInterfaceDojoEventUpdateCallback(ctypes.Structure): + _fields_ = [ + ("uniffi_free", _UNIFFI_CALLBACK_INTERFACE_FREE_DOJO_EVENT_UPDATE_CALLBACK), + ("uniffi_clone", _UNIFFI_CALLBACK_INTERFACE_CLONE_DOJO_EVENT_UPDATE_CALLBACK), + ("on_update", _UNIFFI_CALLBACK_INTERFACE_DOJO_EVENT_UPDATE_CALLBACK_METHOD0), + ("on_error", _UNIFFI_CALLBACK_INTERFACE_DOJO_EVENT_UPDATE_CALLBACK_METHOD1), + ] +_UniffiLib.uniffi_dojo_c_fn_init_callback_vtable_eventupdatecallback.argtypes = ( + ctypes.POINTER(_UniffiVTableCallbackInterfaceDojoEventUpdateCallback), +) +_UniffiLib.uniffi_dojo_c_fn_init_callback_vtable_eventupdatecallback.restype = None +_UNIFFI_CALLBACK_INTERFACE_DOJO_TOKEN_BALANCE_UPDATE_CALLBACK_METHOD0 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiRustBuffer,ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UNIFFI_CALLBACK_INTERFACE_DOJO_TOKEN_BALANCE_UPDATE_CALLBACK_METHOD1 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiRustBuffer,ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UNIFFI_CALLBACK_INTERFACE_CLONE_DOJO_TOKEN_BALANCE_UPDATE_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_uint64,ctypes.c_uint64, +) +_UNIFFI_CALLBACK_INTERFACE_FREE_DOJO_TOKEN_BALANCE_UPDATE_CALLBACK = ctypes.CFUNCTYPE(None,ctypes.c_uint64, +) +class _UniffiVTableCallbackInterfaceDojoTokenBalanceUpdateCallback(ctypes.Structure): + _fields_ = [ + ("uniffi_free", _UNIFFI_CALLBACK_INTERFACE_FREE_DOJO_TOKEN_BALANCE_UPDATE_CALLBACK), + ("uniffi_clone", _UNIFFI_CALLBACK_INTERFACE_CLONE_DOJO_TOKEN_BALANCE_UPDATE_CALLBACK), + ("on_update", _UNIFFI_CALLBACK_INTERFACE_DOJO_TOKEN_BALANCE_UPDATE_CALLBACK_METHOD0), + ("on_error", _UNIFFI_CALLBACK_INTERFACE_DOJO_TOKEN_BALANCE_UPDATE_CALLBACK_METHOD1), + ] +_UniffiLib.uniffi_dojo_c_fn_init_callback_vtable_tokenbalanceupdatecallback.argtypes = ( + ctypes.POINTER(_UniffiVTableCallbackInterfaceDojoTokenBalanceUpdateCallback), +) +_UniffiLib.uniffi_dojo_c_fn_init_callback_vtable_tokenbalanceupdatecallback.restype = None +_UNIFFI_CALLBACK_INTERFACE_DOJO_TOKEN_UPDATE_CALLBACK_METHOD0 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiRustBuffer,ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UNIFFI_CALLBACK_INTERFACE_DOJO_TOKEN_UPDATE_CALLBACK_METHOD1 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiRustBuffer,ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UNIFFI_CALLBACK_INTERFACE_CLONE_DOJO_TOKEN_UPDATE_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_uint64,ctypes.c_uint64, +) +_UNIFFI_CALLBACK_INTERFACE_FREE_DOJO_TOKEN_UPDATE_CALLBACK = ctypes.CFUNCTYPE(None,ctypes.c_uint64, +) +class _UniffiVTableCallbackInterfaceDojoTokenUpdateCallback(ctypes.Structure): + _fields_ = [ + ("uniffi_free", _UNIFFI_CALLBACK_INTERFACE_FREE_DOJO_TOKEN_UPDATE_CALLBACK), + ("uniffi_clone", _UNIFFI_CALLBACK_INTERFACE_CLONE_DOJO_TOKEN_UPDATE_CALLBACK), + ("on_update", _UNIFFI_CALLBACK_INTERFACE_DOJO_TOKEN_UPDATE_CALLBACK_METHOD0), + ("on_error", _UNIFFI_CALLBACK_INTERFACE_DOJO_TOKEN_UPDATE_CALLBACK_METHOD1), + ] +_UniffiLib.uniffi_dojo_c_fn_init_callback_vtable_tokenupdatecallback.argtypes = ( + ctypes.POINTER(_UniffiVTableCallbackInterfaceDojoTokenUpdateCallback), +) +_UniffiLib.uniffi_dojo_c_fn_init_callback_vtable_tokenupdatecallback.restype = None +_UNIFFI_CALLBACK_INTERFACE_DOJO_TRANSACTION_UPDATE_CALLBACK_METHOD0 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiRustBuffer,ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UNIFFI_CALLBACK_INTERFACE_DOJO_TRANSACTION_UPDATE_CALLBACK_METHOD1 = ctypes.CFUNCTYPE(None,ctypes.c_uint64,_UniffiRustBuffer,ctypes.c_void_p, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UNIFFI_CALLBACK_INTERFACE_CLONE_DOJO_TRANSACTION_UPDATE_CALLBACK = ctypes.CFUNCTYPE(ctypes.c_uint64,ctypes.c_uint64, +) +_UNIFFI_CALLBACK_INTERFACE_FREE_DOJO_TRANSACTION_UPDATE_CALLBACK = ctypes.CFUNCTYPE(None,ctypes.c_uint64, +) +class _UniffiVTableCallbackInterfaceDojoTransactionUpdateCallback(ctypes.Structure): + _fields_ = [ + ("uniffi_free", _UNIFFI_CALLBACK_INTERFACE_FREE_DOJO_TRANSACTION_UPDATE_CALLBACK), + ("uniffi_clone", _UNIFFI_CALLBACK_INTERFACE_CLONE_DOJO_TRANSACTION_UPDATE_CALLBACK), + ("on_update", _UNIFFI_CALLBACK_INTERFACE_DOJO_TRANSACTION_UPDATE_CALLBACK_METHOD0), + ("on_error", _UNIFFI_CALLBACK_INTERFACE_DOJO_TRANSACTION_UPDATE_CALLBACK_METHOD1), + ] +_UniffiLib.uniffi_dojo_c_fn_init_callback_vtable_transactionupdatecallback.argtypes = ( + ctypes.POINTER(_UniffiVTableCallbackInterfaceDojoTransactionUpdateCallback), +) +_UniffiLib.uniffi_dojo_c_fn_init_callback_vtable_transactionupdatecallback.restype = None _UniffiLib.uniffi_dojo_c_fn_constructor_toriiclient_new.argtypes = ( _UniffiRustBuffer, ) @@ -816,6 +964,12 @@ class _UniffiForeignFutureDroppedCallbackStruct(ctypes.Structure): _UniffiRustBuffer, ) _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_aggregations.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_cancel_subscription.argtypes = ( + ctypes.c_uint64, + ctypes.c_uint64, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_cancel_subscription.restype = None _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_contracts.argtypes = ( ctypes.c_uint64, _UniffiRustBuffer, @@ -861,6 +1015,40 @@ class _UniffiForeignFutureDroppedCallbackStruct(ctypes.Structure): _UniffiRustBuffer, ) _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_starknet_events.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_subscribe_entity_updates.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, + _UniffiRustBuffer, + ctypes.c_uint64, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_subscribe_entity_updates.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_subscribe_event_updates.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, + ctypes.c_uint64, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_subscribe_event_updates.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_subscribe_token_balance_updates.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, + _UniffiRustBuffer, + _UniffiRustBuffer, + ctypes.c_uint64, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_subscribe_token_balance_updates.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_subscribe_token_updates.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, + _UniffiRustBuffer, + ctypes.c_uint64, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_subscribe_token_updates.restype = ctypes.c_uint64 +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_subscribe_transaction_updates.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, + ctypes.c_uint64, +) +_UniffiLib.uniffi_dojo_c_fn_method_toriiclient_subscribe_transaction_updates.restype = ctypes.c_uint64 _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_token_balances.argtypes = ( ctypes.c_uint64, _UniffiRustBuffer, @@ -909,6 +1097,9 @@ class _UniffiForeignFutureDroppedCallbackStruct(ctypes.Structure): _UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_aggregations.argtypes = ( ) _UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_aggregations.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_cancel_subscription.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_cancel_subscription.restype = ctypes.c_uint16 _UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_contracts.argtypes = ( ) _UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_contracts.restype = ctypes.c_uint16 @@ -936,6 +1127,21 @@ class _UniffiForeignFutureDroppedCallbackStruct(ctypes.Structure): _UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_starknet_events.argtypes = ( ) _UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_starknet_events.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_subscribe_entity_updates.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_subscribe_entity_updates.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_subscribe_event_updates.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_subscribe_event_updates.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_subscribe_token_balance_updates.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_subscribe_token_balance_updates.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_subscribe_token_updates.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_subscribe_token_updates.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_subscribe_transaction_updates.argtypes = ( +) +_UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_subscribe_transaction_updates.restype = ctypes.c_uint16 _UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_token_balances.argtypes = ( ) _UniffiLib.uniffi_dojo_c_checksum_method_toriiclient_token_balances.restype = ctypes.c_uint16 @@ -7243,6 +7449,10 @@ class QueryError(_UniffiTempDojoError): def __repr__(self): return "DojoError.QueryError({})".format(repr(str(self))) _UniffiTempDojoError.QueryError = QueryError # type: ignore + class SubscriptionError(_UniffiTempDojoError): + def __repr__(self): + return "DojoError.SubscriptionError({})".format(repr(str(self))) + _UniffiTempDojoError.SubscriptionError = SubscriptionError # type: ignore DojoError = _UniffiTempDojoError # type: ignore del _UniffiTempDojoError @@ -7280,6 +7490,10 @@ def read(buf): return DojoError.QueryError( _UniffiFfiConverterString.read(buf), ) + if variant == 8: + return DojoError.SubscriptionError( + _UniffiFfiConverterString.read(buf), + ) raise InternalError("Raw enum value doesn't match any cases") @staticmethod @@ -7298,6 +7512,8 @@ def check_lower(value): return if isinstance(value, DojoError.QueryError): return + if isinstance(value, DojoError.SubscriptionError): + return @staticmethod def write(value, buf): @@ -7315,6 +7531,8 @@ def write(value, buf): buf.write_i32(6) if isinstance(value, DojoError.QueryError): buf.write_i32(7) + if isinstance(value, DojoError.SubscriptionError): + buf.write_i32(8) @@ -7608,6 +7826,394 @@ def read(cls, buf): _UniffiFfiConverterTypeSqlRow.read(buf) for i in range(count) ] + + + +class EntityUpdateCallback(typing.Protocol): + + def on_update(self, entity: Entity) -> None: + raise NotImplementedError + def on_error(self, error: str) -> None: + raise NotImplementedError +# Put all the bits inside a class to keep the top-level namespace clean +class _UniffiTraitImplEntityUpdateCallbackImpl: + # For each method, generate a callback function to pass to Rust + + @_UNIFFI_CALLBACK_INTERFACE_DOJO_ENTITY_UPDATE_CALLBACK_METHOD0 + def on_update( + uniffi_handle, + entity, + uniffi_out_return, + uniffi_call_status_ptr, + ): + uniffi_obj = _UniffiFfiConverterTypeEntityUpdateCallback._handle_map.get(uniffi_handle) + def make_call(): + uniffi_args = (_UniffiFfiConverterTypeEntity.lift(entity), ) + uniffi_method = uniffi_obj.on_update + return uniffi_method(*uniffi_args) + write_return_value = lambda v: None + _uniffi_trait_interface_call( + uniffi_call_status_ptr.contents, + make_call, + write_return_value, + ) + + @_UNIFFI_CALLBACK_INTERFACE_DOJO_ENTITY_UPDATE_CALLBACK_METHOD1 + def on_error( + uniffi_handle, + error, + uniffi_out_return, + uniffi_call_status_ptr, + ): + uniffi_obj = _UniffiFfiConverterTypeEntityUpdateCallback._handle_map.get(uniffi_handle) + def make_call(): + uniffi_args = (_UniffiFfiConverterString.lift(error), ) + uniffi_method = uniffi_obj.on_error + return uniffi_method(*uniffi_args) + write_return_value = lambda v: None + _uniffi_trait_interface_call( + uniffi_call_status_ptr.contents, + make_call, + write_return_value, + ) + + @_UNIFFI_CALLBACK_INTERFACE_FREE_DOJO_ENTITY_UPDATE_CALLBACK + def _uniffi_free(uniffi_handle): + _UniffiFfiConverterTypeEntityUpdateCallback._handle_map.remove(uniffi_handle) + + @_UNIFFI_CALLBACK_INTERFACE_CLONE_DOJO_ENTITY_UPDATE_CALLBACK + def _uniffi_clone(uniffi_handle): + return _UniffiFfiConverterTypeEntityUpdateCallback._handle_map.clone(uniffi_handle) + + # Generate the FFI VTable. This has a field for each callback interface method. + _uniffi_vtable = _UniffiVTableCallbackInterfaceDojoEntityUpdateCallback( + _uniffi_free, + _uniffi_clone, + on_update, + on_error, + ) + # Send Rust a pointer to the VTable. Note: this means we need to keep the struct alive forever, + # or else bad things will happen when Rust tries to access it. + _UniffiLib.uniffi_dojo_c_fn_init_callback_vtable_entityupdatecallback(ctypes.byref(_uniffi_vtable)) + +# The _UniffiConverter which transforms the Callbacks in to Handles to pass to Rust. +_UniffiFfiConverterTypeEntityUpdateCallback = _UniffiCallbackInterfaceFfiConverter() + +class _UniffiFfiConverterSequenceTypeKeysClause(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeKeysClause.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeKeysClause.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeKeysClause.read(buf) for i in range(count) + ] + + + + +class EventUpdateCallback(typing.Protocol): + + def on_update(self, event: Event) -> None: + raise NotImplementedError + def on_error(self, error: str) -> None: + raise NotImplementedError +# Put all the bits inside a class to keep the top-level namespace clean +class _UniffiTraitImplEventUpdateCallbackImpl: + # For each method, generate a callback function to pass to Rust + + @_UNIFFI_CALLBACK_INTERFACE_DOJO_EVENT_UPDATE_CALLBACK_METHOD0 + def on_update( + uniffi_handle, + event, + uniffi_out_return, + uniffi_call_status_ptr, + ): + uniffi_obj = _UniffiFfiConverterTypeEventUpdateCallback._handle_map.get(uniffi_handle) + def make_call(): + uniffi_args = (_UniffiFfiConverterTypeEvent.lift(event), ) + uniffi_method = uniffi_obj.on_update + return uniffi_method(*uniffi_args) + write_return_value = lambda v: None + _uniffi_trait_interface_call( + uniffi_call_status_ptr.contents, + make_call, + write_return_value, + ) + + @_UNIFFI_CALLBACK_INTERFACE_DOJO_EVENT_UPDATE_CALLBACK_METHOD1 + def on_error( + uniffi_handle, + error, + uniffi_out_return, + uniffi_call_status_ptr, + ): + uniffi_obj = _UniffiFfiConverterTypeEventUpdateCallback._handle_map.get(uniffi_handle) + def make_call(): + uniffi_args = (_UniffiFfiConverterString.lift(error), ) + uniffi_method = uniffi_obj.on_error + return uniffi_method(*uniffi_args) + write_return_value = lambda v: None + _uniffi_trait_interface_call( + uniffi_call_status_ptr.contents, + make_call, + write_return_value, + ) + + @_UNIFFI_CALLBACK_INTERFACE_FREE_DOJO_EVENT_UPDATE_CALLBACK + def _uniffi_free(uniffi_handle): + _UniffiFfiConverterTypeEventUpdateCallback._handle_map.remove(uniffi_handle) + + @_UNIFFI_CALLBACK_INTERFACE_CLONE_DOJO_EVENT_UPDATE_CALLBACK + def _uniffi_clone(uniffi_handle): + return _UniffiFfiConverterTypeEventUpdateCallback._handle_map.clone(uniffi_handle) + + # Generate the FFI VTable. This has a field for each callback interface method. + _uniffi_vtable = _UniffiVTableCallbackInterfaceDojoEventUpdateCallback( + _uniffi_free, + _uniffi_clone, + on_update, + on_error, + ) + # Send Rust a pointer to the VTable. Note: this means we need to keep the struct alive forever, + # or else bad things will happen when Rust tries to access it. + _UniffiLib.uniffi_dojo_c_fn_init_callback_vtable_eventupdatecallback(ctypes.byref(_uniffi_vtable)) + +# The _UniffiConverter which transforms the Callbacks in to Handles to pass to Rust. +_UniffiFfiConverterTypeEventUpdateCallback = _UniffiCallbackInterfaceFfiConverter() + + + + +class TokenBalanceUpdateCallback(typing.Protocol): + + def on_update(self, balance: TokenBalance) -> None: + raise NotImplementedError + def on_error(self, error: str) -> None: + raise NotImplementedError +# Put all the bits inside a class to keep the top-level namespace clean +class _UniffiTraitImplTokenBalanceUpdateCallbackImpl: + # For each method, generate a callback function to pass to Rust + + @_UNIFFI_CALLBACK_INTERFACE_DOJO_TOKEN_BALANCE_UPDATE_CALLBACK_METHOD0 + def on_update( + uniffi_handle, + balance, + uniffi_out_return, + uniffi_call_status_ptr, + ): + uniffi_obj = _UniffiFfiConverterTypeTokenBalanceUpdateCallback._handle_map.get(uniffi_handle) + def make_call(): + uniffi_args = (_UniffiFfiConverterTypeTokenBalance.lift(balance), ) + uniffi_method = uniffi_obj.on_update + return uniffi_method(*uniffi_args) + write_return_value = lambda v: None + _uniffi_trait_interface_call( + uniffi_call_status_ptr.contents, + make_call, + write_return_value, + ) + + @_UNIFFI_CALLBACK_INTERFACE_DOJO_TOKEN_BALANCE_UPDATE_CALLBACK_METHOD1 + def on_error( + uniffi_handle, + error, + uniffi_out_return, + uniffi_call_status_ptr, + ): + uniffi_obj = _UniffiFfiConverterTypeTokenBalanceUpdateCallback._handle_map.get(uniffi_handle) + def make_call(): + uniffi_args = (_UniffiFfiConverterString.lift(error), ) + uniffi_method = uniffi_obj.on_error + return uniffi_method(*uniffi_args) + write_return_value = lambda v: None + _uniffi_trait_interface_call( + uniffi_call_status_ptr.contents, + make_call, + write_return_value, + ) + + @_UNIFFI_CALLBACK_INTERFACE_FREE_DOJO_TOKEN_BALANCE_UPDATE_CALLBACK + def _uniffi_free(uniffi_handle): + _UniffiFfiConverterTypeTokenBalanceUpdateCallback._handle_map.remove(uniffi_handle) + + @_UNIFFI_CALLBACK_INTERFACE_CLONE_DOJO_TOKEN_BALANCE_UPDATE_CALLBACK + def _uniffi_clone(uniffi_handle): + return _UniffiFfiConverterTypeTokenBalanceUpdateCallback._handle_map.clone(uniffi_handle) + + # Generate the FFI VTable. This has a field for each callback interface method. + _uniffi_vtable = _UniffiVTableCallbackInterfaceDojoTokenBalanceUpdateCallback( + _uniffi_free, + _uniffi_clone, + on_update, + on_error, + ) + # Send Rust a pointer to the VTable. Note: this means we need to keep the struct alive forever, + # or else bad things will happen when Rust tries to access it. + _UniffiLib.uniffi_dojo_c_fn_init_callback_vtable_tokenbalanceupdatecallback(ctypes.byref(_uniffi_vtable)) + +# The _UniffiConverter which transforms the Callbacks in to Handles to pass to Rust. +_UniffiFfiConverterTypeTokenBalanceUpdateCallback = _UniffiCallbackInterfaceFfiConverter() + + + + +class TokenUpdateCallback(typing.Protocol): + + def on_update(self, token: Token) -> None: + raise NotImplementedError + def on_error(self, error: str) -> None: + raise NotImplementedError +# Put all the bits inside a class to keep the top-level namespace clean +class _UniffiTraitImplTokenUpdateCallbackImpl: + # For each method, generate a callback function to pass to Rust + + @_UNIFFI_CALLBACK_INTERFACE_DOJO_TOKEN_UPDATE_CALLBACK_METHOD0 + def on_update( + uniffi_handle, + token, + uniffi_out_return, + uniffi_call_status_ptr, + ): + uniffi_obj = _UniffiFfiConverterTypeTokenUpdateCallback._handle_map.get(uniffi_handle) + def make_call(): + uniffi_args = (_UniffiFfiConverterTypeToken.lift(token), ) + uniffi_method = uniffi_obj.on_update + return uniffi_method(*uniffi_args) + write_return_value = lambda v: None + _uniffi_trait_interface_call( + uniffi_call_status_ptr.contents, + make_call, + write_return_value, + ) + + @_UNIFFI_CALLBACK_INTERFACE_DOJO_TOKEN_UPDATE_CALLBACK_METHOD1 + def on_error( + uniffi_handle, + error, + uniffi_out_return, + uniffi_call_status_ptr, + ): + uniffi_obj = _UniffiFfiConverterTypeTokenUpdateCallback._handle_map.get(uniffi_handle) + def make_call(): + uniffi_args = (_UniffiFfiConverterString.lift(error), ) + uniffi_method = uniffi_obj.on_error + return uniffi_method(*uniffi_args) + write_return_value = lambda v: None + _uniffi_trait_interface_call( + uniffi_call_status_ptr.contents, + make_call, + write_return_value, + ) + + @_UNIFFI_CALLBACK_INTERFACE_FREE_DOJO_TOKEN_UPDATE_CALLBACK + def _uniffi_free(uniffi_handle): + _UniffiFfiConverterTypeTokenUpdateCallback._handle_map.remove(uniffi_handle) + + @_UNIFFI_CALLBACK_INTERFACE_CLONE_DOJO_TOKEN_UPDATE_CALLBACK + def _uniffi_clone(uniffi_handle): + return _UniffiFfiConverterTypeTokenUpdateCallback._handle_map.clone(uniffi_handle) + + # Generate the FFI VTable. This has a field for each callback interface method. + _uniffi_vtable = _UniffiVTableCallbackInterfaceDojoTokenUpdateCallback( + _uniffi_free, + _uniffi_clone, + on_update, + on_error, + ) + # Send Rust a pointer to the VTable. Note: this means we need to keep the struct alive forever, + # or else bad things will happen when Rust tries to access it. + _UniffiLib.uniffi_dojo_c_fn_init_callback_vtable_tokenupdatecallback(ctypes.byref(_uniffi_vtable)) + +# The _UniffiConverter which transforms the Callbacks in to Handles to pass to Rust. +_UniffiFfiConverterTypeTokenUpdateCallback = _UniffiCallbackInterfaceFfiConverter() + + + + +class TransactionUpdateCallback(typing.Protocol): + + def on_update(self, transaction: Transaction) -> None: + raise NotImplementedError + def on_error(self, error: str) -> None: + raise NotImplementedError +# Put all the bits inside a class to keep the top-level namespace clean +class _UniffiTraitImplTransactionUpdateCallbackImpl: + # For each method, generate a callback function to pass to Rust + + @_UNIFFI_CALLBACK_INTERFACE_DOJO_TRANSACTION_UPDATE_CALLBACK_METHOD0 + def on_update( + uniffi_handle, + transaction, + uniffi_out_return, + uniffi_call_status_ptr, + ): + uniffi_obj = _UniffiFfiConverterTypeTransactionUpdateCallback._handle_map.get(uniffi_handle) + def make_call(): + uniffi_args = (_UniffiFfiConverterTypeTransaction.lift(transaction), ) + uniffi_method = uniffi_obj.on_update + return uniffi_method(*uniffi_args) + write_return_value = lambda v: None + _uniffi_trait_interface_call( + uniffi_call_status_ptr.contents, + make_call, + write_return_value, + ) + + @_UNIFFI_CALLBACK_INTERFACE_DOJO_TRANSACTION_UPDATE_CALLBACK_METHOD1 + def on_error( + uniffi_handle, + error, + uniffi_out_return, + uniffi_call_status_ptr, + ): + uniffi_obj = _UniffiFfiConverterTypeTransactionUpdateCallback._handle_map.get(uniffi_handle) + def make_call(): + uniffi_args = (_UniffiFfiConverterString.lift(error), ) + uniffi_method = uniffi_obj.on_error + return uniffi_method(*uniffi_args) + write_return_value = lambda v: None + _uniffi_trait_interface_call( + uniffi_call_status_ptr.contents, + make_call, + write_return_value, + ) + + @_UNIFFI_CALLBACK_INTERFACE_FREE_DOJO_TRANSACTION_UPDATE_CALLBACK + def _uniffi_free(uniffi_handle): + _UniffiFfiConverterTypeTransactionUpdateCallback._handle_map.remove(uniffi_handle) + + @_UNIFFI_CALLBACK_INTERFACE_CLONE_DOJO_TRANSACTION_UPDATE_CALLBACK + def _uniffi_clone(uniffi_handle): + return _UniffiFfiConverterTypeTransactionUpdateCallback._handle_map.clone(uniffi_handle) + + # Generate the FFI VTable. This has a field for each callback interface method. + _uniffi_vtable = _UniffiVTableCallbackInterfaceDojoTransactionUpdateCallback( + _uniffi_free, + _uniffi_clone, + on_update, + on_error, + ) + # Send Rust a pointer to the VTable. Note: this means we need to keep the struct alive forever, + # or else bad things will happen when Rust tries to access it. + _UniffiLib.uniffi_dojo_c_fn_init_callback_vtable_transactionupdatecallback(ctypes.byref(_uniffi_vtable)) + +# The _UniffiConverter which transforms the Callbacks in to Handles to pass to Rust. +_UniffiFfiConverterTypeTransactionUpdateCallback = _UniffiCallbackInterfaceFfiConverter() + class _UniffiFfiConverterSequenceTypeWorld(_UniffiConverterRustBuffer): @classmethod def check_lower(cls, value): @@ -7640,6 +8246,8 @@ async def activities(self, query: ActivityQuery) -> PageActivity: raise NotImplementedError async def aggregations(self, query: AggregationQuery) -> PageAggregationEntry: raise NotImplementedError + def cancel_subscription(self, subscription_id: int) -> None: + raise NotImplementedError async def contracts(self, query: ContractQuery) -> typing.List[Contract]: raise NotImplementedError async def controllers(self, query: ControllerQuery) -> PageController: @@ -7658,6 +8266,16 @@ async def sql(self, query: str) -> typing.List[SqlRow]: raise NotImplementedError async def starknet_events(self, query: EventQuery) -> PageEvent: raise NotImplementedError + async def subscribe_entity_updates(self, clause: typing.Optional[Clause],world_addresses: typing.List[FieldElement],callback: EntityUpdateCallback) -> int: + raise NotImplementedError + async def subscribe_event_updates(self, keys: typing.List[KeysClause],callback: EventUpdateCallback) -> int: + raise NotImplementedError + async def subscribe_token_balance_updates(self, contract_addresses: typing.List[FieldElement],account_addresses: typing.List[FieldElement],token_ids: typing.List[U256],callback: TokenBalanceUpdateCallback) -> int: + raise NotImplementedError + async def subscribe_token_updates(self, contract_addresses: typing.List[FieldElement],token_ids: typing.List[U256],callback: TokenUpdateCallback) -> int: + raise NotImplementedError + async def subscribe_transaction_updates(self, filter: typing.Optional[TransactionFilter],callback: TransactionUpdateCallback) -> int: + raise NotImplementedError async def token_balances(self, query: TokenBalanceQuery) -> PageTokenBalance: raise NotImplementedError async def token_contracts(self, query: TokenContractQuery) -> PageTokenContract: @@ -7765,6 +8383,21 @@ async def aggregations(self, query: AggregationQuery) -> PageAggregationEntry: _uniffi_lift_return, _uniffi_error_converter, ) + def cancel_subscription(self, subscription_id: int) -> None: + + _UniffiFfiConverterUInt64.check_lower(subscription_id) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterUInt64.lower(subscription_id), + ) + _uniffi_lift_return = lambda val: None + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + _uniffi_ffi_result = _uniffi_rust_call_with_error( + _uniffi_error_converter, + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_cancel_subscription, + *_uniffi_lowered_args, + ) + return _uniffi_lift_return(_uniffi_ffi_result) async def contracts(self, query: ContractQuery) -> typing.List[Contract]: _UniffiFfiConverterTypeContractQuery.check_lower(query) @@ -7918,6 +8551,118 @@ async def starknet_events(self, query: EventQuery) -> PageEvent: _uniffi_lift_return, _uniffi_error_converter, ) + async def subscribe_entity_updates(self, clause: typing.Optional[Clause],world_addresses: typing.List[FieldElement],callback: EntityUpdateCallback) -> int: + + _UniffiFfiConverterOptionalTypeClause.check_lower(clause) + + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(world_addresses) + + _UniffiFfiConverterTypeEntityUpdateCallback.check_lower(callback) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterOptionalTypeClause.lower(clause), + _UniffiFfiConverterSequenceTypeFieldElement.lower(world_addresses), + _UniffiFfiConverterTypeEntityUpdateCallback.lower(callback), + ) + _uniffi_lift_return = _UniffiFfiConverterUInt64.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_subscribe_entity_updates(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_u64, + _UniffiLib.ffi_dojo_c_rust_future_complete_u64, + _UniffiLib.ffi_dojo_c_rust_future_free_u64, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def subscribe_event_updates(self, keys: typing.List[KeysClause],callback: EventUpdateCallback) -> int: + + _UniffiFfiConverterSequenceTypeKeysClause.check_lower(keys) + + _UniffiFfiConverterTypeEventUpdateCallback.check_lower(callback) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterSequenceTypeKeysClause.lower(keys), + _UniffiFfiConverterTypeEventUpdateCallback.lower(callback), + ) + _uniffi_lift_return = _UniffiFfiConverterUInt64.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_subscribe_event_updates(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_u64, + _UniffiLib.ffi_dojo_c_rust_future_complete_u64, + _UniffiLib.ffi_dojo_c_rust_future_free_u64, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def subscribe_token_balance_updates(self, contract_addresses: typing.List[FieldElement],account_addresses: typing.List[FieldElement],token_ids: typing.List[U256],callback: TokenBalanceUpdateCallback) -> int: + + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(contract_addresses) + + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(account_addresses) + + _UniffiFfiConverterSequenceTypeU256.check_lower(token_ids) + + _UniffiFfiConverterTypeTokenBalanceUpdateCallback.check_lower(callback) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterSequenceTypeFieldElement.lower(contract_addresses), + _UniffiFfiConverterSequenceTypeFieldElement.lower(account_addresses), + _UniffiFfiConverterSequenceTypeU256.lower(token_ids), + _UniffiFfiConverterTypeTokenBalanceUpdateCallback.lower(callback), + ) + _uniffi_lift_return = _UniffiFfiConverterUInt64.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_subscribe_token_balance_updates(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_u64, + _UniffiLib.ffi_dojo_c_rust_future_complete_u64, + _UniffiLib.ffi_dojo_c_rust_future_free_u64, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def subscribe_token_updates(self, contract_addresses: typing.List[FieldElement],token_ids: typing.List[U256],callback: TokenUpdateCallback) -> int: + + _UniffiFfiConverterSequenceTypeFieldElement.check_lower(contract_addresses) + + _UniffiFfiConverterSequenceTypeU256.check_lower(token_ids) + + _UniffiFfiConverterTypeTokenUpdateCallback.check_lower(callback) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterSequenceTypeFieldElement.lower(contract_addresses), + _UniffiFfiConverterSequenceTypeU256.lower(token_ids), + _UniffiFfiConverterTypeTokenUpdateCallback.lower(callback), + ) + _uniffi_lift_return = _UniffiFfiConverterUInt64.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_subscribe_token_updates(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_u64, + _UniffiLib.ffi_dojo_c_rust_future_complete_u64, + _UniffiLib.ffi_dojo_c_rust_future_free_u64, + _uniffi_lift_return, + _uniffi_error_converter, + ) + async def subscribe_transaction_updates(self, filter: typing.Optional[TransactionFilter],callback: TransactionUpdateCallback) -> int: + + _UniffiFfiConverterOptionalTypeTransactionFilter.check_lower(filter) + + _UniffiFfiConverterTypeTransactionUpdateCallback.check_lower(callback) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterOptionalTypeTransactionFilter.lower(filter), + _UniffiFfiConverterTypeTransactionUpdateCallback.lower(callback), + ) + _uniffi_lift_return = _UniffiFfiConverterUInt64.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + return await _uniffi_rust_call_async( + _UniffiLib.uniffi_dojo_c_fn_method_toriiclient_subscribe_transaction_updates(*_uniffi_lowered_args), + _UniffiLib.ffi_dojo_c_rust_future_poll_u64, + _UniffiLib.ffi_dojo_c_rust_future_complete_u64, + _UniffiLib.ffi_dojo_c_rust_future_free_u64, + _uniffi_lift_return, + _uniffi_error_converter, + ) async def token_balances(self, query: TokenBalanceQuery) -> PageTokenBalance: _UniffiFfiConverterTypeTokenBalanceQuery.check_lower(query) @@ -8131,4 +8876,9 @@ def write(cls, value: ToriiClient, buf: _UniffiRustBuffer): "World", "ToriiClient", "ToriiClientProtocol", + "EntityUpdateCallback", + "EventUpdateCallback", + "TokenBalanceUpdateCallback", + "TokenUpdateCallback", + "TransactionUpdateCallback", ] \ No newline at end of file diff --git a/crates/uniffi/Cargo.toml b/crates/uniffi/Cargo.toml new file mode 100644 index 0000000..88f6d6d --- /dev/null +++ b/crates/uniffi/Cargo.toml @@ -0,0 +1,80 @@ +[package] +name = "uniffi" +version.workspace = true +edition.workspace = true + +[lib] +crate-type = ["cdylib", "lib"] +name = "dojo" + +[dependencies] +dojo-core = { workspace = true } + +dojo-world.workspace = true +dojo-types.workspace = true +torii-proto.workspace = true +torii-client.workspace = true +torii-grpc-client.workspace = true + +starknet.workspace = true +starknet-crypto.workspace = true + +tokio.workspace = true +url.workspace = true +anyhow.workspace = true +serde.workspace = true +serde_json.workspace = true +tokio-stream.workspace = true +futures.workspace = true +futures-util.workspace = true +stream-cancel.workspace = true +cainome.workspace = true +lazy_static.workspace = true +crypto-bigint.workspace = true +chrono.workspace = true +num-bigint.workspace = true +num-traits.workspace = true + +# UniFFI +uniffi = { version = "0.30", features = ["bindgen", "cli"] } +uniffi_bindgen = "0.30" +camino = "1.1" +thiserror = "2" +hex = "0.4" +cargo_metadata = "0.19" + +# Platform-specific dependencies +axum = "0.8.1" +open = "5.3.2" +urlencoding = "2.1.3" +keyring = { version = "3.6.1", features = [ + "apple-native", + "windows-native", + "sync-secret-service", +] } +directories = "6.0.0" +tower-http = { version = "0.6.2", features = ["cors"] } +base64 = "0.22.1" + +[build-dependencies] +uniffi = { version = "0.30", features = ["build"] } + +[dev-dependencies] +uniffi = { version = "0.30", features = ["bindgen-tests"] } + +# UniFFI bindgen binaries +[[bin]] +name = "uniffi-bindgen-swift" +path = "src/bin/uniffi-bindgen-swift.rs" + +[[bin]] +name = "uniffi-bindgen-kotlin" +path = "src/bin/uniffi-bindgen-kotlin.rs" + +[[bin]] +name = "uniffi-bindgen-python" +path = "src/bin/uniffi-bindgen-python.rs" + +[features] +default = [] + diff --git a/crates/uniffi/build.rs b/crates/uniffi/build.rs new file mode 100644 index 0000000..2778088 --- /dev/null +++ b/crates/uniffi/build.rs @@ -0,0 +1,4 @@ +fn main() { + uniffi::generate_scaffolding("src/dojo.udl").expect("Failed to generate UniFFI scaffolding"); +} + diff --git a/crates/uniffi/src/bin/uniffi-bindgen-kotlin.rs b/crates/uniffi/src/bin/uniffi-bindgen-kotlin.rs new file mode 100644 index 0000000..f9a2f4d --- /dev/null +++ b/crates/uniffi/src/bin/uniffi-bindgen-kotlin.rs @@ -0,0 +1,55 @@ +use std::env; +use std::process; +use uniffi_bindgen::bindings::KotlinBindingGenerator; +use uniffi_bindgen::library_mode::generate_bindings; +use camino::Utf8PathBuf; + +fn main() { + let args: Vec = env::args().collect(); + + if args.len() < 3 { + eprintln!("UniFFI Kotlin Binding Generator"); + eprintln!(); + eprintln!("Usage: {} ", args[0]); + eprintln!(); + eprintln!("Example:"); + eprintln!(" {} target/release/libdojo_c.dylib bindings/kotlin", args[0]); + eprintln!(); + process::exit(1); + } + + let library_path = Utf8PathBuf::from(&args[1]); + let out_dir = Utf8PathBuf::from(&args[2]); + + if !library_path.exists() { + eprintln!("Error: Library file not found: {}", library_path); + eprintln!("Build the library first with: cargo build --release"); + process::exit(1); + } + + println!("Generating Kotlin bindings..."); + println!("Library: {}", library_path); + println!("Output: {}", out_dir); + + // Use library mode with Kotlin binding generator + let config_supplier = uniffi_bindgen::EmptyCrateConfigSupplier; + + match generate_bindings( + &library_path, + None, // crate_name (auto-detect) + &KotlinBindingGenerator, + &config_supplier, + None, // config_file_override + &out_dir, + false, // try_format_code + ) { + Ok(_) => { + println!("✓ Kotlin bindings generated successfully in {}", out_dir); + } + Err(e) => { + eprintln!("Error generating bindings: {}", e); + process::exit(1); + } + } +} + diff --git a/crates/uniffi/src/bin/uniffi-bindgen-python.rs b/crates/uniffi/src/bin/uniffi-bindgen-python.rs new file mode 100644 index 0000000..e4f37bb --- /dev/null +++ b/crates/uniffi/src/bin/uniffi-bindgen-python.rs @@ -0,0 +1,65 @@ +use std::env; +use std::process; +use uniffi_bindgen::bindings::python::run_pipeline; +use uniffi_bindgen::cargo_metadata::CrateConfigSupplier; +use uniffi_bindgen::pipeline::initial::Root; +use camino::Utf8PathBuf; + +fn main() { + let args: Vec = env::args().collect(); + + if args.len() < 3 { + eprintln!("UniFFI Python Binding Generator"); + eprintln!(); + eprintln!("Usage: {} ", args[0]); + eprintln!(); + eprintln!("Example:"); + eprintln!(" {} target/release/libdojo_c.dylib bindings/python", args[0]); + eprintln!(); + process::exit(1); + } + + let library_path = Utf8PathBuf::from(&args[1]); + let out_dir = Utf8PathBuf::from(&args[2]); + + if !library_path.exists() { + eprintln!("Error: Library file not found: {}", library_path); + eprintln!("Build the library first with: cargo build --release"); + process::exit(1); + } + + println!("Generating Python bindings..."); + println!("Library: {}", library_path); + println!("Output: {}", out_dir); + + // Use cargo metadata to get crate configuration + let metadata = match cargo_metadata::MetadataCommand::new().exec() { + Ok(m) => m, + Err(e) => { + eprintln!("Error getting cargo metadata: {}", e); + eprintln!("Make sure you're running this from a cargo project directory"); + process::exit(1); + } + }; + + let config_supplier = CrateConfigSupplier::from(metadata); + + match Root::from_library(config_supplier, &library_path, None) { + Ok(root) => { + match run_pipeline(root, &out_dir) { + Ok(_) => { + println!("✓ Python bindings generated successfully in {}", out_dir); + } + Err(e) => { + eprintln!("Error generating Python bindings: {}", e); + process::exit(1); + } + } + } + Err(e) => { + eprintln!("Error loading library metadata: {}", e); + process::exit(1); + } + } +} + diff --git a/crates/uniffi/src/bin/uniffi-bindgen-swift.rs b/crates/uniffi/src/bin/uniffi-bindgen-swift.rs new file mode 100644 index 0000000..5396425 --- /dev/null +++ b/crates/uniffi/src/bin/uniffi-bindgen-swift.rs @@ -0,0 +1,71 @@ +use std::env; +use std::process; +use uniffi_bindgen::bindings::{generate_swift_bindings, SwiftBindingsOptions}; +use camino::Utf8PathBuf; + +fn main() { + let args: Vec = env::args().collect(); + + if args.len() < 3 { + eprintln!("UniFFI Swift Binding Generator"); + eprintln!(); + eprintln!("Usage: {} [--swift-sources] [--headers] [--modulemap]", args[0]); + eprintln!(); + eprintln!("Options:"); + eprintln!(" --swift-sources Generate .swift source files (default)"); + eprintln!(" --headers Generate .h header files"); + eprintln!(" --modulemap Generate modulemap"); + eprintln!(" --xcframework Generate XCFramework-compatible modulemap"); + eprintln!(); + eprintln!("Examples:"); + eprintln!(" {} target/release/libdojo_c.dylib bindings/swift --swift-sources", args[0]); + eprintln!(" {} target/release/libdojo_c.dylib bindings/swift --headers --modulemap", args[0]); + eprintln!(); + process::exit(1); + } + + let library_path = Utf8PathBuf::from(&args[1]); + let out_dir = Utf8PathBuf::from(&args[2]); + + if !library_path.exists() { + eprintln!("Error: Library file not found: {}", library_path); + eprintln!("Build the library first with: cargo build --release"); + process::exit(1); + } + + // Parse options + let has_swift_sources = args.contains(&"--swift-sources".to_string()); + let has_headers = args.contains(&"--headers".to_string()); + let has_modulemap = args.contains(&"--modulemap".to_string()); + let has_xcframework = args.contains(&"--xcframework".to_string()); + + // Default to generating Swift sources if no specific flags are provided + let generate_swift_sources = has_swift_sources || (!has_headers && !has_modulemap); + + println!("Generating Swift bindings..."); + println!("Library: {}", library_path); + println!("Output: {}", out_dir); + + let options = SwiftBindingsOptions { + generate_swift_sources, + generate_headers: has_headers, + generate_modulemap: has_modulemap, + source: library_path, + out_dir, + xcframework: has_xcframework, + module_name: Some("DojoEngine".to_string()), + modulemap_filename: None, + metadata_no_deps: false, + link_frameworks: vec![], + }; + + match generate_swift_bindings(options) { + Ok(_) => { + println!("✓ Swift bindings generated successfully!"); + } + Err(e) => { + eprintln!("Error generating bindings: {}", e); + process::exit(1); + } + } +} diff --git a/crates/uniffi/src/bin/uniffi-bindgen.rs b/crates/uniffi/src/bin/uniffi-bindgen.rs new file mode 100644 index 0000000..a5b7643 --- /dev/null +++ b/crates/uniffi/src/bin/uniffi-bindgen.rs @@ -0,0 +1,4 @@ +fn main() { + uniffi_bindgen::main() +} + diff --git a/crates/uniffi/src/dojo.udl b/crates/uniffi/src/dojo.udl new file mode 100644 index 0000000..e5c7e8d --- /dev/null +++ b/crates/uniffi/src/dojo.udl @@ -0,0 +1,470 @@ +// Simplified UDL - just the types that work easily with UniFFI +// Complex recursive types (Primitive, Ty, Clause, etc.) should be handled +// via procmacros in Rust rather than UDL + +namespace dojo { +}; + +// Core types +[Custom] +typedef string FieldElement; + +[Custom] +typedef string U256; + +// Enums +enum PaginationDirection { + "Forward", + "Backward", +}; + +enum OrderDirection { + "Asc", + "Desc", +}; + +enum ContractType { + "WORLD", + "ERC20", + "ERC721", + "ERC1155", + "UDC", + "OTHER", +}; + +enum CallType { + "Execute", + "ExecuteFromOutside", +}; + +enum PatternMatching { + "FixedLen", + "VariableLen", +}; + +enum LogicalOperator { + "And", + "Or", +}; + +enum ComparisonOperator { + "Eq", + "Neq", + "Gt", + "Gte", + "Lt", + "Lte", + "In", + "NotIn", + "Contains", + "ContainsAll", + "ContainsAny", + "ArrayLengthEq", + "ArrayLengthGt", + "ArrayLengthLt", +}; + +// Basic structures +dictionary Signature { + FieldElement r; + FieldElement s; +}; + +dictionary OrderBy { + string field; + OrderDirection direction; +}; + +dictionary Pagination { + string? cursor; + u32? limit; + PaginationDirection direction; + sequence order_by; +}; + +// Controller +dictionary Controller { + FieldElement address; + string username; + u64 deployed_at_timestamp; +}; + +dictionary ControllerQuery { + Pagination pagination; + sequence contract_addresses; + sequence usernames; +}; + +// Token types +dictionary Token { + FieldElement contract_address; + U256? token_id; + string name; + string symbol; + u8 decimals; + string metadata; + U256? total_supply; +}; + +dictionary TokenBalance { + U256 balance; + FieldElement account_address; + FieldElement contract_address; + U256? token_id; +}; + +dictionary TokenContract { + FieldElement contract_address; + string name; + string symbol; + u8 decimals; + string metadata; + string token_metadata; + U256? total_supply; +}; + +dictionary AttributeFilter { + string trait_name; + string trait_value; +}; + +dictionary TokenQuery { + sequence contract_addresses; + sequence token_ids; + sequence attribute_filters; + Pagination pagination; +}; + +dictionary TokenBalanceQuery { + sequence contract_addresses; + sequence account_addresses; + sequence token_ids; + Pagination pagination; +}; + +dictionary TokenContractQuery { + sequence contract_addresses; + sequence contract_types; + Pagination pagination; +}; + +dictionary TokenTransfer { + string id; + FieldElement contract_address; + FieldElement from_address; + FieldElement to_address; + U256 amount; + U256? token_id; + u64 executed_at; + string? event_id; +}; + +dictionary TokenTransferQuery { + sequence contract_addresses; + sequence account_addresses; + sequence token_ids; + Pagination pagination; +}; + +// Contract +dictionary Contract { + FieldElement contract_address; + ContractType contract_type; + u64? head; + u64? tps; + u64? last_block_timestamp; + FieldElement? last_pending_block_tx; + u64 updated_at; + u64 created_at; +}; + +dictionary ContractQuery { + sequence contract_addresses; + sequence contract_types; +}; + +// Transaction types +dictionary TransactionCall { + FieldElement contract_address; + string entrypoint; + sequence calldata; + CallType call_type; + FieldElement caller_address; +}; + +dictionary Transaction { + FieldElement transaction_hash; + FieldElement sender_address; + sequence calldata; + FieldElement max_fee; + sequence signature; + FieldElement nonce; + u64 block_number; + string transaction_type; + u64 block_timestamp; + sequence calls; + sequence unique_models; +}; + +dictionary TransactionFilter { + sequence transaction_hashes; + sequence caller_addresses; + sequence contract_addresses; + sequence entrypoints; + sequence model_selectors; + u64? from_block; + u64? to_block; +}; + +dictionary TransactionQuery { + TransactionFilter? filter; + Pagination pagination; +}; + +// Aggregation +dictionary AggregationQuery { + sequence aggregator_ids; + sequence entity_ids; + Pagination pagination; +}; + +dictionary AggregationEntry { + string id; + string aggregator_id; + string entity_id; + U256 value; + string display_value; + u64 position; + string model_id; + u64 created_at; + u64 updated_at; +}; + +// Activity +dictionary ActionCount { + string action_name; + u32 count; +}; + +dictionary Activity { + string id; + FieldElement world_address; + string namespace; + FieldElement caller_address; + u64 session_start; + u64 session_end; + u32 action_count; + sequence actions; + u64 updated_at; +}; + +dictionary ActivityQuery { + sequence world_addresses; + sequence namespaces; + sequence caller_addresses; + u64? from_time; + u64? to_time; + Pagination pagination; +}; + +// Achievement +dictionary AchievementTask { + string task_id; + string description; + u32 total; + u32 total_completions; + f64 completion_rate; + u64 created_at; +}; + +dictionary Achievement { + string id; + FieldElement world_address; + string namespace; + string entity_id; + boolean hidden; + u32 index; + u32 points; + string start; + string end; + string group; + string icon; + string title; + string description; + sequence tasks; + string? data; + u32 total_completions; + f64 completion_rate; + u64 created_at; + u64 updated_at; +}; + +dictionary AchievementQuery { + sequence world_addresses; + sequence namespaces; + boolean? hidden; + Pagination pagination; +}; + +dictionary TaskProgress { + string task_id; + u32 count; + boolean completed; +}; + +dictionary PlayerAchievementProgress { + Achievement achievement; + sequence task_progress; + boolean completed; + f64 progress_percentage; +}; + +dictionary PlayerAchievementStats { + u32 total_points; + u32 completed_achievements; + u32 total_achievements; + f64 completion_percentage; + u64? last_achievement_at; + u64 created_at; + u64 updated_at; +}; + +dictionary PlayerAchievementEntry { + FieldElement player_address; + PlayerAchievementStats stats; + sequence achievements; +}; + +dictionary PlayerAchievementQuery { + sequence world_addresses; + sequence namespaces; + sequence player_addresses; + Pagination pagination; +}; + +dictionary AchievementProgression { + string id; + string achievement_id; + string task_id; + FieldElement world_address; + string namespace; + FieldElement player_id; + u32 count; + boolean completed; + u64? completed_at; + u64 created_at; + u64 updated_at; +}; + +// Schema types - Complex enums with associated data + +[Enum] +interface Primitive { + I8(i8 value); + I16(i16 value); + I32(i32 value); + I64(i64 value); + I128(sequence value); + U8(u8 value); + U16(u16 value); + U32(u32 value); + U64(u64 value); + U128(sequence value); + U256(U256 value); + Bool(boolean value); + Felt252(FieldElement value); + ClassHash(FieldElement value); + ContractAddress(FieldElement value); + EthAddress(FieldElement value); +}; + +[Enum] +interface MemberValue { + Primitive(Primitive value); + String(string value); + List(sequence values); +}; + +dictionary Member { + string name; + Ty ty; + boolean key; +}; + +dictionary Struct { + string name; + sequence children; +}; + +dictionary EnumOption { + string name; + Ty ty; +}; + +dictionary EnumType { + string name; + u8 option; + sequence options; +}; + +dictionary FixedSizeArray { + sequence array; + u32 size; +}; + +[Enum] +interface Ty { + Primitive(Primitive value); + Struct(Struct value); + Enum(EnumType value); + Tuple(sequence values); + Array(sequence values); + FixedSizeArray(FixedSizeArray value); + ByteArray(string value); +}; + +[Enum] +interface ValueType { + String(string value); + Int(i64 value); + UInt(u64 value); + Bool(boolean value); + Bytes(sequence value); +}; + +// Query types - Complex enums for query building + +dictionary KeysClause { + sequence keys; + PatternMatching pattern_matching; + sequence models; +}; + +dictionary MemberClause { + string model; + string member; + ComparisonOperator operator; + MemberValue value; +}; + +dictionary CompositeClause { + LogicalOperator operator; + sequence clauses; +}; + +[Enum] +interface Clause { + HashedKeys(sequence keys); + Keys(KeysClause clause); + Member(MemberClause clause); + Composite(CompositeClause clause); +}; + +// Error type +[Error] +enum DojoError { + "ClientError", + "SerializationError", + "NetworkError", + "InvalidInput", +}; diff --git a/crates/uniffi/src/lib.rs b/crates/uniffi/src/lib.rs new file mode 100644 index 0000000..a5c96bd --- /dev/null +++ b/crates/uniffi/src/lib.rs @@ -0,0 +1,11 @@ +// UniFFI bindings for Dojo +// Multi-language bindings (Swift, Kotlin, Python) using UniFFI + +pub mod uniffi; + +// Re-export all UniFFI types at crate root for scaffolding +pub use uniffi::*; + +// Include the generated UniFFI scaffolding +uniffi::include_scaffolding!("dojo"); + diff --git a/crates/uniffi/src/uniffi/README.md b/crates/uniffi/src/uniffi/README.md new file mode 100644 index 0000000..5b17f1e --- /dev/null +++ b/crates/uniffi/src/uniffi/README.md @@ -0,0 +1,307 @@ +# UniFFI Types - Organized by Category + +This directory contains UniFFI-compatible Rust types for Dojo, organized by functional category for better maintainability and discoverability. + +## File Structure + +``` +src/uniffi/ +├── mod.rs # Module definitions and re-exports +├── core.rs # Core types and utilities +├── achievement.rs # Achievement system types +├── activity.rs # Activity tracking types +├── aggregation.rs # Data aggregation types +├── contract.rs # Smart contract types +├── controller.rs # Controller/account types +├── entity.rs # Entity, Model, and World types +├── event.rs # Event and Message types +├── query.rs # Query and filtering types +├── schema.rs # Schema definition types +├── token.rs # Token and NFT types +└── transaction.rs # Transaction types +``` + +## Module Organization + +### `core.rs` - Core Types and Utilities +The foundation module containing: +- **Type Definitions**: `FieldElement`, `U256` (as hex strings) +- **Error Handling**: `DojoError` enum +- **Pagination**: `Pagination`, `PaginationDirection`, `OrderBy`, `OrderDirection` +- **Common Types**: `Signature`, `Call`, `BlockId`, `BlockTag` +- **Helper Functions**: Conversion between internal types and strings + +**Key Types:** +- `FieldElement` - String representation of Starknet field elements +- `U256` - String representation of 256-bit unsigned integers +- `DojoError` - Comprehensive error handling +- `Pagination` - Cursor-based pagination support + +### `controller.rs` - Controller Types +Account and controller management: +- `Controller` - Account controller information +- `ControllerQuery` - Query for controllers + +**Use Cases:** +- Account management +- Username lookups +- Deployment tracking + +### `token.rs` - Token Types +ERC20, ERC721, and ERC1155 token support: +- `Token` - Token information +- `TokenBalance` - Token balance per account +- `TokenContract` - Token contract metadata +- `TokenTransfer` - Transfer event data +- `TokenQuery`, `TokenBalanceQuery`, `TokenContractQuery`, `TokenTransferQuery` +- `AttributeFilter` - NFT attribute filtering + +**Use Cases:** +- Token balance queries +- NFT metadata retrieval +- Transfer history +- Token searches with filters + +### `contract.rs` - Contract Types +Smart contract information and queries: +- `Contract` - Contract metadata +- `ContractType` - Enum for contract types (WORLD, ERC20, ERC721, etc.) +- `ContractQuery` - Query contracts by address or type + +**Use Cases:** +- Contract discovery +- Type-based filtering +- Deployment information + +### `transaction.rs` - Transaction Types +Transaction data and queries: +- `Transaction` - Full transaction information +- `TransactionCall` - Individual contract call +- `TransactionFilter` - Advanced transaction filtering +- `TransactionQuery` - Query transactions +- `CallType` - Execute vs ExecuteFromOutside + +**Use Cases:** +- Transaction history +- Call analysis +- Block explorer functionality + +### `schema.rs` - Schema Types +Type system and schema definitions: +- `Primitive` - Primitive type values (integers, felts, bools, etc.) +- `Ty` - Type definitions (Struct, Enum, Array, Tuple, etc.) +- `Struct` - Struct definition +- `Enum` - Enum definition +- `Member` - Struct/enum member +- `MemberValue` - Runtime value +- `ValueType` - Value type variants + +**Use Cases:** +- Schema introspection +- Dynamic typing +- Model definitions +- Data serialization + +### `query.rs` - Query Types +Powerful querying and filtering: +- `Query` - Main query structure +- `Clause` - Query clauses (HashedKeys, Keys, Member, Composite) +- `KeysClause` - Key-based filtering +- `MemberClause` - Member-based filtering +- `CompositeClause` - Logical composition (AND/OR) +- `PatternMatching` - Key pattern matching +- `ComparisonOperator` - Rich comparison operators +- `LogicalOperator` - AND/OR operators + +**Use Cases:** +- Entity queries +- Complex filtering +- Model data retrieval +- Historical queries + +### `entity.rs` - Entity Types +Core game entity types: +- `Entity` - Game entity with models +- `Model` - Model definition +- `World` - World state + +**Use Cases:** +- Entity management +- Model introspection +- World state queries + +### `event.rs` - Event Types +Blockchain event handling: +- `Event` - Starknet event +- `Message` - Signed message + +**Use Cases:** +- Event listening +- Message verification +- Event history + +### `aggregation.rs` - Aggregation Types +Data aggregation and leaderboards: +- `AggregationEntry` - Aggregated data entry +- `AggregationQuery` - Query aggregations + +**Use Cases:** +- Leaderboards +- Statistics +- Rankings + +### `activity.rs` - Activity Types +Player activity tracking: +- `Activity` - Player activity session +- `ActivityQuery` - Query player activity +- `ActionCount` - Action frequency + +**Use Cases:** +- Player analytics +- Session tracking +- Engagement metrics + +### `achievement.rs` - Achievement Types +Achievement and progression system: +- `Achievement` - Achievement definition +- `AchievementTask` - Individual task +- `PlayerAchievementProgress` - Player's progress +- `PlayerAchievementStats` - Player's achievement stats +- `AchievementProgression` - Detailed progression +- `TaskProgress` - Task completion status +- Corresponding query types + +**Use Cases:** +- Achievement systems +- Progression tracking +- Player rewards +- Gamification + +## Usage Examples + +### Querying Entities +```rust +use uniffi::{Query, Clause, MemberClause, ComparisonOperator, Primitive}; + +let query = Query { + world_addresses: vec!["0x123...".to_string()], + clause: Some(Clause::Member(MemberClause { + model: "Player".to_string(), + member: "level".to_string(), + operator: ComparisonOperator::Gte, + value: MemberValue::Primitive(Primitive::U32(10)), + })), + pagination: Default::default(), + no_hashed_keys: false, + models: vec!["Player".to_string()], + historical: false, +}; +``` + +### Token Balance Query +```rust +use uniffi::{TokenBalanceQuery, Pagination}; + +let query = TokenBalanceQuery { + contract_addresses: vec!["0xabc...".to_string()], + account_addresses: vec!["0xdef...".to_string()], + token_ids: vec![], + pagination: Pagination::default(), +}; +``` + +### Achievement Progress +```rust +use uniffi::{PlayerAchievementQuery, Pagination}; + +let query = PlayerAchievementQuery { + world_addresses: vec!["0x123...".to_string()], + namespaces: vec!["game".to_string()], + player_addresses: vec!["0xplayer...".to_string()], + pagination: Pagination::default(), +}; +``` + +## Design Principles + +### 1. **Category-Based Organization** +Types are grouped by their domain purpose rather than technical structure: +- Easy to find related types +- Clear separation of concerns +- Logical grouping for documentation + +### 2. **Minimal Dependencies** +Each module imports only what it needs: +- `core` has no internal dependencies +- Other modules depend on `core` +- Cross-references are minimal and explicit + +### 3. **Consistent Patterns** +All modules follow the same patterns: +- Types use `FieldElement` and `U256` as strings +- Conversions to/from proto types +- Clear documentation of purpose + +### 4. **Self-Documenting** +File names and organization make the purpose clear: +- `token.rs` - obviously token-related +- `achievement.rs` - clearly achievement system +- No need to read code to understand scope + +## Adding New Types + +When adding new types: + +1. **Determine Category**: Which module does it belong to? +2. **Create/Update Module**: Add to existing or create new category file +3. **Update mod.rs**: Add module declaration and re-exports +4. **Update UDL**: Add type definitions to `src/dojo.udl` +5. **Document**: Update this README + +Example - Adding a new "Quest" system: + +```rust +// src/uniffi/quest.rs +use super::core::*; + +#[derive(Debug, Clone)] +pub struct Quest { + pub id: String, + pub name: String, + // ... +} +``` + +Update `mod.rs`: +```rust +pub mod quest; +pub use quest::*; +``` + +## Benefits of This Organization + +### For Developers +- ✅ Quick discovery of related types +- ✅ Easy navigation +- ✅ Clear module boundaries +- ✅ Reduced cognitive load + +### For Maintenance +- ✅ Easy to add new categories +- ✅ Changes are localized +- ✅ Dependencies are explicit +- ✅ Better IDE support + +### For Documentation +- ✅ Self-organizing +- ✅ Category-based docs +- ✅ Clear examples per category +- ✅ Easy to generate docs + +## See Also + +- [UniFFI Documentation](https://mozilla.github.io/uniffi-rs/) +- [UNIFFI_CONVERSION.md](../../UNIFFI_CONVERSION.md) - Detailed conversion guide +- [CONVERSION_SUMMARY.md](../../CONVERSION_SUMMARY.md) - Complete type mapping +- [dojo.udl](../dojo.udl) - UniFFI interface definition + diff --git a/src/uniffi/achievement.rs b/crates/uniffi/src/uniffi/achievement.rs similarity index 100% rename from src/uniffi/achievement.rs rename to crates/uniffi/src/uniffi/achievement.rs diff --git a/src/uniffi/activity.rs b/crates/uniffi/src/uniffi/activity.rs similarity index 100% rename from src/uniffi/activity.rs rename to crates/uniffi/src/uniffi/activity.rs diff --git a/src/uniffi/aggregation.rs b/crates/uniffi/src/uniffi/aggregation.rs similarity index 100% rename from src/uniffi/aggregation.rs rename to crates/uniffi/src/uniffi/aggregation.rs diff --git a/src/uniffi/contract.rs b/crates/uniffi/src/uniffi/contract.rs similarity index 100% rename from src/uniffi/contract.rs rename to crates/uniffi/src/uniffi/contract.rs diff --git a/src/uniffi/controller.rs b/crates/uniffi/src/uniffi/controller.rs similarity index 100% rename from src/uniffi/controller.rs rename to crates/uniffi/src/uniffi/controller.rs diff --git a/crates/uniffi/src/uniffi/core.rs b/crates/uniffi/src/uniffi/core.rs new file mode 100644 index 0000000..0af019e --- /dev/null +++ b/crates/uniffi/src/uniffi/core.rs @@ -0,0 +1,260 @@ +// Core types - FieldElement, U256, Error, Pagination, Signature, Call, BlockId + +// Newtype wrappers for custom type conversions +// These will be represented as strings in the UDL via [Custom] attribute + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct FieldElement(pub String); + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct U256(pub String); + +// Custom type converter implementations for UniFFI +// Note: uniffi::custom_type! is called by the generated scaffolding from the UDL +// The UniffiCustomTypeConverter trait is defined in the generated scaffolding +impl crate::UniffiCustomTypeConverter for FieldElement { + type Builtin = String; + + fn into_custom(val: Self::Builtin) -> uniffi::Result { + Ok(FieldElement(val)) + } + + fn from_custom(obj: Self) -> Self::Builtin { + obj.0 + } +} + +impl crate::UniffiCustomTypeConverter for U256 { + type Builtin = String; + + fn into_custom(val: Self::Builtin) -> uniffi::Result { + Ok(U256(val)) + } + + fn from_custom(obj: Self) -> Self::Builtin { + obj.0 + } +} + +// Helper functions to convert between internal types and UniFFI types +pub fn felt_to_field_element(felt: starknet::core::types::Felt) -> FieldElement { + FieldElement(format!("0x{:064x}", felt)) +} + +pub fn field_element_to_felt(fe: &FieldElement) -> Result { + starknet::core::types::Felt::from_hex(&fe.0).map_err(|_| DojoError::InvalidInput) +} + +pub fn u256_to_uniffi(u: crypto_bigint::U256) -> U256 { + U256(format!("0x{:064x}", u)) +} + +pub fn uniffi_to_u256(u: &U256) -> Result { + let s = u.0.strip_prefix("0x").unwrap_or(&u.0); + let bytes = hex::decode(s).map_err(|_| DojoError::InvalidInput)?; + Ok(crypto_bigint::U256::from_be_slice(&bytes)) +} + +// Error types +#[derive(Debug, thiserror::Error)] +pub enum DojoError { + #[error("Client error: {0}")] + ClientError(String), + #[error("Serialization error: {0}")] + SerializationError(String), + #[error("Network error: {0}")] + NetworkError(String), + #[error("Invalid input")] + InvalidInput, +} + +impl From for DojoError { + fn from(e: anyhow::Error) -> Self { + DojoError::ClientError(e.to_string()) + } +} + +// Pagination +#[derive(Debug, Clone)] +pub enum PaginationDirection { + Forward, + Backward, +} + +impl From for torii_proto::PaginationDirection { + fn from(val: PaginationDirection) -> Self { + match val { + PaginationDirection::Forward => torii_proto::PaginationDirection::Forward, + PaginationDirection::Backward => torii_proto::PaginationDirection::Backward, + } + } +} + +impl From for PaginationDirection { + fn from(val: torii_proto::PaginationDirection) -> Self { + match val { + torii_proto::PaginationDirection::Forward => PaginationDirection::Forward, + torii_proto::PaginationDirection::Backward => PaginationDirection::Backward, + } + } +} + +#[derive(Debug, Clone)] +pub enum OrderDirection { + Asc, + Desc, +} + +impl From for torii_proto::OrderDirection { + fn from(val: OrderDirection) -> Self { + match val { + OrderDirection::Asc => torii_proto::OrderDirection::Asc, + OrderDirection::Desc => torii_proto::OrderDirection::Desc, + } + } +} + +impl From for OrderDirection { + fn from(val: torii_proto::OrderDirection) -> Self { + match val { + torii_proto::OrderDirection::Asc => OrderDirection::Asc, + torii_proto::OrderDirection::Desc => OrderDirection::Desc, + } + } +} + +#[derive(Debug, Clone)] +pub struct OrderBy { + pub field: String, + pub direction: OrderDirection, +} + +impl From for torii_proto::OrderBy { + fn from(val: OrderBy) -> Self { + torii_proto::OrderBy { field: val.field, direction: val.direction.into() } + } +} + +impl From for OrderBy { + fn from(val: torii_proto::OrderBy) -> Self { + OrderBy { field: val.field, direction: val.direction.into() } + } +} + +#[derive(Debug, Clone)] +pub struct Pagination { + pub cursor: Option, + pub limit: Option, + pub direction: PaginationDirection, + pub order_by: Vec, +} + +impl From for torii_proto::Pagination { + fn from(val: Pagination) -> Self { + torii_proto::Pagination { + cursor: val.cursor, + limit: val.limit, + direction: val.direction.into(), + order_by: val.order_by.into_iter().map(|o| o.into()).collect(), + } + } +} + +impl From for Pagination { + fn from(val: torii_proto::Pagination) -> Self { + Pagination { + cursor: val.cursor, + limit: val.limit, + direction: val.direction.into(), + order_by: val.order_by.into_iter().map(|o| o.into()).collect(), + } + } +} + +// Note: Page is not included in UniFFI as it doesn't support generics. +// If you need paginated results, use the specific query methods that return +// collections directly (e.g., Vec, Vec, etc.) + +// Signature +#[derive(Debug, Clone)] +pub struct Signature { + pub r: FieldElement, + pub s: FieldElement, +} + +impl From for starknet::core::crypto::Signature { + fn from(val: Signature) -> Self { + Self { + r: field_element_to_felt(&val.r).unwrap(), + s: field_element_to_felt(&val.s).unwrap(), + } + } +} + +impl From for Signature { + fn from(val: starknet::core::crypto::Signature) -> Self { + Signature { r: felt_to_field_element(val.r), s: felt_to_field_element(val.s) } + } +} + +// Call +#[derive(Debug, Clone)] +pub struct Call { + pub to: FieldElement, + pub selector: String, + pub calldata: Vec, +} + +impl From for starknet::core::types::Call { + fn from(val: Call) -> Self { + starknet::core::types::Call { + to: field_element_to_felt(&val.to).unwrap(), + selector: starknet::core::utils::get_selector_from_name(&val.selector).unwrap(), + calldata: val.calldata.into_iter().map(|f| field_element_to_felt(&f).unwrap()).collect(), + } + } +} + +impl From for starknet::core::types::FunctionCall { + fn from(val: Call) -> Self { + starknet::core::types::FunctionCall { + contract_address: field_element_to_felt(&val.to).unwrap(), + entry_point_selector: starknet::core::utils::get_selector_from_name(&val.selector).unwrap(), + calldata: val.calldata.into_iter().map(|f| field_element_to_felt(&f).unwrap()).collect(), + } + } +} + +// BlockId and BlockTag +#[derive(Debug, Clone)] +pub enum BlockTag { + Latest, + PreConfirmed, +} + +impl From for starknet::core::types::BlockTag { + fn from(val: BlockTag) -> Self { + match val { + BlockTag::Latest => starknet::core::types::BlockTag::Latest, + BlockTag::PreConfirmed => starknet::core::types::BlockTag::PreConfirmed, + } + } +} + +#[derive(Debug, Clone)] +pub enum BlockId { + Hash(FieldElement), + Number(u64), + Tag(BlockTag), +} + +impl From for starknet::core::types::BlockId { + fn from(val: BlockId) -> Self { + match val { + BlockId::Hash(hash) => starknet::core::types::BlockId::Hash(field_element_to_felt(&hash).unwrap()), + BlockId::Number(number) => starknet::core::types::BlockId::Number(number), + BlockId::Tag(tag) => starknet::core::types::BlockId::Tag(tag.into()), + } + } +} + diff --git a/src/uniffi/entity.rs b/crates/uniffi/src/uniffi/entity.rs similarity index 100% rename from src/uniffi/entity.rs rename to crates/uniffi/src/uniffi/entity.rs diff --git a/crates/uniffi/src/uniffi/event.rs b/crates/uniffi/src/uniffi/event.rs new file mode 100644 index 0000000..9c57692 --- /dev/null +++ b/crates/uniffi/src/uniffi/event.rs @@ -0,0 +1,47 @@ +// Event and Message types +use super::core::*; + +#[derive(Debug, Clone)] +pub struct Event { + pub keys: Vec, + pub data: Vec, + pub transaction_hash: FieldElement, +} + +impl From for torii_proto::Event { + fn from(val: Event) -> Self { + torii_proto::Event { + keys: val.keys.into_iter().map(|k| field_element_to_felt(&k).unwrap()).collect(), + data: val.data.into_iter().map(|d| field_element_to_felt(&d).unwrap()).collect(), + transaction_hash: field_element_to_felt(&val.transaction_hash).unwrap(), + } + } +} + +impl From for Event { + fn from(val: torii_proto::Event) -> Self { + Event { + keys: val.keys.into_iter().map(felt_to_field_element).collect(), + data: val.data.into_iter().map(felt_to_field_element).collect(), + transaction_hash: felt_to_field_element(val.transaction_hash), + } + } +} + +#[derive(Debug, Clone)] +pub struct Message { + pub message: String, + pub signature: Vec, + pub world_address: FieldElement, +} + +impl From for torii_proto::Message { + fn from(val: Message) -> Self { + torii_proto::Message { + message: val.message, + signature: val.signature.into_iter().map(|s| field_element_to_felt(&s).unwrap()).collect(), + world_address: field_element_to_felt(&val.world_address).unwrap(), + } + } +} + diff --git a/crates/uniffi/src/uniffi/mod.rs b/crates/uniffi/src/uniffi/mod.rs new file mode 100644 index 0000000..7abd7b4 --- /dev/null +++ b/crates/uniffi/src/uniffi/mod.rs @@ -0,0 +1,32 @@ +// UniFFI module - exposes Dojo types to multiple languages +// This module provides a cleaner, idiomatic API compared to C FFI + +// Core types and utilities +pub mod core; + +// Domain-specific type modules +pub mod achievement; +pub mod activity; +pub mod aggregation; +pub mod contract; +pub mod controller; +pub mod entity; +pub mod event; +pub mod query; +pub mod schema; +pub mod token; +pub mod transaction; + +// Re-export all public types for convenience +pub use achievement::*; +pub use activity::*; +pub use aggregation::*; +pub use contract::*; +pub use controller::*; +pub use core::*; +pub use entity::*; +pub use event::*; +pub use query::*; +pub use schema::*; +pub use token::*; +pub use transaction::*; diff --git a/crates/uniffi/src/uniffi/query.rs b/crates/uniffi/src/uniffi/query.rs new file mode 100644 index 0000000..7ca87dd --- /dev/null +++ b/crates/uniffi/src/uniffi/query.rs @@ -0,0 +1,271 @@ +// Query types - Query, Clause, KeysClause, MemberClause, CompositeClause +use super::core::*; +use super::schema::MemberValue; + +#[derive(Debug, Clone)] +pub enum PatternMatching { + FixedLen, + VariableLen, +} + +impl From for torii_proto::PatternMatching { + fn from(val: PatternMatching) -> Self { + match val { + PatternMatching::FixedLen => torii_proto::PatternMatching::FixedLen, + PatternMatching::VariableLen => torii_proto::PatternMatching::VariableLen, + } + } +} + +impl From for PatternMatching { + fn from(val: torii_proto::PatternMatching) -> Self { + match val { + torii_proto::PatternMatching::FixedLen => PatternMatching::FixedLen, + torii_proto::PatternMatching::VariableLen => PatternMatching::VariableLen, + } + } +} + +#[derive(Debug, Clone)] +pub struct KeysClause { + pub keys: Vec>, + pub pattern_matching: PatternMatching, + pub models: Vec, +} + +impl From for torii_proto::KeysClause { + fn from(val: KeysClause) -> Self { + torii_proto::KeysClause { + keys: val + .keys + .into_iter() + .map(|k| k.map(|s| field_element_to_felt(&s).unwrap())) + .collect(), + pattern_matching: val.pattern_matching.into(), + models: val.models, + } + } +} + +impl From for KeysClause { + fn from(val: torii_proto::KeysClause) -> Self { + KeysClause { + models: val.models, + keys: val.keys.into_iter().map(|k| k.map(felt_to_field_element)).collect(), + pattern_matching: val.pattern_matching.into(), + } + } +} + +#[derive(Debug, Clone)] +pub enum LogicalOperator { + And, + Or, +} + +impl From for torii_proto::LogicalOperator { + fn from(val: LogicalOperator) -> Self { + match val { + LogicalOperator::And => torii_proto::LogicalOperator::And, + LogicalOperator::Or => torii_proto::LogicalOperator::Or, + } + } +} + +impl From for LogicalOperator { + fn from(val: torii_proto::LogicalOperator) -> Self { + match val { + torii_proto::LogicalOperator::And => LogicalOperator::And, + torii_proto::LogicalOperator::Or => LogicalOperator::Or, + } + } +} + +#[derive(Debug, Clone)] +pub enum ComparisonOperator { + Eq, + Neq, + Gt, + Gte, + Lt, + Lte, + In, + NotIn, + Contains, + ContainsAll, + ContainsAny, + ArrayLengthEq, + ArrayLengthGt, + ArrayLengthLt, +} + +impl From for torii_proto::ComparisonOperator { + fn from(val: ComparisonOperator) -> Self { + match val { + ComparisonOperator::Eq => torii_proto::ComparisonOperator::Eq, + ComparisonOperator::Neq => torii_proto::ComparisonOperator::Neq, + ComparisonOperator::Gt => torii_proto::ComparisonOperator::Gt, + ComparisonOperator::Gte => torii_proto::ComparisonOperator::Gte, + ComparisonOperator::Lt => torii_proto::ComparisonOperator::Lt, + ComparisonOperator::Lte => torii_proto::ComparisonOperator::Lte, + ComparisonOperator::In => torii_proto::ComparisonOperator::In, + ComparisonOperator::NotIn => torii_proto::ComparisonOperator::NotIn, + ComparisonOperator::Contains => torii_proto::ComparisonOperator::Contains, + ComparisonOperator::ContainsAll => torii_proto::ComparisonOperator::ContainsAll, + ComparisonOperator::ContainsAny => torii_proto::ComparisonOperator::ContainsAny, + ComparisonOperator::ArrayLengthEq => torii_proto::ComparisonOperator::ArrayLengthEq, + ComparisonOperator::ArrayLengthGt => torii_proto::ComparisonOperator::ArrayLengthGt, + ComparisonOperator::ArrayLengthLt => torii_proto::ComparisonOperator::ArrayLengthLt, + } + } +} + +impl From for ComparisonOperator { + fn from(val: torii_proto::ComparisonOperator) -> Self { + match val { + torii_proto::ComparisonOperator::Eq => ComparisonOperator::Eq, + torii_proto::ComparisonOperator::Neq => ComparisonOperator::Neq, + torii_proto::ComparisonOperator::Gt => ComparisonOperator::Gt, + torii_proto::ComparisonOperator::Gte => ComparisonOperator::Gte, + torii_proto::ComparisonOperator::Lt => ComparisonOperator::Lt, + torii_proto::ComparisonOperator::Lte => ComparisonOperator::Lte, + torii_proto::ComparisonOperator::In => ComparisonOperator::In, + torii_proto::ComparisonOperator::NotIn => ComparisonOperator::NotIn, + torii_proto::ComparisonOperator::Contains => ComparisonOperator::Contains, + torii_proto::ComparisonOperator::ContainsAll => ComparisonOperator::ContainsAll, + torii_proto::ComparisonOperator::ContainsAny => ComparisonOperator::ContainsAny, + torii_proto::ComparisonOperator::ArrayLengthEq => ComparisonOperator::ArrayLengthEq, + torii_proto::ComparisonOperator::ArrayLengthGt => ComparisonOperator::ArrayLengthGt, + torii_proto::ComparisonOperator::ArrayLengthLt => ComparisonOperator::ArrayLengthLt, + } + } +} + +#[derive(Debug, Clone)] +pub struct MemberClause { + pub model: String, + pub member: String, + pub operator: ComparisonOperator, + pub value: MemberValue, +} + +impl From for torii_proto::MemberClause { + fn from(val: MemberClause) -> Self { + torii_proto::MemberClause { + member: val.member, + model: val.model, + operator: val.operator.into(), + value: val.value.into(), + } + } +} + +impl From for MemberClause { + fn from(val: torii_proto::MemberClause) -> Self { + MemberClause { + model: val.model, + member: val.member, + operator: val.operator.into(), + value: val.value.into(), + } + } +} + +#[derive(Debug, Clone)] +pub struct CompositeClause { + pub operator: LogicalOperator, + pub clauses: Vec, +} + +impl From for torii_proto::CompositeClause { + fn from(val: CompositeClause) -> Self { + torii_proto::CompositeClause { + operator: val.operator.into(), + clauses: val.clauses.into_iter().map(|c| c.into()).collect(), + } + } +} + +impl From for CompositeClause { + fn from(val: torii_proto::CompositeClause) -> Self { + CompositeClause { + operator: val.operator.into(), + clauses: val.clauses.into_iter().map(|c| c.into()).collect(), + } + } +} + +#[derive(Debug, Clone)] +pub enum Clause { + HashedKeys { keys: Vec }, + Keys { clause: KeysClause }, + Member { clause: MemberClause }, + Composite { clause: CompositeClause }, +} + +impl From for torii_proto::Clause { + fn from(val: Clause) -> Self { + match val { + Clause::HashedKeys { keys } => torii_proto::Clause::HashedKeys( + keys.into_iter().map(|k| field_element_to_felt(&k).unwrap()).collect(), + ), + Clause::Keys { clause } => torii_proto::Clause::Keys(clause.into()), + Clause::Member { clause } => torii_proto::Clause::Member(clause.into()), + Clause::Composite { clause } => torii_proto::Clause::Composite(clause.into()), + } + } +} + +impl From for Clause { + fn from(val: torii_proto::Clause) -> Self { + match val { + torii_proto::Clause::HashedKeys(keys) => { + Clause::HashedKeys { keys: keys.into_iter().map(felt_to_field_element).collect() } + } + torii_proto::Clause::Keys(clause) => Clause::Keys { clause: clause.into() }, + torii_proto::Clause::Member(clause) => Clause::Member { clause: clause.into() }, + torii_proto::Clause::Composite(clause) => Clause::Composite { clause: clause.into() }, + } + } +} + +#[derive(Debug, Clone)] +pub struct Query { + pub world_addresses: Vec, + pub pagination: Pagination, + pub clause: Option, + pub no_hashed_keys: bool, + pub models: Vec, + pub historical: bool, +} + +impl From for torii_proto::Query { + fn from(val: Query) -> Self { + torii_proto::Query { + world_addresses: val + .world_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + pagination: val.pagination.into(), + clause: val.clause.map(|c| c.into()), + models: val.models, + no_hashed_keys: val.no_hashed_keys, + historical: val.historical, + } + } +} + +impl From for Query { + fn from(val: torii_proto::Query) -> Self { + Query { + world_addresses: val.world_addresses.into_iter().map(felt_to_field_element).collect(), + pagination: val.pagination.into(), + clause: val.clause.map(|c| c.into()), + models: val.models, + no_hashed_keys: val.no_hashed_keys, + historical: val.historical, + } + } +} + diff --git a/src/uniffi/schema.rs b/crates/uniffi/src/uniffi/schema.rs similarity index 100% rename from src/uniffi/schema.rs rename to crates/uniffi/src/uniffi/schema.rs diff --git a/src/uniffi/token.rs b/crates/uniffi/src/uniffi/token.rs similarity index 100% rename from src/uniffi/token.rs rename to crates/uniffi/src/uniffi/token.rs diff --git a/src/uniffi/transaction.rs b/crates/uniffi/src/uniffi/transaction.rs similarity index 100% rename from src/uniffi/transaction.rs rename to crates/uniffi/src/uniffi/transaction.rs diff --git a/crates/wasm/src/lib.rs b/crates/wasm/src/lib.rs index 6abdd2b..d401a76 100644 --- a/crates/wasm/src/lib.rs +++ b/crates/wasm/src/lib.rs @@ -30,17 +30,14 @@ use wasm_bindgen::prelude::*; mod types; use types::{ - AchievementProgression, AchievementQuery, Achievements, Activities, Activity, AggregationEntry, - Aggregations, BlockId, Call, Calls, Clause, ClientConfig, Contract, Contracts, Controllers, - Entities, Entity, KeysClauses, Message, PlayerAchievementQuery, PlayerAchievements, Query, - Signature, Token, TokenBalance, TokenBalances, TokenContracts, TokenTransfer, TokenTransfers, - Tokens, Transaction, Transactions, WasmU256, -}; - -use crate::types::{ - Account, ActivityQuery, AggregationQuery, ContractQuery, ControllerQuery, Provider, - Subscription, TokenBalanceQuery, TokenContractQuery, TokenQuery, TokenTransferQuery, - ToriiClient, TransactionFilter, TransactionQuery, + Account, AchievementProgression, AchievementQuery, Achievements, Activities, Activity, + ActivityQuery, AggregationEntry, AggregationQuery, Aggregations, BlockId, Call, Calls, Clause, + ClientConfig, Contract, ContractQuery, Contracts, ControllerQuery, Controllers, Entities, + Entity, KeysClauses, Message, PlayerAchievementQuery, PlayerAchievements, Provider, Query, + Signature, Subscription, Token, TokenBalance, TokenBalanceQuery, TokenBalances, + TokenContractQuery, TokenContracts, TokenQuery, TokenTransfer, TokenTransferQuery, + TokenTransfers, Tokens, ToriiClient, Transaction, TransactionFilter, TransactionQuery, + Transactions, WasmU256, }; const JSON_COMPAT_SERIALIZER: serde_wasm_bindgen::Serializer = diff --git a/dojo.h b/dojo.h index f8871bf..7101981 100644 --- a/dojo.h +++ b/dojo.h @@ -15,7 +15,6 @@ struct Entity; struct COptionFieldElement; struct World; struct Transaction; -struct Subscription; struct TransactionCall; struct Struct; struct AggregationEntry; @@ -29,8 +28,6 @@ struct TokenBalance; struct TokenContract; struct Contract; struct TokenTransfer; -struct Provider; -struct Account; struct Ty; struct Model; struct Member; @@ -550,7 +547,7 @@ typedef struct ResultSubscription { ResultSubscription_Tag tag; union { struct { - struct Subscription *ok; + Subscription *ok; }; struct { struct Error err; @@ -1123,7 +1120,7 @@ typedef struct ResultProvider { ResultProvider_Tag tag; union { struct { - struct Provider *ok; + Provider *ok; }; struct { struct Error err; @@ -1140,7 +1137,7 @@ typedef struct ResultAccount { ResultAccount_Tag tag; union { struct { - struct Account *ok; + Account *ok; }; struct { struct Error err; @@ -1560,7 +1557,7 @@ struct ResultSubscription client_on_entity_state_update(struct ToriiClient *clie * Result containing success boolean or error */ struct Resultbool client_update_entity_subscription(struct ToriiClient *client, - struct Subscription *subscription, + Subscription *subscription, struct COptionClause clause, const struct FieldElement *world_addresses, uintptr_t world_addresses_len); @@ -1614,7 +1611,7 @@ struct ResultSubscription client_on_aggregation_update(struct ToriiClient *clien * Result containing success boolean or error */ struct Resultbool client_update_aggregation_subscription(struct ToriiClient *client, - struct Subscription *subscription, + Subscription *subscription, const char *const *aggregator_ids, uintptr_t aggregator_ids_len, const char *const *entity_ids, @@ -1696,7 +1693,7 @@ struct ResultSubscription client_on_achievement_progression_update(struct ToriiC * Result containing success boolean or error */ struct Resultbool client_update_achievement_progression_subscription(struct ToriiClient *client, - struct Subscription *subscription, + Subscription *subscription, const struct FieldElement *world_addresses, uintptr_t world_addresses_len, const char *const *namespaces, @@ -1761,7 +1758,7 @@ struct ResultSubscription client_on_activity_update(struct ToriiClient *client, * Result containing success boolean or error */ struct Resultbool client_update_activity_subscription(struct ToriiClient *client, - struct Subscription *subscription, + Subscription *subscription, const struct FieldElement *world_addresses, uintptr_t world_addresses_len, const char *const *namespaces, @@ -1800,7 +1797,7 @@ struct ResultSubscription client_on_event_message_update(struct ToriiClient *cli * Result containing success boolean or error */ struct Resultbool client_update_event_message_subscription(struct ToriiClient *client, - struct Subscription *subscription, + Subscription *subscription, struct COptionClause clause, const struct FieldElement *world_addresses, uintptr_t world_addresses_len); @@ -1976,7 +1973,7 @@ struct ResultSubscription client_on_token_balance_update(struct ToriiClient *cli * Result containing success boolean or error */ struct Resultbool client_update_token_balance_subscription(struct ToriiClient *client, - struct Subscription *subscription, + Subscription *subscription, const struct FieldElement *contract_addresses, uintptr_t contract_addresses_len, const struct FieldElement *account_addresses, @@ -2026,7 +2023,7 @@ struct ResultSubscription client_on_token_transfer_update(struct ToriiClient *cl * Result containing success boolean or error */ struct Resultbool client_update_token_transfer_subscription(struct ToriiClient *client, - struct Subscription *subscription, + Subscription *subscription, const struct FieldElement *contract_addresses, uintptr_t contract_addresses_len, const struct FieldElement *account_addresses, @@ -2205,7 +2202,7 @@ struct ResultProvider provider_new(const char *rpc_url); * # Returns * Result containing pointer to Account or error */ -struct ResultAccount account_new(struct Provider *rpc, +struct ResultAccount account_new(Provider *rpc, struct FieldElement private_key, const char *address); @@ -2220,7 +2217,7 @@ struct ResultAccount account_new(struct Provider *rpc, * # Returns * Result containing array of FieldElements or error */ -struct ResultCArrayFieldElement starknet_call(struct Provider *provider, +struct ResultCArrayFieldElement starknet_call(Provider *provider, struct Call call, struct BlockId block_id); @@ -2235,8 +2232,8 @@ struct ResultCArrayFieldElement starknet_call(struct Provider *provider, * # Returns * Result containing pointer to new Account or error */ -struct ResultAccount account_deploy_burner(struct Provider *provider, - struct Account *master_account, +struct ResultAccount account_deploy_burner(Provider *provider, + Account *master_account, struct FieldElement signing_key); /** @@ -2248,7 +2245,7 @@ struct ResultAccount account_deploy_burner(struct Provider *provider, * # Returns * FieldElement containing the account address */ -struct FieldElement account_address(struct Account *account); +struct FieldElement account_address(Account *account); /** * Gets account chain ID @@ -2259,7 +2256,7 @@ struct FieldElement account_address(struct Account *account); * # Returns * FieldElement containing the chain ID */ -struct FieldElement account_chain_id(struct Account *account); +struct FieldElement account_chain_id(Account *account); /** * Sets block ID for account @@ -2268,7 +2265,7 @@ struct FieldElement account_chain_id(struct Account *account); * * `account` - Pointer to Account * * `block_id` - New block ID */ -void account_set_block_id(struct Account *account, struct BlockId block_id); +void account_set_block_id(Account *account, struct BlockId block_id); /** * Gets account nonce @@ -2279,7 +2276,7 @@ void account_set_block_id(struct Account *account, struct BlockId block_id); * # Returns * Result containing FieldElement nonce or error */ -struct ResultFieldElement account_nonce(struct Account *account); +struct ResultFieldElement account_nonce(Account *account); /** * Executes raw transaction @@ -2292,7 +2289,7 @@ struct ResultFieldElement account_nonce(struct Account *account); * # Returns * Result containing transaction hash as FieldElement or error */ -struct ResultFieldElement account_execute_raw(struct Account *account, +struct ResultFieldElement account_execute_raw(Account *account, const struct Call *calldata, uintptr_t calldata_len); @@ -2306,7 +2303,7 @@ struct ResultFieldElement account_execute_raw(struct Account *account, * # Returns * Result containing success boolean or error */ -struct Resultbool wait_for_transaction(struct Provider *rpc, struct FieldElement txn_hash); +struct Resultbool wait_for_transaction(Provider *rpc, struct FieldElement txn_hash); /** * Computes contract address @@ -2333,7 +2330,7 @@ struct FieldElement hash_get_contract_address(struct FieldElement class_hash, * # Parameters * * `subscription` - Pointer to Subscription to cancel */ -void subscription_cancel(struct Subscription *subscription); +void subscription_cancel(Subscription *subscription); /** * Frees a ToriiClient instance @@ -2349,7 +2346,7 @@ void client_free(struct ToriiClient *t); * # Parameters * * `rpc` - Pointer to Provider to free */ -void provider_free(struct Provider *rpc); +void provider_free(Provider *rpc); /** * Frees a Model instance @@ -2365,7 +2362,7 @@ void model_free(struct Struct *model); * # Parameters * * `account` - Pointer to Account to free */ -void account_free(struct Account *account); +void account_free(Account *account); /** * Frees a Type instance diff --git a/dojo.hpp b/dojo.hpp index c06810f..70a6d19 100644 --- a/dojo.hpp +++ b/dojo.hpp @@ -8,9 +8,6 @@ namespace dojo_bindings { struct ToriiClient; struct Ty; -struct Subscription; -struct Provider; -struct Account; enum class BlockTag { Latest, diff --git a/dojo.pyx b/dojo.pyx index 9c0dcd2..7bbe56f 100644 --- a/dojo.pyx +++ b/dojo.pyx @@ -54,15 +54,10 @@ cdef extern from *: FixedLen # = 0, VariableLen # = 1, - cdef struct Account: - pass - - cdef struct Provider: - pass - - cdef struct Subscription: + cdef struct ToriiClient: pass + # Main Dojo client for interacting with the Torii indexer cdef struct ToriiClient: pass diff --git a/src/uniffi/README.md b/src/uniffi/README.md new file mode 100644 index 0000000..74dfd3d --- /dev/null +++ b/src/uniffi/README.md @@ -0,0 +1,93 @@ +# UniFFI Bindings + +This module provides foreign function interface (FFI) bindings for Dojo using Mozilla's [UniFFI](https://mozilla.github.io/uniffi-rs/) framework. + +## Structure + +``` +src/ +├── dojo.udl # UniFFI interface definition (required at crate root) +├── uniffi/ # UniFFI implementation +│ ├── mod.rs # Main module definition +│ ├── client.rs # ToriiClient implementation with subscription support +│ ├── types/ # Type definitions organized by domain +│ │ ├── mod.rs # Types module definition +│ │ ├── core.rs # Core types (FieldElement, U256, DojoError, Pagination) +│ │ ├── achievement.rs # Achievement and player achievement types +│ │ ├── activity.rs # Activity tracking types +│ │ ├── aggregation.rs # Aggregation (leaderboards, stats) types +│ │ ├── contract.rs # Contract query types +│ │ ├── controller.rs # Controller types +│ │ ├── entity.rs # Entity, Model, and World types +│ │ ├── event.rs # Event and event query types +│ │ ├── query.rs # Query types (Clause, KeysClause, etc.) +│ │ ├── schema.rs # Schema types (Ty, Struct, Enum, etc.) +│ │ ├── token.rs # Token and token-related types +│ │ └── transaction.rs # Transaction types and filters +│ └── README.md # This file +└── bin/ # Binding generator binaries + ├── uniffi-bindgen-swift.rs + ├── uniffi-bindgen-kotlin.rs + └── uniffi-bindgen-python.rs +``` + +**Note:** The `dojo.udl` file must be in `src/` (not `src/uniffi/`) because UniFFI requires it to be at the crate root level. + +## Supported Languages + +- **Swift** - iOS/macOS applications +- **Kotlin** - Android applications +- **Python** - Python applications and scripts + +## Generating Bindings + +Use the provided bindgen binaries: + +```bash +# Swift +cargo run --bin uniffi-bindgen-swift --release -- target/release/libdojo_c.dylib bindings/swift --swift-sources + +# Kotlin +cargo run --bin uniffi-bindgen-kotlin --release -- target/release/libdojo_c.dylib bindings/kotlin + +# Python +cargo run --bin uniffi-bindgen-python --release -- target/release/libdojo_c.dylib bindings/python +``` + +## Features + +### ToriiClient + +The main client interface provides: + +- **Queries**: entities, events, tokens, transactions, controllers, contracts, etc. +- **Subscriptions**: Real-time updates via callbacks +- **Message Publishing**: Submit offchain messages to the world +- **SQL Queries**: Direct database queries + +### Subscriptions + +Subscriptions use callbacks for real-time updates: + +- `subscribe_entity_updates` - Entity state changes +- `subscribe_token_balance_updates` - Token balance changes +- `subscribe_token_updates` - Token metadata updates +- `subscribe_transaction_updates` - Transaction updates +- `subscribe_event_updates` - Starknet event updates +- `cancel_subscription` - Cancel an active subscription + +### Type System + +All types are automatically converted between Rust and target languages: + +- **FieldElement**: Starknet field element (represented as hex string) +- **U256**: 256-bit unsigned integer (represented as hex string) +- **Enums**: Rust enums → Swift enums / Kotlin sealed classes / Python classes +- **Structs**: Rust structs → Swift structs / Kotlin data classes / Python dataclasses +- **Options**: `Option` → nullable types in target languages +- **Errors**: `DojoError` enum for all error cases + +## UDL Definition + +The interface is defined in `src/dojo.udl` using UniFFI Definition Language. + diff --git a/src/uniffi/client.rs b/src/uniffi/client.rs index f9c46d2..645fc42 100644 --- a/src/uniffi/client.rs +++ b/src/uniffi/client.rs @@ -1,16 +1,6 @@ // Client wrapper for UniFFI - exposes torii_client functionality -use super::core::*; -use super::controller::*; -use super::token::*; -use super::contract::*; -use super::transaction::*; -use super::entity::*; -use super::event::*; -use super::aggregation::*; -use super::activity::*; -use super::achievement::*; -use super::query::*; +use super::types::*; use std::sync::{Arc, Mutex}; use std::sync::atomic::{AtomicU64, Ordering}; use std::collections::HashMap; diff --git a/src/uniffi/mod.rs b/src/uniffi/mod.rs index 8ab2d0a..c422a6d 100644 --- a/src/uniffi/mod.rs +++ b/src/uniffi/mod.rs @@ -1,34 +1,14 @@ -// UniFFI module - exposes Dojo types to multiple languages -// This module provides a cleaner, idiomatic API compared to C FFI +// UniFFI bindings for Dojo +// +// This module provides foreign function interface bindings for multiple languages +// (Swift, Kotlin, Python) using Mozilla's UniFFI framework. -// Core types and utilities -pub mod core; +// Type definitions organized by domain +pub mod types; -// Domain-specific type modules -pub mod achievement; -pub mod activity; -pub mod aggregation; +// Client implementation pub mod client; -pub mod contract; -pub mod controller; -pub mod entity; -pub mod event; -pub mod query; -pub mod schema; -pub mod token; -pub mod transaction; -// Re-export all public types for convenience -pub use achievement::*; -pub use activity::*; -pub use aggregation::*; +// Re-export everything for convenience pub use client::*; -pub use contract::*; -pub use controller::*; -pub use core::*; -pub use entity::*; -pub use event::*; -pub use query::*; -pub use schema::*; -pub use token::*; -pub use transaction::*; +pub use types::*; diff --git a/src/uniffi/types/achievement.rs b/src/uniffi/types/achievement.rs new file mode 100644 index 0000000..ae67098 --- /dev/null +++ b/src/uniffi/types/achievement.rs @@ -0,0 +1,239 @@ +// Achievement types +use super::core::*; + +#[derive(Debug, Clone)] +pub struct AchievementTask { + pub task_id: String, + pub description: String, + pub total: u32, + pub total_completions: u32, + pub completion_rate: f64, + pub created_at: u64, +} + +impl From for AchievementTask { + fn from(val: torii_proto::AchievementTask) -> Self { + AchievementTask { + task_id: val.task_id, + description: val.description, + total: val.total, + total_completions: val.total_completions, + completion_rate: val.completion_rate, + created_at: val.created_at.timestamp() as u64, + } + } +} + +#[derive(Debug, Clone)] +pub struct Achievement { + pub id: String, + pub world_address: FieldElement, + pub namespace: String, + pub entity_id: String, + pub hidden: bool, + pub index: u32, + pub points: u32, + pub start: String, + pub end: String, + pub group: String, + pub icon: String, + pub title: String, + pub description: String, + pub tasks: Vec, + pub data: Option, + pub total_completions: u32, + pub completion_rate: f64, + pub created_at: u64, + pub updated_at: u64, +} + +impl From for Achievement { + fn from(val: torii_proto::Achievement) -> Self { + let tasks: Vec = val.tasks.into_iter().map(|t| t.into()).collect(); + + Achievement { + id: val.id, + world_address: felt_to_field_element(val.world_address), + namespace: val.namespace, + entity_id: val.entity_id, + hidden: val.hidden, + index: val.index, + points: val.points, + start: val.start, + end: val.end, + group: val.group, + icon: val.icon, + title: val.title, + description: val.description, + tasks, + data: val.data, + total_completions: val.total_completions, + completion_rate: val.completion_rate, + created_at: val.created_at.timestamp() as u64, + updated_at: val.updated_at.timestamp() as u64, + } + } +} + +#[derive(Debug, Clone)] +pub struct AchievementQuery { + pub world_addresses: Vec, + pub namespaces: Vec, + pub hidden: Option, + pub pagination: Pagination, +} + +impl From for torii_proto::AchievementQuery { + fn from(val: AchievementQuery) -> Self { + torii_proto::AchievementQuery { + world_addresses: val + .world_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + namespaces: val.namespaces, + hidden: val.hidden, + pagination: val.pagination.into(), + } + } +} + +#[derive(Debug, Clone)] +pub struct TaskProgress { + pub task_id: String, + pub count: u32, + pub completed: bool, +} + +impl From for TaskProgress { + fn from(val: torii_proto::TaskProgress) -> Self { + TaskProgress { task_id: val.task_id, count: val.count, completed: val.completed } + } +} + +#[derive(Debug, Clone)] +pub struct PlayerAchievementProgress { + pub achievement: Achievement, + pub task_progress: Vec, + pub completed: bool, + pub progress_percentage: f64, +} + +impl From for PlayerAchievementProgress { + fn from(val: torii_proto::PlayerAchievementProgress) -> Self { + let task_progress: Vec = val.task_progress.into_iter().map(|t| t.into()).collect(); + + PlayerAchievementProgress { + achievement: val.achievement.into(), + task_progress, + completed: val.completed, + progress_percentage: val.progress_percentage, + } + } +} + +#[derive(Debug, Clone)] +pub struct PlayerAchievementStats { + pub total_points: u32, + pub completed_achievements: u32, + pub total_achievements: u32, + pub completion_percentage: f64, + pub last_achievement_at: Option, + pub created_at: u64, + pub updated_at: u64, +} + +impl From for PlayerAchievementStats { + fn from(val: torii_proto::PlayerAchievementStats) -> Self { + PlayerAchievementStats { + total_points: val.total_points, + completed_achievements: val.completed_achievements, + total_achievements: val.total_achievements, + completion_percentage: val.completion_percentage, + last_achievement_at: val.last_achievement_at.map(|t| t.timestamp() as u64), + created_at: val.created_at.timestamp() as u64, + updated_at: val.updated_at.timestamp() as u64, + } + } +} + +#[derive(Debug, Clone)] +pub struct PlayerAchievementEntry { + pub player_address: FieldElement, + pub stats: PlayerAchievementStats, + pub achievements: Vec, +} + +impl From for PlayerAchievementEntry { + fn from(val: torii_proto::PlayerAchievementEntry) -> Self { + let achievements: Vec = + val.achievements.into_iter().map(|a| a.into()).collect(); + + PlayerAchievementEntry { + player_address: felt_to_field_element(val.player_address), + stats: val.stats.into(), + achievements, + } + } +} + +#[derive(Debug, Clone)] +pub struct PlayerAchievementQuery { + pub world_addresses: Vec, + pub namespaces: Vec, + pub player_addresses: Vec, + pub pagination: Pagination, +} + +impl From for torii_proto::PlayerAchievementQuery { + fn from(val: PlayerAchievementQuery) -> Self { + torii_proto::PlayerAchievementQuery { + world_addresses: val + .world_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + namespaces: val.namespaces, + player_addresses: val + .player_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + pagination: val.pagination.into(), + } + } +} + +#[derive(Debug, Clone)] +pub struct AchievementProgression { + pub id: String, + pub achievement_id: String, + pub task_id: String, + pub world_address: FieldElement, + pub namespace: String, + pub player_id: FieldElement, + pub count: u32, + pub completed: bool, + pub completed_at: Option, + pub created_at: u64, + pub updated_at: u64, +} + +impl From for AchievementProgression { + fn from(val: torii_proto::AchievementProgression) -> Self { + AchievementProgression { + id: val.id, + achievement_id: val.achievement_id, + task_id: val.task_id, + world_address: felt_to_field_element(val.world_address), + namespace: val.namespace, + player_id: felt_to_field_element(val.player_id), + count: val.count, + completed: val.completed, + completed_at: val.completed_at.map(|t| t.timestamp() as u64), + created_at: val.created_at.timestamp() as u64, + updated_at: val.updated_at.timestamp() as u64, + } + } +} + diff --git a/src/uniffi/types/activity.rs b/src/uniffi/types/activity.rs new file mode 100644 index 0000000..29c37e3 --- /dev/null +++ b/src/uniffi/types/activity.rs @@ -0,0 +1,76 @@ +// Activity types +use super::core::*; +use chrono::DateTime; + +#[derive(Debug, Clone)] +pub struct ActionCount { + pub action_name: String, + pub count: u32, +} + +#[derive(Debug, Clone)] +pub struct Activity { + pub id: String, + pub world_address: FieldElement, + pub namespace: String, + pub caller_address: FieldElement, + pub session_start: u64, + pub session_end: u64, + pub action_count: u32, + pub actions: Vec, + pub updated_at: u64, +} + +impl From for Activity { + fn from(val: torii_proto::Activity) -> Self { + let actions: Vec = val + .actions + .into_iter() + .map(|(name, count)| ActionCount { action_name: name, count }) + .collect(); + + Activity { + id: val.id, + world_address: felt_to_field_element(val.world_address), + namespace: val.namespace, + caller_address: felt_to_field_element(val.caller_address), + session_start: val.session_start.timestamp() as u64, + session_end: val.session_end.timestamp() as u64, + action_count: val.action_count, + actions, + updated_at: val.updated_at.timestamp() as u64, + } + } +} + +#[derive(Debug, Clone)] +pub struct ActivityQuery { + pub world_addresses: Vec, + pub namespaces: Vec, + pub caller_addresses: Vec, + pub from_time: Option, + pub to_time: Option, + pub pagination: Pagination, +} + +impl From for torii_proto::ActivityQuery { + fn from(val: ActivityQuery) -> Self { + torii_proto::ActivityQuery { + world_addresses: val + .world_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + namespaces: val.namespaces, + caller_addresses: val + .caller_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + from_time: val.from_time.map(|t| DateTime::from_timestamp(t as i64, 0).unwrap()), + to_time: val.to_time.map(|t| DateTime::from_timestamp(t as i64, 0).unwrap()), + pagination: val.pagination.into(), + } + } +} + diff --git a/src/uniffi/types/aggregation.rs b/src/uniffi/types/aggregation.rs new file mode 100644 index 0000000..1d964bb --- /dev/null +++ b/src/uniffi/types/aggregation.rs @@ -0,0 +1,49 @@ +// Aggregation types +use super::core::*; + +#[derive(Debug, Clone)] +pub struct AggregationQuery { + pub aggregator_ids: Vec, + pub entity_ids: Vec, + pub pagination: Pagination, +} + +impl From for torii_proto::AggregationQuery { + fn from(val: AggregationQuery) -> Self { + torii_proto::AggregationQuery { + aggregator_ids: val.aggregator_ids, + entity_ids: val.entity_ids, + pagination: val.pagination.into(), + } + } +} + +#[derive(Debug, Clone)] +pub struct AggregationEntry { + pub id: String, + pub aggregator_id: String, + pub entity_id: String, + pub value: U256, + pub display_value: String, + pub position: u64, + pub model_id: String, + pub created_at: u64, + pub updated_at: u64, +} + +impl From for AggregationEntry { + fn from(val: torii_proto::AggregationEntry) -> Self { + AggregationEntry { + id: val.id, + aggregator_id: val.aggregator_id, + entity_id: val.entity_id, + value: u256_to_uniffi(val.value), + display_value: val.display_value, + position: val.position, + model_id: val.model_id, + created_at: val.created_at.timestamp() as u64, + updated_at: val.updated_at.timestamp() as u64, + } + } +} + diff --git a/src/uniffi/types/contract.rs b/src/uniffi/types/contract.rs new file mode 100644 index 0000000..4f88575 --- /dev/null +++ b/src/uniffi/types/contract.rs @@ -0,0 +1,85 @@ +// Contract types +use super::core::*; + +#[derive(Debug, Clone)] +pub enum ContractType { + WORLD, + ERC20, + ERC721, + ERC1155, + UDC, + OTHER, +} + +impl From for ContractType { + fn from(val: torii_proto::ContractType) -> Self { + match val { + torii_proto::ContractType::WORLD => ContractType::WORLD, + torii_proto::ContractType::ERC20 => ContractType::ERC20, + torii_proto::ContractType::ERC721 => ContractType::ERC721, + torii_proto::ContractType::ERC1155 => ContractType::ERC1155, + torii_proto::ContractType::UDC => ContractType::UDC, + torii_proto::ContractType::OTHER => ContractType::OTHER, + } + } +} + +impl From for torii_proto::ContractType { + fn from(val: ContractType) -> Self { + match val { + ContractType::WORLD => torii_proto::ContractType::WORLD, + ContractType::ERC20 => torii_proto::ContractType::ERC20, + ContractType::ERC721 => torii_proto::ContractType::ERC721, + ContractType::ERC1155 => torii_proto::ContractType::ERC1155, + ContractType::UDC => torii_proto::ContractType::UDC, + ContractType::OTHER => torii_proto::ContractType::OTHER, + } + } +} + +#[derive(Debug, Clone)] +pub struct Contract { + pub contract_address: FieldElement, + pub contract_type: ContractType, + pub head: Option, + pub tps: Option, + pub last_block_timestamp: Option, + pub last_pending_block_tx: Option, + pub updated_at: u64, + pub created_at: u64, +} + +impl From for Contract { + fn from(val: torii_proto::Contract) -> Self { + Contract { + contract_type: val.contract_type.into(), + head: val.head, + tps: val.tps, + last_block_timestamp: val.last_block_timestamp, + last_pending_block_tx: val.last_pending_block_tx.map(felt_to_field_element), + updated_at: val.updated_at.timestamp() as u64, + created_at: val.created_at.timestamp() as u64, + contract_address: felt_to_field_element(val.contract_address), + } + } +} + +#[derive(Debug, Clone)] +pub struct ContractQuery { + pub contract_addresses: Vec, + pub contract_types: Vec, +} + +impl From for torii_proto::ContractQuery { + fn from(val: ContractQuery) -> Self { + torii_proto::ContractQuery { + contract_addresses: val + .contract_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + contract_types: val.contract_types.into_iter().map(|t| t.into()).collect(), + } + } +} + diff --git a/src/uniffi/types/controller.rs b/src/uniffi/types/controller.rs new file mode 100644 index 0000000..6951fce --- /dev/null +++ b/src/uniffi/types/controller.rs @@ -0,0 +1,41 @@ +// Controller types +use super::core::*; + +#[derive(Debug, Clone)] +pub struct Controller { + pub address: FieldElement, + pub username: String, + pub deployed_at_timestamp: u64, +} + +impl From for Controller { + fn from(val: torii_proto::Controller) -> Self { + Controller { + address: felt_to_field_element(val.address), + username: val.username, + deployed_at_timestamp: val.deployed_at.timestamp() as u64, + } + } +} + +#[derive(Debug, Clone)] +pub struct ControllerQuery { + pub pagination: Pagination, + pub contract_addresses: Vec, + pub usernames: Vec, +} + +impl From for torii_proto::ControllerQuery { + fn from(val: ControllerQuery) -> Self { + torii_proto::ControllerQuery { + pagination: val.pagination.into(), + contract_addresses: val + .contract_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + usernames: val.usernames, + } + } +} + diff --git a/src/uniffi/core.rs b/src/uniffi/types/core.rs similarity index 100% rename from src/uniffi/core.rs rename to src/uniffi/types/core.rs diff --git a/src/uniffi/types/entity.rs b/src/uniffi/types/entity.rs new file mode 100644 index 0000000..5e7c7cb --- /dev/null +++ b/src/uniffi/types/entity.rs @@ -0,0 +1,130 @@ +// Entity, Model, and World types +use super::core::*; +use super::schema::{Struct, Ty}; +use chrono::DateTime; + +#[derive(Debug, Clone)] +pub struct Entity { + pub world_address: FieldElement, + pub hashed_keys: FieldElement, + pub models: Vec, + pub created_at: u64, + pub updated_at: u64, + pub executed_at: u64, +} + +impl From for torii_proto::schema::Entity { + fn from(val: Entity) -> Self { + torii_proto::schema::Entity { + world_address: field_element_to_felt(&val.world_address).unwrap(), + hashed_keys: field_element_to_felt(&val.hashed_keys).unwrap(), + models: val.models.into_iter().map(|m| m.into()).collect(), + created_at: DateTime::from_timestamp(val.created_at as i64, 0).unwrap(), + updated_at: DateTime::from_timestamp(val.updated_at as i64, 0).unwrap(), + executed_at: DateTime::from_timestamp(val.executed_at as i64, 0).unwrap(), + } + } +} + +impl From for Entity { + fn from(val: torii_proto::schema::Entity) -> Self { + Entity { + world_address: felt_to_field_element(val.world_address), + hashed_keys: felt_to_field_element(val.hashed_keys), + models: val.models.into_iter().map(|m| m.into()).collect(), + created_at: val.created_at.timestamp() as u64, + updated_at: val.updated_at.timestamp() as u64, + executed_at: val.executed_at.timestamp() as u64, + } + } +} + +#[derive(Debug, Clone)] +pub struct Model { + pub world_address: FieldElement, + pub schema: Ty, + pub namespace: String, + pub name: String, + pub selector: FieldElement, + pub packed_size: u32, + pub unpacked_size: u32, + pub class_hash: FieldElement, + pub contract_address: FieldElement, + pub layout: String, + pub use_legacy_store: bool, +} + +impl From for Model { + fn from(value: torii_proto::Model) -> Self { + let layout = serde_json::to_string(&value.layout).unwrap(); + + Model { + world_address: felt_to_field_element(value.world_address), + schema: value.schema.into(), + name: value.name, + namespace: value.namespace, + selector: felt_to_field_element(value.selector), + packed_size: value.packed_size, + unpacked_size: value.unpacked_size, + class_hash: felt_to_field_element(value.class_hash), + contract_address: felt_to_field_element(value.contract_address), + layout, + use_legacy_store: value.use_legacy_store, + } + } +} + +impl From for torii_proto::Model { + fn from(value: Model) -> Self { + let layout = serde_json::from_str(&value.layout).unwrap(); + + torii_proto::Model { + world_address: field_element_to_felt(&value.world_address).unwrap(), + schema: value.schema.into(), + namespace: value.namespace, + name: value.name, + selector: field_element_to_felt(&value.selector).unwrap(), + packed_size: value.packed_size, + unpacked_size: value.unpacked_size, + class_hash: field_element_to_felt(&value.class_hash).unwrap(), + contract_address: field_element_to_felt(&value.contract_address).unwrap(), + layout, + use_legacy_store: value.use_legacy_store, + } + } +} + +#[derive(Debug, Clone)] +pub struct World { + pub world_address: FieldElement, + pub models: Vec, +} + +impl From for World { + fn from(value: torii_proto::World) -> Self { + let models: Vec = value.models.into_values().map(|v| v.into()).collect(); + + World { world_address: felt_to_field_element(value.world_address), models } + } +} + +impl From for torii_proto::World { + fn from(value: World) -> Self { + let models: Vec = value.models.into_iter().map(|m| m.into()).collect(); + let models = models + .into_iter() + .map(|m| { + ( + dojo_types::naming::compute_selector_from_names(&m.namespace, &m.name), + m, + ) + }) + .collect(); + + torii_proto::World { + world_address: field_element_to_felt(&value.world_address).unwrap(), + models, + } + } +} + diff --git a/src/uniffi/event.rs b/src/uniffi/types/event.rs similarity index 100% rename from src/uniffi/event.rs rename to src/uniffi/types/event.rs diff --git a/src/uniffi/types/mod.rs b/src/uniffi/types/mod.rs new file mode 100644 index 0000000..4b669d8 --- /dev/null +++ b/src/uniffi/types/mod.rs @@ -0,0 +1,30 @@ +// Core types and error handling +pub mod core; + +// Domain types organized by category +pub mod achievement; +pub mod activity; +pub mod aggregation; +pub mod contract; +pub mod controller; +pub mod entity; +pub mod event; +pub mod query; +pub mod schema; +pub mod token; +pub mod transaction; + +// Re-export all public types for convenience +pub use achievement::*; +pub use activity::*; +pub use aggregation::*; +pub use contract::*; +pub use controller::*; +pub use core::*; +pub use entity::*; +pub use event::*; +pub use query::*; +pub use schema::*; +pub use token::*; +pub use transaction::*; + diff --git a/src/uniffi/query.rs b/src/uniffi/types/query.rs similarity index 100% rename from src/uniffi/query.rs rename to src/uniffi/types/query.rs diff --git a/src/uniffi/types/schema.rs b/src/uniffi/types/schema.rs new file mode 100644 index 0000000..bc88eff --- /dev/null +++ b/src/uniffi/types/schema.rs @@ -0,0 +1,331 @@ +// Schema types - Primitive, Ty, Struct, Enum, Member +use super::core::*; + +#[derive(Debug, Clone)] +pub enum Primitive { + I8 { value: i8 }, + I16 { value: i16 }, + I32 { value: i32 }, + I64 { value: i64 }, + I128 { value: Vec }, // 16 bytes + U8 { value: u8 }, + U16 { value: u16 }, + U32 { value: u32 }, + U64 { value: u64 }, + U128 { value: Vec }, // 16 bytes + U256 { value: U256 }, + Bool { value: bool }, + Felt252 { value: FieldElement }, + ClassHash { value: FieldElement }, + ContractAddress { value: FieldElement }, + EthAddress { value: FieldElement }, +} + +impl From for dojo_types::primitive::Primitive { + fn from(value: Primitive) -> Self { + match value { + Primitive::I8 { value: v } => dojo_types::primitive::Primitive::I8(Some(v)), + Primitive::I16 { value: v } => dojo_types::primitive::Primitive::I16(Some(v)), + Primitive::I32 { value: v } => dojo_types::primitive::Primitive::I32(Some(v)), + Primitive::I64 { value: v } => dojo_types::primitive::Primitive::I64(Some(v)), + Primitive::I128 { value: v } => { + let mut bytes = [0u8; 16]; + bytes.copy_from_slice(&v); + dojo_types::primitive::Primitive::I128(Some(i128::from_be_bytes(bytes))) + } + Primitive::U8 { value: v } => dojo_types::primitive::Primitive::U8(Some(v)), + Primitive::U16 { value: v } => dojo_types::primitive::Primitive::U16(Some(v)), + Primitive::U32 { value: v } => dojo_types::primitive::Primitive::U32(Some(v)), + Primitive::U64 { value: v } => dojo_types::primitive::Primitive::U64(Some(v)), + Primitive::U128 { value: v } => { + let mut bytes = [0u8; 16]; + bytes.copy_from_slice(&v); + dojo_types::primitive::Primitive::U128(Some(u128::from_be_bytes(bytes))) + } + Primitive::U256 { value: v } => dojo_types::primitive::Primitive::U256(Some(uniffi_to_u256(&v).unwrap())), + Primitive::Bool { value: v } => dojo_types::primitive::Primitive::Bool(Some(v)), + Primitive::Felt252 { value: v } => { + dojo_types::primitive::Primitive::Felt252(Some(field_element_to_felt(&v).unwrap())) + } + Primitive::ClassHash { value: v } => { + dojo_types::primitive::Primitive::ClassHash(Some(field_element_to_felt(&v).unwrap())) + } + Primitive::ContractAddress { value: v } => { + dojo_types::primitive::Primitive::ContractAddress(Some(field_element_to_felt(&v).unwrap())) + } + Primitive::EthAddress { value: v } => { + dojo_types::primitive::Primitive::EthAddress(Some(field_element_to_felt(&v).unwrap())) + } + } + } +} + +impl From for Primitive { + fn from(value: dojo_types::primitive::Primitive) -> Self { + match value { + dojo_types::primitive::Primitive::I8(v) => Primitive::I8 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::I16(v) => Primitive::I16 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::I32(v) => Primitive::I32 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::I64(v) => Primitive::I64 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::I128(v) => { + Primitive::I128 { value: v.unwrap_or(0).to_be_bytes().to_vec() } + } + dojo_types::primitive::Primitive::U8(v) => Primitive::U8 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::U16(v) => Primitive::U16 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::U32(v) => Primitive::U32 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::U64(v) => Primitive::U64 { value: v.unwrap_or(0) }, + dojo_types::primitive::Primitive::U128(v) => { + Primitive::U128 { value: v.unwrap_or(0).to_be_bytes().to_vec() } + } + dojo_types::primitive::Primitive::U256(v) => { + Primitive::U256 { value: v.map(u256_to_uniffi).unwrap_or_else(|| U256("0x0".to_string())) } + } + dojo_types::primitive::Primitive::Bool(v) => Primitive::Bool { value: v.unwrap_or(false) }, + dojo_types::primitive::Primitive::Felt252(v) => { + Primitive::Felt252 { value: v.map(felt_to_field_element).unwrap_or_else(|| FieldElement("0x0".to_string())) } + } + dojo_types::primitive::Primitive::ClassHash(v) => { + Primitive::ClassHash { value: v.map(felt_to_field_element).unwrap_or_else(|| FieldElement("0x0".to_string())) } + } + dojo_types::primitive::Primitive::ContractAddress(v) => { + Primitive::ContractAddress { value: v.map(felt_to_field_element).unwrap_or_else(|| FieldElement("0x0".to_string())) } + } + dojo_types::primitive::Primitive::EthAddress(v) => { + Primitive::EthAddress { value: v.map(felt_to_field_element).unwrap_or_else(|| FieldElement("0x0".to_string())) } + } + } + } +} + +#[derive(Debug, Clone)] +pub enum MemberValue { + Primitive { value: Primitive }, + String { value: String }, + List { values: Vec }, +} + +impl From for torii_proto::MemberValue { + fn from(val: MemberValue) -> Self { + match val { + MemberValue::Primitive { value } => torii_proto::MemberValue::Primitive(value.into()), + MemberValue::String { value } => torii_proto::MemberValue::String(value), + MemberValue::List { values } => { + torii_proto::MemberValue::List(values.into_iter().map(|v| v.into()).collect()) + } + } + } +} + +impl From for MemberValue { + fn from(val: torii_proto::MemberValue) -> Self { + match val { + torii_proto::MemberValue::Primitive(value) => MemberValue::Primitive { value: value.into() }, + torii_proto::MemberValue::String(value) => MemberValue::String { value }, + torii_proto::MemberValue::List(values) => { + MemberValue::List { values: values.into_iter().map(|v| v.into()).collect() } + } + } + } +} + +#[derive(Debug, Clone)] +pub struct FixedSizeArray { + pub array: Vec, + pub size: u32, +} + +#[derive(Debug, Clone)] +pub enum Ty { + Primitive { value: Primitive }, + Struct { value: Struct }, + Enum { value: EnumType }, + Tuple { values: Vec }, + Array { values: Vec }, + FixedSizeArray { value: FixedSizeArray }, + ByteArray { value: String }, +} + +impl From for Ty { + fn from(val: dojo_types::schema::Ty) -> Self { + match val { + dojo_types::schema::Ty::Primitive(primitive) => Ty::Primitive { value: primitive.into() }, + dojo_types::schema::Ty::Struct(struct_) => Ty::Struct { value: struct_.into() }, + dojo_types::schema::Ty::Enum(enum_) => Ty::Enum { value: enum_.into() }, + dojo_types::schema::Ty::Tuple(tuple) => { + Ty::Tuple { values: tuple.into_iter().map(|t| t.into()).collect() } + } + dojo_types::schema::Ty::Array(array) => { + Ty::Array { values: array.into_iter().map(|t| t.into()).collect() } + } + dojo_types::schema::Ty::FixedSizeArray((ty, size)) => Ty::FixedSizeArray { value: FixedSizeArray { + array: ty.into_iter().map(|t| t.into()).collect(), + size, + }}, + dojo_types::schema::Ty::ByteArray(array) => Ty::ByteArray { value: array }, + } + } +} + +impl From for dojo_types::schema::Ty { + fn from(val: Ty) -> Self { + match val { + Ty::Primitive { value } => dojo_types::schema::Ty::Primitive(value.into()), + Ty::Struct { value } => dojo_types::schema::Ty::Struct(value.into()), + Ty::Enum { value } => dojo_types::schema::Ty::Enum(value.into()), + Ty::Tuple { values } => { + dojo_types::schema::Ty::Tuple(values.into_iter().map(|t| t.into()).collect()) + } + Ty::Array { values } => { + dojo_types::schema::Ty::Array(values.into_iter().map(|t| t.into()).collect()) + } + Ty::FixedSizeArray { value: fixed_size_array } => dojo_types::schema::Ty::FixedSizeArray(( + fixed_size_array.array.into_iter().map(|t| t.into()).collect(), + fixed_size_array.size, + )), + Ty::ByteArray { value } => dojo_types::schema::Ty::ByteArray(value), + } + } +} + +#[derive(Debug, Clone)] +pub struct Member { + pub name: String, + pub ty: Ty, + pub key: bool, +} + +impl From for Member { + fn from(value: dojo_types::schema::Member) -> Self { + Member { name: value.name, ty: value.ty.into(), key: value.key } + } +} + +impl From for dojo_types::schema::Member { + fn from(value: Member) -> Self { + dojo_types::schema::Member { name: value.name, ty: value.ty.into(), key: value.key } + } +} + +#[derive(Debug, Clone)] +pub struct Struct { + pub name: String, + pub children: Vec, +} + +impl From for dojo_types::schema::Struct { + fn from(value: Struct) -> Self { + dojo_types::schema::Struct { + name: value.name, + children: value.children.into_iter().map(|c| c.into()).collect(), + } + } +} + +impl From for Struct { + fn from(value: dojo_types::schema::Struct) -> Self { + Struct { + name: value.name, + children: value.children.into_iter().map(|c| c.into()).collect(), + } + } +} + +#[derive(Debug, Clone)] +pub struct EnumOption { + pub name: String, + pub ty: Ty, +} + +impl From for EnumOption { + fn from(value: dojo_types::schema::EnumOption) -> Self { + EnumOption { name: value.name, ty: value.ty.into() } + } +} + +impl From for dojo_types::schema::EnumOption { + fn from(value: EnumOption) -> Self { + dojo_types::schema::EnumOption { name: value.name, ty: value.ty.into() } + } +} + +#[derive(Debug, Clone)] +pub struct EnumType { + pub name: String, + pub option: u8, + pub options: Vec, +} + +impl From for EnumType { + fn from(value: dojo_types::schema::Enum) -> Self { + EnumType { + name: value.name, + option: value.option.unwrap_or(0), + options: value.options.into_iter().map(|o| o.into()).collect(), + } + } +} + +impl From for dojo_types::schema::Enum { + fn from(value: EnumType) -> Self { + dojo_types::schema::Enum { + name: value.name, + option: Some(value.option), + options: value.options.into_iter().map(|o| o.into()).collect(), + } + } +} + +#[derive(Debug, Clone)] +pub enum ValueType { + String { value: String }, + Int { value: i64 }, + UInt { value: u64 }, + Bool { value: bool }, + Bytes { value: Vec }, +} + +impl From for torii_proto::ValueType { + fn from(val: ValueType) -> Self { + match val { + ValueType::String { value: v } => torii_proto::ValueType::String(v), + ValueType::Int { value: v } => torii_proto::ValueType::Int(v), + ValueType::UInt { value: v } => torii_proto::ValueType::UInt(v), + ValueType::Bool { value: v } => torii_proto::ValueType::Bool(v), + ValueType::Bytes { value: v } => torii_proto::ValueType::Bytes(v), + } + } +} + +impl From for ValueType { + fn from(val: torii_proto::ValueType) -> Self { + match val { + torii_proto::ValueType::String(v) => ValueType::String { value: v }, + torii_proto::ValueType::Int(v) => ValueType::Int { value: v }, + torii_proto::ValueType::UInt(v) => ValueType::UInt { value: v }, + torii_proto::ValueType::Bool(v) => ValueType::Bool { value: v }, + torii_proto::ValueType::Bytes(v) => ValueType::Bytes { value: v }, + } + } +} + +#[derive(Debug, Clone)] +pub struct Value { + pub primitive_type: Primitive, + pub value_type: ValueType, +} + +impl From for Value { + fn from(val: torii_proto::Value) -> Self { + Value { primitive_type: val.primitive_type.into(), value_type: val.value_type.into() } + } +} + +impl From for torii_proto::Value { + fn from(val: Value) -> Self { + torii_proto::Value { + primitive_type: val.primitive_type.into(), + value_type: val.value_type.into(), + } + } +} + diff --git a/src/uniffi/types/token.rs b/src/uniffi/types/token.rs new file mode 100644 index 0000000..439a513 --- /dev/null +++ b/src/uniffi/types/token.rs @@ -0,0 +1,209 @@ +// Token types +use super::core::*; + +#[derive(Debug, Clone)] +pub struct Token { + pub contract_address: FieldElement, + pub token_id: Option, + pub name: String, + pub symbol: String, + pub decimals: u8, + pub metadata: String, + pub total_supply: Option, +} + +impl From for Token { + fn from(val: torii_proto::Token) -> Self { + Token { + token_id: val.token_id.map(u256_to_uniffi), + contract_address: felt_to_field_element(val.contract_address), + name: val.name, + symbol: val.symbol, + decimals: val.decimals, + metadata: val.metadata, + total_supply: val.total_supply.map(u256_to_uniffi), + } + } +} + +#[derive(Debug, Clone)] +pub struct TokenBalance { + pub balance: U256, + pub account_address: FieldElement, + pub contract_address: FieldElement, + pub token_id: Option, +} + +impl From for TokenBalance { + fn from(val: torii_proto::TokenBalance) -> Self { + TokenBalance { + balance: u256_to_uniffi(val.balance), + account_address: felt_to_field_element(val.account_address), + contract_address: felt_to_field_element(val.contract_address), + token_id: val.token_id.map(u256_to_uniffi), + } + } +} + +#[derive(Debug, Clone)] +pub struct TokenContract { + pub contract_address: FieldElement, + pub name: String, + pub symbol: String, + pub decimals: u8, + pub metadata: String, + pub token_metadata: String, + pub total_supply: Option, +} + +impl From for TokenContract { + fn from(val: torii_proto::TokenContract) -> Self { + Self { + contract_address: felt_to_field_element(val.contract_address), + name: val.name, + symbol: val.symbol, + decimals: val.decimals, + token_metadata: val.token_metadata, + total_supply: val.total_supply.map(u256_to_uniffi), + metadata: val.metadata, + } + } +} + +#[derive(Debug, Clone)] +pub struct AttributeFilter { + pub trait_name: String, + pub trait_value: String, +} + +impl From for torii_proto::TokenAttributeFilter { + fn from(val: AttributeFilter) -> Self { + torii_proto::TokenAttributeFilter { trait_name: val.trait_name, trait_value: val.trait_value } + } +} + +#[derive(Debug, Clone)] +pub struct TokenQuery { + pub contract_addresses: Vec, + pub token_ids: Vec, + pub attribute_filters: Vec, + pub pagination: Pagination, +} + +impl From for torii_proto::TokenQuery { + fn from(val: TokenQuery) -> Self { + torii_proto::TokenQuery { + contract_addresses: val + .contract_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + token_ids: val.token_ids.into_iter().map(|t| uniffi_to_u256(&t).unwrap()).collect(), + attribute_filters: val.attribute_filters.into_iter().map(|f| f.into()).collect(), + pagination: val.pagination.into(), + } + } +} + +#[derive(Debug, Clone)] +pub struct TokenBalanceQuery { + pub contract_addresses: Vec, + pub account_addresses: Vec, + pub token_ids: Vec, + pub pagination: Pagination, +} + +impl From for torii_proto::TokenBalanceQuery { + fn from(val: TokenBalanceQuery) -> Self { + torii_proto::TokenBalanceQuery { + contract_addresses: val + .contract_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + account_addresses: val + .account_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + token_ids: val.token_ids.into_iter().map(|t| uniffi_to_u256(&t).unwrap()).collect(), + pagination: val.pagination.into(), + } + } +} + +#[derive(Debug, Clone)] +pub struct TokenContractQuery { + pub contract_addresses: Vec, + pub contract_types: Vec, + pub pagination: Pagination, +} + +impl From for torii_proto::TokenContractQuery { + fn from(val: TokenContractQuery) -> Self { + torii_proto::TokenContractQuery { + contract_addresses: val + .contract_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + contract_types: val.contract_types.into_iter().map(|t| t.into()).collect(), + pagination: val.pagination.into(), + } + } +} + +#[derive(Debug, Clone)] +pub struct TokenTransfer { + pub id: String, + pub contract_address: FieldElement, + pub from_address: FieldElement, + pub to_address: FieldElement, + pub amount: U256, + pub token_id: Option, + pub executed_at: u64, + pub event_id: Option, +} + +impl From for TokenTransfer { + fn from(val: torii_proto::TokenTransfer) -> Self { + TokenTransfer { + id: val.id, + contract_address: felt_to_field_element(val.contract_address), + from_address: felt_to_field_element(val.from_address), + to_address: felt_to_field_element(val.to_address), + amount: u256_to_uniffi(val.amount), + token_id: val.token_id.map(u256_to_uniffi), + executed_at: val.executed_at.timestamp() as u64, + event_id: val.event_id, + } + } +} + +#[derive(Debug, Clone)] +pub struct TokenTransferQuery { + pub contract_addresses: Vec, + pub account_addresses: Vec, + pub token_ids: Vec, + pub pagination: Pagination, +} + +impl From for torii_proto::TokenTransferQuery { + fn from(val: TokenTransferQuery) -> Self { + torii_proto::TokenTransferQuery { + contract_addresses: val + .contract_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + account_addresses: val + .account_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + token_ids: val.token_ids.into_iter().map(|t| uniffi_to_u256(&t).unwrap()).collect(), + pagination: val.pagination.into(), + } + } +} + diff --git a/src/uniffi/types/transaction.rs b/src/uniffi/types/transaction.rs new file mode 100644 index 0000000..8d0657a --- /dev/null +++ b/src/uniffi/types/transaction.rs @@ -0,0 +1,128 @@ +// Transaction types +use super::core::*; + +#[derive(Debug, Clone)] +pub enum CallType { + Execute, + ExecuteFromOutside, +} + +impl From for CallType { + fn from(val: torii_proto::CallType) -> Self { + match val { + torii_proto::CallType::Execute => CallType::Execute, + torii_proto::CallType::ExecuteFromOutside => CallType::ExecuteFromOutside, + } + } +} + +#[derive(Debug, Clone)] +pub struct TransactionCall { + pub contract_address: FieldElement, + pub entrypoint: String, + pub calldata: Vec, + pub call_type: CallType, + pub caller_address: FieldElement, +} + +impl From for TransactionCall { + fn from(val: torii_proto::TransactionCall) -> Self { + TransactionCall { + contract_address: felt_to_field_element(val.contract_address), + entrypoint: val.entrypoint, + calldata: val.calldata.into_iter().map(felt_to_field_element).collect(), + call_type: val.call_type.into(), + caller_address: felt_to_field_element(val.caller_address), + } + } +} + +#[derive(Debug, Clone)] +pub struct Transaction { + pub transaction_hash: FieldElement, + pub sender_address: FieldElement, + pub calldata: Vec, + pub max_fee: FieldElement, + pub signature: Vec, + pub nonce: FieldElement, + pub block_number: u64, + pub transaction_type: String, + pub block_timestamp: u64, + pub calls: Vec, + pub unique_models: Vec, +} + +impl From for Transaction { + fn from(val: torii_proto::Transaction) -> Self { + Transaction { + transaction_hash: felt_to_field_element(val.transaction_hash), + sender_address: felt_to_field_element(val.sender_address), + calldata: val.calldata.into_iter().map(felt_to_field_element).collect(), + max_fee: felt_to_field_element(val.max_fee), + signature: val.signature.into_iter().map(felt_to_field_element).collect(), + nonce: felt_to_field_element(val.nonce), + block_number: val.block_number, + transaction_type: val.transaction_type, + block_timestamp: val.block_timestamp.timestamp() as u64, + calls: val.calls.into_iter().map(|c| c.into()).collect(), + unique_models: val.unique_models.into_iter().map(felt_to_field_element).collect(), + } + } +} + +#[derive(Debug, Clone)] +pub struct TransactionFilter { + pub transaction_hashes: Vec, + pub caller_addresses: Vec, + pub contract_addresses: Vec, + pub entrypoints: Vec, + pub model_selectors: Vec, + pub from_block: Option, + pub to_block: Option, +} + +impl From for torii_proto::TransactionFilter { + fn from(val: TransactionFilter) -> Self { + torii_proto::TransactionFilter { + transaction_hashes: val + .transaction_hashes + .into_iter() + .map(|h| field_element_to_felt(&h).unwrap()) + .collect(), + caller_addresses: val + .caller_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + contract_addresses: val + .contract_addresses + .into_iter() + .map(|a| field_element_to_felt(&a).unwrap()) + .collect(), + entrypoints: val.entrypoints, + model_selectors: val + .model_selectors + .into_iter() + .map(|s| field_element_to_felt(&s).unwrap()) + .collect(), + from_block: val.from_block, + to_block: val.to_block, + } + } +} + +#[derive(Debug, Clone)] +pub struct TransactionQuery { + pub filter: Option, + pub pagination: Pagination, +} + +impl From for torii_proto::TransactionQuery { + fn from(val: TransactionQuery) -> Self { + torii_proto::TransactionQuery { + filter: val.filter.map(|f| f.into()), + pagination: val.pagination.into(), + } + } +} + From 7da04736063834dd52d0bd2ced29e7d904b66e8e Mon Sep 17 00:00:00 2001 From: Nasr Date: Thu, 16 Oct 2025 18:18:13 -0500 Subject: [PATCH 05/16] add examples --- Cargo.toml | 2 +- .../python/__pycache__/dojo.cpython-313.pyc | Bin 0 -> 455154 bytes bindings/python/libdojo_c.dylib | Bin 0 -> 13112512 bytes bindings/swift/DojoEngine.swift | 949 ++++++++++++++- bindings/swift/DojoEngineFFI.h | 1013 +++++++++++++++++ bindings/swift/dojo_c.modulemap | 7 + dojo.h | 49 +- dojo.hpp | 3 + dojo.pyx | 9 +- examples/python/README.md | 117 ++ examples/python/fetch_entities.py | 129 +++ examples/python/subscribe_entities.py | 114 ++ examples/swift/README.md | 248 ++++ examples/swift/fetch_entities.swift | 100 ++ examples/swift/run_fetch_entities.sh | 76 ++ src/uniffi/client.rs | 43 +- src/uniffi/types/core.rs | 4 +- uniffi.toml | 4 + 18 files changed, 2818 insertions(+), 49 deletions(-) create mode 100644 bindings/python/__pycache__/dojo.cpython-313.pyc create mode 100755 bindings/python/libdojo_c.dylib create mode 100644 bindings/swift/DojoEngineFFI.h create mode 100644 bindings/swift/dojo_c.modulemap create mode 100644 examples/python/README.md create mode 100644 examples/python/fetch_entities.py create mode 100644 examples/python/subscribe_entities.py create mode 100644 examples/swift/README.md create mode 100644 examples/swift/fetch_entities.swift create mode 100755 examples/swift/run_fetch_entities.sh diff --git a/Cargo.toml b/Cargo.toml index 12008a4..4ac5655 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ starknet-types-core = { version = "0.2.0", features = ["arbitrary"] } # Core dependencies parking_lot = "0.12.1" -tokio = { version = "1.39.2", default-features = false, features = ["rt"] } +tokio = { version = "1.39.2", default-features = false, features = ["rt", "rt-multi-thread", "macros"] } url = "2.5.0" anyhow = "1.0.89" serde = { version = "1.0.193", features = ["derive"] } diff --git a/bindings/python/__pycache__/dojo.cpython-313.pyc b/bindings/python/__pycache__/dojo.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..945038f40dd55a10b720c586201268f3439a5e44 GIT binary patch literal 455154 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 z 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
    BNlnKj9Fu1 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 literal 0 HcmV?d00001 diff --git a/bindings/python/libdojo_c.dylib b/bindings/python/libdojo_c.dylib new file mode 100755 index 0000000000000000000000000000000000000000..e3c147c1c0aab6875016f920a54b188177e80e94 GIT binary patch literal 13112512 zcmeFadwf*Yx%j#5YgZbxoD--GRYtW zur<3*)oNRUX=^4ll~$;x_LM-ZqP7)!(f0J5;{<4(Nu+AIm=Wl_-)HT;lgSN5+jD+@ zy!m`4`?A(v`&rL@J?mL(zy9IDe-2j4rT9zYH-cYoic$}%TDhgh@Z0THs(67iN8k0I)m~}kqC4+dw2V8w+bbAlwdVjO*YWMCKJeXE zQBk_+{)$EStSDVkzOYYwHt-y7D_(tGdz^5VO1DP4T` ztxKrUyS-muVYL@}#d=b%d$(bOq7S8|iz-WRT~>bABI|DN_O_1RpbKsY57S4vHms`p z{~)C*<1RHHhq+N&I;XItu(bH9E3dV=+2&uL%_yqpwX`Wef%P=~{B29RsW5PR=Tg`D zd!h$i!qZ=Kia7SAYft#jwc!aDS@6kqd_Uuw(x)P?_XDie&$v?GChNjy-*c|L*0s}5 ziyP(nJIhO#ue@vFk~>T9S+Q)u_TF=Vp*`nRT9kIySWWByrKPu&uPE=n(Hp+^{1$vO zXIgdSI=;Q`C#^H|N#(Ld<+qgHSH4WNK=1Z)e_^%vxXrY39pB!_UJZ7&XM@?hy_Wy5 z+N-mllk52Qh7Z)#ilXQtOMqxjTFIS00LouXlUGcXRobmR>RM%F8dFGtZVTrRuoLpD))s+Hkg% zSl7}{d|N}fzK35%ulrN4TfS)7@~L;1FJCrw&XS6I?^<;Cise&pS#;l`JD1!e7w6o) zWckXwE2iGEq6Y-F%IZ3G)BQ@FJGeoGzcOA?MSa0~ zL=FA2(!W=^{uAf%a$r~KI^=p9lsg^)cF8!7@}6^kQnM&+{j^oV$DcQU(0TTo=W{QM zpY@2mb*w(uv`P3?!es88#?Sc^8&Jki+7j63tKYmYPfxveMFMq2ipP_y^DCU4qA%qwCbUcPcf>z81R6-x>U*JZs%cs_yIk5Kt<8jK7$XxcB&y zVZqMQ(}G9m4-X!`YDDnFs*%AHtqJBKLp6HT7xFU`)zZ(nR7vh=m3P>1HI}(OW}7jx z(e3qJGpl-Bpv_2Yg#KxnL)6mpQL04BeUGOE4)Z*=>Vit;yXFzfkJ!)t_zD&H<8Za@ zh@qmpuTt-Mb|#x1mp96L-k+PIO8$72+Pb|c)!ba<&Cg9xS7)ZEr3*c(q|WV)j(s#e zkmXSq$hqfqZ*=YmwJpMXCJ!m@RHwDfYR^duhBAG#V#O*NHk5hU1ohr!Rp*-FDej=> z^QzWU`WAx^XCpydDeB3)raBg{rXf@vK{yu&MpdW;9ZUNGlN0@n9fHB zj|m(F)(^l#?qF|p^M2P}<(mCQR*ITl=l@edo$*9Lga3=24aT_6dcSM$0p1rfMm4q> zqZ{`b>5X^N_s@aH>=fsn77V$`&b1B05cU50BvtY!@R(7YYK}6xVQJ4Xf{`2*UET|p zwpL{dEG-FYx`+BHlUjq9dDJ$Q*fJ|Jr5mTW{Xk!Mhksc-c)nV7smx$r>ha!e~;xo8;hkY;8iWk zyuvpw;GAF2dEJHFuXUSl%8RmGW?_Qwnh(D=E`T4A)?e8n%Cc0}AEX?gDh;7dOW-GR zfSyZ3BGZKb1#SblJ@&o1HvE6*ol-8c(tf!LIQK)y(%Y0RSUoQAk+SLSM>Z$evRUZ6 z=K89BWRvodn+K3h%1rMkm(6M4`oERUd%ye1W%HRqpH4O(r0@SK*?g!MEdMXd=B4yo zc>J=@+p<~o@n!S7H}sUv&=u-Ekh9S?#SjyTQ>VE8+;0~c{*_S zkWJuEc4QNI_|0rvHn}gdsVG}P`x?GblIc>u-)Vh=&WRbu-osa=Vm}9AKi%de<&CDg zeAmR#ld+g9*q*MU>VR4j^1GU1Q&conz4yD>uGEe~Y-`BBtDw!_TA&hLO(Fk_1!}l& zR>;4Tdo2YnmugBye?-ui*}j&7EFbp`qbb|Bi}O~_6PiL5F4Jfl8aT1)a&+Ql=s`p4 zL9yW>^zkj&+z>W<5BNMf|39eX0#0}EgkPC4|De5x3{T_qE4SheHDm#xXN_4F_Ggcj&6=$ zkwVbcx+{?L-^D52@ zIj=5Q;a1UdUCo4eEPyJn)z*A`6;Gr^{**b04*daWhU85*9zrU<=DDBJx2wxl(AZ)fQ^-hDbS zoB{2}L;GY?{5he0-nsZw!mIW0>M;DCYu)Dkr6U3je%IdnIEMXha|Oqv+!x+xDcV@j zQnZ2JdVVzpA^5aq*V=;cFmLn~@qLVuok4$kXLyshIq1Lf`3587`Cw}X#~V9$yN7g! zuk}VFTcm6Z_r`P{NmkLFyM9d@uYo(GY3Ht2Ie&$7H|M)Kf0=VvQ_HTG3PMH|*T3Od zQ{X{{*7LsEE>DNcEpqe{GV^jlS(4EdzSJA7EW*dIWveVnWb0RyzgST2c5`mYSGij? zG4x9FB^AEZzbaIXm2%w^De2rYohRE>V@V0JHFg z^q~yiXrVvC8v<(?{2{Ole@I`-;E@*kB|IYiyca$>TwfR*ov6$*_(gQh8%gjjp~F$= z#AjY|L(fr-$M9jogXot_ZSy30Ho6Xe_4iWO4ed^>x*6Jj2^!yoKeQkS&CQO%L(}@Z zuXR?@%e?y=&`GoOMNgbyEtpTzeOo*NI|937LmKzJ^#F`--q z#&Ul$^(OI?a_LJ8eR*z|< zEgpZ8@?n$@Cr3-~g#6V7VV(~mYsc${2Ew!Lb`4eHTU*@Z-%!-F&}}r8Pw>t1 ztu1U?v%$-?t0}w=nq7u27%F@R{YR*#6RWNV&g<}7OQ4nIw>r4jwyxzgE%!Hk6&qOH zQczWm{#!SzNo1$NIHP|$Weqo-GG^R49C>u^t?>p^;BDtRB|$~?*ugd1%o2OBF10C~oX&X6ZQe+`9_(r= zzZ7hbWithDuBI*i1)Uw}$}PrC&v#5w&94=GzO!Qx*R5QSQ_XD~FKcSsXf(Bzw#@24 zzfjiP0lqq*_Y~Ut48OLCzF8vghk2LS7@uupeA>pm!u9%sNhR3AYZ=2lZSjc@nG`$Y zL%xMie8{)hDIfAJeBwi{g-?9Qwb&;gavcVTA>Oe7yByvEpSaRHyveGh;~8+ZfN|Ba z!sdg?Ma>cV5jloFq+jn$nICK$bcNN2L7#6DSlfnO*|cw+yQyte%dGwDTule*=PSD| z>x|IvgClu9y{P#h{XCdl7(GZo@13B6cciMQ=$Jbj-NDd0u~B~P(wc(M#Fkm2n?mcv zhS_#&U15{hII(r%Dcyx-2P1s4#>FcG@jG24w&Ht~9beMRH#LUrb$pbt;W4lM626GgNc*Q7@K41@75`&hL5lb<6ID=EZRFlV z^w&2_WJ*nCn4Y zi=OjvUC4Dxlk_K4oM46;(GS4m_!2&R=r$>{-**e|6I^-l_hQD7ESR*@s8sXu))+Wyg`Zv9~B4_qdR9kt?wspVf3y=G(Sk`AcN$e9AwG zU%Brl%dZS^6n+0c9RGj65*+|8zW$5C%8ZJCiR>j(zLN6$ z`Ndk3_8y&|ft?$JuQV3FGD-WD(-}93kL1X18@fV#7wxkc_$&rv4ns9%i#@5w@0=m_ zr2p}2?q|>=+TP%I8Zz#+?1hZULp=MN@1rMfv;566{LQ-RmkKslGe*WItgGJ5xiwy@ ztA3Sp8ArLe{~OMKO^iS_t-vp+TlYXy*;<9p#uluVF)riOwfGi>7azdDC%utAei2)K z13qbzjv>UqC%mf5_uQkbvFaXsth#4ST}GE~`6@Vz_dU-L+=A1s=!`Qd>l1@826gNC z`Xuwu3r6TzZ;W_#7@EWwA6hsyz-Nut`A&So(f8pu!QXOp`?H13;SSYYbD`R!T-Z%x zP0w*6xC{BgiJx&4%I}%J2cgPbZq{{nrb^Zzq~AjvC%e3pKpqrxWb51iLJuDSVqe|%eaL83~35?oP6F#dR=<8;u{D-CjE&8^ z$&ypSE93nVnfLL+W8q?DevYHa?4Y>uhOasan!1`K_VrnQGHy7Bp9{ak&ClSM53P?@ zAk)OQ>#`>c;&@E- z`|+zRetH=FV^9_=Hqhy*=sV)Is|E*87zR3BHD=bTXyzIfO@n7@ptU0=nl$wIaKU2+u*lwiugSX zI&+iMwr$+6ycszkPF#fcm^*zRJ5jRRP}^i4G@E^6ezWY5x1I){( z>Gz@AD|sKfk#XK{;TPYm%CDjS7!y`rNV~MxLVMCy2!5|L)b=Cj--fj>2R*~R(Wg?q z(Yl4!oL`#sBk2l#f8p)kXxTz!p1HtE-YNcno&PTdRY{B?(3K7TFLhSBhjuE;$T>+X zFY-pK6fl0y8x%{=qDyuBa~)$&_&5jsdL{P^+CUe|SW@s;d83M+Sak*XzZ`o* z%(~c$Sv${*e$?}VBYHk7&y9zMCxdS^<;R!&Jow>lF2GG^6>Wc=>nqfrNjpzBBfsaoc&MJY4sOW{Huy((3QujWcklgf zE%Pso zEhW2<`QgN1nD*zT@&3J&%rNjofJe`tZ%#6$Z(-mM1Cz8JUZA4U*q~q)_BLD1W=x~Z z{q!aNT~84={F|u)y>aLpY4PY>jvAM{GJDSZkFe(bS=Jmqxo z-m12Rp!CuKWT zNxR+G4sia?o35zfsq-)N9~uSy#I(VAJAI2xNeo)_ahdJlLFUMVImX_0-f@}GY)W!4 z0uC?Z`H10;wkNxxiyL`9&5Rlu#N0C)kMWz!+%`Dbk@d9ryo{nURq_G(34;ILGEt`4H~QX=Y5M4Vji2|<*XWjm zFgR}TkLr{$VIz1BgX1vx^nlOsH24~P3J(ZB9uoP0M#A51;6I9PbNKq+hpqQIa?tj6 ztmG2nM%mlJE&T3D?Th0I@=pE>S^iFIrui-6TTbpqdp-FQ6P50p;Kg}IPCvMA+pje4 zoH~MQblCJ7+S9WCW3_G2d4;FMlPy2$%ahXnF`Flaw;Z1A09TT`qInaXbWBXLdGvJj z%4uf%#BQDpPMH~$c^C0pg%83L(H-!C@WA)snW!-i9v#;x{2$K)uL(_aJm$BsdqOV{ zIWXwWrGtlQIbQnpN!pez^3O^yq*z z8c2`U8Najb>9rq0BP*A0B{ce_Tczbr!1ogUXvc3u%=4(KUBq(H%gmj4&O$FUcf!1k z<(at<%Df7_t&RhS)2F4$fixE7_s_UyjXWpW=hu2-KeSGmt z#E$Np;f;>rm{q0BW7yA5euDQ=@JC2eieghI ztsHu;e~sMVwW zAXm0B-Dmo)iQYFZP=ow=82=y1Nezm=9mg+RJcRh3$J}T8IpVKN-t@f*#GtkmMt6_Y zvZCVwb&Ppr{9ecWc@25eGKP0?uZnoUPOg0mt+DosgrR{A_~W5^<|)x34h(a1 zw!l}aEVIYhul`Ca&u{1VVtM(;W9ccx+4|F04gVP{sd?1O<#|eSdC*g$X9`l?0Z0Ea zw$w3=Hjd$mmjoG~cZ8?aJaIa@G=e_suifyQv66QD|Dy|v@((@YZO$Fi@}Dxd-vCZz z%$@D>FxNb)aUs{UV;O;%-<{vaeYqzwjSIPVwAZ~n?p3C?+!(GW=fJL8P2H*77aijC zgS8bU@&25fctRWflD6+NQW?8TP8>0<%h9jPiAVU0h{Y#1IdrJ=T6AccOj{|iPHSwipO23bNvuVlZy|22pJ$Fyo)^B7=N*1>?13}(+B{j6+yGqL;fwA2vU-f| z_g&ck*gkthdcgZkY`VlzM90s&d;tA%GXHGe$JZZ0Bcu1Ye(NO0QC;JDd}PM;TQ9>$ z>oKm!=Woa77oSXQV!RK1z^wv9oPHN&_vm-^^#1$3e|>tOZd-T1BgF&s`y@V(x9I=2 z-+!dvYvChJ@9LiPo^X!U?;!p3?y&kP>kLvavid2pt+-gt)}{e$c&Wr{^6`J{agY|SmjqusyZK`A`2+C9N$hFMx&OC(@xDuS`HF%U z@jsn7iG!O$Vlba~a5JGN?^KWPA2*{#W>$COCOFx`%>d)^txYExkGJ4cf7Ezfc*z-$ zJN(DkTl15|tRyDYF5~fdp2Dwej~kE2^Hsdg$b-jvU(+Iybto-tgJ8;RjYtQhXr_!zFlZSQ}Gc@y6GK%olwBxY)iBnRbU z;^}jUs}~brFCxxfNFL)$I`^w>nl&d7nritem${k0vSZTZ3vLZaoZOC03m=T(=k&)J zhx{ioyqc58rfYlkYftZfiN7fQ>ZD)t4&u|b@qKe*u+qob^f4Y5hc~_S*~_!7_zxcZ z7FpX9#?Oc_-jbZ--1BOlka*n>i5<<%XFrMs%)>Uy(#)SYhEt$H<<_fP6pnZ$C5S1VtZ z`B}THd~YmoEq-10cjDTq>)Fl(yRPfcvAj2_>slCBH>)Rn>CQVtvAiUCXOYEEK6{So zXD;$Lz=7m*3l1uoj}#n89=Fh0=;-i~!*}I>iIMns5btkn&WvA;kVfRvYC1v_q?-|+#IQ8OnS|RP+PTgYacD-}(DC?cR z@jY|EycpaCQc_2mIpYgsdayw;iO=vU_{U!oae4YOITyle?&Pdu3zjUr)`K5Zk zP;%dxFBCkA-DQQct~)NSuK2)ZGPj5iTxr)8+{u_M%dYPnWel?Cvnn7k$Me-_yI#Cc zAijX(Z}+zUvVKQkmiDHw#!ldikHLAm%9Z&LI!E+jHuXf`$a6Bj)3J8e!u}c?kn2{{ z(H~1)%<(?rRx<=1^vhBfS(iwxwvgjYx4J;bX&>}z-7;Ya^R89actGG`Z;cCdoF|(+ zO!_Ffv`?~L*SRbYiwOME-(Z7#adm=mnWe2nL}NbL=Kb-9#xIoBnKQ{#)rQy z>w+IacU$owE3R9EZL+Sr~3jqPtvWUwwkH6FFs$hPHJ@RqsM zbjh~~4Pvf>H6}98x!*52nQ4rpM-f9A-FSd^*RM-w4b&yTcrmtV4mnINox^le*!N|1 z!G6o9fc<-)6806J1oonCyytxi*q3}t*f0Jhuutg5d(x+X-TNtFAN@&SukMEZP3A>E zDZdZ@l(4_Ob^v}i4Ay&jkbx9rp?gi@A>>N*$r0AXgpyT|oD;LPaF||~E`H?;VLj(o z>p3gY%w%paUDaHp_+_K7-i!?is06j`Ew@_g@kvfTdYs&Y+~GA(Ou`PNxKbJ=$1Rje zymPE?R%o4-T9hVMmB!&Y)iMr-z(vs z#9$smuc>>`ZGJbpEg4*S&}}K?h{$}T0#}|!mE|_S0*>VQF!);53rC~laP$pu1Wvc@ zh{qARmhm|93693K%<>72STpFu7PT3L5~XgxT3 zRO4tK@Xm$Cmj;1f>$%?e*>iWd-4$BDQ`~J+Bp);PGb$kK*0pWo`b@4xr(ObHehzL~ z@5y?q5%~8bp+g$)8pS(VSG6jg^+K|?%HpTzi0^!`E7=UA)0rdGxiQ25_H5sGhUCW7 zN^Xod4_}w^dGt@#1~&M|bV_baic95rb}BOk9*W4G4EPdtIqtm@SNkinS?7PVU^Dw8 zz^~*Vk*_e4`4EXylH;PsL-b4fCiyKpm{-|Nn_=>8WDQG0*LXiliyk*LOuWF# zEwJ-h8lIj(UX6RN_%#iF;z6tPC7;C_FVJ>H=jGvwu?Cl zLCGUZKAsUc2LBy*?4se)V}#In9dFmq;UDOI8&W@K zFIKga3(qkbv(`>3%rP6EzJPgD#;tF9g5j%(4~}fn>r5oxDs&M4?LdyiLdRlf$6;qr zZ+!K^^uV9tnOydVkTHylF-*-5$se<0vFlk6;f#$MlF7%3xF}Q%Qt8lV&j1492{)OI|&Y;>*Vd}1LJ@^URi4s&KwvA>%qYn zz(Eb;vL5~IjBOYBi5!VNmi2CI`cJ7NqGoBwCbKn;vy|bbhEjGhLGG-M&tz$<>^;~A-eOpnD+H-I>y7uoA%yg6^KHAZx?*U3cqYx95EWp(4tBD*a6Xe{ro ze=?4<^{41>nOlihzlPj?*5({3*84)dFLc<7YwEpt zPW$*c=>Q);0-i0?E(pE`-Xz~d@U(?~YhBMiJz>%H;O8(gN8eM{xGhpOC=g=&Cw9&0 zhvpArbuy0LnW(mnLYKvt^|rt7Fn1%oF_8V8lm;EiDYfnIRwriHpZ(SRsK_S;zmEOA zZk_li%Dl0_^4~;0POO@bPjWrJ$#wWBCHN}W5{ra9hP8ghfwwoTJO9nFP6k$D6u%Rk z{T_KF24%^r$~14bcwxlm_hNaUrEC{;Dhf?74e+ebTXM`Yd*2g@<-B>P<;Ur=tTW9h z&xn62eo{KPaMth17~aKC$^=gE|4u=45`|Vr-fC zbz1*@LcgvAo%65o>w4qB_UpEa{}OL2+ikz@3%zkr-@~ud&p9|anP0aUc@e*EKpcDw zziuQrIGJC!{Lshp>om;qev9qb>HFfNR91KSbzS#9u3uM4KgF*b$ZvVpmX(wGExl;r z_;m+6d-CI{`gN`JtG8e0Nk4VJE{k^lU4Gpi9|u49o$88S z=GXoH;(`6TU)yD;;@3S~@vrymO2NzjtA5>ha6XVUdG<1LYL?UIxiY57QPD%wRCKQ7u`{M$JfSrhp2FHi);31!M+X)Ag~VQF zTtxgPSUWu6`9gx(V5D`1c~{Ud_BKpBFNn=0&)_WXkLYY@HFUf%d>i>5caR&sMDoDM zS+j$iJd={K6-<4!ODt>!)zA1CXGTsPL z&wHcrQ(9v!{g!vioZ8HBDV!JPXP%{&`dEV|_1Y+NpGCd|{1%V*I^ufLhlUfeyh`vb z^eASW`zGgMCkC*9T)9$kRpE;M{-|XyqE0-sHC4wm$w!#Z_)+KmO&V|K@~q|=KWl5& zv9@L-Yik~MMSlYwnp|g_O-s%T?uebQ*VZ&a6N$r?olYLl#Oc8;)AE85V2)hQ^ZN&x z5$F_bHTDXv@DW*CNt^(h32h_Gsl#5mkuTe2g=d?QRosJ?FAyu%G3%Te!O$~yE_X$D zF8B8<+fdSDCVvz>8qgk8j~TIg5%>hwSh@jN+~^@=I!J=ZI?pJHDX z`zm(Aajl-ulwXY!`0l*Jo((uTlj$4Y)j9Lx2`*mNH{MP=oixfY$4Wgm-`JVhBXj6Je< zD{+fGMRjNC+>`HDTKg*ZC~G-WmwlHq$rI_X>`}@jt}zsyC3z9D_p)4j?4#)3Kg_W9 zbJg(=`j`4e3%@hOPSTHGQ!evf-@sP77k|VWarS&UY$RZF3~Y{@^^h*|5>#V!zstl{ zZjE0nC2PSS2L~DZr*+vLA92+TY?HP<DV24M^C#$OqKUZTj5Jp^w{c@Zo5O<`+-^P&h6DI zV7+ftiEuEz(`A5{pv&_L`+llUyNSwB9)t8>x!QEushF^xw)ObU1mdoMv`*+ULt zgq(JnTiZ35{NE((#6;}dS*cH^Fs7c(e4ygK@NUW?6%^Z+%em(^6&wT3#_7I~w(~{O z8aLF5t)o4jbMRx;vGCJu~jrE%SAhi7fY5_HD{UAISW)lSAd?bP3=8=>lu7GHd=?nX}NN zg3sS^e-*K8k@XaN|0olAPeg~D)X(&f(ECChG7_2lw`Bh)vM=)$GQMr_!7uC+u@iY( zJmI?F?Z1?~ENhR5B4|=JL42q5#`8O4kCpNM3&Dr*A+~7SSmMAk2Nv^>I4PYgtF3or z|1;L-9e#W&p@sELfKiS6>E90%RG_k&J&z0(?N2W`zHlA$(<1M=gY~@4p7{AJ{~%TJ z9rV|Cif5SLhL>`k`DZ&X>$bxgdTsPE$6w2_V|0AGpoaQ-efv~vj-q|yDE2-e$2Sq3 z_5%A~h_6*OQP15(o+KA~lPfCoC$TN~DfResPmAxBXm+#?HY50m9r%b{{u#bvq!m8} z->-cmHVfaczdW!5IfLO*SyLtJmd7<_BNviO_-*=>PoJ{mWM{%eRgwkF>mDE$^Fgd@ z-s$#9&K%39fPbo6=AbO!5}hCME8VAd`h?DmhUm-bh6)H@$ae#J({dWL)cb~N8cSYV zTH}cyp{KTBN8lkTQ|xJ_RW+IvV~MMP8gY`d8Y? z^U$`R_4@epo6)BZude$b_E@Mrd4{V)=B|74)-d4l9ZR0kF0k@$*~dov|Hx8*yyjzW zko)kKHLmpV%@FH4$=c6?aX|$>YYlYqY@T7Bj^3_uc+K`VBlxec9kSw(UE_laYkc4v z3BTFTdU#g&?v=6jI6-`P{Pzz0_IL23V~iQ}I3YXNJP6-?2;T|M$-W;4ZN8K7LQ4i~ zBjB$H{M7+}z4HilAG3HeGMl5Hu>*V=5&ndZUGx>+gzscr5!s(&c8@FA|6_^NPi5Y1 zbmu&19c1hfzAeexUrT8C3i$=|dygSbhkqru3 zu~Oy=Z(NCv@$F(*8;DLte&!__>^ZejNN1Bg1z%xa-D`;8*a&n&fEsQpOtK z(ZKFDX#dLMA^MPKU3c?PF}jxi?hzgu0}dR0<%~ftviZl!mvP1*KFLq;zoGZ$6&myy zgYa%khgf+or$K{o@x}QyO685cN;QXG_MT8v)QJ#$&;|`f4j#asXgT8EfrGKfJbY^; z^E|b*4gcKHru?^kb^lZU6Dzq({B7p^@wfM=x*6sb zUd#Sgy&KD$fcpQ`ueil{jU)tJg9~ zjOLTr-C}f+ZFlz!WOswBKDOQc`0!hH*MfZjyZbrlHIUuCm9pM;H*?F$?e60jciY|9 ze=xA!ouAad-OYqo2eP|Gz|)`IEk~Bng?)I={J_u%^{wY&P+ zk7;+eHvQ}EZZ~iCwY!vc+m%mhcOQW_ZM&=c+K=7U_r>mh@RcsR+jZ|0?CwY7=hW?P zU;K32-5&Vq&+eYZJlChSyI->T=hN8T^P#~<+1*WIpJc3sy-IrLliA(b;`e?+yL0i^2-!;&j&|B|)x;dfk$WniELe}>@Mv&JvlKifo-}N|3T<#EKbJ-tWa`WT$BKhcB zKiHLM5|i7LVazn=vcHChagg>ku@4gGjF6`mpL-r$O+KHI(J66-&BgA$mte~Vil^1t z@id7wNGvT|;-dZJy@}u7KwHGpwpw#I7fGz;y{m@05K%*)M4K*NFRE#J->S(YskMaFjWux7e?=Em2~A zR(z{ByzT+vy~u*63*HMYcwBQw71!FUNz*|pWCH8j*@Ct73IUm~xJhJwc zkCa+#US*7!D*F)?Tl*2w$9)sK*QUw(O1-Bgd&TKJEh|{x$r=**&eeXy+LuH2E!jux z<9h6*_?rXub2l-o{^|0s>F0TNKQEx4*}(0Ji!(^>r~?0Ytt7{Q7@eGZ?A+1FYQ3+u zj^oPr-R6qUvuRa$5I-MZzN+2!;nhs@nps-k=p2J9DQnBI*H{ztlRZk_|HlxSlP0z+ z`H%c5fp`E}SQ`?dQ& zT6VvP?HWLKxAFyFv!dYSvgvt+bQWt=O|SgIFN-B?cJDw_||JWp+$U493Xw zAof?=ls(DbV{E9s|K_mZ!BxuIe{&{rt*4WM9nU5QKa1`>__`-J8$0En!TpJYXlJmV z_mAAcp5Dx_23gA_@xsmYY4PO3uD$mz1ow}Lzp-$p*%miPTZH`$@!Y{Lql<_$%ejmX z)=%#hmpcWR>(1{5GxJM_nCBC?ThHqsZkZPg@$D{wy^Ui$?9+kWbx7Npt*UIM`TRwe zUt9QLEbp7xnZ-lBQQ@r=;z|*6NFoONBKZw7l1V&1N5}JO^K{g6KPilS%QHL-e}uk>ev0Sq-Il-H zgST^tQ+@#5yLg&DhUsI3K91FBqT=3oV<<|Ya9$KB!9@kfvk1x#=+b0R@qqZ ziJB|D&6}=N`nzjha&ef`Tw0z*3^Gm@vxpnV!&{lrR~B2@zg+Y3u9>V2iC>?e5{%4O z(Z3$-<>yyedzGlsz%2aD`kl#{&OFM{pm!v5Kz=<3R6A+&WNQw{<{do;1b+zM#Ds6) zs}6V}@=TJsRj0~lorGob*fhXSExt6)!HC8*X z;(Oz#r7`AX|DBm;Rh*t$$UA({uJt~0Nm#Qe=aP#aX3bFq-QN9e^=^7HhN<<~^bFhd z^vIkZ^z5L2@6ex)X$i9as8-e=g>4#lKtstd36Dh9)1f(h-RAe0Nxfvr9((qXrM_cN z_P2&VyuEpnzB_9X<$Iu-U)Zmwi(hzOJim;FU%3oitZ#2pbUJE;9Bwv_#Q#Egu&+oBJ_;0_({K zvqozOW0Rqb>4&j)>onGr4`&DMD9AUuqDYi>n-+u3DSQ1G;Goo zm!)qCrlt{6%^wbveZ{RPT(+LfWus0t!r}GS%JL3H($?4R-YZ(6nSt5RD?a8$p z_`q%i_Vyv#CJuKEIIGM=lB!Pj`4o` znlCPYdYP>4*JUoXbO>b)JYV-snIBGTyspTQwR+LHtmAHRx6BIV_-2LB*V5m}gXj)# zVZLXKx;o_y=Cs&TCilF@$Kuy5O&C-Bm2!C7Gp8`WL8%#1|G%aF9CBBW$F_wGxA|wT z$IkUOw{b2oCX;JZYK*yKU-G80p`4akEpFee&A=k#)o0jG;Z5ORdylX>+LoL%$=8zD z%A3StG%k~@?^HC9?y#Qx1apnPxbyR z-Yl{T4>}urU3&_P)$j6n)$>&+icm?}AB>Qx$?q!S;w&M%v?cMCr z5wEvjM;M+LohtYjy)^;d=-|Z_iIrRqopv6ubx`O6 z^E3I@*k&jBep!y5vE~fXGn2J0X}Gy7cB%D?rGu=p&6G)gjEr4`SM?Z%cV9l$!bymI ziMsB?XaB{u@XYtnB_q&7C!JF?PS?3SACSv~T@UWZZxh|pmad}x=@fFuw=UnObI0`_ zZDsZNPsoSXDSzSn9UboIJo0DaV}_B{nUbSTUdL!+(aC1M;EVho_267`zuBLxqe#aZ zg>NL!O!Iatyvj>dq?`ffY)+t2=lZ@Z&iI)nG@2R6|eYwuTq!|1nTv|B(s9}H4a87Ip7EAijt zp2)5r97oczmwuO-RR|xj-_lnLjX;<@_TAsY|6%WvP^NEIe>fC9%zf6hU1*MUp<9Hf zu60KbRk(HTqwITCnW*yay{0v|;(fL4zJ-OsBflRUJi32KF!p71ZL7*=%oexI8BJ?Q& zUbE&g9)JcB`VxV+BRd#x!Pi0PCHs*?mT)hJ@g+PHoezB$2#w?&5boC!J1;xc@NpOyxI8~f)|FR0mK7txY@Ob?EV9_EQcidOt z;N9iG!?$mox*`wvlB1pX-)h@o;C_@G?fY+K56w3R2Rq;H=KoZO|KaN$@(uXEsFI`e zGlQM8{&8`Tbv2;5qC+B~9V6WHKm_AIgG z79P<&0em92QOVOnW<_3)*m4&}?sy+QV>e$HTlqqL`MQ2^Fapm_?akNV(;17)w<0wU z3jZyM=Re80>*l`%_)p|`M zs_tHmvp#aV`%+6zbFc2(AO9C@Jhv5SJ=-OxPlK;5$k#LO=!cPBvYInW_o?nm;$|YN zJnP8n;#X{01>X^H9RdEVpCGH~?M7ttvhvTGLL&yE+TNrx)@w&M#n4Ud(4rk)ZAYft zAG7N-=4*da%F@jC)ja11u66t-4%cxF(WhCT2cORrMZ?fGI~nRa{8jKdOYq59H$2~H4nM*k&E!gEGLCmKo(n%&7>#U_ zd)8j@;!lLRmY9);F;YA6l<+ey@d^6SpmG#6U>~%a&-A6i{wX#MTo;)c!q-k7<7>#{ z>+t38UD0nt1Mz9P^d;Zq(PJ{+8Jc9%f#*l@eDjU1!TVlN+g`Y)Fc^K)6+QYFSM=Ch zuIS7}-Mz z8#qM1Zy0@RG;zo6)SE)RsnnZBy%}!(-Nf)k*ez)DMzu{FKeS=SdYfa#5VO6*9o+(N-$5L*<6Z9Ur|b~NX*~ad{T%wH z{TTQB>=7R0m@}MjX&IJGu-`&^vJri!c)0n_Addba<~zfTX!}Th@N#>)LEO%;=q7%4 zCfA~$a|~i$MzmuJ*W!Qd0H4yAR(JHs%bX({YH`aftqW%%Bfl?+P63^{`_x68Jm5BU)_y~33y`%8n@l8E>Z#;D?7ygTQF9u%@#Cyn& z@ZOK$*@xi0ci_Etc&{Da(|ifqI(hb(H|dk)|F1+4>XJ@An53g56dvzXh``jJ>h zWkO#a*y`9-o)Q11%MJ-o!_N`;`G#;WI|L6qIiwB&E&C~cYx{hj$0laU`iBZf|4h|7X$o@Q@zww~6n@k;6rR*JS8OP} zsdWiF-T{w?;c=}We$X;2D;wQ#IkdbW|bjJRI{>G<#T;kq5 zW5r@K8dn}n3jD#*WB4ZVdTc^gx4$F2nL*#Op0jlrbsfJl*Wb&pgdSoi%bvApp~rss zGU6*czKq1JWt=6xjKC@5POX=rgRU>}Yv`cIme3&z9U{=74Se4~ZikGeJpITtF1fwQomJew)T? zdgGt=i!XYqUh^@J`GfC*UzcCUZ)%nILh~2X?fJeZVtFIjm%Z>|yR7a)bGuzuwKvqk$1<-<8g2!vi6*BV0qFqW6P9<7jGZAQYn^9 zeUv=?;GOPyBpJWSch75N{iNaPSa>Vv_FR%Dr+Y4`jxp?q_!EmM8^c`E{mdnOKwQ@0 zp-K4DgW;i-3n?Q$Ep_9|i3gYD=IkCjsnB-~afsU`P8>oHy5l9K z#LPp>}!sTd}<7;7wWYpr0+f z$V`rVHoGI1x0*E%x#A-;KalHE`9EMxv3e+LG?)vQxSi-VSGM*2t`z1(LKo5BmoI4! z=Oi`@4cd^&ZFeC@*A_)9%bB|uS`&{DxePIGDTbbzfrNZHAIG^zF>fmC`p+&5%39S| zMynDTpUS*#=q=hIwx%Sm#=XqhM&Kvlv%E<2=hZTAyAYWwBkuUt66WJ>qFGQBU6q1_SaQ2a}X;J;q z{MPE>fl+CN`rJj|74bN09(H774m|f1YuBXSAF1b|UikGfle8?;w!>5N&Qv95(`N5? zIlLt?s~WyJCVF-*>&d9sLx$^FPqqTS3GBMad<0x|`5?=|)0dIqRqp7FzxA58_FFRC zBJ0U`M(2=R>+CndGsu1ivj5IT@cpnm+Js(e%ARWFl0bvMLj(Q&=ni-Eplv%OzoO-8 z=8e(s5%hZpdf=T+?x@V=MC!RGV*=>a?IWa_*m=Gejh$aWc`3i;Bg{wz-}L4FB$5ee)QjgF1=&zi~m3H(Jk=U>Lj(ah41LB zPURb}*wgmH_w}9#rlz{k_+Ln5PU2=eBL+VX^EF0 zL&A^lGkw?0SYUmho%>yMPJvE85;(@IrSk6n-s=Ote^6&R^jr=-ArtelBb1i#r#`C)F>x2T6SkU{z>y<;)HtAdMc?WcF z_deOz!k6=D6TZ=N5AefS(F4L4%sp7X+9+%O0e<3}$ENU>_&pMf<-2t{Hm+mc(CpYy z59>xpm}@5X16y@BY~<~JBG?XL`v!y!SbD$)PlOG-!<3Y$bK39=jiE8Zxm#?S_?w{hYR|94u41Q11s-}f2O~>nva=R7M;y^CHv@X zW4Nuei)QuI+0Vk8&%vWFxTCKg=&iG@abwo7Zk@fDeV$cf%dGZ^nZYvILxb43%pb5` zx%M*iOf#|?+4I}_bmzI&ygoAE_?4oQBk-EUgtV;`{rm_yERV4-kmz7^v&5Gp@MPo> z>Y>-gztg;Y9&-{dbngpAS`PO^lLPn)md|JD-qp}izG zW&W0ZkK*TV+jF}6CNy^X7Pj?@<^NiJ6Zv-frhQ?%Z=w%6=$p)yb0pJDd{mM?{DZkOv9<=T#!Z$@6b{3yzPQ(z1@26`+sJkSQ-Lim4@cUAkv zab3P>9qq*XqQ4-9ul)>r?#|QCd@OT!dz`tux#$e$V{0cdmvplESmy2a=zY2Hd!6~% z2}@-z+igzdTNIA}Ch*Aq8_xXjuNEJ^@D;l(tH3x3EbkV|y!JjqPa%^q8)cIz>+xLO zXY_MxD9fQtw^jF9)2SnQPY+Ng-^Ft7#lP=9$|Uc)N16JpZgUA`L!CCurs8wQ((8a# zsdLS8%4C0&9?zAXtDlpyEcQ3C-gA!m-#jO=7P0A@&r-S%&h>Y>KAU#*HFETAt|!D@ ze~WARHkMQ0Sb{}ji2nPBI7#!EV6R#2o-SZ2rNIDtO8Oe z#jZ2XK1!c0cm|ux*k3~CROH(6?JKbvz3pm?Epxwv&xHSP15Uw@j1#|ii3&J-TZ^qP zqfB`6WvR>YCb=f|J^qGq0ipjuYugwP?2+++4?QKZ^1mZTmd}+aF}wU4ORq7u>5c{T z%`ddRNtL_5mmSKn@&U^j|M#~SNqlahe3R;*clN)w?WDOY#i@Ibk+;%m??EGZE8_pi z-iNu2FLUkrEg93t=W|a!QTqEv^rg^6@}cGWcIuX(r(`~?im|B9VdPuklEWx#hxYw- zNT3~GKSgr9rz)LOw)m@-uJzdYU$4sZItOe+R}NS<@g&Is3y)A29G&Xb&-r-nc)i<{ zTriJo^hVDdooiDYKZcb2y_L`>zka&xMYvV=5SMRW=cAuRpGxjtv{o5&-T{*)D|lJ)FmwBecLU@p(rkPk2UX88htSps7z?B%n{ zTt6i>h&|sbW2$!Y4A)N?6s(yznD1dEn&M}NS%(+R;aR_|DOKjBVuO1^gIHN27|hMvYh)%gbkTbTEy*z4(PWW68pdnezohHvPFfl=D3 zS)ig%@U2R0#a3-Ac*lO=lU$F-mZ-ona(Ce29=P-Zi)X0XChy*D`B^=9ItM>%6}Vny zYKHx!g^lt{okvwvE&JPn171^v(SltZuKy?Rs&w0K8Ei|3LayvVrU}YKk~0F zkX(%#^3C>xqXXbx_TP|ixt)j1+$cJMwqK%c$L=3~Y}43EWLjw7LOxo}MAdJu?gj93 zc5!!1rHF42XVH%hci?N0k0893%i6hyX=>YtymKD=Wlf$srw@P0dW-(}YqP*~O8k`+ z{E&VN-?Z8Nyd1yp4)nd21?UqG?^BE=1YV)fmw;KlZ^H~7Qa-D;Weq@wRRWho19-2C z20EuN!Q!(!jNrG0*WtS#+Iu1hp6}$@(HVu!ny?rAIqJL5uX)15K8#M;d?~A)qw_?qd$M+6RHOe}%$fb1u>s#8bm}gpuAEB@>FYnV z&Lw8Xo+f;cME1JMXv|>$vi@YCfq9^K{oXK4k2!kCg28%vjq8d$a}v0f^(?t(+21E& zZ9~n|Dk$&&QCkMzJ#mrOR~YmRv1J0CrssYJD~orQv<6qP&SB<)LfIoNTC>CmKEA-x zOHO|>r0j5#f&SqAHSZ<`AOB0Te&-Xm-WtR+A}bMt`pB84 zA9Hy8C+T)NMVHXOU$K_Zf#c^k9GT=iH?dX=JJ;m%Zz!npZ!9QF6}|INK`bXRe=Kmc zp{s<)WS=d)R~GY9t2$zjS?eScO~)^HbiO>}==`4$Z>d4=dStAC&fon}I-fCu*cwOY zi(e!17?mf;uiKUdS z^)^)C#W;0r0!?%tX6< z=O1HvGZ{m;-ij+P%QH`W)_T4w%=6Y5L+@#XFTS-%ou~ctmDi37j73)Ty_WM#@qwl9 zWilRNUBo_YxwFUNW7Hky)Ga$t>sow%-KLB!Zl&BF2lRPQDP>vqK8ND3%lZj>KiZ2>++2!GN&G|J5R+o zE)RV=-*^T(rvH5(`v2Cf_UqlN$#2_v_F9l(2gSfW6@Lv1tk)eZ(CqEmrK> zd-y7Y^(_g(6Nbwi$$k8neEC-I*NLNKlK*#??2CYJt=PLX^9=UpV?7q%v}PVt={Qa5 z=2>Rgugq6uo|^TC#D=1C;VaMAXPU(vD>7!9KV+==Qr$)7q7nG6+N*fl*jSG9?#Vt3kSD2d{AI6O0xOjo^BineQ)9SC1@Pq&laQfjsJ)F zbWeYL8hKUo>7H!(^!w=GEbY;nO|Y@TsmF$ET+WpZ=@|pYF+qPpvj> zKK;4Hr-?S7ZssUslYaPgYij>|$~Z{#X{{}*TjON4_U%*P(<49b%YT3WXWx6*^uwpw zJ^2(^`{mPGn@{_P^`rTecKhYitu~+5R#>;OjD#`9|((-sVcRdq$<&GvkrAv1y%ejZI4rjZKTc|8?&FgZsm| zzwA%3boO25+rJs;f-&gnv3%D&iFJq`9cP(-F8N*Rz2C_^ew&Q7WliM)wS>4;6MB=M zYRZNej?|NXGDAhPe7g$js;djKe61Y)9AD(PrXcq-#1JZ^oNt&L>$ty@`&9)J&zE(h z*MD_rAk6w=StBI#Gj-K36>P44xu9;{tfso^-JHL|_ix>tzsmV*oVz&x4d=fu;2Vui zD_G-Ix9)+avbBo+zl%5mTXG>sH~Z#zo64(=rW31fq>o=@ZP^Wc7d=U@CyReicopMe zoLGD0IQ_@xt1W6d&6GZW@P%;!Uv*1CRW)>jCVGv@K)A{p-i525 zgAeiR99%81arJj_xRA0J{|NsX20lXfH@YX`BS?OI3|k+Ixq|JC>om{#T}?5@TdDBl zY*%VWA$C>vNoe!87AWRDL;e>F)Nmg;DLc8>Qs8o_rc`({!niXVJPHom45KL<917lL zKc!HG%RI7rC~|f=ym49AceZs*H%FP*+k5)#0^SvWh@~H${~y$IAt!F+M42)FAoc?B zG)}(){)U$Yc7at@tuIhj8ww~F6U3!5Ysek6x^mzRZ)_`YYg#W!`; z!Z*lHwaD3Sjy1aPB5wo9r|?-_wXdMTZ|n`xX41-`fd=E6PT{LM_HwODet`ETG}R@4 zjbkFmRUDDWc5?qFXK&V z<9)sXUwI+&tcdr1&Kq?_R{dW5=M$?6fqPfO8*dFsbIyeqWsEBI8+z6M^;<*qc=TCd zlJ_&B>89}DDN{~vST9bQG1{y+Do zO=tqSp{gVSF##(A5*0{7F{q#-_I3j1pm4Gd|iUlcl5>SkY z2nvXmB({KMt(dT4exJ`NxpU{vq=5T8zd!Di%*-k8`<}O*_q^wvkvUDGuVJzDaO-P| z?&~ns7wXyjnuzbgdY`ofGzx)+`H0;X-jUOY1*m03exLP!aec}vKv&Z+Z{e6#BYsrs z$60~Nuq{}V7>4oi!sBocJhJuzkNw-gBcSlOR^fp-pul4@;()|si~|qqMLQnEJ%ll| zkA0ouPx6Lc=LdEqLFS@ufRH;E9{&C_&=>QdFnG*uOuypy>A0hXyozx+5%6;jShNS2 zO1nhEhpAuJ}uSfWYy;`rH`KmP3*MAdPmfFr$Yy8+CGTBd49?#QzGZ5JdFB`=}m`D--`E* z7slFQ>d-jE2j?uFSlK&)@toA~Z`?Nw`u3_dtV_%NXrov7ztB-3$Rg!G`O9nGPw#5J z&9c<(1%Uqw==$fuyM>6=76MMvs^15l%Sw9%ZuLE8JXeMG$g^f@;BBMW*u;9Lp&rZm z5Z{zGB4XPbFMPe?#Ls9eqTgwoVXv1f+6ja+fhYMeSOWfp9n!QTKJ0&6J@M-m9tE6s zVLfPfD>xm(F#%2wB6dz1_CVV=f`&Jcz7D(iJj$@o73lMd6LOlaaL{4f*4F9JBZdyr zR(2Nn%m3Z*j#GH=RPsR>?g0!zz;LO8`*VCd6EK@aCvqK4*zRhq#~B#g?A~0r$Julk zFFQ_Vd`?q3?6&mnOfkj{pUSb)w%dpGUg)G{Mt5n)YCr87AdDv3qu!-%hkja)HLS|G z9>|?Sd85d%IM4Q(sxJDW4cw&a+F@Yd-~E7fKJZLH*x*88gVART&wu(2zIV%QG=1`0 zwe6dR^Di5_#rPYX*JyoZ*Pr&b*Q&O?zMs6Yo8XIELEq-d{mcHq&rQC1fgUD&Tdr>w zf$k~gIZDn_TI4JhV{!LF%2}$AGn`Aitmdn0-uHFw1sTI#SHgdamV+BWGcVcD{QiRA z_tfxpX!}>i?^`iu&bDWZu?>XJ0xs);hpV3z6#IJx|K!qF%JW(2ye@`=;mn2b8~i9+zLYSgo=zNj4m5d=^N|qxB;DyR6hoiY;kg91lJD$&40P#(>tn0~ zUTUe+SI{>#Y`FBxJ|BV4Nn85p5k^_z)`^w(0Iz#9r0=+Ox?wGc{vw^KmG4*uI#X`q zG@X=Q)-(#^1K^o8~F+e3jfU>hgap90|*QT9;qo>K=Llms4wjMMh9kB0w9onV(sH@V-s zvqy~FlRxeC?Dlir&K|;kb|DOeInS`h9Vd1FU4SjoMJ`g6Y_EcB=OBK>dPdN&hG87< zelMr83@~458%NFo+{V!Yy~yt)P`)BDRruA!Rmy#Y);GD(Uh3#T_(;%~b^Z!i-SiO4 zC4<&;z$?^88s@@}CRW~yeitY>e*?d5RdCiReydgd_E!bx7VvfiPRVOQd<(%|3i;22 zO#XWP`z7GfbMT%v(diqcw84WXp`M+moVsqjphdJ!bhDAih;{?8M&1KVkBT{9 zAlwh%?l>t{Cy-{eo6s{t?-gJ!5v=DrPh?E??_~rEJ1PAJxo?ktO9f0qzk#kozoDL% zU5BUc$gvVx>GLcBQU7jI&>izrEZOqFx|;ht?6$YsKUxz|ceS z(oOjG-xED}32BP?ikH%H&T4RRyfxQ{`ip%c?hr~0(3T?q$=#OTg#J6q7uTRpYqs=q ze5WlHa%;1te`8-5$7SH9(2(}=^@X~x!HNe_&(7C&9-QXFgBt&ln!cdR1n4aNo_6hU ze0v1+jp0YTe*#@h|71yO#6RJjkosTX33<~#!!Y6xnGx^dXXy8bD7rL|KW%i;JUYn1 zE84e6BJ2)+eKJk*>q+ES@Vaw;u<`xY`864^*!fVy5a)n__QziCzaOz4?mB>O({^{L z(tUpcO#JpSzMbqs&+8S;)Rk9U9}Dv%ZNU7A=-WQGlQOpTBkCTTY&&4ypkQ8ZgLxQX z1`MMV%unN624F^N#$IXi z>{`xoDf6Y^cj%jCW>*=jBX79PC1wlQV{IvYS@x5Lezs*`PtAPU*J}6$?1TO>=h45Z zzG@&V&c4nOc&CPQf!p#{a1--JoI{?AzV2R}8#PA?;$5#Q*qFN`u?X_6(`-yqh+$sBId)bHP4?AujenOqr?88occe4*)u&)l< zhYxgL?XVB)KaBNJ>@-;7Vq*jF$2a5rQqpk*{E2%?I`u8hzoUzH;Fh zI*&4Fh-a+UwF!Z2s_2s@7{_m^@f2pPK#_zfdeSI15{(KVRIlz_vm(Y1> zhIRh_*sC)rR^N5O8Z3RKvACn{K)rOw>`5kW_FvRb@xSLe7yDed7@q*JdU;n zxDkc}0YeZltQBj7f$(wo_AGF5%E8{u#dBQv#ceJ=QoxlOK7er9>@?{4Vhz`im~)0P zr+?c3-I;<|)${lpK>Vr{yuq<1J#=h<{%a&QAn9>{gEj`nN7L=bp;%K_W1kNG!x%5i zz}f`c+)vSL7xaf6Ht1i$)1CXvIi9bZj+e^*e2)G|Z!u=7T+=q`2h=*+HOunE-AYB! zuZ#oo9ti5al=6VZHca@mHf1`3>-bmm}kzQYH7S_WL1Gl+DE2mR)`pf%hZw zBkP^BzFVLH_)<=3r%fOHFW_jer|0G;ukVIwvk@2!KC##7+*i`#N#Ha9-|X~ayFQE` z=ec7I^P5G0**-_PwT}@X-Gk8OoOe72`V_$T6YqM-cTe#h{66t6L%w^0?}n&33v{1- z&QiY3;n&!BOTYvAinic;vR)b5;@R-K3zI>&Jj5^o5BfHfrQMQtTGH!gXWPJ!b!v!% zqt5kcm*e#p=UD%V{QVaPJcf?IA{B5^mbDxgpxm7LfOW;gc}>I7cOm)?iN1dk zeTUFD&icR+i_v|DMBk!JY~P?uI{FTkxMY= zznO!aT;zcpps|o$=-y2c*uPR?$0Vp4*;vr|)*gwjbf~l<=4e>@CHZ ze3#$9tN>$zzK;%J&kA#dX-5Y%<@{6tc({k)v$OgIaDUDwox_8iucnX2$+-z~#+nE# zzFQT4BpuEDuV$K&&3YSA?|(JcTeo_T_05Pidih2*Tjf|k1HAuNuszcXY}aCsj~8r< z6l|rjunF5xi}9c>@If9;_>)=(*Wtb97tRUv|KS6rEORa4b)0KhT9VsX^GCGa%2j?< z(e#LK8NaSufc(z#^e5~*s(FazcfZB8%arhWfOq4>{~bNgZH1osM|zL-WJS;6vGk1g z(Lqb$qr*2BK04N-OJU=n!EQBTkYUAP5z7!8yA@5=EmAN$Z5XL@Z<^8)Tk3&9Vje?A9( z@ErUt#QZ%%XRK?gbyDz{nhT|dKLISEKaR&)&hSzF`Aysl%W|Q_{H9U|Zwk5al}sfp zLBDyc-F|<$nR+y`-a4eJQYPk=b`G*yd3;BLrWza9fNdY)}>%cp$G zEog^6?PP_!iT?!+Jm6$3$3iTEeUC=pI(|hM;sVmAd;@Zl?M9Qd@!82;jZ??MKg)nU zWSz4hmxUWnuA~f6HxPH~ie$o%bL&{=x~2ioRXF%}ciC4ul$o2g4v!gm7?d%eqf?>pY#j`u#`=egDnTQt^Z z{FsRxS#vbzYd`)IzNdL>`ay;@s87yr>RFz#lIAnt=3M_y^jEl8<_7%=JUHK20lr{P z(D6?&f2Ws-#nYEqgjhv7bBHlMj3pGK?ys1)kbcxq00RMy+ZoaR{X<37xw!Q^i8lnt|caT%>h#0`0lC$r2PB}-n!VOF6b)e zHq3X2Y>0T}BFu9*FSHO72y!Fx^dN&3ew>4n zm@CVGx0wH{;cNFnb z?`Gj0Y4sxTJrwU<{g&Fi>;YNE>@~o-V5W+rO_#jC`hCXHeAWX!*iK6L6u?N0VeHQJooKNMVK85EwQ>F-=6cYMI`Z?4$ zbuIcPI&QI0;2rI&*!8b&`yRBd=j)<9z$o=sYWNNX#~kWT(8$hTeK`ieZ5Q@j1QVxJ z4%;pHY!=FXhI!qm_&IG5*F*0)r(ap2KeutN-`Dtyz$Fkq_jK%=CcdVOCI27#4Ry+apijYj*Xqy1uA`(1b8ykEdH68MCH zOC^5b_YUWij>b69Pjus@)Q$O-9DDni7Gq2SM~m-zs2GEk@Znf@3r_c2hvF}J%Qr~J z-6Lb1fxhhiDBIEgXn)nt0jSTp{~V4F#?;j6b_J>W>@Vt{rWBRz-Z_-VN( z&AE0!7<%n&|9Zd~YumpbaN=6I9*_apwOyuflawOI=n3G}AK%=@-t2N>V*|#=&ff)! z|B}DzF7(K2$oHoocF!HhH!>!>0&&rbl1NOp0&&q*h>Nb$aZxp|si?P=LF^Lugfy)} ztdM-xvd#$F+50B#WDGD6e(T;PeT0&s9I*Sb8(tEOrvMg8S`P_$d`vz8*)oc*^3 z^S>3$w??KQgt7C!u#o2Emg7d}G_R zS!wuQM%Zk+CI$Y5nTGQZWgPuZdmMcc^m7pSYMJeHTE9T2G5yPe%`#pd$}qB-J7aGT zwm3RQxesx`&YPljgkhWaB%@z+Oq2p8-Cg9eDxp9)j_4)mt91%Of_r$Ed2IoAx$#xdikJ{iI@-yN-{rypWt!8;^j*dmId$1 znB@%6^aIrC2u;K9xYP7+`#{sP{sfv%?*L7Y^Pp*}qUooYOEKnkCusApcG5IY(X<AlPt6PFyf?nhx!5{^lf%dDB=r$}+9+CJ z&adZQub`f`C0$TX$V@A6ty6Gq{}D1be|+V+yJVaX_Y^@l1;Q3+nt(Bn$4}4!K4mUw zO5Eua7E!0_eUHt}-uoW0j%UCoFm87@=-VOW+spRKD}~ux%>$m$AUBSjTT#g)F<+jM7)(3B`yHCPbDlkk6|U|Z-l87b4=2E1n6Cf@)fKTEob7MbMhPa z{V&6q7v;rSm;c;5dfz|Bqtp){UhVrYgdLv-KObi>-Bs!jiM^!NC?n@zk=Vxj_1$CE z?L(;RrE6)o*4E41OcO9)2YB7al)0&e=zk7k4fLVlpDZJuoL4MT@rT8o3gm*aBQ71A;v568B1Y2#zvzL(MF5T&%?O`oz^3cP5PVz`UF9rXVv=2 zGQgS%*bc^TuorK5=&&IkKJ174Aa73q59)|g^2k><9k#O-9hMiZ!=78;ejRoz`g7A^ zM+*A&vJOEWA9dLF(TM-!Cv9;nIt;K_>!l7mAGFy{_-2hN(~aJ$aowO>sW_Uek2X`hB;xNgbeR9r|84F*KbQc zeV+2)L7EQr;M3VS=VovDw1PApIZn#{G2&4Z>7kWZ)g zwGLG@tv#-P*>?Pd>;o20J_RgyDVkmYn!d+6HoscT-w%CG!MM!W=mG%uBN@E=_=s3ulD(^b?ukYM?7eHh_cV)6-|FT z7W{@^d+c+iqUjvabO-A>&P=78dd)Fjsd1<2L;Jv|v;G8{7IuK9Q#@$;3*tq=)xE6$ zz-J_%E(UEDwUegP6iw4W)3OfI^gcKH?Dtu};fyxHrx}>fb6!7K`Se5D_UThe)1QER$?X@*Xu?7t1U zAKO8i_VnP>zwJYOp$a(es~@@Ut@g|QqaHLpTIkb&H9^s|@tFQ)zu_ljzYRY!tY~^A zXu1=1IwJeud)TM~to`q;KD~rA-AA8iP6uduvIk8ElTYFE{D2rCW&aV-X0fJe8$QqJ zil*tH={+tq#a_N;d$Zqo&^pHGqhke5DH%O^1M{4|kBJv)yP4 zyYAEe=U&+L0i@|Z+V!js&@|42rq7e6u>A{LedV{^wn-_@5=b(>Y@A=5~OlXM51}7y3&6{jJ@| zP5^>Hw&R-1yM)SW(N6&rS!2b8x{T-xfOJ1R>!*&F%J#en@b1%4Ios3vhPn4Yi zI*(W5LmE^8$CZ$8;{W;0+@sQ4o~exU~*xoc4#XGupLJ%%QSL%x1u;lNsoIv@-{;yCx~$`$Nys7LC4!T?ulo~abL%L z&qSH;nV75c$Z&oRXfQX?2inU0-Hb6Y9;Kg;#(s$4;za9oj>-H^a!gP^6ML(FQhP;O z=&!!F(7%noaR;X8oA_P^d_O)ET>+b%;Q(y1B4!H>Q-&Y;-_qFZU%lYWfO)q~= zy$l_)qr2204}mrh;@2J>G6nXEH0=kP-r+@4BQHA?AARnJFPVHaMd}ael1%E4k_0Px zC-^8Mw@K{l8=TuTeMl~NDOvGSUUp^@%%ORJ^|4kd&Sr#Mq_*Qs<;JyfS+2xBxzjV<37 zVvf!JIEIx{*Lg1QHTWjZx8#^( zZ#wz;-#d zhhl6OjdaobK@Yv3H_4&*eby|F>-0bO-bsAXH}U-ueE%0Wd^=$0K5B)JLn2?=XANw_&h=Mz?p5OZ zC)>Gro1I$@e6!r}Ezfhe>;B2n@BS7w6pgE#L#6ggVRJ zuBQ;+k|b*b@lBLx-G@-$b$r$L$oRJ2_wO8E^v&_T8u)%UV&C}rjdt+!6K(J_&Ri1w zd`jm(pPx%r-^6z`@O=*Wy6wv~)4F4vs#@Kf`_NT#Z|;viE_vRk>19I}=@9LZr z+JvuFx!xky6$l@I{w)`J51O1@c5y~dWis?-4Rm-R&Ys7?@FK_X>>bfLhR79)$}tSl zzlTk?ubVEyJi(b`_|mrSfd-z*kG4hrB7E#T*S7Oo@)y~5KIQ}Vw%yib(_V}{M}l>0 zfRDXyt_`k~7rT}9f_V`YI0jzKO*Fh00bb@Ye>J>6=2voT z?0u3xdR+dvsi&~XAFHyY$H(A%j>T`{Z)*5LjK%x-9y4F6g3VI%CB($V`F6Qtz9jW( z75*1~E^OV`)H9uwpW6+7Zcq5R$lVotrJb<3vG$g zt*CF;tr5Rbem6l2!K3Zy->>>79nyjKJ;2+^gRRA~?_c9SZ#wZmdp~dL^*a2irQko# zk5|Cw)92#6gq&c9d~1FRu1<)Gy`-&a|Ga7U8uxkACdOX!608TYACs|{DWJ_{@&$Pe zu)z0?l7B5jgv9_|NYnL@>6{MIG^N^|rn``zvA63~)xdFIY5Ml+_S5t+51L-5XgX2R zwCO0!Kk#c0O`lvXX?hiC`VH&Y;u&U@Jo6z4olSl%`aGwWF)A^vdpF5@ zQoP2II$`}*_gtEXzjV)~p-o`Dd%u)pRjqJ~oNMO|&*gxJb>qePDX{;*^EuRi)`6?Q z?{(a#06We74ZHa_FVQ;wHS80}NU{#P5V^SU zr@I0^4ab1z;fS&DsDHSse+cSRCT>>vX`Q3}3Bt8m!IjRw>JzP-a8C{UJPSS!Wg`Lj zU5)zx!0#&jT=mXg+y#*b_z2H9d@621?vs&gY&mgVrd!%hSxxcW?V!t(z zbGHq)yk*3`Ugn;X)rnRBdAOu`A!6QF?Cx0J@+WAYc6PD#j9iK@ZqB(&iK9 zZ-X9>lGdQZFwh|gI+Q}rImWjECIc`u55xUm_}OKaeEiwRiJ*V9k5C=uBS`+dWQDuW zX1DWNwn@_qSI9HH{)YZ*UHau-6T5$N;{&n&)ZX|vZm`$gNZ%$hcM|gDz}XJ_mK%A_ z0puUBKj(nmWbPmQRMM_xZ_jGOy7sGRzngHB`Xjz^d-wL7?Lp_(bmU2j);$34jShGT zCtw!m@yvkFREStyX=09;Z}Lp=qUqQVhy6Xo*Qd^v=>^{7Sv!moPDeb3XYB~TDRG=U zLm&h1pkFjigE&LLer|(qC*GqSeHK>;?TJ2Adm4`I;MddK@W`2%ov-d4SOoeqKYvsl z=YWYKrlH}{aqmk%XY3?j!aM~qmqed?Aou{^1q|vtVc@w|N3nm{+jEm z!DraV(!lqO`#J7mF078;W9p>6FH`M>IZW<_38B4$k?P$s^4$!+%TwoDOqB05{^zyP zzG=jc?HZh)WjY*XW{<>NH?NL))4=Wfl!xaYZyyUV&8<>L|!uWFm{{s{hb^C5T# zU3>Qu{Z<8=5Bqkyh>ycIC&lIxeP88mo4;1|ncK!QKynqF!p^IpKRP|RwwWbBm}=5F2PX*r;q+gZKdd?`$;fX!ce5jxp{` z|Ke!tbDZVIJ{DvD>y{HRUa(Ewj@)1H(FwiF zeo6Y<-?jdFQNyI#CSQzogULmsk;M0_P&B#o&!9+*1j~Zv=_wT z$5qhdkVWE8TfukV;vMg@XY7-?&0FA?UD+?E={KB1Svx=HccV1zFw>a%aGz@5UDR1- zlCi0eug@*Gt8~*G$ZaFzfwpp6{qdVv_8&O6(u}M6$n1e1?uazIUVB%K-+bHWyP&ad z5BA0vU(m?@*Q5V$AZz;m=p6W0%!#nyAHB!1zO-r;ZJNuPlT8MMkLhuj33=JT9+z**L%&`p&X z1KMnkIr)e@0Nd2^%(LpiKQVXC6balTez*_y>^Y$vTbUD@5}pIvQWnnxEN$xO=~90t zOx`OUz0pihY+XkiVehL89X@4cOGy87NX2|F=a>g3Cza~8Y!7KxLkPEy~sPM${Iqn%J~lMg-u zOm4mfWu*dqWA`h+dQJM3;yrYQ_A6`gz5wz`K4abwW%y&fD?DRD<>{dPy(Q{C<9eUC z&$t}&T#sOq|CpI@-?_yt^sFcR6!PW+i&4Lb7(@)Lp3O$Tz9p)e_oz(TaEA7 zOC(~JLFi>&&z^_y!fUbl+Ftt6435hVskso~n-=uPSqO$=EjG?|O`Ci(jJ_*iNJbvO z0AKPq2KXrqRqpt-o2(I;{seXq`q{&sX!43qWh|j2#XyI`>399Y1x0 zZxP@N0=}zBFSIZG4As7-*G|av1)$UU_!0lF9QK7e=IKFwB>p$Ru0h{Xw(UNNUPl`G zGGav-=a}!xXPNdY;`h*%v~|1}K=5w{WDe^XS}&%7r}Y2AheH2$U*>Z9c4&ij*+wa4 z0Bz{C5c2SH;E?4x_TwF6A8)NktZwewc-OH%k+cIp>Tzf8ChuF%N8V{6=CUG>3NqN9 zJgUcERe4l4{ z^QD+OV0J~_zQ&K{h=mXEd@0N+rX{1jv1l(2d4fF0uMT~rpv}ACqia7h1e#Ny5N7&} zi(pH%kMjj+G!|{rMj7yFbpPYxjX*Nm$wZ$!0T<5P{?P;;?4t|%5d8wDc;Jx^*mOP0 zIAJ8N0{}nQsrbyl2ZR2lxO0oJFZ!MLU`ih~4Bu_Q0mhH?0|tOz#MQ`&z%n%f=a{1o z{W$yk5vCEKk31IN47A5@JcpzKIwrYm?x?I!akoIKF*|F-!hTr?7(G#LHs=nNyPHS& zaHed*Zp<-oHveMKzz6!*HQ^cWAI3A!5!UeiC(+w~e(V(~tG7Wv*?E9^))!Dd5PTty z?E@%VK-~tL!@CH1_CM{F?uWDs!mqLO!R@bf4S4z{uzOLy3GCkO@D-)qi?;1-n>^4N zvd$dEhNRr3tNi9Sgyqqm`MZljb2r;}$nw^0-(M8|KILZ=;5pXzMZ*$=O<-Q+y|5b# zFdw2$`VDgn`VjQ5oq3Tbp-twyy5%HJV1LjPnHWp@5;~`GEZ(n29XEew6uxP_sO{_y z(1X4j{eUUZleDu7ktgA0XS-v(Z#blX**yG6?=FtU__E~L?a*7U{uJ)z$hZ5vtK)dbblKd&?l$#Gl~>~Qr(OjencFZ~iyXwq1p`^_|{33nO=%uzk|S+5S)g ze`>fV;GYkAy2_2qJS2;9<1r7Zz!}C`|JeC*0_6t!$0;{&J>R`JrXglJuZoU%_4-<&%$!PS31*G4mO z{yN6-P|~X;mR|pCgI+6ur`^w9N_r)pD)r1=oFli-&wdp3c%~(JSdXWMEs?YWY{*>` zZ3`b;wXJ=~e}XnY4(VU^1AfH&YCPM0i6ZDv>X`uiu|n8P_AwE->3Ar4IRw77$3y1| z+_0{r?6TG$SHBc1vusb7o2_Va7GQ9bQ^H|ps#p+w724Z8_%<_8kNZ)|*Z9SmuaqIi zkCVINPMv=yKSVNuR0hX(vH^M>oi+{0gVVPmf}>HF6rwoIGPI4^9` zGOZIiUT*v3#tFRK<(+5Hy1_G&FhkcpvAuag0ONNj=&$ud8sOTN;j?PyOW0N;7Dbpi zX1n70gnv`8v0W!@X@Z8S;Uv)TTD0lP_bxW}K=QqZjr}*yD%QMZ*A*kl`z|*2wWY1= zir-$0=KY`Xyf-%XOVn#kS9Bx)1HO|0zn6`D6*}Tb(CG;BKk$DM&vyP7JZHPV_#B?w z3_k!ieA#P_Xty4B0;&0D3FbkZbN_;G1VeEDf~UP&=z z%AQxkI^;upoTM6MoNG6yZHPVxt6(PP0RM$=I$iqp_oM%9;2q%~0Eb$@aXWBGRr-Vd zFz?0QPch~_x}Re=bQd|mUuN;nlR#MN95bx(D@OZzZya+TrZ5)`^tcRjee%zE#70P$ zAZWZ9Z8+)dQ)^#(J?K)j=Ufj8@g3w6G-`?O&fq)f1MzN%#PtHc8>Vss)Eb%ALubC| z&_lL3IOoq5pf$(+lP6{FqMaUYbU*mb=zEAr7t+#R53se+u|Mw9BOML|9qw|_!8{`8 z#pIm(r%t-!iOVr3xP)^?p??R-GkJ0Dw#fO?G#>;!g>2q7A?mE_MXEoI^A+o(dBbh| zdZ4Y)9ntOB;hw%;o|#5laghUV!e|(N>z4Nt!Q=T+u;@0JC-}gUZsHuzYv7y6dj?Nz z3<H$T8w$G4z?h>IXbf?R`XHIQw_EofU9-}n}M#8^l<hSKLPBh=$cz`5 zE7B{x3u6?07IkX)JV!fcIog>fo_mFl1>K$c$m@Kwg{Xa~d89LH-X6P|_ zp87htx<|`=>Xent^^UBS3cU=U;5+DK=Ahr2Dfuph_NbHW`Xn9WN4?DU#sD6!2hLUH zgLyryH^sad`M<#HYQDGWIBCTTk1z54iR9z-@)XZCX2VOH#Py+i<&6 z;kE(tk%#xLd$%AbjCC?58JgbqKCU4+TRE6vSYvRWg?V|=RMJ0~kz(D?+~dU7?`Q0f zx|H$5S$B5PRC#x>^apuI<3sgQ59#{tOP8x5( z)|++mx>=>DL;G?7T;qE)-{r zMD(W*cUm$|uFIXtd^EsGUwb!lk4?Z=f3V_F)oze|q0UKYi!lBLFn)+Ku&deFnRDvJ z)LXa@5_+qjiMS~A!tAF|CzG(^|62Ud^9cas>>~WnvoY%M_e0z#M%_alp>@w+R?6HM z6KhE(eJ>b2%4e}pp& zf`G3C@Uwj}PgL#edE(FDvA<#*XW~cv|KrAU9_KY*yh7@f4{*MAXo%96huQQc^h~}( zzmaE!ek+OS%Xo~H=0(~TtuL$5F6DKs=0&tu;b^Z#U!uLApyQ}7k5c7>{vOt~Vs4N8 zU*L5p-#g{W12^9?iCg(T;`YvRcie7KxS8$5?PZ1A?}MdW61VXRw-VsC3-4WdowAdj zU0{Abw&Lu0P984w8;k)K#_GOoMJ6tyat|0Q;2jg5j z>Y;I{yArssAYGhei}jaMz$oLN>VEik-a&ey%eb|5zvxtqk?{Wk(_Jp`(8mKVEk4*# z;P0FV4dy$?JSd&-2CF&Gkm$9XeuCB!U&D&n;YMaxe0w< z`xyWCSs62?AMKu#lp6kdxoq=?XZw`-QI2CQd}dqQ*QvI@Mj6uXUC6^Y2koH$|Fk>L zHY|^xBN}NDyLb>{?C!XvgsXrH;d=t`37c1GoH_~drvW2uHZR?n-4(V8{}vdV+P=pDA9dgm#`|sj902cZhV0OO75RPEh7Y4-3v8>@ zk3AV3ypQIwRY@_rm-0uu>m`Httx6KKxCpe^c96T?N!>WP%`+!25j0H+pN81WoDChj z3;8@Tj*+;twj0zj#Wo!?RgGIVV09nc)bJz)$B}@8dFPJ+Ct-t-ztC-))H7MA|8Ksx zjft2W2Mucp?sOu}=zl@JWBe~|+xGlN`dPXx`GE598}@&Zx4NT`8_sp0LA-P3?W z^Elt8U1$2S9utTB{P@Z}@Rx<}1wJ;BUoeUOBIw0=F6O6VPAl%(#9sY-kh@Th`O?AQ zapIj1IWrCO7S2~mU*3_c`Mk_$jw~-(a~$thuYitZetrmTR~%?GHN;^|kWV1#Y*WGE;Ft65jZ_l;k0rNPlCFNBD2kY)9x&?Tr(yz3Guyw2-f(|FH^r6UaK77+Q z%~^lxGU}V?Hp#0Tcjx<*UnPHtHf=n-NYFMAE~Q=sJqSZ<@;UPfxqt6El>cE+G|y6Z zCEsYA+Nl^h9`L~@9l7vLJr#1eIj8a-^m!%bZk+pV#k>i5=_1dd8ZrH1<$7Q7O97COzLZzk`QKAT-PQ};*sSNZ~To{#lA$v5_TlqFs7 z;^(FB@*l|V3@6VNAr}k0!toY54>Fts8TbO{+Ht>6GS99-K0Eb}y?qTA=ihovkAE{d zUP*fL`y8AV$2i=0_Dvo~dtN-w@+01qG0Qc8_h{5{j+4+e9=`ptz!mv=FLGW=e$2;y zpkO`DTEskQZ_fyL;d#vAu2KHx^^i|}?m`Llg@Z12itf&wyVXlMX3^ts=TXdiTlO(O zg#L6)UdJD}?zEJ9t4rdn(fG^w!w&=dm;DDnMN?0`L0A?ql|1lw(6kimA$OO?C->Z@$L z&<`6E2U`Q%crEs@!PW@fvJL05Ax_)dD0;6C_PlXyVUMk5f3I(xHSarj=RbXO^P_{(clUcA;_69E5s;4u#PeT%HJqHnwK z0_5mHE}Z;NIWC=|`~}3oMO++n*l$s`CJuL_!~TYl&mV-HVJ^wBz?ptU0rD7~^Qd>1 z%6Sy@-m;*YN3FxV(uu~VoAYE2WhU%l18fX*!;iUa1ML@ZtqtvyW{0AE_DTBlot^$G z(N^KsyvpUU-S;Z`YujKzcRFpulPFL6&%u0_{=}3^vCfUQ8-8n+dk}ho=*z;ni=^YpwtzRoJrUD1%)FAJr6Q0Wba3nGXBF_TX1|*p@)}z2|zD-3?kjkN(OKOQ0nLdVw-1y2l6!!w30Kn zRKV4~dDi)8zh$0<_NimE9BY5^VF7h)-Ni`#=kJ#*}O zg|9~YP8^)=U#f7J1{`XDgVP>R=LeKrI`wERc*m(n&qjOHqai!Zkb6kkr;mLqz89X6 zCw%tyv^PPw2VE5{=Q>X)BG<giK*y0wy>G+u=>)(j=r%4AB zylK}LkbxFof7Kh(cm4%BG2}si196S}u;;9BtDNh!hi<<;8ySbT==SZilvfAcKqK<` zy(+(TJ>YYb(NxkDIp)kYuZ2$}_=SEGaBffT_d5zsx7_cw_{O~^gkPL%fn2l_*nMaG zr&yQbT&qw<+v}a*qdsXkj`ja9 zcFpp#k7bNO&ly;D6w309%h1Q}YnF$9BiAfHO_TEo`Wr)82kV^Yq7LP(0AsZU-#6pu zlxI`TAJecmg<}W9Vuh`r6saVDb^e*19tw;h5x1Jx^}*M>Gke`QvamNg(n!oC(-k^ zh5k-`ooyI@aDPcO&uV{TfUi?u9piS^Tcp-2N$ZDS?_Nfq?G{Z-;JX7cMqQU>rf-!r z?E;z>xzMwt`mu*iE^D++vFXQTeD8>U-1Cf*bI6HXd%xm);ns2O*0(!!dsz2qOK*Jk zOsw93j?EsBjXgQwmCW>-ev{VxYpUr>?i7E2&NcKkoH6!y&<17I$)_Eq>&qH$54-a` z>CgeY^Mr1%9d_p-7dklcq3xj`nbuY5$j$Ayfj4MaFz;|1(R+wU;B{%Wrpk!*zRkZS!o_H_H>Sq)FS$FqJw%!PYi zZbp6)V=u=IK>j~|Vh#&fOb0A>Kj-@;GM@Dkbm(EILaVtn=UdbLId$ z%iYg+Y)v*kEthLVKSM75>VQ+*4a$;^#n4^~9fUc$-YZZ5zb1q;#_fJqF?^(mpCw~A zUq014PyxR~$LQ!!f4c;^0U0?j8lY1UvG_j#2Yny&HuwC+gPuY@4tQ!nyzyM{zs=K3 z#3JndB3DTC>qDGMuB*tt-&-Q%U5xKv^1fWRUg4q(G|nwPD%OYu%)Mk>k!`L5%!03p z3;0^^U3-!5VTVNd!y@mW$NR!F+HZrNKzX5GJZ#WH_5*vuaScw4^kdh#_X1!0vvWQw z#?Y83)^omvPaINr&n$wE5GpxcysyI@BcbW?e*^z#nm8|QOs>Q)FSiBnYXMKe3As(_ zNq}ccu85CbiFYF)GuYETyNK(A*ehL)dryKHiPjZjottBvFLD(Z;X89qCgQByA*dtA ze_Rwl6)4;C_mxRv&*GcNrw(CE029u)AJ_N``er`FEt?#&gxIY;AA;@koZl^w>0m}D zYdPAP+bI!uBShdS2VaE}CuTR`?uNHfj=5yP)t#)HzCxY)MC%yjS!x&u3`)qh^Ph%u zyn^%J3eE<^f(hp`{3V=02b{&g&kkqE-@ZK|N3V>{+aQcR0OR3+`|<<&mmPw?)LGo? zc{SkCXBM!J5a?%zzYg~dX}L`U4veE0pbgeHbvug<3u9e2Tt9=3GZY<}H*vZuZ>K5g za_Rfc3z+*t+JbjS7J{}~?-I7DXyX9YW?S_Ac7^1F38=%fP4^%l-;Nh;jvcRb+uUm> z>T*nnDmYpHJJjd=^*QLkgZSR2ueDC#7&-M|sn7w2$cH8FoD)xCp6z0vHJRu6ihX`k z2R-|Q%$4G|iTFl(c4~paXXWA@+em167jHfCgv^J!6>v50AM3lA7h%qWT-r1p|A4R0 zeSFMSsNnblKH|mr`Xamo4$BrJ2G4i5KLtJF(A#xN&Pac|{x~7U&7P))xu-2XLAEPn ztAX%UF71+bny-#dp+A-yJ_9(d15R$S9Ut(>$J&=^H2gFmA@`eVLHpP^3-uWHOH6_- z;rS6Q>q4|i*zZtyMsDR6){x(H_^U zn9Jbo-!0DC{G_r^m=lJ6j;uvdrbHh0lXf_I?7n}pYamO_(|3$6o|NVhux8)J|5cFR?}KCBh#b{`bD1i~fM8#cWqY&_1q zWX=ZHNkKbtPhoLq@?w(p7~;Cr;k40J%0@4ujmEcI5Z9AB_+(+D>u95q8*o1EPvBWA z@|*iUts9p^H|H5vCD+SW<9u_mF9Ey<8_n1^E)NklaN)brwwi0Tb{oiku-C%ciThoG z^_{JCXlL%aBxS25T=W4$YjI{SY;~=;2S)B6^RmkqDA-CAY|9mF!af5wZJ+<)fDPjx z1zV_{_W9)HF7_F;nXdZ32mRaa7INaE>{c=SF0D6@1ME4V$v^u?+hdN!XzcIJ#y4T- zL94lnR z>Yj(XtP=o?c3fMt(LS_6eUfK`Js$Nb7d4RAuJiLweh;I8~7If-WjMn2JMm8 z4d{OQqv`N<`R!eiLk_;_GD+}yI=%;|`>n;0fg@2z;M--qt3SGKS&}$o46-Zo%k^Af zMHsdL{;7Bmnbz;0#e1H+-WxO_4{^LH6PsZt=ofypAzCID0T#PV5FXwYa1do8ualL) zaUP=lR|S6>=0Ksr6NOCl*D?Y4y~gW)4;*gvz+tY!;VbMBA`VX3sdV75x3W{TELL`S zo|}`_=X$_-x`Oi+z-i~Z($3K`=7T=eGByLWmNqhE@@90 zyHAyuydwFCGWP7o<^{d+o#Rn~du~@^ym*cj^X1u&8$Jhn;FGTK;k^)9s=nq;ud&VW z7~5_heVD3`%g_hgJ{UOLY1f*}2GAE}_H-L9dZRvN_G8HF$$W2YNX*HmpzHiI#h|6?H}c%9@TjjqZ<9*%1>G9SZ+Yy($BO3l{1wX%Q zoWHAx#b3|CLg+K!kt1EL*3a1I6!ginIzQ|yWyRTFotks8zxOM8mofKugDTrH??XG; zh))ytI~42_gw6_tr+{{=QNFcYIqBm}i1Bf%dqIcSCs>Q1_w&&&^?nZKw$%G|sq)*Y zSkDylbKCJk?-$@Z_plFwJ>a}oeshmQo%DQC*&O(0zjia0^};;mD#UJeo*vE`v$p$F zzcFBYKD@v?Pw&vmu4Thjp5B8QZRhEwqdey)v3YvZ$L@>o%+m|{6Rm$keuMSN);}>9 zox3hU`Aibe+D7_JI2#8()7?tW8E^B_Aw3kX%drmYg)4IsTf_CIijLv>70S1U>u2~* zT&X{6lI3A(uzJa>z`=5Z(j%#anY8Kj{oqEy+`=zK)J9Q*<^<#MNx&~4d>t7b6 zKxZsYw2nnQY^2gNynmT`rnsm4b~NsJlJq%2`j`05c~K|mAKG#GE&5!J0;Q{m0aiC3 z;Xv>p&&@CFgtKkoU#2?l<}OFPVUgN{P!4|M{Idt@P^Ngd)jb%G;Nni!9FFBJI{qo) zOXHkszVsh&ML7+hmwrh0fbrKSB#g_z>uxYIw%~-Z0d)u?eP#$yuI_C<^_F8bMP7F z4#@&W(8Qrhm9@DDt5E@qJ56j7T07_Q5UegghvJ^gXqu z^|DN92lAkDFXr@$M3tx|CsNwyHU`c|tAI@oE%tFeH^yND>(GN1MPIb_8C4TE2%;o1! z?2B{%qJ4dSTZ?bx)q~Y|upDi{(}2kIVz_HIJLxzS3VvaD_)9s9a+PF9OZ=` zg#M!*)H;xGQ4c=MKA`_ZzeA*czhCq*vE6ap+jSqq-21qZeT-3kUYUm8vk3P3g<8le>Z#}8qa9@b>f;Q9P*Fk?eX|w0r z=veb@Rf&ZLp5xCa#ON!PVePyWKAYt*5bX?5QaAhs2%=meF=k>x)mHafwBtuIaGf zkjIv~8=sMR1`k26bob(q_Ud%Ck5KFM29f_N_4GpOW}ze0*%pAy9=E8o!DRO#)?OTY zU%0Tnj{0_-Uc6Z9>%Ri0k5gUrbwX9P$UQSH4?G#CN*{ zd=R=t#u0;vS?E~lU+|vsg%IGWQ2JGWyMT4b*Py@1&vu+2dxH{e{`xJVA=6=~+ zdpim9`q2FSV(z*j&brJvl%Xwnl(^x&E>B%G#9^Q8>qJ5L^yEFzs>KeB0F2Hx!z1_( z@*~Qrb)lhr=g{SY`3`znlp87aY&zdT9|y!4?}2ZqW5xG8`Moc{LpP5#0^iWLt|lx> zM{7RrF61a;1Ks=#Gc9(WvxqU1yhLjo;(14aJ|doi@fCR;0r_nY@*{-5rQ*;9_|7=` zM(pVwh&u9{dmO#->7=qk#8VI?TE=m8&S$EyF6EpneEO)=AB=|=aIGCN*<7qoIpg8A zoX-rF^O-YIPQ&3fpV^{d5%U%oSls3VHA8m2oa=s0h0cwxV z=g^mD@_mf|enz&b?E!2+XtB&ED~B(SdEW@?=sz$Hq4zMhT-)Co(f?mQ(zT3h{DkvY zmU$^p>igI7T5N>YYacxVeeX}QDn9|uA5YEZJue#(cL`1G<*x5h##A(9-xbuAw!YV* zZ?>@tZO|U1DV%kCv?d*!)cEivK5Sh(7X z318YlxC+{U>ud!V^+YCo!60C=$ArCNrze7ULYGS)Gzj|I>x@U69Dn9M_^`)`=g%Gk zo|rqaE9R1I#9~qQaK%4&rbvCkdgP1V{P>Gl`A?9JISdD!!Nw z{@}L(xTjC(f!n5t_#)Ok@IKD^3Gca2U4EPFx_;eniPR4VP`;)sIhYxd!Fb@$HIYl` zJAtlF8*|v3(Kd!_=XU>^{WG8BYUrEb>dw~LXlL#%I)_8TTh8_B`7(#&GNqTy+a_Z@ zBHlH(^1G)b%s)VvxxxIwVhQsY1vB)Fu#0+5;B&z2W@qvpdaydm&Pe}h+f%V~0_xgz zfQx>s@E<|5*5Yb!0vE>BOvN8vRJ|6R>@p?`6@H1pk7N59^3;!4^+;nw(U^SuQ%}iv zcK#>;E}hj^{jcwYfMVjnB3|yCYLLiKU8aO7GUnD z+9qFdjO=rk0=3S_ey>N{Jo{jk!lh+>)`d1_seV?eey&14l(%D{zn@`!hs=$6IZ>=3 z+xvDK>o4wg&#kxDBOhr$VcWejul@k^YoT8g^E{qGwFr3e?yE}hmmL<<#9dvO!*CA4 z`=RJF9t2#7zqWBEa?xvGrwrWvq~}5VFYX%nv97tdYkqf8tRG*zA9MrOD~4gcgMJM4 zNfl(4e*7Zl%HUgP+<`8~TdoJx;XBtWKEwN?QAd7rU$02SSkb4fpgo1}tl|7=k$XPO zw|t+W$`6i|{|fIJ&!3EOB!ASXJee~5m0|T9p^en z5a&bbb&gY&ESWfG-D_U(?vw7gz3hS8au3{|QMmO|xH7YaON^e_d#QlY;Mi*e=T2pvcmACUKb=sCUo3ZU% zt|^%D#>h`VU!GsSziOvFxaTX}pFw}QsAtDL*8}%sU2xYj;>AnHDPF2kW0CJM7K0Q# zw*nrvISzDjj!Az7m+2UjR0UTl#^gV?F{yCaHoK2M5OC23Tx6s1VDw2Hx)XZr0=##P z8C0FhbzYHQD*TVUc&l^`WG~NWeUJHnXl)PShtJ*6Bl{qJr4GEd2DRa4)0US?hu!k z9k`G#kK%hD(#vLB%%F^Wp?0X#w9Wq>Za-=J z`Oc^AJvarlcpdNCjGL5CYOy)R%-sV%UUTxEAMAU)A{XP|kvPf-B?n${ltb}dTi#U*{OtT|_Q`1?4|A?Ve%bkO^jyc620Jd+ zIpkfoxoD5J&ln{6>ofFU8|MpGXB&5>-#6G=j5g-q)GttvcepPC=jfT?z^(lPJcq}5 zA0+!7YxrmTK?~~35b$4!GlYEL|ICw&JI(Y_;-1J~(N-PWshHlctPXpHC?~#)hmR^n ze&;ao?vA5y{*7<$(&qh)7sncDv+Dul5MR#H%Mp&?jLxe5tqAp-esWO(Vvt z!XLObguD?$>`jWSkMm9w(wcq%@n-pfC^HDZUKRbseE{FWpNzFtesO15D(14(W9r>*uSc67ioR2BEp6#Lvd$~}4dAXH(w=>%wDkSk6C8(L;d_7|`){6SY}#|J z4`*f?Rs+h{CK*kFAD$X)4Z=9yP=2)a`9PjWW`^@HpROzIS4N&iJ%Jzl^8eFUnT4`h zi$+?>2}Y&hG2qF+yZ`z!&a?F4TuXn{`PI$y4%yTkXEgnSK7}3*UM%$R?HGURTk6sG zFpf0?;pffFvgVwVQ<;S}adz?5p$GDsLckWRpc|irn9`pJi zi~1PTUWkj|l*xLtva)L*K^@SP<^O^54O5JbW_6Nf`VjlXo-927U{)vaIosUN7$Kh% z#do%MG4q*GCVSveYXr^?tr(nF8AjXTfk#xrU^FH@*a!RWa0e>rl8G~x7ol(NJ1y^G z49`UQ-I*W1LpaJ-RY{@W{%_ zadDfTe8j)0@|jVUqFlAls+`xivGQ}@rphOetgM*Vv(bpF8f^^4ncs1zHde&-Z+v8) zZ_}fX#BJif8JY%S}C@&{FGu}9rwsSSsHOoP-Ls7Wfia;s?6|;d8bFkl*_^Qv?mqFA6wbMP!-4}`B?mRx4;k2{4hZdx8n0s9E{NuF;x<2^N8 z&KM}#3q71CWT60k1tBwMtcMRc^Wy9Z#0S{+m7u|Jw6PiZ*9iQ75%|{t|Lwqky956k zfxjp-oPFBo0~-Gt;J@90|90Z<7JQfd7o5Q5OBdT;P37xBg`l@hi{9`#b%X zAK&w8M_IY?u)AI0cY=Oy-#*8;G$UQeMp+Cp5)#sKu$2cAS zs2<}Xz>%?w$zA)G={!%;rKPTeKDk)Okg=lFaDUWg|6@>>XV&F|R-vVVtKR@#gn>Bl zuagfB1RsQEK|g~Q)u2Vg0`P<86YyCt2cIw&LOxj!J*xMpus`XyW?35$Hz)suuy=yI zdN1if__fh5r*wpqihGt??8Fzsz23s{NsLyPW%7Fc8nU> zw(WR0<9}>BU^8|e1>12nY{!f&>x&_KZ#xcj(zz|$f&T2a;}_sM_i@;cWB&iK9f2Th z2Y58N8oUoa^@B%qz@u~UtZm2pPq*K8e1W_9*j{L{&2~U$2EGB=e_YuPw0$LL@c)DD z*nFX~9T*p3I~K!stZAR^`0~rvZO40<@a@mE9S;IW+K$)IZbxm$ zZKzAz@eJy=*pBxCSC53AZq0T~2OosOHrw%_&31s#&T;UGupQu&`w?%7u^rH_$F7$A zBWwrwCkcCjh3x<=v>iPG&wRkxyvDcbmy>Z9z_p2$d*-S8a*A*dHEh^z@Ch>$Ft5NI zhKCcijONOS&hFX_`3#w=N%UsjB*DXO?9{CE-B~~zoh z@g`l5bgDt!1RV2>0Ze-(7cCh2OkY_)bf5_mACbrsWDgsl}KIKN~}%&~0v{K#w#6KQn!=6+=cXyHTu-z8)JHtOkqic^h^>Cf(GbsN}E ztQW9vwqd6EvTMhs!-wx~`EM+m`WePb*WvyZ#B}arOd^BpwTPqWZ>C{1acmmVZxiaW zf8EAAXrsB4@gvV|_+{+GrdrV0DDqqB<0LKL!1oeGgQJnlKv-s+WNe%f1Z{IbN0d)T z`M)671^onCz8lfsM|MjRJQslp@N%pH8^^)80cX#Fe*FK)=H6wkjkSm)&=0R2ZZ&~+ z)P*%Ar-*SV!Z_q(?}`EVDTAQ9Wne5mhR_gH zF>{6NWBfYW9)Wj%@6;bL6uHJK_=RKAf}=0|Bjif7H{+CS@+$QMWj+MF>H8aLru7`! z%E15UqAjno%PSP&$de+JQ9r62ci$D4=&rP^ua)(4zn?!;H}f&r%N*{QPwOt?l3fc*M0Ny5F$LIs#YUG+$SB!(E72~O{ z`oJ+pgE2-zCLLoe^nq=Rcfrn5AIySoYE2(}r{#8_hdwY&>vOb4eQ+k)5`DXr75V^W zx1lWc!AZI-cwnplEU1drB7o zmamffi~YZvSK%87U67RSq6=udYe!pkfZ5+zJasF^O4n0spLgLLxNq{{AHXg}`3C`v z#c$~UxBBC(U8t|eMYpvEZ7qbKP>ZD93XXu7*BoO@@D0vIC#c`W$tboBB7@VLN>H8QyipyT7V;4HzS{ZnWUf z5Acn1nV>GO#(xvubKJf}+h^mOb1kTOUbjs@!^ftM-;8@bQ!#eI#PLgNZ%SPfnu_rXn$ZU6&Lk zj>EWh!(WbHXZ+2@-!4mZ+jhC0j`QrCa&3Y)WFM)rkCjEEcc70QSLi-cR3HD3xi^oG zs=ELG@62SGBSdp?uGR-EksVJa)>qY=8L9A54m9|VWYziu)QCe*!fR;?? zC{++pTe7&IR0Zj$d|GXt38<6c07=~ zpL5SiG2YSHct;mM?LLyjxS+OIuIgTPg}-#U%U?&?az~$f_p&_h$AD+Pf1M`_d~>+Z z>2OM`d>VS*RpaUZK%PRXv z=nIkk5Pc-R@KXA(5xb`HPo5@ydNF+}avXvOr0ji^l{m>l^hrxP;iM_g$p2i*$a?cR zlreR}ZKR3aon@qjs$;eKZzWyEk2jlnq50>e3B5Jcc?0R^Wp^E!QS9y*-R>SOnlcGp z(?lnbCU*DVPe<5Y(#2nB-tJ~;?a;>RqL&?+&D-4!YzFmQN<9s7&Hc^n8?@y$?Cw77 z?gqo|8hJB>K96B{_hWal%`M4pq}_dyxRH#Zb-O#J8M`~i`{Eu$hM~m?-^jijCa;(> zJgDEfGOUf6bFjP6Y(HK!rJlYr%UR{KWxG4ZdxG-1-5t|V*Jsq#V0RZAcGrEmZg-*c zKRj>M?vnrRX#Tj^U7mMNYFXyGTV!s+X~XU|)4x{P>te{B*xhTuzY&wBa%Z)>SCCKa z?z5C_NyhrpZcU!xk5QBnyZabr%(S19CU*B>BTcirxw_pQ%rmjO#b$oZ?vC+ZNV?D% zPu+`n7S4}leM=W&Z^^_9Q#fBcmh-g@yURCFy4@AMH^yJcI-W8|k9uTiv(p^k#_D!8 z0T~LgSB`F1b-O9~ot+f58N0bTuR@ojvx}zj?y0Pin8G>Pv0mM7Vh6B`Qa+TdsL0P| zEzZTeR;Ulz z!|sVc^grzNA@Wn^NF8myvoznnH~66;GrWIHY_F1Qz}4($WM;LDTW{{$jLdi>hWch! zU^({L^Hx@10Jd)wwBiex<*l-_9y`>WZ3`InNFPW&rHGVl~T^AK1!V$f7pBJnQ*f8lxQqdO@l_UZ4`*OKf^HtmZ;@y?)(*r%P8 z(PW3T8%Y!U^qP?tBJM17O(R|G(-tFL`hPNMLhI$!`6B6O=0{oA<4DzPkjRflTLv~D z!#%}MIfZ|*8K1DH({SP6Cl&R?h8S-JZ3-IsHjppmiP2-U8<9!)w}klYQ`(p#rAd5N zTayXz%9=B&<62|P6*|E8fd|@avE*UkCb33|)0uqwa-YVu#&~N2x;VybztBCU7#hqn zR^H5O;7x-L#u75Nt>;}QDXYEHsN-(x_>^%}8hm+lXRaFXbnynEQLwm!XS0mq)-C20Kke2mVI5<|6t zU1OV@@}d>bPe0K4Q1CvsGrXodd~$IEPc=tNa=G8szx44Jlo6imW0oPUhBVRB-Ho(R zeuBn_pO7v*_eaWiJ`bMj1kNVUWy5o8wl~jnapXH+o_hrvg@>#dJq<=CmL|`2ZH4DP zqm5>n^X0jJP)9VLd!J{m@!a*#x6E^u&L7Tm@fM!DP3vEiXQK05o`vV8Q$~31QR>n4 zm|5P+|Hc>ig&N+ylKE)0)$BnqQO~{ex3=lI7r;~aNA%ollo6ggOg$~}+yaYE^HWB6?tobao+~3wc<#SO zn#ptPHJXykXH$MZ&%Q6u{gZMg&&9%Xw?yGN@fXgQ=N^Q{NS?d78J_#NSIa!N2^xMV z&pksO(Rl7jp0&nvCtqlp=MsJdJ@>x7k>@Vf`q$J`(e<3u!gGBnBRn_NhT`c{VdEja4IX7j5=U%0rmh@bvh36JfMtII=mVxK)B29Sic_Yo#bA=jB$>oD6 z|3{uh({r^+IeQ0HDtiY7AACZaYnnaike_*O`Ch=h|8qDzE!(CLdtyGr;V7?n*tPE+ zWW7r;o3Z5qo44}GRIMHI4T=^QxQ_T9--KxMO2kxFKu7&zr;qjMtDVFQLW>i8CuSu2 zR>ToMa@f7$SCk!THfOoE_TgH)x0o{GFN6m>)$lNWL!9c-F;4Y(wo@e@u(}~0pcGHB z@tsNR6YWb%`DQ0bU4o~b^m&vQpLVCiwl{JTX7?AavN~_ zI&Laube^|+x4p09wper~=~4NV`OhDNPp`4^>D2ySWvIcU-@2!K3JncB zTAAGfzWw1(_mq9)4-bxkKlu%bfj?v5&zK1QB<2gww?yKs6iun7eB1c5Xvz+yb^a{Y za84=j#-3clpKC2Rhu_h0zL0nRz9pQiM{4{j@^9r)tE|8Mghkee^=*{%H{DYnYs7G~ zle00R$~onV$zLoO&UdKc`}r+!s7Dt&)Z-pUQw#$-ueOWCko0@niXnLm+koM$)w+!T z%fRp&3x>1a)-n7C@;zR|@D1XKHsXnPVwn!#*=o*2cO+=|9Y;@|Ku?Ms3$L5<{UX?f zrp9}^od?nVsrfV%F3*oQEpc- ze^pi>e`Qv9aR*;`k<80=YAV-hI#!jd+m|TBQ$y$`CH6|@732I$>^T18`Pb(mmDsV| z#}fOL=XU<(xyRm=~zRo$%oD|5$3m@6`E74z=@ zfeu3tY<3noqVq6i(+|gbiz%~*GT~9!DeO}iJ9Ts%wrWy@t?H!PsvGH>Cbo+73d*-h z7m)YWa8E6^*^;f={J74?$=h|j{{XJ0&dq*J=i~mo^XZoGuD+~QT~LiplzKJ0pWLev zN56Z@N-K_)G0}0PTrv3<3x>()fnNMl(FGakf&me_phD;Ggh&iYpWjvt$@_~oU^v6T z@K)p7?@1O6ztv)R$>n>|17lml@JHg=QY+5Q@T~Zw4Loa$i;lI0XEOxvHu9|h@pE}L zxvhA^vk7g$`=eDl&)&XG=h<&4WAbcwgJIlA9691|t`*pPy%LP3edG;CB z|5ASgj=AyCaim-^`9C6m_#L|%{*d2p)->+7tH(cP4W!ja-K_KM&5;0iLs9c#AO?cLDGGU5gmDF861!lhNeq!WEou2z6XZg+JIpv!xu$ZH9kB;8B>3ULHe2b&G}L7H90CU-@aj4fkwAI^GjN{*VCn^{U6xhB+8@R6zwEiiSvFg~ zKP~r>EG6Lz{#R!8&s~+JRKA;)Hp1<)+gKlz|5%pNp7me(k7s32Z#s2~Unaho_+-cR zu`NDtlGay8r|Q02P5z_!YTbO{*Tq-s-qcsSOxFuH&>wE=*p>7*z(&&xE%{#Ld*!UI z6U09k->a~hajReRy}Fe@%lcf=3BLz($uGWF!M~+1Qp)@Bz9+T5XnwAdH6B08_-h+B zwLx!0jK3B`L&Nwhw_S9er<{zx7LdQW@z*Z-PTgEDz&K0BUuPeU;Ca$#n;5qmA1Ipg za|36gJz9KVs)ln)`K#=GCOBtXc;095{9EXZ%$9I&!}#lVD~1u{uS=~M7PXI#p)vmI zFBmp6{%V3@K@#pEJyI+Dl3MzPSG(m_|PpFwvi7LBQb=xe$`eC z$$NVnFdXuT?u+g>Wcex!hBm{G`Up9`vPBGAj`eLa@M|vCmu1B-w{vv-j9A}gf}bVU z*M#>j(|PZWRS`On^!{zdjlA94fLrik!L4igF2jfajxwhFzOhS}-zDHyPkMCuZ5g+V zTEOjVsoRV*7je8qe<56rzqy;=JNTUY@HzK8)F!-l zSm(VykrPcDbM<|uJ>kGFq~`Hj?a+SpSOtN1+8NE*CrUIG-AlN zT-R7Jv~_I(!xV2Z`SS$B*^C|M@tec=aRKAU`|V9JT&-jH_mvUyOZrdSiXnLiwgJN< zD^g2V@XeC-`$hS#x`eaI#7``N7saMHE!h6+AG%yW2DbJVv29td=NPy)rw{9?yFspV zyG6&<(1%}=zcsmjAQI2Z82?kQt#bX3Q?1MOAHh@f;gVN%++L#(Onvx(5tGm1om)sh zUwzo41>DN5xD}}+$I~ijWlq((}LT@25#TNYq$RZ+;-z9 zNnbR_Z#P?UtL)w?Zr8Q}w@)64kYD&M?|a}jx(&G54BSFnb$;t>!R-@c{^EIX>)sM> zKhjulfq}0U8;%(3#aQvR^=tuOeXJ+`LR-gr#gRBO)(cU-O>#}%|EjIa^~UA8e>jHy zY(*cwN#B@qeSr}pn#eomPGF|X%>SH(JhAc~*;lRV^%J_t~;zk|WZNM$l@Ug$yqT_a< z1-Hl8^G9&o1aAFW#I1Ed=PE1jO||$r9=`v#VprLx1?=#1$S?ka=HuYsgy-YuEW*!O ztob>O7_Qbad?FG<((7qYo8*_gU)Q%TzajB+jPKda{US6!r@!v!T=2S%?FaOSDc8OC z>ex<$mR+PrmFpi#e}2grv_bYG^r!d>BKsQe+WNJCzpg*a$R9<2HsWu@%6=M&Kk2_~ zEB@qttPS|D(Ck!7`5|MTVxa}+{~BwTPQkx-wS;qZ>pc9d6~iYjJdE!>+lpasT67F4 zC%*c0!LWH>y%9r$hl493^Z@DO+KM50U2VW{l<;s1zPb-xAhxNG1>0=~4{re5R1Mqa zV(%@lVYm`ZTUx_Vi#{Dx#J(xtV+}(S8nOZCrzM=*uy$cLcCl{tr(JbWE(IHv-gvX*S8pJ7kXPT9AKBmTKe$N7Vgb)8T}-Ti(uqKl$qXvErI5Dc4-wKvLpK-a-TA~7WWskUNB-j!{@aGJrZ zXAbHZ-fh9~B7;{?!l(0E#IW_)=ZDzK26>N&eHK_TtQ-&>LnHP%O)zXe_SuNxVI9N& zE{l+N(ywSMhUC4x4H!BM4A1^a$1u%;;TU7i=TBhRvqcPBpY!>x6~hQV>}bW%HYhrV z1|K>E!#48aqmdZGTSsY6n`D{1wZ~hR<(ECWEdS)cI))#DyD7^{jq&L9yz^bsqswyZ zKIu=a7)Fe%{zm-`vYdNybPOpc?$@{xDU^o*D zTN+n=V9akkV8QmRu?GA*c=MhXv28tG@=tuU1{sgA>EbUK*zR!_4UUejVbgCCY@4^~ zjo4P`*nYM&LdHp-)K+ZCo7)C#6Ak|Snl&5Ze-5xHSeee?+dS`2uV-ebLIAn*Sctbwx{SYBsW$UV!r& z-iCLz_#gdeuBi!VW2}_&iM;P`q(|2kEyu3D#J3P$ZZ3AUg}NJf*>-7kUN&M^W#o^D zU7ds3@JJp8%V$i?T3aJS-qi+fLUT0V{t?YibuG`?tmAec_?SBOQ)5l-8Tj{CE#lU? zo%*AJofdnJuv5RVVwXE4I(CMg`nh1&yq#*q5F4Y#|CU7P0n#V56+`l7w*kXU!`6F@ z@zI4A49}ong~vC6VZW9z{E@!{ZwDu`lVkEwbQt z(C|rZyz|~4fZK)^aGPhv%{Hu6+-9@^w?m!?`38&Yz6WmO+JIZGf!oO!b=-bp!R=`S zw^xwu0i=gLv3t+VPv#pW_EK8Zm9wQd52;hm4kzdHh}{sLQrI`8_#f~v=S>yN(!Y0m z=RrlcSA0YIN1pvdQAUkd*jpn>*&+MGi2TfpQ8d0kyXboApXNI=e=28D#cKPdYj!zz zxL3}J3T;$;WgC>e;l*}es3Uu~W3$uU!@U9OSxtL2S>f6vG*IsnXs;(d?2&!rW1yS8 z1XEu6&~SivqgLh=iyu7>Yr)2G{=jd?rX}6A2IGX-*t*- z&GDiVtM@7OHnjQ7{A%qxw6?bSt8W{5F(5R6aS$20zFGRaN2UKIt!$$#jmR=&$)R}P zv(oQCmPnKLY-^yud&~3>Fk~rg^T~M$4YEW%e>Lgndb2_QU!ecO=IHmNN2Pyp1pQrl zG}8Y}6#B;)x*+UHKX3XUwb1W2=r4l)CpdFbM$+9MWz3nkDAiIb!a2~iBag!iZkTb)2li9H#?)-k_P(E9%+={ z!$Jdcbp+o3MRW95_l-*bPOU8RTddo{o33c&|9|tWLH}6fmwiAqTNtkH+cN#<%CAm8 zy!pOKKi3ro{gu!^0{Yu($5%@^3-2s?s1f^3R@yDR^Pt_dht1mYHevsqNjtpbHE4eV z+T*?l?K2~2fAWDw+J7B|_K80N?ei_P&oXEi8^53QbM;Pixg8oo|Kgh)>Axxp{r|EV zeB)?VZrg-?wuSzm8uSl?{*9!!m2d13v>&waO`j;VA2Mi<;{UaY_D&Ys9R}?&(EdPk z*teiFKib=r@BcfX5&N%r)*!PMzW-y(Im%R}>#FzbFqm1~nw-_|sN|}#HZ>voGM9Nuo@nDNS8_%=m zc(U7%AX8(^K85y6HQJNQhd}!V($CRnE!e@cdxW1G?OiWh}S{EaQhdo;8R2_d%~v*ydGxVEsaCd85AYG9KAr`O*R8Z$Fu%9~^Jd2m zjr6ym2VOMk=RNBT`qx8$x9>^+uOjHb>dr>`S4N@#lwrfe)#p$DZ!PrSZP0%Y^nXrz z^Jk{p_-qmIE#V35%Q24Wv2 z9_2PLI04Uc-ar#sa3c#{__jhYSYgP*Q^>--$U+ISu%ba0x@xjeWXM9XCJSB5Ux0Qw zgQOxZ#$UkM8x z{=@Hj%&6a~(X0Ec)TP^6cuuQ>eb3GO#YX-!)M=huEq!uW`-UQ=T!p89*@ixO&!8z< zpE&p?@O)+ao8MSu`&iMG>kXPec$!2I4{k9zpE@=Y> z54VEBYWnzmF?i96!O5a2DF)4teNPPj&>RNTrx^7;6oJ8R!_M6g28X_CT{g$Jg2CD! zAe+CmVz8P0|DZ`^^Xl)3!A;F!Kz%!n`Z6OhIQ_iN2P1i2E*P{Rn@*$sB9md((KpB@ z^9LJ^`qMRfTaiujKWpUgYS3fq%UW%HKIi}Pd|4a%1@U!%S$5g3d$Fqq8q>MvW@Pid`SFn<5}V=&f= z0s3TFzrugO6YDSNz=f;E)Q}lKyVjZQb(x2iG{rWB1?IEr)BH zzn@Kc(A~jCn&MylwW1c@m7~r~?C3A}S%s^h*zFQp<|f+I2Wp(&#Wl{%M0i#9OUS)Y znI>t4HRCho-4bWGB#HCPFQ6?ah$D26^8um1W05PET;y`cL4PXOz2sWXB<#mIft)!R zPg;_s$+?7mNRx9X`|_W|e{a96xtRO8GqYgXWPhL^c{7S!a}#sb+DUfK5Ur%{N>`v` zG5^J`Kq}X%#je_6d1@{D6bF{i@CU+_aqujjyh%KdCvQ@*%l27rroDZxFEsmNZ=kxL zcTiR$XEvvJo#}Dj!17zzH}_5uh```^RM{TQF&^BJVDCXhvNU!_bPk%hGuv1 zN_u?X_!9aiJKi8pTF8PIqG@G4q zLT|5ULx+;U4V>jTpx70fK9=*WV$_01+^)i&HdW5n*0Aph&Xg%Ac2cHWdHxF>O4P|? z)$C;Di0ngK2xhE_$y`T%$)^-mWCbRJ%S~g|+6^(P5)1y>;E-SJlKpW5< zu7}Ar{VbJiFARzts46~CEPUHn#74SjxqKCddS;GX@0>E{FVbM2>jYE7>yo>jR5 zkFdXQzbfjH>ll9^iR+G4t{`W4);vbPhUp^*&p6w&4w(#XicxFBF?#f{Jg!^G~U(CHH zD=>=tF>=2oOMM)E03+dx%HpM2KQ_a_E% z5)<@tU?uo{PMdCoo}cskKm5Xu*uC{LI!is(>(p6$XUoY9r79!H$9-HwzWh{W z+BWutJvnQr_ZV@s6&L0C%4t(wMvSj^u%aHkuX~ALcmjJkuw9NCbZ|Z#ZFhH7hKIcHY+rkF@~de{f2zo-h;Dk@S52AuH`l8 z(dU)al9lvtAv8Ga!&?TX)o)9PRlIc$XZhUU*6o^Ma~=vg63f#$BjV^})-FZhWABlB z>fz2!@fqJE0-w&xkqzAqeC&<*Jfh)a^NHR6LnJ==I&TEJHR4m-yBU0fndgsBynzqr zJx0UlX7G6$e74BhdGu{jUQXt~809)S=dlK!af4e`xLb+xO?bFmJA3D-ySgb`YU%5X z+vnFSo#@XDy+3zp`%oDDnUUag8vS{QzWkEDJoHMeZ#R88kG`zSNc0_&Gbrh=&?dXD zwjXQ7HYnZ%XKIPgdpa+!U>#^AFCO6B^b%+>d9Zv#rcZbyKLX=*@QUzYflV16uYgRG-b$BsC&D8x<-BkWOZdQwWifRKe)GYy^s7cJ$G2|*OSA9K6U$fQ zTfq{(wPGp!YGQf#-lp>WeX)F-cB0o*IV1Ayi{Q$&6;ttPG)yxT??5m$^;8Y%XBSOH zpG`rpUFWNxajg$Mr^R0ju}RiCD!&UG{gPa6i+4}4!*5$2XkT)eJ}9a&`bQb+bsGI+ zI~E?%foIy8h7~{YYUd0WTr*~VP>)NJE7_cLZhFUh%@T3+~UJo6Gw+GAn@pB*sri@lL@Vy`~t zeI`zMfa#JgQ#^jLUt1vR$cvRrJkf-Yaz6 zp?!;;QvMnK(9bC!#?~F1%$XgFSby$d?YWYp?Robo=k#LN?|vVB)31kecR@S;`*7}Q z2hPe(16%q~^mO7n&M@*Q-gjwtXp`bYpR0xNzw^=2-r4-m?mpW4Hu>Hz9pjDdqotFyeAa`S16j1gBc-rbd;jCeRxSv}}MyH>BZW?sviz&_cWlTy&Lq=@I~ zE9~Bbla$R%0;%2r@1Nb@=Iu{iuUyZbxU};CzqwytF?tX>Tg(4vBY#16E&qDzDl_sX z49(5V=KbmPiI%s*tXt3P7-93)kpBg-s^tH8}+PZ#tApst}BU3p%5kE8U!MXKyla$pHi~4wTxemZn-_Gcn686YhEzH~H ziyp9*i{6+?ne;%s_f7b5NvX?wAVci7vs^IWHB;V|%X%1njxMr1?^FlbazA_9wvz`49xmdj)8nillrf9 z88q7)>KD1WoBD@E=DpM9)y92hdoMA{1{&Kd@;r;O7etnQ;M{i9kas$Hdo;~^I6ck4 zzQEByll1ph7}CcsHa%*_Wg~$B+#qERZAT! zs3ZNH@+n&RXT@LQx$u@-Vvq3-znhr4j6Flca#WEusk10C*QbEd(`)P{wlk`-EzS6_IkqTW|*!#~m2@tv4H2_Bs2J2huQ!|>t09XhT%Sad7D?KAeeqQ4r`Q?>M4Nf%xX4#-j0;Y$V>2lt0BkKWt9MAnSTv)_^K zOzOVUM&D{N7%-N0YvpKXk*p2trx&-r*?Ib-ID#0n-7Qy6G-?(SzxJX8qZ$oXq>=7pTMs3JEX-_u>ASCb*i zh2|)}dVD)QUZ9VMOA{Cm)Bj)6?sutQbnQ%ZweMp5JiD@`{N=H}!Ib?vJI8mJSjnBF z`A6ocLrLpQyR>}pYWb^rzQf~kd;#+PlC&4eH-vn`50fl){Q0Lj>X&E3TdyOnG%k0L zBIlK*=lQ-%z4oG%dHc~D=Y9`hZ3>iOzSc>qdJ+ukcOOaN;lP`g^}TfGlsY`wov|?94l~vGclE?^Toy z4ND+~jr|+O85}n$s`lROSl?G;;(WoR&VyET(c>%9S2DgmyXac_XEObC4gGaByu|v@ z{20yO)z<=dBCRvex{#;ox0Xk-qxhL>Fhj}I#;r9Yyib98_-W)kk#8aG=5TmFG@L70(%_n1qpvRN->TLVolhus%m&f>e zD2G2f6`%X^7~0yqV#!BYO2xNj)waFj?>@S`UC9>5&+FIPdmPHaXI*RWd8neJGHt8p z=lBSWA=C1F{cH(`)?;_KJ8rB`B-S)(ZsF*~waVRPuZZ`^~d(d`sz2t z`6RE51%k8jD{0Fc54S6kyp_bNg-1e@7}HQksT!UpW4lm3XV(#LKE2pp5}KT&hKN4} zri#vWuC#si>wO}lW}g53wVr3!Nj*=(XAkX5Z|~eKHZQ!eeaUvlt%brHlfaXDpI*-T zcVugewzgArW(q?m_mpGgb%Jl3uCFV&$oleyc8Q}Ump?boj?AW%Z;exq1Sm5T-Xm7FrJ$RxGya!y$Du8R zjI9tI)GpJ`Y8=64wR~^&q7uJWjzRmS63ntfr$?K$b_^JnE2^s(DJUoaz_&YwE zQ&FezT=azKKk1WQ=nv@=6K|o{d=`@SSo%xa^at8x>egcs*gwTH8Q)5I;gfIHhS#*? z{;Pw!o)!#+FQ3-1O)3BD#dgMl-O5ivli*jVC|d>dJ3nWKm!h_86z`w+LN3h*@P;$9uP{o^Wu!Q%5aM zM{L;=Ge#a)$ea@2{HJ0YLT1c(LqA__yiJ{cclVN0&~zHxpxJ-}@p{a-y)xV^M?6}K z9oMGV^w@ERO|2ckkC;%}SYi^xY^tVzDo1+jUbm@Y8xHNXv8TUHJyXs9J2thhy1n<+ z!I$~Shn=!{%N?ET%N;R$>xT64g^m(~{KDZ?j(nJvrs5aG=MpPTA(rgedoVv984z3B z6Mv#tdFRvJI4e&{skFpMt9qa>(3cOMBCdBbJY23NMq1d>77-)0sUheNLAPSitzit^ zA?Q9CL9>P_bf3uR<0BuqqC16FXeygA+UIlhs9)!>@BOPiwM6;=ewR3DQ~VjLm^fPT zFVDD)@}28X{z{MWoigxW2PRs~p0T$^=T{Xj1x(5u*AX+-F?pVM>X=A;y=S?|TOoRK zF1XJ{SIQh<+FSUKv?&DrqW@;%v)M1?{9pJtG&v7^>B~yRn@gG0-=&sVd8#zN)2IM^ zBW>E%{oFQX5NFrgl>XDEJe9=zI>HypHnoy=HQ}p#&LPH5<`8Q)%L-p54663s5v%i+ zZ}2c;An?>#w`-@PYrV!(Ge;4pHh7A@6J9$rnExR*wH*GayQxnDPvIY`b@Wa7kkP&} z`X+5eg)8kV_$gWVsdN1Xux-Rn=cnJmGmpYgZpH@E-hr>5+g{IWMth4Q+M7yyd(qy0 zHg#!adpGFqE!}Rkm$GJiA33YfF*Ms=+vxLdZ)jtTE<@7he$m^ULz~yea>o3B!^36V zv+l22?EIeKXW?mIeHTtO`^T2sI1f<;K4!W?zdfhw^AXlGkvZqdrm^($jA1^FkBvUn z(|Y;?+x18Aa9Ypi451mAH5>` z34UoJZxRl-JOW=awdjEH%>7euz46S( z{7yIY-A?Ag-RQWTU6dm^A1l+2!%t_hffbB#gY=8^#~JK&=-FJ&9~8f71pF2vk5cLI zN?u!fj92EHMDE9-vr*Bl zP&deNb=2nkujQK!zU0Y$bq); zof#vF4e5Dqf8?_+MdO=w!bj1*t(CPkHZ|01GKBrPa*PIPW}LkCgb)IsI@o7X{7 z4!wJLA~9F7<;RWoCE}OV(KfN=n%+HxuBCl--zZ}HSBp(=(7)3S{cAJy?--gk?&>ZIH@p&};cp*Ax8~zzO>Hs<^(oXHG?^c4Zn*tx~ang@gy)tXGfeq=R zL!=K!lHbi7rEunW>)-6(2)6w+5@VMFkPWoSXTl!z*!na|RPjp|Ir@P1meP#1D z=<59=eWIuDH)V_cY|t@H`&0Lew6-*-V}y>)cQw^Bk`^@db*bqeMd%vIquF`hZ`Iiz z@HoCLSKW#{7tD(FZYk+p5}^My8K#}mrXcN+_)P7c2_LXJZout3yJr;em+SEsdr)6F%!TZo3!)s3QpM%c2gFW?R402rVXUBMdwK28i zHiyA?$exw&)?e5tlfqxWKZ#GkoUg`n{;zAa)!K8p2%8-q|2^|DtBMaPL{c( zBLy!slJ5M)V?lMMcyt&7~8M@Bl&3uzLBXmu9hVJtxM)0MK0h;&_?JHdh z@?1s?r9qw}`0-P)DzxiyoglnWu%37hu_}=%i6f+;w-nH_Lpf_Di{+HGdi+@f2}`?Ml|g^-G^rn(-B%fT@H^7lK#_e zMMJvu-=K|6`>$?5AK#&2eSP86iuyidRDV&T_bX)RgkdY%!#`gcxVFGzptx>nxv z8v3@@K|fB1X5`uDNUqm(qbIpu^y$Uu64A5e1BUx*H+12;tE993D3SF?=wRfkmh(SE zkJfS)NQkq}g7C#nMxU*~ALRXwW3pc5bHMU7`p@i-w2Srr2n{m&V`fuXvRl$c zZX_1))(QN>frkAezbQ`>o@?44CbnY71n-0 z;qP=^6&idl-uZ(Y+u4=&lo5B(@HS*f=o$^))-j@_nX;5K$nYg2WJ&U9_ED23iMi?H zxFqm)+3+W~hKG+J4?g7{rF5A0j@NXb()LbxMA_MJs_n0uPq{}?hI?ll&w~F7kEr2U z(FA3L=-w5~qc^cv!auCTGUccj?I|3fx2JAHFJJ8!iYj~%WAM*OV=OOe!2@yh8~hVz z^ds`t;D@Zz{gCe~Poo0BJ>rEf!D5HmIX5_moIh4^nh7(d(hKCj{4 z3*064kXr7CM@{=CHmxUZjb3cLmE`HMwsl=ZZKSb6+iwuZAEV^r;Tw`Mc zVr$Vc1C6okI`X&2#z|hyM@WF^-n|UQoi)G)^^0-YKv(YXY2WW9M!x#Hr z<2GV!;_oCF`Z|Pf3>}B9<8Z?_-YoQ*epEUAZ^nl5Bm3w);%nW(D}as+&FR=^haN>1 z?$5(NZXByEo|{mD{@HAfsmw830KSwl+f4o=$80vzL?@f$wRcu`E|Iwv(ZTny7l>)g zD$u!+cI;W^9-I;*Hey9$6Cz_p&Sdavj1_HeZER-Ruv}SRWyFc>^^N1PIDdGJITmaG zd}@h|%|b8bHd)7;J49b^S~@GnJMx#QCHJY})ZjtQ&)KY0u)i+rD`jo8#MPKLObsxP z5`S;cl5ApZ{(tu@(QTfh*}N6I!oz#om6VO7i`=KZ8$W8-EG2UsdDoMsydOX66Yg*4 zUi=&Utj&shgtwFNj+uW9k9Y}RO7yGttYEk|!Fa|@^oYkP7eG&_><26Oik*_N&2@Lj zl^oB=RVA)hL99pOdVzxQwBzuzjDZx!)|HHdB(4`1Fy=6ZAmhdy#^>Iqa~OfnokqHi zxv>>z!sqbufzx5pHSBv75mQ6Ih0t@g=)2W-MCcoQC((z>DNR1LvZ8OaIgC+eJnb@F z-yD%Sj4m>Vv3g=|rdQ^~%7+Z|?F+=%zc$@8s(E%S~)S4a*4Sy?kUI5D#y<% ze`zG~A)Wuz#107Wo3SCy2Wy-Yy9%ALiGDTP(?q}Meyc{S=#tGx8B^%`r6EnzFGC~s z%Vm1p-e`vwCyy z_gh1TLf@R*C;8tr-zVm{`;v(MFvkiK=hEz8#8^Sb2?u$nH4bD0s{*jf{l<`woMGOX z+YI?2w!DyM4Sdt-T>W=IpHJQF3`WcaF_sP8L_25LReJ=TLB_Be-{^KqD{J!2#7kS? z8`i6w7vF5`py^GGZ)Qa2o4>&evUXA98`{%^Z}hnejaK2C{#L#ruW6UY4{QV9(2gI< zH@BI5(~?b!=o6D~o}1fLjvM&Kj3KsxZx+!0=H`43{8!hLe6O|RWAtwB*9Kn&e(K%* zs=-&s!z1p5uVfv7=+wgXv3z$YdwJ@6i=UXD&pLuU))VBi_Tp`AKWfv*(tIZ72sFFX z;aq<7uvSL1f&E8#|G~Vs`8`fuMo(Yu$BH_Gw#&G}9Fqn;y3bURqzvChek~r}t9f6y zl$ePb{~iS0GH#T(%)~r&Rqmx;iG$bSXGlB-J-2zHt(|uh@;{GwINuwo5(}@>W8j+y zSz_Q5rLMvH9DydcJq%y><49lE{Dv&GJQ@6DjiUDLK#gHoDrXF+n?+o|bk+9z`%My!AHAlhxj`p;=+?O=U7{eY|+D1fGdS&Fwadoszti~%IiAo8S9 zudLmv!lvZ~MtgJcS>#)tT)xqHivGBc{-~@o_&;rgH_71tbw|S^t`+|0du4^b^N{yS z@}7q7lLy*oYW4j30`CTRXLj01S!ca^NyX)??_&Ne);(qNCp}9pCqLi+tX5*QZ-X}H zCQP0Mf2OH0(s7x1h% z&otY&jyY@Ap_=cJHrMcN$#n80>vgZr%NgyJwHRg|?S1Y9t*)!dCu^3dYqN7*66@+C z>S9cF1$ol=mPx)#v10$;fAnv9$MG-EB%ZLEy5w470TL&cYZ=3@Fs{YNlQq1POTudw zk#?<-E_}C)>kEy08E?z@ZK~z|0j_^x+?zh|ZS3tQ*D0iXjAuf}SmSz}nLoleor%2^ ze_MRh$L~ljxu1NG&`zmKXjW#%c;h&4=5C|BN#}I#e`eN6UYWDaH)xQ)w3a{dYIw~| zGjHVk(FNxF=ktE4_YU4K@0NKQ`7cFg{)g{@1qF zllFJwS+?<9?#1tw=dz!J)FVE!8IOAHQN66>J4yVE*yl)*%loKvjYApLhcW{!bxA$) z{4Smg?k26}&??V_URj4P=_1eTeji>F8G|Y^Vn;H*S@me=5_z|jm3f~tPlwms%lfp6 z^)cS3s8ilm=i{HgS_h`GZmu6#_2t*cz)aqg$i8aAb2iJnV~xGmo0`{sZ%y_4#x-mQh%1$lzrnU`U|nTLMJ=17 z+qQ=9oip_H%LUkVS@#`C!f$2`Ux;tz4tNyWY}%7<<@kl=zdh28?-8zq#<8s7BwHsdE?a>89NNoa`5%#6l-|taS$* zZr2v-4>(whKbgG=z(dAi^4=Fo-(_F?vW%gF@DFXrSIGybJaEdzS9w$OQA*dRco!7K zm4w#fV}2KI60@9Xd>1Ntw%*dAD_7;d|Oo_hSqjc&k-+ZplDzWje^n`7hxFgZ7W$7oV_WFIHUDb9|6U_q>p$v_ z+JDr2snLI{(HSxHUyJK%IZIgfPY8Q@Yya{+gS?~O^E2~ z?+&6PEEjO3}qd-o&9t?OS1|R*-yu_EX(d$o>g!Pe(>=r!Z@xc=BW?Mbxm*0&nc|AIrG=+ zyJ&kE2{z7nWyHdN=Bd9R&Lnl(cxS<%@>H)ugWTU&)!SQGb#vyuvr@HktH6I3buYXp zpKqA;a+Pt)v{>d(*lz@PsJ)gimwaR3qjCI7nKM=j;=QA|zLowm?{m1n(Y$x3c!zL* zgXMlS_fxo+_N}8ntz1Qn_d?RIGV^hNDfi>``@>4<2yY+muQ2b~C#47XIp#gj`*WXV z-t)XK_oK~w_DgBc{cy{DH|{UvUhK;Wc<9@>#_R96PP9DhXu0lex$eRB9`Y8zqd~rB zt13w?si;;)$^8fTQ?f5rS#|w3(H{w`Cf6srZ{7a&+Er6t+_B-F-LXpNs~+q(wSC31 zDgIU4?|IbLK52$6Y2M1AkM^8l>oBiw&Dx&hW1Z!R%8dGU?it(H^6aYtYkB58^fmu} z+haX<+LXIjc3#OExE9!Byvy)y#1AWcdmQ_$C?hZ7EWE{U z$7e>$Vkv&4d@onnpYPym7wrq>BM)a6?Q>QuTN}QUtHM@I;=8ZDIchKBq)%fv@Fg0) zk+*&?_ef#;lC(-?%W1JO`N$XLOrKfyEcpuT3okX^m94+4$+v_RylWiq;+rV+@09ym zc-MU1Rr)vP?D+>e7pYsDaQMU>F?k5YUBG0U*-Kn zc>gu}`$gZjgzYeBsMrDx!=Qn3lApZ;8ru9cbj)3!%i0dRuaIw8LVTYUI8^Nl3|s07 zeLPML%}Z28p9hA$1?c_I=`)cO(H-YO)hZ-F7ma8V4v`y?)^%B4Qw_FFtk@gDvR&C>+emF3S`wiT0 zEOLomsM%S`vr1P%5_DGcpW${DUdbHcOO=$Xbj@_w{Ifbj>jw4$+sJeF-@9+3T`k16 zgs>-zi@RjrcMWriVvm<~$t=V^6vXEK(O{oID%1eZnwhyVxfMUonu%zGRC%u8?DN zW@ys*9V?!6ZXZ7^XL~5V!w##CQH(v??wNxeKFhaDi>viL+Z^MxJ=+5FVpZo=!~lZq z+crN|-PMI_@6Wuo`GdW+`(o74{us3kyX9PG*Uv@7Uf1rASHlP5Y1>8K(8t_=%C*?< zO4cjV-a9YB*PJ(2Ju!bQ-%`P^#y3$CbFMV@SFggS5q`TGx{kj-fwfu_)MM2XG`zZA z-l0VCRN)^~X9dPAbp^AR;zPWd706%eI=K&d4D(x=s49%9YAavB`9)D>oIVY`;K z%d%%hdZKp%F_BtiH#|R4^~rjzb$nMdCsD112c=&E(5xuQ-maV2Lxg&Ftp*?ZCHM_} z!ya|AH(lre@5*PdICw&Q1~)tra4c~J&-o;?L&?4NKKS)-QrDZV0(-G*W?V7#ah=F}dyPkDu(#n+ z=s8*KD)_d@HS+}HqSM@mxj)7IcibEF7SwV7HTTF)5ZNi^+qwX96GU!G*{fc3R}h&g zWe?HCePdJ&qlaU?b7lU{=u<7t$C@@`a!vXbzpS7p%^L)>c{jjE?D6Q1kMozZkEJ_4 zp8qTOkKunT|FQh%@o(oppMMAcIs7a9=kgC-?AsS)kGg`pid+k?$x|2p)2`0E2l>yx zLM^OACJjGraZT^c!q0nq-OI1^dsdG1*E|b8Yw4E_#jb}Jv5s?6tmEqS9jhLEw#xPS+A7z< zFGxQ`{taAzQ|zjnG*+!U!1I+nf1I@aJpY*IPjbJ8`%k$)z`ck2<=lVB{XX8m6S}LR z`yJ@q&EALGid|p4UhKlQKPbND!Tsd_xXSf>Pxklxl9qV7$!R`-!$o_}>s$AuqwKosyc+F$f} zZf0=@_USa_LtXn3JkCJoW-pdoX5c`st}S_V0WoUtLUF0@aj%hw`R;K8d`GZqw+%N2N>+ z^^JR&Jv=F6(x>g?sl6lKyZSN4{NfwDv_$s}W+$j~XZ2>UPi)ZB>>Fydsem-G1=p?a zP;zYcM0G85%I>+$>&x>C^|{r+e(IQy9egFB(N4ZY+ji4dv6Itz&xhRaA8Hr9KuMK7M7qo_s9&0rfE&rLRL!=YcaFUgsQ?%V&SZW~^ipxFlY z!ooMhF3|qa@33F!NbJv%0QD%Ix6!@tWR=E`@!LGR80)>8wJs@(>ng6Rxz6<4(b*2q zTUqNnUe0v|*Ogq4_OEyB&kCGg;;IQRag`?h8hyIdRTICIef#$D{2_nv5N-Kp33~#L zS8I+gaUD1*`5y2G4p8O`@R_VIzmTBTB`4~A_|2QHnxk*Jf`dJ-zz`4q0ebe(1hw`X z?8&@1HE@7uU%bg44<1)=0MCw+zLEVsPEJtO(-YJ~;R)CxaP8-DolKgjp6&?#1E%e$ z-7wTUaHz7qmi`%pZ5!Bm()Q52c008G;@%mwd((}ZS^rH8( z0uJ64X8+kD>_w`i@6HO%px$9|YA_iZJ9=E{MSsr2tcE0MQ)aO_UJ*2GWjN$g(y zP2}(dK0pW`K>9Xt2>R*M0R0)HKLhk_;790FvmY<1%*$-(OZvHvejZOhI}fmaYH7aT zL4QjB1n8$AeP{Mt8vUA1{|4ySApI+SFMWQ1zL)-u>`&=OiFcMxRHl82k6G_XDh~{< zrcKqZz{c*;!XeiHW%?!!DE$9+Ea4C6ho^PW`l+{E)_o_FMW zI?ty{{;uU6WE_s&6&n)UzA^WDd{gkv5g*(|JCd>&ZM{ zboGu2_@i}*w5JJV|=pNTz`sxvztADtFfz7c|M)A4|%?i=aaeKUE~@+^qTFp zvwLegCp37%j!>`o9ol$=u}NS~j=KFh)?Ur-)(}@DwtuAVCiZ!exb1$%H6K^HN|)hZ zeae3~#*o$d>dAeKLBfoKKIHj6d9L_F8z-?QNbHhBJ(lE9)sE1#n`alfUG>Qh^;AEH zdOE|w*tJJy2zmsI(BwGi8MmXXOVW0k`xKiX`p?`KxrY6aZ4W#A!7=zAqqr`@=Nv*i z*%P^zylF*`W`&-l{r5Z7^rFYI`WHQ(6&S$t!Bxo4N@QnM)(QO3ljtk6Euu?;=n`p9 z0DU6uG20<}F?f_T2X_6XNxnnz{3kipV;!BUn(S2TQ=M9y0_dkx8BX=|0H=C!rMrPH8Q3{#dk9R$XLzs1S#s<{;)dWlll_iL*{^yX`&6%&eX7|nxrY6f*A>5)6=aX) zb?jBWo;|8J$R5>`7>6=vv7SAy1MIC_!ye0}>;bY~_5c~feYV_JWd+%1IgroqCi-Fq zZHg~;$sXl_*<5$ze-i1FxjtD$yU915`>EVJ$QR~*4ENdGf5G!Z+>hfvpZlZSf5Uw| zc(T`XAif9tvGc!=vHD5!oF-3vDt4CVVeTE>@e}z!B5q<8ac{KnWl5dU+= z^?m(;eT;F!)Du6Q``-SbWwe;3i;&=IE0DE`?`-Q3GP z=()uo7|inll73^ue(^!iP5x=fP@osjQj73e61~;vAC)-?iMiYful?WZhtlHR^e;Ae zd9uH>7@NJ3cK$!!H|oY*-$0v^DL$Rxlf(B^W?$7vU$xp#QyB;K^9SSUhmGV8)8plM^@P9f^;(rOU zxs?80hK-)Uy_@SI@)y(JEkumXxM;N2NgkE~Z<66J$N`G*h$Mrm8 z<3Bx}@BeHq=^H$*7nWV&-`sbsKe*B3`eKvEwUM#%%WvoUk37!vCq1seEX(t6xhCHq zT;p*aeb(bzcTJ8zxR`4X*Ei<+w{pLY{mO#NJ+2cg(T%;mFnZyi^&?IZ*NwC8_6M7H^f9g^W)Z&uW)>k<8(sE0{}W z9~)vjtWgnJSi!Zd!H~2vp4DO#C0)ytY`JERTGD0RP>8zZzl`5!Tr=mpS-IqA-u0~c z$;*lL7BT0$w`AWW*+5vcx6e>C@<@8ym=M+ z8lfxq^(^^}vI_AP8{@3+_Vz3ZTJBGA{~zx4H93v@x_wRh{$|ocr0;Dey@vGNq)W^` zvaXML_9o9{z9us6Hh)(8k{~{JrJUn{-!1DWB;WPi%a~v0n`Q5)Uy$!9<5_^1UXYmH zB}>C=nBYozL-3(Yn)w{L2ynjJS@4u}@g;w;T%S+T?s?v88}qxvu26%cI5VO%F&t02 zw`R;04g1^6ywXF|_kvNk+@Hqxk#(U@81G54yzeyY(L-bSPJtMs{M(p|2@q44eVIl= zduUvaHs34%+Oxs>vmrc_eVK$ViPx{_NO}IXJgilc@)wckJ|mAw$0+W9$xqf{X>B4# z;$IV25+Lr7`@1;yQ|W8YCDHrnVs8y+iloid*Rw3HGs@z72OPc2XRQmb zk?(Fs)9z9HM)DhBU?4H1PcPN!l6kcuM!H7lvMI=@GE#i&;jB5(=*dfXQ0BeP@|~63 z*BbIm8`Y2CJMj-*FJpXi(M+wZtYbVZb9Cr(tvtG1c=yBC!fWDrUo!9OV!ZQaP3HCW zY%;&-Ts5)2-vzOm)^FQpqSs}8*4BB%i1+Q}ZPS)VaoOOVDSI}1Wl6qO^XsNXzzR^lwS-iHd<<3{USbc&3X?fu!uiuZ+(TY3H-Yw2sLPxii(^#JC$TH)J- ztLc*h=sE-41?bXGu+65u5*=^mmA37Bt8)o4{?*PP-|e4{Q^Vmn#wn~XlsGx@@-Q)U znU4q(M={6q))+5ar-t8^Kd#2hbkyEAKYcA#VT zh@O;oKeCcN&<)!l@%`X9VnNu4nn_Dt2e1tXu?+`^?;j+-{~5O7b8N(C%m;kVyg(uH zCG#)#9&VSTv*M5IYV+Sw&-WZ655)eo7$ENv-2Mn|h4viZV%8yrnAZp}uOaj4Hs=3r z=+1UGCzO=7S4Np-N39R9k+pZnnd4Y^2XhtBYOU{K=?CUWB>g`#lS%?yyV)Btv|+*y zWPIeY{a2_9`5wn@w|TEz%AWi5wNr6E!aKFO<`wpQpEE(nCq!Q4waI!V@h`M>f_!7r z4_=f$Phbx}>Fc5|nMb3IGT$P7{ZVOn%?#Ev={!AI+p`c`qs?c3v_Y2xv2`o>T}+$I zx$S!mo^DAFj^3fmL8>7K6X{=Y)b_~JeX^W-vz_f)X=fSbqP0_W&}Y0$fku&wLgXt< z8(CY^;=1%8vZUGLP>ihCT|Jv`tg**?mK3zt;ixZ;4@AC$=pB)P z6xt%h3C{ko3z zQ)a*VsAmxGtfL-too8s@73zu@WlJgjegK-%4VnfT|02t^tckpU`%fq*Ykl7}-xncw zR=fNOWg_LWJ7srM#}3MGH|mfzmYQ8NWawV>NE6jtV?~T*-vFLl~ z79C^dN71VvEDNt$&wGUbod1X)`9I`)j{9aOJ;izx^!AFEl#$EXgKVz7 zueZ>CYvz4b)P;VKJ@CIIKkI5n-2b-U&T{~(tbg`zI}h=2H9{J;8C)@eagC45m>)k$A_ zRdsFV163WgwN8&xkM^AZd;520eb;rYgX*NcL)v|kckGJg9r(f*W8dW7$^JGEcF9v& z5Sya1mLc9;*Tg#t`sb+`q-$%4(s&1L%%y!@kdeOpNMEh6&vpl{^H`^2-luZ^vxfT) z{~vX4A0Jh9?f*|^AQK1>FhDR7fy5d#z0yhr$1suyNP9@HpXC?xZq^%DS!XdQzz1KeHOa=>-GC%UbENU=j^ke_u6ZH*4lwY=sTdLj>a=1)H}BkCwcB5PZgi%2=vjvQ>=HP z2k~x>LBA?Er8A^wLrd9tN5#oInZ(Ih)RFHU#y6K0ej^qh)AVyQe8T+q&~N|7n2kV7 zxS6mQEXi9n7N%(K`JuLl|L2&Z>W9w{vpw?HF-6rGxG%nL08<2p`77)t!uxnP7?`3o znI9XRF2Opbu?J|3=W^B}E!y93EqjsdH{a?4bMt3#MLq-f(t_XZO+MR#>qvikah`rH z{OKwKp8^t>)0myEBNE${dGTdAkV(GY0Zz(C;r5t zul^}IMdps!5%}!ayH+J$A2`I>Ry*KFH{o|5O6Ppq!oT?3-c8(Izx%K~KR9`!;)&O+ zsR0ANpZI;qNy%4igfj0YZm+~4^V&~% zA39BYdT`y_+-3NS1m;?TzUDo`%uip%c$ZD^FKNirGPwH=J0ER=+<`}#Oj%q)LVmDU z{2!BNCAlz*C)0)D_-o`{2MHhvOYBG%axE_968eGVL(3?`W0_JGRX;gjb*B zUym#zglzO#+{53PSJAO4obg+$%2hK+ifWxSB>al*^O8K{; zPo{4pyU;Dux9`)p9d+oSH=}o^e^1fBCmYa1Z>e$1dgIwJAy|>w{~q zvFp~F8kn=gz{*S%tV}k~Ad`s} z=DMPFcQ<#E$K*f~SQ&g^?m)JETw!Kn^T@)?eE(5=*kiXZI&1h6bTkHL25jDkf|t>% z(5?BL`krf`1v3-M4Rj(;iLNG2_-P9>Q%m1$1T(XRwA$Q2lz!^mEa6+3Q!@hFv$$W9 z^J9;%SQp;ItMD?{DnH&kOuWoag_pUu$xoSj=NIW`7Z&L~W#~eFV zYee?-ykKP-vp$E-E#+gZUd-SOz7w1b`IS6Kn^>n^{Aa6A8FiBBiYxQ(&fK4PwKk=p5gW0u?4yZEKddak;l>sgNrB33VykGcJRrmhulk-ft{WQcJ5fB z{_&Dp_eYhr?hh9s%PXsOpITV!J~_YE{r)_3f~C~2n0gh~D&5@K>B!x337hlSQ{;D- z-{mKbdClC9FxNXuL+;9lm_z?e+WmgFXD;dUNS{yoLek4fe}eSIq*svsDCvtxuOxj* z$lZCYNMHJ~U9WhGbnrBSukoI-DYWA=#MiLCRu+L%bm+c<@ve&*HvL=*`ZDTX zUNAZ!{(Flf$lvK_xdZf2F>?_af@*X23~g7fTV$7->>YdQ_x;8C*#q=_nN!zTUu4hF zw(`t2=Hx-*Tli($8!vh9H;D~ne?MQ72^WG!DqL(XuQ&g3a{TYA0OMa*>-0Y zI2ZD!J+?c3Jww_<`B7dtfj*XVo$M{|RoDWSpY_8vi_ZJ;vwny*LS%E#Ji>m%x#leEsQ2aq z{XyacLm)O)KVgk}2z{iN{5<5R{LAC>UF2F{=DiH|FzZ=)Ph?>dC-YZfcXrcH?d%~Z z&`a$l+<~69jJ`ZFSXa26ZNwcT{W$3jgpZO=zlpA}bJwR09cJlVbf?M9F$_-&&xd$^ zGtall^W?XM{8oqPJL2|{zMpg-bS?A&=!4M9p;tifhTd!L$?QjR7sd!|#%3mSuL*bW zTttVfft3n_lZxr9!AmKeIHguxg{fllgrW4&w`rZMZsLr}|k-Z~UFIg*DQ#GmAappmMz1m1SB6HHo zoOJ5ZoPx%#gZ#HR^$Q^<^N)O_UZ-XL8M@YUp*siabs$C6%c_&C3D35p6WuyX=|rWT ze$F~Jf7^@%KbRjsdeK67jN%&fz34?t@k_QMftlz!2{yZtrp3&;`Ap?-M=tKdLS^@E{3-@9CyYA4omX zFP@=nf9E<{I3ugBN-r2!M-Mjhg7pYzguoK{(V4SnOdyPoS#uJfO!x%x9nh)JDbVPa z!|0f`UfQvbc0CGx4BA0@KXg0vap-Q+KY$KFw?UsFd<0*Fk$crTduX(6!Q=$nZE_}A zjQn8_HU)d&ZMNTO$k}Bry655H^`dW=Gr8cl!)=G%8oF<#?><7~i;{xL+DwdE51 zBkRmL)*>xADX4UhrPc2D(-MOprZ|JAiw6bIW(*GY%(DmOoU8PVeWsq#l*{;@Gvl}7 z=dIKcl(ofUw+B9R2%mHj?ANw}wSNkIq7&a>gA;>VDHwbge4w)knlr1jn1A>~=Pdp? zuR3S*4{r$W+J?SRQ`mj5F!LCr^IP4X4QWAN!7$gKne*EV?15_R&|6N8bjjGuN1nQb zebmc7DEb-M3pWw&VqYjR^@xmP*+-Iz`S0_cdfE5=G`cA2zhrQ{?^3SNbc$r9_AjNyUi?v z=+MHPfkr>m-|!jY{)O*}U9r5EX+7ge2(*14TX1Ar5-+-<8+pEm=R|KN|3*Cb%6%uX zz6TjXl=_FMyP?av6$G)104y(YVt>-QIv&Oi%X7Z4Fc}Mix z6=u78-@I4JSf%gJ(f3kLZ$;7?;e-Bj3q0y#_*-OehgnPijXv>n=bT2FWt~0q(C~Wo zJo}-@f(BI~yJcOCihL~b(W}09lJ|Ux*K;rVqlSF9FgAW z|EE*dY5Z<8%WTMi=PI2L08npz5AG#Z>M5Dzji z(bY=b{*5xq+L48>Rq|?o&1{<*Lr3=#^J^7r%Bl;O>*&&(7PS1Oj&2j}8pS^B5*;1m zPWCa8RdkA88G9_b^Tsn)5n{WKfEDO_8t0(vJa)5Jgv#to6+{Hoz{B!{!d5M zZ(==Bx;x}i{mYRvF_1C?BlddN9WcT39snLSZ?fmES z&;C_7g}f31!G}c`IK|Kf)|NEy!Oz0kVswG{&kRz}ue+bJTRNlb zm=s%Q&NNuBbcw(^o&aUH0%^(p7Y% zQup^L12Q^8cgVc&7u})5@yWVF=D6CM(H*ik|I*YQKEJ+t1agpsfanevu;+>o9JO|m z?{nt5_84s>`;6!i_fc+IsY#@uRr|E*h{T_^h)d62D9D% zfc`-G?fd9p-!}DhQO1cEKV0$SB#fQ9HBMgOJ8~vH#&@QfWfl7>Y}S=-@jvN{sl;3N zlv_GXS!3Sed!Hli4YQ2j=9}Lzzbj+>XQW@gUTh$JJ-=G>xy#d^G2;a{^NN|T%)3L3 z!C$w^JRI9(WA2?}FH?7)F}}U@_vPa|pEi+w{v|UHjkWH5?hA+?^Ofe>slgY>+L-}v z#QU77pJeSjV6LGLQl>ic`K!7|bQ=AkYm|=%O9$EKxIKXU4NKYs^0fwiVCvVib&w&tHw2a!c>r>vrjObDajdmFtE_VFuQ@n_KbfNNa= zd9a_0uYt+vH=l~+=||1?soY+XUI$ZB&=DB|A@3a zJp#S7hH}_CuX+x?)7amD&IHcUS5Lmqb(bB)f54CDerel2ByfVTm**@x z3jLTxg9|wh?TMo`=!c;tKhf`~_qZ?k=fwZB^&Iqj&|H)%`6~Yk{{cPMqVb<_82T=Y zhR=T+y2zqQe-m1Cs_K2}^CM`{sfy3}9@-QJHWnUi#<#`ArI~T*=0Dg1^}L61;)754 z6Jtlh>j-<{%S)O}o#(JQ|GRz^D(r#Jf!`AOrT4}n_(a>Z->_!*ZcKD}GqLL*g5Cig z!=&vghAmJ&cS^91{?j6Ry^6P?2WS0GN=OQLcG?2j#ET7+*h7VD-*A`XN2D_uTcKq1 zC}~bGZpgpuLhx3OUk-!RI^B8)kCnjM7DpZF>HVI7hb~m+ z_{1UT=H9J#%Y0t50iOZPZ^6+j{o8X1)bV!3hmEcl-P_Yj_a<}L)_^Q^ijDiL(!q4m zuGl0l6+89)Dd^zlHg|{a3@k-{eG~g_Bj+S#r-n?ZbN{^N&N63nmrBojy}NR}dQRrQ zNAz&WUBqr9>X_+5mfT!2DgoPz@rF#bEv4BT=NrS)!M(8%-wiKvcKyKA!F8B+>+`Yq z04t#E))yv;4$iP!XWZQ6w+A}WMMak+>hQ+DjOpPVj29<7aVosA10GrWEQPR)HO8Pu zd;I%#=;G#==sgQd{;DqSdz4Mz%Q)P}k9F^Y*x8ZC<2R3}_h1KEF81qn>yb&VcYDNs zeGB+&M=|}%FK3AE!6vd??AL2~X5)Hy3z+`$d93wfzdn12VZWX{MDI@-q9gw??AM(` zz;X^z-_aj9B#sYy(RW*NNzXORZFJ+EM+)_&w=$>MH)Wsn)r@gnoB{@LBQ}R( zpUxRlbPi$8kD_ZIRF@ZwaE289g}pXEn3z@&Jjppy;~Z(jhTX|Jc9Qd>#`)26&0+WB z=vK8Vbo)NyI4_-C(W>m_Pws+VO?WqXZ$|FE1)YBbviYspx^Ea0cp|+(Uxx0f+c8)_ zy%BssU5#7TH`$l9EwsbtR`(?QXJ{J<*P)wmvYzcGzg^g$Z-cI5%rua;m2hgcd(vj) ze$UwTCu+bCY_RK6Hqm!_D4z$N=Tg44^gDK4_J3c+7}rGcslYie%=vCo@~oho@gfT) zoR2*jVa|1vz#PcgPIRi1z#4?766X9@UW7jRF50~edXeN2a!2O#o4Ovq40c`CsHKa? zxR&A{tuq7`V{eh(xhzQ!Pg#%7VZA%yWWLKj+_XEFH9+Q6wLS39*A8V)-5yAqG&o?{ z9oq2uVc94und4N()pX_p^2VNhoS%7KVMO!5oZeJ@zm5I9=Q!(2)-<)Yq+dv^_uwnS zM|s5dF}#Q|$@mppj%bK8sjN$^onfAjkXO?hY|h2Egt{*X}j9S}&%-Y_=8YTYAJxffC@Z0J#`p6U9A#&3F{l*TZ}A8)-c&Sdb4f1+^Kz~HGQ7= zknplrRk6+puA;9**_(%1&y~G7b-x>X``@#sZ9^tun{r=aF3OU}g$^2>S4h2z}l`-$#nyAfEDXBfN|H zl)gbe(7U1cLQjXzrH-2kZ&~l|URbP08hCdrbPj1#c$PIgQn%jyd)DOcvLQylZXvCK z_f9b9I+$yxk?l;y7JWMHd<8 z`jmY`WB-tSMD`Qu&#?5TITvM)_A=*s!OvUmEBn`>%Cc@4McAR!;xDG#$i~qwvT7`l75Erd{E<7I`V_i4&LpDK0x|@=swbW zMIOpGviQak;!?=Fjr0)VWS)0I!SYg8w(40S${9j#NFJr+nL~IUc?nKx z7kmIZ(6Hz}XOdn>I(ktpm-JFFVYlYJe!em*Fk~uaZcl2C=|*#Sb_&m?@a$Bc%_6U5 zhw{htKZP0E}kW!_IaQ*KYqu)sedD;Aun$gISd znfL&f`FxP|wJL;-I=rA(O!-PFANo?IBb`SWeQ9(THri9M2cJoLA#tK3MX##m5=K{= zgiZhX!qI`G{n*C0mo!KF1~*S8Z!c#NjWg`AZ}vBIq3aR7+Swdrr^v|E8b)ubm6A4(xP#yWTkQCRvg;Sx?0Vl3e3u?24|J^B zGQay`yIntbg8dG?Q`C{>O4>j7^=R8*$}_t;DK+_Z7wxO|Z?RF&p)ONe;R#v|8})3$ zS%k$#J%h9fg2%Ysz+)_<{=1z6c#Kri(^{D`hK+g`{H?5GvAVF1h~1{D3v0 zv(`kXI(2ur6Jk?_`~4ZIrr%?l9_d04x-BQCJMxTX>7i zV_-4rO#5`sQ#STP%lAq+*RV5Bs0D{n=yxZu7h3*TB01QnPw~S;g2R~3b5p@VRp!Y)`fj$bo5nJ?Q{I_w&I7nQJ#9<@aMmWT;7Q52D{O^-^Y(x(b-Y@ak zly2jH7x7N)NO$wU6(4tuzfN>zqN9~@et~nn@YPy&o_-(W;2+gawpuVAwO~BJB7}EI z8;T9N|NqzRr|=_j?N^<~xqYM9{&U`GwY)%YM{J&2c?iriNd9|I2B&Pkhz?Rqk21Y|BD)^%l*?!*>cdEnK!Vc`j9gGVn<6$G%fMousm^R}hhF~);_TOSNF81Lj zZllby85dh{u^BJnKMt>fPVW+|#>QFD*o-49@*zV~YhLS^0i4DZ!)}~&I(IIlnmCQ? zn!bq4UUUM2)5zlv${0>#|9bZ2^@g4J!Sw@n;_#wjc+eP5177s>zV!ok;_#wj_|O0Y64uDe>JMn{@rQwNAvi5wq7anLIXK2>2k66FX z!aJRUcj|!`I>Y)UGCPIes2XC(m`qu=?`A8WwTw0HW7a|IoZ`t$2>kQ_IF1VLfe)ir2a#jM%agcw(a&Sf$e_;yGv6t{Z34`e{&*$olWuEI5w!=K9%X!N>)2lPt zarV%5c+3r>gTB_Gu2y8nUeNl9uaD6ypkIfUHB4l~mt#6?^TBj*rb|Hoqak||n_=tOH40yW{RDLu zd_~Xw!ZzW=r zSg40v3JqLEXnY`oe-_I|SmfD{Q?99I{*q5G>#^9oN&Xfs&k4>}Y`!P)n`owM$mbSr zO03s7S9kL-da8+LUL|J#$-8%(&p&9rC+BzCc@@5LmJ+wbjFw9>my0i_UZAW=Ra)dmJ`TZbOHVJp{y@^&@YHi)PuhP^}WnQzL(yV`39IFQ(hv^ zefP%-A7R)wwyDPTMNrS*ipl>N(o7c=5fo(JT3+B`Ob>JJ!wM=9PvTjFM&myeZ9js;VBd6_P z&3>OX`y}$oQ^+Y#vR0pB&Gu{<5v+JdFcZVTObic-UPmw!=g^aDpBcbR+(BC^ojy7q z*<<|ds~+?(zXIPDuYXyKj^B9h>TP|#%vrzknmqkA!Jv=8_q>Tg|51f4P>-%wBkvt1 z27NnwnyfFsz0bg)d(maQ1s=h}d+}KF{~~=Q{;yS@>3>_EZ&`Wbi&^E#d+~W5B3=46 zoBr@pj<>)|TyBfpx$6H7PtZzRSag~V8Jf$(FujrS6bIqlgr`tJq7?`KU;Pj$S@k=naTkfZ__HM10 zaoq=hVea2rKQ#UvW8?lbbT{edJ}!P8!)Kt)y?3E>x9ga(TvydX)~_dh)a>UGiF?`5jRxg`pq~;iF$Xi z#3h&LJHTzgqpCO?ae_PS;asTd1urKyD5_rYbE;ltPNQD%b>d4%)eGKE>`_#`;O|84 ztm*~-rfh1se^}POd&`pRz4&(5%=?I=sk05A2AlEKYx*=8^;hOslxLH!g4Yq-_O6HU zX+R%aJ`Hv-H>^IBzJ2NW{sy_DOL(wN{JgC1{jBTYFg_X6!}(nCUw}*FfsGI2BC;x|Y+C|Eh4gC(^|C?|wg<}=YMeOW##~p#b ztgHc?i&kXdT&9EZ02?xSI9QESaX6PN*xZXf^Hc08zrvpRE$o@S-0ioM`d`GBU-ZJV zrwINfoRF|!WduJw*y1Ohu}#|rmceV!Fz+HM1GfSu99foNG(OFmkTeu~{A=>{sv93} ze5wn+=E+5komtMtr|tRrIMzwYyBrzG+DLl98+pjJbSJnMurl(#!svjfS@|;WKb5a9 z1=I2rI!Ny~(YepG>FZv|*PnhdU;igFpGgWolLCHbo@;3VccSDBY83p;1!SaOq%86+ z!OuKh!7~-}Tx&B8Y>IUk$pY{*UnVawDYvcs4fq+(9pZ~-T`Og4eaN-8;L^KDysw~- zvuySSH`A4`FEPuKAh?;GytnfqS5@ZN7;Xk!*KOWg3iX%G_pG}}6qaS8fv?G@t;aF; zZ{SBfcK*qM(S&y-DNKr@$3wql(begJVbK34jvfR3Eof=S9ptC-$x95_iQjBJ2b~OE zXVA)?{{rK0qeX*-IR{;9(O_j{UimDV^gie+iv}yx1-&|sJ_Ef1`W)l*Jnh*47RCzi zGQ&TNi~F$|e#iVj%Rl(~=L=%^`q51(E!@jOo;%HaJ&d_V_Lw$k3BOEOd=z7_IyVES`t|fZl%YBjH|%T)8Vld)RUNW^M9RBm^e%UFEwO{{>z6Ztg0htRhzcztCA) zjE{Kk=`h!h&aC3bsvECky&$f_sr++4vGe-Ii|{zBBHZDTnH12#9?&-E1n6h(@L0_q z9@aYKvuC(uO2b5zKS$-B4-V!?AKF zx+Ll-XR5FMO8GQs_Od1key<8Um(GR7jZ4AxJO!3V+kD9FX{8L@KkWslv+A4NOUYSk z-3$0Jc#(AO;qd%|bh)2nCq52dPS9nY^F`8Ko>t1zQSJ7EwTp7s>Ewy*olgy4Gg6cb^ls93lHN}Gn6Y)8$fG;y<4$DKeb}}3fw_pzbD9{f!A3tH2FFC*+ptTJbspVo26 zoriyet|PQvH+QG>(k}FAG=+PN9q?M>qZ|37tihUdQP8siS)(cU^K7^dzU@)s(t|61 zBYg(83>~!3p5l@{Y~}APj8uv%6JD+yT*pNCKEZXAkB~4}6ZBpl6U!lM_{vk_HzEa$ zLW)c7%DKorf7RfaJzWWU4`Z{3zPvbH^bdD%HoLB=^(nzotyMUxiS-7LEI#3H66{pv z$mY(5xy@bhFn9SAu-P~8Q$rj!mudrK?VXkPHh1Fl_Z-i>S0m5hKN8xZ?kp_Uqs#f_4Am#1)0iYW4bC57{K?M*JJ2&VPtSheg&qM-*}`ehf(2T{7&Xcx`TuSr*p1}>pbr1x&cmKSOC_8pVdS2S@32$C z4s;uQlkdWV8h0ijJB=V8?cki12llEE?A4-5o383*`8Y89Ld88kA~1yePcG>X=AtL_ z8pi4!fi-UY9Q-a{pHoTuV4qS5?q+ssVX!!(Ab4M4esF$iUhoX(ijO&0e8idJLy-|9 zLq3HJ`J~8?TaX)vkSVuub~u9m>nQgAyU=NwZ55%M9a7%Y=$AVDZe=rif`3yE96<)$ z(Za8n^fSbFqX+na{}AL9(t2~NRLgMOIj`u%Rzexde9z2r5XSEY|GvN->PZPd{ z^jq<8_=3rU&xS4;0EhBr7Q6 z>Kb<*`haj1VPB2AU}JtT58D{A1$uu;jXQr!fx3I7V|k6cFf}hY8=PCme9{)yxM!v0 z2aDt`k}`Dli@0~BsX(uMh`UH0rF^yEwl>zdm$ib`N*%0stl&P7)nKsp5x<}3tDt?* z2cQo^FN0nVy&D=`|N9NJ;a1ADt%k7$PHZ!GjchTnUcyUu?Bn_Ut?tTzZNluD#3C&IHNBkyhP$TZ_gtOIO_^NEFU~q$z0ZBlkc?lrJvnByuNx7 z>n->vg$o1!l$2x>pGm(oaA9`@-t>*A?`B>0v9@m~pNZ(SCkZZWIp0~a-aQFiSf=2@ zRwHYz61o){Tp0Zvp}#ZPH?jm5#+c|}Ok}cWWC<>ee(#|FBjA}jz&L3~2p^>$V4EUU z(8r*ULxX3EfM-(ot+cFn>kZ(-LcH5X+CtLGcy>R}9so18Xo#+JkBjQp7SckzcZT`b z%RKA@<534LY%@Rba^NV?k&%9Y_q&;&AJn*ex3C8`a4*)@Ir<;A!5t#7a=Z=f&Gvu=alCG;lfuVEVx4bEjE zn6OEL2{Un169p3n?+~S*WsFY(6ZQ}5Pxh<`dseJJ&AltupX_lOdt8J)u7f>J`Z6qi zY0g8LpFPZ-AGHpR@x!u@j{h;3Fy`$!c$RK>7VRMK(bo#+L_cfvxnP?9U;A3|d-Si% z!h}g5$MydnFkvw~82x7XZn63^h6kg+1t+HPV2p(h#zYJc7T3?x$0r02cBgGY_vt~6 zf5e{PqGLERp_dJf^~ zq;I{uxe-j5oE?@5zUl~=uneA^KzcUM=J0G5;VC>@N?w)Zl}vgHacQJyke&*i20Z~f z3)%tggie7@H8ElE55l7g9;}n|%30Qe*jj3p86HuUIfu1a%53t9R+;;kg9!tZ7Cm-D zAnBuduY0AuQ}1e)GJ9%L0=eM9L_Q!o46##~!N1JodidY^R>6a%xMF@ueDGJb@I$4o zZoz(uU0swrK?MI5o=Mzl(yK_HPIv`-3V5&!g{grO!Gj$sX^tMW@L=SLTqcaq&u(N0 zC%}K4L;u@_9x^Pla?af6mcv{5;H_%ey9>#;n0z-9F6FzaV8T|DRt23)+Ds`6c(3f) zjh);--n+}LpXV;?vwQ9O#eL+ng6GQoZXMiM7q~I*vvidRCT!zi$~3#V1WcIdaE-ki zOjtJc$$@8_0uD^>EddV}nLt=DVQHjg2qx?f0~1zB8=Q{Agr$(4+8V=zb;Ea`V;zgt zg>^*k08n*dExDvFte0Wd8u7ayoie+zdo}opDyM!PKXPYlOut4^~9QbRnU-^Oyn=1by z;@_B2D0^TAxUdO+cY)x-vUx7c@6KaCERZu)GIWa2tur2AtjOIQTB_eYo;Lh@=Wpem z2c9Zl@Kl@W?=A9e@KgYvDP;GllpE&lJO^$(>cp7KTdQ$#J6E?Ll7TN8YF~ zQX9E9L-0{ccu(E$F$Bz$+`|GsO5MZagcdATQVbWRo#6T0YVLhVZTi-TVdulOcLl2j z165bb|E3u=a&N|xL+)z1H>0+MIN6uy@V|aWE%#>l<=zbL$*9I(jh}lnYUJJwFj3XY zS51bjt<9>fkcn;L?hL=&oq_LzYJAnGb2a`EH_6=@U>aZlQh&oH^r51kMwYms8ecWF za#x0VZ)c6%m4QF+_1u-QLGH@Pde$Aze%AdgcV#>;cV*-}>pnf@S@*`og5V2sSB81E z4s0k0*2`TP8PB@UOnBDqm%B1JYoFol@8_>|9|I9pgcS9ShCjuwW06dOTbO|q*{^bO40B;-qib&;@zhuTEkCg`r+v;NY* zjp=V+^llr`CD^b<6aO~g8lJbXPd{x=ujldvuup4UZxsx2sb}zSQwg6g{%sx;eOv54 zjG+qiRPz($|B@f_rv&6scaTSI94&j`ZNxo8oZPW>F*i?FSPCVdPsi`Z=%#GapCVo4 z{Fh>)MmHUtgPs%~>@c!r4L(e;FY=toxaD1uyNWLM2Rvt`X~?9)$fTbBLVv^A6tK#a z;rqOoNLl4wSzkX5FLBuXrr=Amn6qaoo3yF?tLNYgZJh1qemAlHEOON7R&Y_LdNT8v0f-S#Va;kMfL!?>5^}%FxTVRuCs?7A^N`ShVzo zw1wzWB~I0cHtwe_w%%iVtz3NDP*(AIF@tX{A@5${Da`x?QxM9OG^CUB_%a>@@Gka7+$FlH=~j zc-wpz-cH6$|JMxv5MQRvmh<}(zc2EOm5(#~*tqh^_n$(}1N~;SWoHTg ze!6(}kLLS~r=9ZtAI&Fy9X)1vbe0BZ#}kc>gf_<7<@Fj}BR5JV~Fo$a~jh7=6SZB>T+uU+iy? zyL`sdc4N%;`!)1R*5H-cfs1Z=5BGCaN92Bv>zW=2UIhmOFK6LkHdPFADY-Cfh`h52 z>}9mrz`==&a82tSS zy? zX`fTH(@FO5Q|#q(S5(DwVB@YC5nMbrB`CUC>6!%`I$=GbYy=C$RKAD&Xss%kXeMYB_0{%6v87a0Yhq78Yn3 zXAsUaGtrADz=NMJ7*aoR99SUQ#4lJN+C}!CQHY4G9%7ToUHR_Id9npQxEu-Fno)u2fU4{2fRxd-bK{|-bVZ^t9rnngyBzAJ>YTV ze4^?Be-nn!iS9~N=ZPtT{h14&4J~)Ka36)j{`4#_&{ql8#hwtj<_mv`t=kiSp9#-i z4f|6KR;K$tus@7r3;UDMVcln9jNk8ZXH+WK9|PNR_rQH7=)b@B+@-#X9;H3JrY=06 z@ov0Rd{sPY3*Q#3;vV`$u!@!svAxCrbDZM$ct`y2dar_0e35i-rui*&-`2ODmv4cu zdQJ4;xBhLI$Xe@Lx0skn-iyaXR*^0|X9V1o7hYR1k&5^KX5M+L-~MIUC-@@6jIOn@RRssb2~Ae8pqD4kJTu;l3xS-)!pl zB+qW3Jo3EA3)CLX8L9}|=4B=wWqgC>xg?*kd9RC%@2TXI!?P>N=Tp`@oX_9lUKdIK zB5P%q8E^4rvQDp{tTz(BnD;Ec=d;jr!EZ@9E?-|KnR&>X{21?Eo_;Oq^U3Q@-gldM z471)5{t&+7C-Pq0Tx1P0@Mpq1vd7Cla^y+cx~nJ-e>O6(*xXa%=V&?aKENKVaL4AH ze3<9{+MN8&y;q)-Z{i<9`nu*Sef?8Or?1zVeVs*J0{@tUEVG|c7Shr;bykEfkk)Z*RCCdBV=&bIR_wnPjvL;`D0>4n} zD!{!h&ezw1eG`99PlJ8?*vv<;ZeOSwj$fyHTuU?Y0|m}a^b@~NwdwbekKhpe{I3RI zA$U0X#-{}fDEWhJyAeKoli=K%^7XDM;DMmOSYh~iTDx<&!mItkY1B#lNqI*U=)dC` z$ycy#9(2;_arDXp-Ys|ltlNN(D1~*aDbO<<#(RQw!@u5W5Asa8_e;u@Py0SXpD*P{ z{Hr!CDexfS+2SL~q${BFEgC%2ebDYW`XOi+wB)yg{M384L4ji8r&`ZJ-wQp(pz%L- zTVN)1jzxoI%Z1LiXwqjvXIV7qdC(Iq8m!wC=!`h}cIY(d^Nh>?Hvc=#|8wU51@nId zST%X>)BMA4y&8{iTlk~&`oTQ6hu@{V@VKTIny$hNg8{jO7v?-DYo*}99=I1?nDevn zqqb438_Pq6zI8Rc5xO^ZSGbS=MZ{Oa<1Qf{om))*x&j)#ouxo}wMo=bFn7k^p?PdF$L z-U_d(u;K7h9q>V?!A_ThV>%|-X?Q|-sxa~*#Y>$ajLb;!Qt(t^cq_$A!G8(n8gjWqIo=7;P!b1C&KD+As31V6Nre=u`uvE$N#X1A@_( zc-dd&U&h9_uvwSqH}PJA87~-ZNteF5i8{pB(NA9*@|8h>hn_ITnf)v5kto<;OQ9uv4PkFlp1!HYx|`~*|6M$3t3B{GWl;O|1_Mv}WhwIp15X;i zf9?700G_nuxBUyo2%Z#P)WVZq$C-R3{49F?S1rAMJf8I3S?KoL`?-$_Uw6n;M0R6g zN~f{DmDB%|JgI>w{V#idQ|Z<5q;ECjtCjByo>Z`-mwz`NPx>0)^}KF-P5G6S{zM)V z#s*KYtmF8u+^rOyZ^KV4>q|D+LUZr!VV_;~ae8Cb?~rjkS?%^dG`>;i-L)0hH?GEy zu$R3$%HHg&80T8GcwAtz$cnx+&gFTMGv!8}??PUjYTz&TaDUaxi1?B-rIc-YIsJqDAyU3c}Mg6+A zB)ZutCP5s%9^*bcHDD4c+I=UxqLb$4(-i0f@lK?i9ck*~goA(B? zb;`Y~M2{X!(8K60qNj%_pLWr`U{2eJ0~-)N%`>Iw{g2_x4n8BYxhz-+j>Zd?HE)P5 zxUvZhCwxd0zQb2D+;tw^kMLwGUoml<8-}~Q@Dq8Q(MA3}XA=J6-%HT*Ih%LEuOQ=6 zI8fnJ1OuusOE9pT;6Qr{1-m)6NyeIt!3AFcw^_SV;Wn#ZWNyn?V4vwE{iac1H#@j{ zD*K-1F4h7Ix7jIv@1(BinmRkUdunfDv*0yFS1i0twO}>He*ybJG{n7AdyASod0+6E zqBD*5j%bdbD;5SOiSfF9hwZfsBG*G6qHr)(rq8?f!Gg`imJw{`iNS)+eBQWs>K5*u zLjQ|z5M(;9#;}?6Stotgzm6yH5H$zMm6@fX!^5&7CK+|0*^!QV2GaJyU1B zKPUZ5`!tQ^?kWB!ns-lWd)cG+tw%QsJ`;IW7c%xJcCpcAL%6F4e5Ty}v5RMRuXisJ ze5TCDdlWwN)uc5^3bWW*ie2WsA%f3*RpB#>@p)G`M19YY0}l=C*$6(9yf=w&K>ADY zRvLP~F#5jeR=&3ad?sT=c+Nb*l9}c5au;K?atN45WH^*TuuD>pr>TeFS!8T_xIanT z3tk7=muIcty|QLZpn|)TqTo@zc84x^D_J~Cb>aZ_t2%K2`&Et4M_-~t@R_g1eB+t@ zq2hEf;&KO7e4j9nCt7_o*k~~B)#$(k|LM0E2J^X>ubTVx z^6Hg&bil&yP6W5Nl(H;+5g&D&KYRt) zIpeR+BRg5pZBD|xM=aMB%yL~|X8QMt3VK3pn z8UwpngkL(oJ5lTmC-8h0`Mrprx>E2hDU9h<#&kdN4tQe0kvREJCf-T7kN95rzLRnO z>(n|tGtiS|(_gd?t&jOA+Rd|jYsriDaPaOv=>5* z(188Z)%VYXC+b-S1_9iTq_s!DD&kAeN7>~bnQ#{Q!E=hAc7=mcYfWw-%=5y_>5qd` z#v&`oDv55J?5Im`t6P@&0n^l*ZbX0nPa;!dXmnKs%|ooUIn&ukJ*VE?CHpCD6Ud z-23Q5&Q^kf?B157|Ncyp(ZBd{i&XO7R_5(?dF%b=}(#`U@MwfHjHUIKm*K3Ut^N}XEK&GCK*`R^ipn*2+_6N+EP zEu=RPcbxQg(l--6R-=5`^>lpNz%1t6)f~kapSq7?3F-TIb}!FX@$PEq7U+Y}E1;J{ zAAsJ^H&Xcqz81xQs`y{jYDxDIZX-Pe&3WiW&Y0fCrXRZ#q<4^h27aa&UgI?3KKKvu zyVnO6?>Oo0#C4PY0qMsGpC&!G)W9slCoi1}9g_)$G$^b2wyaH?(2QX zUA%%>tSiPpp@~`KoS`AJJhj&FSJeduA&f5XEWCIZavZJlFyA4MZ1T$?zh#7{@V)i| z<_>9#peK-)MO-C&Saxw^=Mw(W4GPv#UjbHeHTf*$xtV_V`C4#{8}V;fINIeEtYX?= z$}+pzYhe|cqp}ui$H}`LTb2`t4XolZ!q}uJtYRB!*n}B8_%~)m@xc@2zRB2qf?(Ig zr<&!z?kqfL7wcB6F030OKT>sJ?YN{atdZiAH+qnDE~mJ$tA+niqJFN8v)~cVkw?i# z>cU!dzCBUz<(}gUj_F2S+J>vTD6ArFExf~%E%>jaEqjp32<}aECLXYgF<-7JU=CBU zu@S6dn*4|G>1z6M-8>;!Avncko^kr!;yb%SaEf)~gB~!7%0C(SK85Mq=7*p0vtClR z-TZIF25U2MTL=pd&`JDO=mtr9B&hia*UIlv{7Uh^(H!TQ!`2A)QO?0~{X zw}r6a83o(ez)$duKK^SZ9z0_m;f)fHZ@v}$uO@!usGwHGKX$JgnBUVC@i@o(z$k*1 z#D-NnS`EMD3=|`SQn*GZIL8q2mAogoMyKE$!8JMr=ZKFvr{EkH@DrTl=lOw?JIeFZ zO`PL5hvMta#5pF%;T$Uu88}CWiE~W34ClyQa+ly7H_kS2j>vTcLoTu!W8E7!fOVWM zc`B^q^EZV@8CXYrZl!Zqtmqj9>v$M_hQ-r(Y7zo#{zYLf3|~axfBV7ys{5ejY|9z9 zpL4Is6vFUT*4`b@k2mtZ!dozxykLr=D~iEL5BMSyyv3dr@D|7v%U{TAt^nUrFmbe! zseR@N@D|9_#YRca<>GrTf?Pgw5I&Ie^ZT5iJ9goVXg9uy=7YDG2i}5n{3*`O>TU$= zn(WtByB(u!!Nf5ML6KhyU;ZvS$6F}`zry<6cs+t&}^J43{`tslU5 z9>K@m(e(rPPP2S5d?#f*)3V;ccT&bPl<^XLCuKZGS;d|#Qf1;hec(IclTNZWeYhOH zXa)FA*13;ZIK8Yl8jh3`CQ`nWUod7>{+@z|2}vJQUCS{dJ;gXs_J z?pn_V=7KNe_PmT-3!5$P{mAf^(B8|4{`IYqg>uKX?56Xq*i?ejJRSBoDTg{uWO0Zx&# zalxTM3RnBD`_k(L-(W)yo`BxuG4c@|zeV?ecU(lA^uOS06$UE~Q+q#Y1NU1cy54;? zy*=kG>F1eCMj1vo{f<5BEHZh8^W|T~3uXej$i0GtMSdQw1n0ZN#Q8ch z0+D3{IA8hBX1;NT_LX<#E=P$Ie}yGxnXR}U`p8S%8)m%7Ahu8*iC;k6o%{sPD&>*9 z?u^3F3_U4G;VieW*!&7)Rsr`}but z?MwWN%tM}2It4Rc@G62)*lN<3?>#S?@v>hXWlNj>uh1>DI)>b*s# z&&6D@zcWqjZ|Jkgs^YM}oQb8)Uh3Lkx~YM-;%`imaNd)Ma;jILvN zAV@n3PiWM0oJ;t$uX@Onz89V>0-o5r*vKFdVc#@JZke(X|x zQ4m)5)dGX{Ul`{&VrN|_FG zj`OzS^AcU1xAk7v)2-YGXWlQT(#dZXGJ9|4eXgp=Nc9b=cQ4;~YcSt%H z2>O}=eKa&ik-F2u0?AnsnS2)U3WrlYI)?M9WUR=%%2W8Cp#jCJ?k0YU^)B=S&^gc^ef zWuTrw(DM>Y55Utbp%=|gMkky zX0F<%d6^4xr?>Y@hVEZuJeL>P0-t@;urXcv1a}y+HgCe$ThwP$KB!voLAA+eTOfB5 zJiRzi7hJ$9_Up-UJ^&1?z!>ENs%-|or=GEa6<}?n4aH}!ffX3jl*62}?5H&HpVH2G z2ECYNN2Q?~(~iPB9|^f-9)!`6g}Jj*aDet#s_)O>{dGTdu)kf~wC2b7r}&9OU;R^j zSTJ{@%oiW`8L#3l_Cx5|v;%(Rd4Bhybk3M9{G)4A_JVu;?!)NY#J7^@_SbNaveG^7 zL+(SqVrxW0>W)_B=V^_Xd8OK(4vt3J>CU6gw=#HGkB_k70$Pe~%ueQ2#BE_^X zUOe6vP3CUlM{FPMP-}SgyGh(x8C{mB_8hq@SSy?un7#-eTks4#-)#|~>DwK@nxTbi-Hnb1&PNY8_0BqH%s$SNKS$_W(K&R4IG?t0KCMF^ zxEZ}6{d6&!fwEYhca}14A%TFa+6hUgz9d2!^1JdrHV-avu3x^fK77eMr0M(A}d)1{nWWx!sr93|3^0N%LAX#!@cc$gx7~hkohWjvrBpRYn$Gs zOuh4q^s@``1yxqWJ~AWloe|&%__y!_+nu>V!47P9e0#>l+G6h3BVWh0=Pm5OcIO?z zZ7H^obnJb0T#J0=cFOvvp@F6NI%@RY);Nc<3ud4(>vN5g|8~Zz@S5NCffpdZk_Rat zeIq`Gq<_LwXxlA(r!rCZ(dV8_=HQKo86V8YW5^SZ*SgDZA>7VC_m@?q6K33s-=p&D zk#QX*k0Z5inG;K>i?ud+#Ge!6*E4lsZ4#ZcwKkPI1_gIG)&|S*@3h^yF1RbXO8L~O z#Mh2*8D|Trm*v;V>;oe%Iq);V4Ve8P-}PjQj&w#~P!8wdu?4#5nJduaKgL~pizmzq zez|yd@JambEL{d3c^-bwjwR|JBOCb$8OVpoLQW$SIfZQGB=U{-k#lq)6Nw-jk^9!f zufy5t$VqYuoAX%iaw`{~OXl2?hKUDRne^*By=Fa5s1 zSU-D!zAtm?8skCs3~ejVY-3Jhvm0&Umu+vn5Mq3{k9&@(O> zyGox`%6%;dj5%I{zcv|rBD;_I&SaE-_1s6n1!EO|Ig7W{$hs6t-@8ctdHoj zeYAhAgpZJhOn5nID{9@|f=67!OL^d%-U4gwp}x^a;14c<&m4uk@6QE#g}qQ0{D{mw zIWKy^sO5Z>XNtxv-crs(J@f62(q`M8RoD`fH|??A@#`7V9(x=Qo|m@R?p%w!mo(a; zA6-I!4t@w&Z%V*7sr85Yl_caL-yeaVW>nxS;3rpcr{9m*)4jJ8=wm0@0>U%AS78hM z$n+b2*z_BIh&4j&ppM>Q$aK!Kj(Tq{&>tiY`TG60@mtFreh3|pm;5~B7jNfsnD@k& zrS+`5XXjfIC-XOEFNY3K-NCk(K11KfeWUn89E=_?M7@YZw--j&r!^2hN;>OmlGJb4 zrvsCv|4QdJM|05iZRGhno)O)i=;}5TMsF9*BEK!`S;zSpSu1{ou;aX_X{fRDc zIrIwX-O%U?6@SluBw!)$jP6e`GvP(ND>}eRzI9|adn0M+ z{j~X{EtI%H`q`skzOoA%JCE^ye2{*jeGoV<@;S#} zk9w6hcXB7Z(#`OnOZ!>lRo%-K0yBfoQ2E6`9~ePDsB}%}0p*S^W4%V#v;}=+cG7^Z zX*cQU3oTuf&boDxy(3mHSu0snRlSZg58~_9M%odXllZ}aABg4@G$J>2Z^pk4>?jX}MvI?0;w-s|X_@L#eGT~m~L`Z?>^z+EJOx3CM| zq7b}5F?^FBeN(CYb7vBJk3+B)Q{g+N*SPIqHRSHCNG`krdt6pkOP*>5{ z$Jf!54*!!DqCG=kmHc3p*fS;&?&aS}d@|t^#CJfaLZ?7?L!XB3r5*cd*Q3zKpdF<5 zL$^a8hwdi*1LzQR8}u2%NBr(Rk$crTduX(60kZGg#Q*F8eAw*4cdp1kw%<8m$M-$g z@Ol|rawZqwAmO&d=%C53pZw6t3SQ2`*VY6p6r)5m5(*=L>k-ldHfRyuP8dQ?Nj3J zL^@Lo-l5jG6REFu;7+6t;+glcJCVBKSw5&8xD$yrMeH1OAuL??v$Uu@x*bcx}yD0ydfZj!N+5{RR|NH(0 zOT-41b%L{~OZLJ|guB=mN=!YD=x`*x6FG~7MW1sDIf{0>;oAc}#PgPKkG4JO^=C+n zX05~SJ=dk4K?hMtABqlQ7XL~I;mB3`hp#uL*PrHjOW!by_dB4KZX@PfdrZ^q#Q&Cf zk%@Q;Mg^*wQ?ix`Z~j%vEb*707v8)bSwH6me=S zigL=k(r#kUBw?A;Z!xDkSx+ar2j=x2zH60Dd~pbFU!Gs6?p8|Ue4nIr4Bz89!2(E{ z#u+Hg8R+pc<6fm6>Ko-8Eoqt7GmeD7xZ3^({K6aWAX{F|^F2H#x(fMMd9inmc{;Ja z2N^A_r7_rA45zeV;avSRMSdd)BLYsxJ0{aLiL zdY(N(&Xx~+9-AB1RhP)e5+A+ld((K&mv}vXC>}NB-i7IbS(M#3^m;??%vvRKq0ixO zLiAOeDC%~{EbRN}1&n9zK@U2}6>nE8&x>7gR)KMU(T#%d zsxWQAk%3vZ;KM1StQ{-;MqZ!BmQ~fY#!1;mH~o=uyNWes6*ea#>)nI@itWmOMS9cs zzx$Uqdz)z2XqGKzv$v;W5c62%U&cKycjRHSm&MvUhWnt$vTv~_Y0KH?;TOe!lVB}1 z!8yZ!ioe=0zJax6{4bGsG&cde(FA9&v+2kWzlCo+2$fNed8v_4|jzV+^ zWwev0H93$=9eu2w)_Qpx)ROQdkKL*mV<+k`k8x11RQsS{h|Z^ydCTn z@3U8&;@o_a{oxe*gy`-oUX**7QjjZ+42oPdH68`+eZqB>WD<&jUYYmwB)~6TA0(XMGawB>g4pt~%HKVI6ur!)MT4(;1tLrKI7u zcZ4@6jP}D<-4IA;9L==+L44hqk734`2l;e5SUu5g%bq4<|1*TW8w^?XzngO^>FZaY zpShGt?sB?Q^j%k&pP!;kGC#i#4@ciz@vf=4f2Cda@Lm#U*-P5RTpy(F*^~hporxiE z8u#2d9G{3G2s6joo0VS$V{cYAl+Ul%L=KXmY$(6KJ6^Z%bhVr7+GDhltjSVu8}+u< zZYk&F|GxCjsvYeEcUJu=&sqO}@gs02`O5p&K6<5gJ3h^5w>yRRg%>@C9q!w_EAK@a zCtmI@jBk%HSSf3qbnqQHlit90rkQ1p7S7VK`&M`DjHh3x5}#qFiCja~hczaX?|lw> zj9JES^UZIV-<2_*PWt8R#Rk&X^Q$$VyFC3FGyXdA?SI**yUe>o^x>~tWgd=gy6?jT zd`66Gx*&6p@$IF*FCX78&?d6a|Iy4tW39Wbit@yb`AT!`{OrTV+W7@=2;S$4js1(Y zFUed(AEZqGO+J52TA(9`IOh_rU(9$;61fpeVRIH(;l-m5F1e+?IlA7IRS18$UA@I$D zQpJe-1(I62vb(6PWi@V@NeWCz6)`{EgW#Rpi! zO5YUvZ`bXYv3nJy;}0}_QRb3Po+mpbx? zx))^@lqQ(9NxDbZPv!atX61zc-M(JF3GS;I;rG_e&%D1g!Ppobp9D+!hQ)b_es5l( z84qah9m?2k50vJFZ)O}Lp8*dP=7f_t_I7H2KHk}RPv!%SBTO7ea=#Bdskb3VY>A2A zQp#lZa_b(&SMuVv>-^rfdomv^wR{rW&6 zC(d=q(~u8YvhhtY4*6dk8Q%kAkXsy?@%_!n-*;rrk4OHlBlA5Tto+mr4bKfkEb?yz$d0`&ByJQEQuruNL{QuE) z(%J4fM;<*L* zgE)vzQ@q(Uo-vDSZ&Dnn#}CE3{Kf9n?t^gk_Z8i=S$)nM(yPSLM<#gcV$Oa2n8y71 zw~eabcW-V}J?&@@V+Y+^zHDG0%B8kGxrF&!JL@zgL$N1eoXj*!kDnynBtldnZ1;`KIVo_yZOLEYwfYO zc0{I^cH=vL2vH>j5&jW~Q~ac&XRe2lsf!5BGlqHnOV>KX)rV zVf0bfy5i-Ya963vyeDATKDYnk^z5+zNo<8Ydx!RZA&-pzaCC%P9}`;3`!>77#gqZ{ z9WFO@mUnuK;bM5c;`~M8{GgjP53Cc*p3XgG-mtd_Th<(&m4_W%Yg6+%F4S>sv-6HL z*0L5C$IA9Mux8j!V-xoM;r=el@}P8%ar?77+0%vh4*L-EqfF`$2WK3ue1O^0R{AnVup%4v6t86G`q2t2hekOpx=(I z;TT=Fi~UN5vtNlggtt?xvxZ?;k4t17@Wg6#*{luT{9yAvhRMe^kIr2BY|Rt3jyK5M zQTv>9FlQ_{eVu>AEc}7vH+}x5oNyt&0lL=?3wM{!4R`M!7CxEBnqPGDa~O}PuQl^P zbn26|#u+_(5Pkb3Y^Q~%W5QbB8(>Z)U0GUPZ1be#%B*7ckD7m$I^Dx}HL~9nehB9C zj`{Ji;ZNWjK>c`e+jW`V#8}dcd6Ap>S3G-)z`AuM#}UTd2%UGZm-U3&e+2!z*6mKx zy799dqZ?NpEjWB#rk zH<$j6sdw{_$JJ*i=7x)jUt}$@J?9Kfrwpsk(v}3dzJq5aEg4;3!1YeuHS2Ua|KR7a zX{!x#v&L3+GLiaIs{Kaj$5JS(#KFV2WD}-#Zo=nTr;AU74d{2vsDt)3vY!N| z^PCi(Q^ZvbGi$;yvx%Ue?iX{StMVb)2TXE3($kfHk`Ltj#FoTs!AZa4qdx2W{Xx zv|HW#JyzbbR<$FabZMZjZKiH*K_A1K)UF0>%z4-+?KQ4igB#o=T@B~bhc)%uJ{+!W zXWggP@YYplUD)dl_wD1p)vVEV-|F{%H{pk7?IvxEv2mx4u-51z4_c$Uns=9L9j3iT zcO~yClRb@kRb#Es48^PL3`a*w9M@8hWM7hg3BA%(>XGbR-SC56>f|%@^~$S&^dqce z4o-ZHHh(?&!TQ{E{(5;z{z|tK z$y4MaC^s!HM-cf&zE|` z?<^;;?Dfe3^4qM-ChxU2`~PX4NAg)~bjgQEen*uBZ)X(GKptvuE3LV9@;1UVkoQ`n zZFmOCMJMGW!ZSqWIeeB`qk9?sz}ES$#qZE=1R7fTF52^Uo^gVAY~i?*cjRGfmi>Ms z=Qj~{jPu7iU&rxL*6Dt?;D(I7sKY|<#t z5i|b(PiddeJ}K7vUoT^Rap<8H_WECJ7>AgroY9(H?4w%e7|7>c zg}e(pX<#AmO3e!gZ2PFz^ak??Yh=I5^tnx4>`xM6f0ADIC%L$nwZHp#4mQz1G4|QE z*l^!r_Atr2G1K=w*8VmOCmwgU_-;u2VJ6?Haim%MD|;}u;|^@chR47*+|g;T{cY#m z39bFju=XkGX6CS^v8WCUiH?(YMgfUDzKN?qhB6CHL*tx74!smv6Dw{<2RA@hjg0i&36y zSd3sIy4z~j{Z_v*ds#Jo>Wr$ajtuc#a2PZ7&${1g*8Nt~pH5_tl61JSYB&tW(j8N( zu&J~5x0*1*R$1?XC^VdrE zl4{m4SJS7*k8Uoh*7{}Q^#Ad^=)(Ry6??e26KAepnZkU!R%?yNH+Lw1J|J%b@pm`F z9kSjTKT7V@KRd6Se2OEF0&dDlyvj{Nv(~8xmMC9YlU}QJ&&8An);-66&a8V5x*tY{ zEvS8nFgSSa_W}p6wQa9{E1vycyv>IBs4L*#<~^1igvZc+FY^e~elPj_ubbV-elIVZ z{a)@wj$%BplZo$;-pQ0*bX5_y1G|~ccCh|A(PleRcHYWbr5()kWxq-LR217$x{k5l zI*aWnTQ|UVFc#LHixIYivG8ep)NF^p|DN`GVJs|P?Gd(v@o*1g=$EzE3-j(C#>9iz z4#vk9(GdieGu|qLZ4}?J61(0K_*U8~@vfbv@FTQ)=VA7G< zic3dijzaJ3qt0(YU*w^VJIDHWn2!w{U!Xq|BVxksvTu&Dv#TDYam{4dguorv`qW%> z*bWzxvz2u)oC}qfXGX?~Im5+=m^G@{pv)Ro_>h4$s?1H7vbNRzGIl8Lb)mb6K@YQk z%Y^!yqU3$ZH$!$Z!%|w+K1NxKTE8qyOVN=Uf1NQxJVq z>>^92ES*jr>GA^Kpm(T0`T=&sN9=cMT=(i{`x_$nGY)sT-2Ss)iNnVnYdkmFYdrJV z%VpER8c*pE_3TwVdyV~Ujb$$u-`SK;nBJx1dpS}TC# z|EujQw2w80lU*yhQ+BO!J44u%FY!&ru0@GDa= zXE^awnpVd8e{;oC?>&4^rYFXAdngsQWumhN^ArA#^m!4sMS2URi{^vMpX*>micb^P zZQonQ8qAgU8qBh zZ|!{Qi0k%j^m~cu7fd|zhOdzxe(7>ccKVJ0Oy*2%o9b&{f}inDS!C`F)WrFHto>Bm zY3`@(lrH+MI*T>=EoJ^4e%<^`zS3@cuxqH@TuS=8?;mV$7(scJ?ZfkY?lsrkZ^(?V zm+fIb?^T<0!t^NZ#uY!f7-~ce7oB0 z=r;QAHW}W;^1m?)zGM#iGRi37tpb@1&S^k@zMpQIl5pJEXhkdmVP^ zt&fxM?1l5jaKZ}*!vBl#X;JZzkL~l!w_L-~snU0fb8%fyzf2z-qrFr#*P#Cm)nFeZ zZU4_5iS=IUWB}Rtt?sn^R`;yV#f1`U0$@?j-TPh^#TU(@a4l`jAjSY&gJBHh3;L&b z;J2Fc zQMNH`YlcN0Y8zX{^|Fmkc8)NKaWn2^B8gHWY&TOuYo{yJuUTw-xWs6n3 z%>E)1c5Y&S5hqWc|A0K%z_{>Qd7`%Di=++uS;N72+lE^lOx~#X=U`};%ov3IMbfds z%9l7}kUi^4ZZvxBLyR{%zcawW=(*$VcK%`VPHnH+%y(&D^?fh$ePir!#n(He3>~t| zkm8$3e3hO}uo(J}Zev}%V-@e!^L0+;;x^W*e}`)o7NUHHhCF+z%}S|!PPU)@DdMt> z=ghF<6k-nTv-{tV5vFS&q%G1rROiIVns1^FEVgaxA0_Owc3gCg&VSjChwfV%b^Q6L z<02=nL)y6;FInH9x;l?{3~dKTbN)8_ed>4hz5wm)0`}P(ROh1F@4us8RQtW>LCV*W zJEQg*ar+DHwtOb>naFehH0EWrwU0*)dX%(zhIa`vmKPU7oxja@Yg~kN@qL|L2pu%`^;iN`KuYyKwB(ltT;pIkPQ_5OEdJ~i1|@BbyzMDGzVvzWR)nfZj| z9WXPi*dL^eanJRdV^qUX#&ccueVI>Hv&P^4zNy;BtV|hszM5Ye_1kqY-oKpV7V^T8 zzlzK{GfUn&(qD}HU1WWOxrQ*^^S=pmco`EOz)uq4uQ>N2Ka9K$Ih%Qm*7x6q{2fPz zhw&o+J+hwdTyqa$FGXFWd;E?JGcybMn^E#y&N%)_d9azg&ygOvnzW^88gpo*%tuz;>SR z`X|?`edNz&<`41#6J!peJp&SXhmZ6QO<}yWJ)b%~p8Cu_0n1XGR(H6b~_Mn3MHsII)3in;%p1!NyQ{^`Iyo`^UP&)RzP3SQ;zJ_h261&xF zS)uJ7%dh`hYzJG2H|jF_Gs05`8ybizk`vPS613S`=5&m_b!iZQr$3mI=&;sFGxCkaWPy? zo5j^szQBBdadd#W!U{1pn_y~sVQTU|9bsw`+^$UX4d{8hHo?@)ifcJz&S(FyyK|hm zPHoXvaW&|11B{zPHE=bvEUqTRHD(><_R%fT<1!PMtMp)w)~MeW6xeH z#>SqTl!&omZqg-oZ41B6p0IpwE)`?LoJ1VX9Oh!mlZ$X1F$-CjtTpQk;w;u?E%T`g zPk0*NVtn|ohP5eYp2hpjIJ?qKdjV&|^F7ZJU-He&_0YXb-yW*rowHcyO<5_4dyqMT z_0E!CFmE7^dQKhjcI;W%T3e4TD?7asmY!$vyd3zD0J=5JG0hrvqeF{r&SQ;zaiJ@0 z;_Ixjx6|2#{R{m!c{wPpsS72`M*D-j_amvSvuDq&Y#5PT*4fWxy}-QmgINWI+2MO& zW4f@1oI=-l5}o7Q=oUNCF?OJ9G`1GzKEG$abDDWjK=WVb%Cb)c51`jC;<$}+S%>XP zb6@6*k^Ri=?}*qnobJ+5=$41m<+IOJJWUiMwTBe}K!C zSxcXr*zDLaO5$#A_TlHktQW*yQE~%z7<^)M&0^nxPvRe+zF(|iMYXkWKwe#Lv(~_B z?W@+n=D-2Xt;=riNFgkhy#(Ng=B4DampAf6xS$mF3xJh6nT(8$wB&|ESzpATLLdWw z9y1A>(wcR0dMi3_He;H}7W8i_>#pi}EZ^ zNMj4FyVW|}rQ(F|Nk1pXy1gAC|+o3;@oDf>+MLwA4FnKv;6#b^j34sJ_>yt z_v;v4bvMUnIi80PiTUJ5GWVoVCgLfZiTt{2vV7l(Wei_=?+Sd4$!EUy73e}o*3}*# z*7`^7Q8kDmQkzb@5%W9RXUe5#67%OCzN@ztzc74%AIJSVhB52r_^ggy%@@$QsV^{k zjf3z*(<<-1?;n|~q0bdvqNl?c<*|T5Yv_ z{9mm-|EG`8HZG%m!Y*#uAy__-hwEv>4LiiQzYN>iO*>XWd)S3M$j5&lY1Ur@?_&G- zccb@-kMi+PzIU9h$%^>+@1ecum3+|h@lT$2lJ{bTI(x|jY$b*la>M<^^UcM`rF`>Q z%21Em4325HFCB&-T8M6G5ppNzPIE79b_Z=|H*N8yBl!4N-WKwlg`{5tb#60dbPN0f zd%JYO1$AM!Hw=-(oNTPl5<}Fri~fE$zbSD|y)Z*pV1@$4#H9{~sExg04s)&nhNv{k z&p+*Fgeg(JBmdb9k+`uBV2FIw&#yBERenj=_ zre2F5vh(%N=7-2@*>2Oa@$oO7x`8%sGwpmk<@5yQc?-v#e*!xM*Ai~T?*~lvUymJ1 z-C0n^9F6{K5IfXQ-!C>u><}E0VTY234X{JKobRJQKg#(Y#znA0(_p(Vci!SJP<;1C zu|u6)dzxzxb8R=*%0EXtV~O3Qi`b!KoIlQahaGB1K7qWQ^Sd~I1o^1N4l&oy?4$gI z)3N1JpSnojON-)~G{y>wIdkHzvZQ#!6^0aVhcB|@-G3T>s1tsOw!njbE5+NZcyF5D zqPUk-kMwskPaMknETMhvg$>g9FT(NU6Td>@8&6yp@_os0KCm|Or4Z~pM1ALc9_M>F zo>i6QRXVjL`MvVmd&O+L>moW_^XAW_i#dYa$K83J93*mff zZpie?$N%IY)l|VO4UNXXG-!$P+J{bW?LKtZj#Q73LSYnqMSN;259&@%YLU|4>tv zW%#Z>#{P9xHq|NHTF;%dq&@pt$X#XDO*QECp69*5vW@XKGv z|32nC<%F$PnEa4)yp~@LKKV=eU#@UigOwbYDO^6t`7a{e@Cf|Zv5uvhwR4*L;`?L= zzE3ol+`(M(Aah8^=CgF_sQNcpV`IY6k2>K+gv%d=_`g8>J>(nv2-J~Z>?5E(r0+&I z6sVO?e|-7xBfN+>8_vc9$0DEpFfWF+i9;3#70 z0w>Pr-)38i4q9xBTTBamc#`;+D7J-l?t|EtT8nM*p{G%MY|^@Q>;T^~L(lu>Z04^& zn-(+5;#;O`8 zraf&Vd<)~X9>#cvZ(+{c!S39_qXFafWZ{w)hrD_g(Q3C!D%ZoA3wPjmY?Xa*Tie^Y}Jd#=N*2 zKW*r!%pSfg(QU}TNjd+S+i>li ze4=1)GCom0#Q%U_c8htL_qX_E=U(YDW6%x#@!R-ikCHDVdytKdIN~P-e-DJm4hq+P zrDJx62*1KNNoPD%r}Oj_7#ZeGIoRX^=yek8>y%b~*a>&p@`LC+rN@+RNX*PvxG%!I zpg#(tKe}yxe}kjbS;u{Cq=B*D(7tzJ`&?-=B(i5^7T_bDI$?aI^KY(`4HezaXJJsp z8;7RD&&+W6neqOPi~)Y;OFVy<{e0)0;$rk1M=n5au){QOTfkoQS`#ii*JOTrzpmH2 zwD#YT1L(>Qe=e>*z+AWJVJj|EIls|Q=LFLB@*R$_J)_cU! z=wIn7j^=M|S^EboT)wjLJ@IOwF~7-a8^@5&U*-Ha?Q8UHVzPC;(S^Yl+<4wo?|a1d zFP;t;GsWg&+{~|8ujBZ9(O6z_*E~mh=~sR7$BS?B=j?k+=i-yz=3?A%F>o@Gd!MuK zWo)PXoA^bGi@kEdSgkZXte;_jjjxo+2(?Fr`3CLXbIYsAH* z7OULAc`wgxy0Q{~Xn$y=PRq|3KIM)c$7L_5fw&HrCI} z$M`6|X{7V5^eZ0hB@TP@p#_8O7}F{D#?Q;hxz}WGnm%!LALB0(2j7iWe_4X-h1&hQ<58NSV5eKE<>_ zl)urGzY@Y`^P9y_;X}*C?RL1zlJ_d*=Hs0ID8Jiz?kdI#tA09^FH70^BxToglj{cA zr32*a2Kf}HJqw{{8N`?I4yBdKM-w)c5NpoGdX}*myWsotY z`8LLt+7r%v8)HlD9cRAHZfDH5F@BV-Bh-dIntW_aORV?Zo*fP#8=k8tuVqK9>-G!% zuncyc`g+0p*QpTKUaL-tfw_MMJeQqclNcLDfA0vs_j8oXH1(Ubul@A%{duF`pDSV> zZN_;PSF}f55#zkyud7Tk`tC!F>Hhtt3H1#&BQwdady3~9_)Eg3{h}vk#U*%ybJ(FG z+}THo=Z#$ZW$ulP8JIIqB^~q~kJ$CtV?R%OpQtV>pUTLmB;?O?ufkMcO#P+puPdb; zx4&QQr5RT+mKntuO?mz6duY!-GH-yZp&xjhcPZbq`Gx|X`6qETZ8!Y9A68I)V0wtd zMfV+kk87UA*RaM+%!+);_~N4Yn%l7(ea+@;J|i2Ft7SE9yqRkfSL*d+hhB#fdEMGG z=h13d5g3ydlbLT!k7*LKAwMe~IGB=OXNSw}dtv;&9wx@!&K*lpLOC*Tvkoy z-pTi6u30v~!-RC-Gr8fvv+v7(*tPgP?}Ak^zGQwt9wovV8FnR`z3GT!4(ZZJ_-=lL z?{Q@(__uHzV_j$D9mwy(iJ0?Sll%?H4B8{|R^$uFdY7L0GS9TGb^D*^-0vdSy8SO9 zpRupy8sk%@hOm>-VQ@0f5Eh6IgQZzdSbKCB*HsY)_h{a2o(C_plCYl>rn3Dd+tdyb(@ZP>=gZdhG{NTQZGHmrVsXOof7=4X9 z->}RsY(jy?wyfZG^z6O#5q=UnJe_+iy>par17X`{IvqHVtJi6hS;CLs&@dnr< zQU38K;iEXf+7QPtzVs@->fEM^8<}%qFASWBH+iYHM;z~e-jcvx@~+#_t6aTZ+d9tQ zK{}{iYp9=4{}}17zORO|VA_)GQT`v&#%Rp8oOY-LW+k6-dc}yi%6E}71y?BAfDeM zp4G%j?Y;6lnQw8{I)r%ch9T{9OjP^)8qXa=yE>dSh_uh``G(b0`}{|~c_inZ_W1_8 z4OV)%Ij1q$#Z6ZG?99WX;~AZvU$E1&d?9V~h^V&NKi|H_J;BP&+=ZmvHn?)*yHgyi}wnuJjBIi`e3kJ32-RHvxGfUT&S<` z&{sX7$#8^87E7QuzhwPg==zeH*L1*DF%SIy4iA0;D}Uj#IIY{U%MSQ-V4nwZHlIny zr^7zRJMjyfUBg^P*Q@s5_nDY*NiN(GI;sjds;TPpVW}!$sn)Weu3j6&@p@}%V-=oQ!E%Y-Qo zYCrx}dx-2!Vh@qK@elNw2+L&r108=YOKZZrsAFA4@hxY}d03{>n#`2AmRMu@KHBxr41UuS!UtJHd`N4EYq+L%T~-DAMZ|104AUOZ_wnIO8gwPH zCu>rI7$(bKP<#R`Y=YIsNmoQYUH=FS6VLU%OkABZgH0{iNqI`f@Z^TXUeTeu5YF;A_@C9O+>i8GKMBfqQd9+QeC+3*Grh`7DlX58EK5iJMiG_w? z8t@flr!frE9?#!+`~})4Bs!gAU@a!YF!A2-^`q+h&;j|L$O*gPm}23WhQTq#!7(Mk zFXQj7N|ZmkO(J` zian6{28p+9mu4?>r{C;D#)cS4vu@T1$Dr+JtdreeZMSCP4Z{R06j%$h zR6*EE7^d=8V^2TXh`gHP?K~T9q62Q?6pTeDjKzw1Fih-mR>r;;-R|Mx)3q>6uoH8z zLufo`_M+b?|3)x8wWLK|D}JJ2n6T4o-}+AM+G%2#YYhUrBZChUe?yI`2$b_|;{ecfP& zNp)X!iM4@mcEK@GHVwxVu?>(0d6Xe^NydJV!SPHT!!hlKW8!+lF)=<7$COULeSy6p zLg}}gHsz7m;F!J*$3%P_`$T|p8>HNZ+Rz)QJ)+GFa=pes|2`LviR+zq$?}8r8Gp)r zI3~5V=($XLvkQ)iJ#Kv4u=^5!58qMJs(pA;cm9gD{0i-n+9&xyN?UE~54gtoKw8T) z_R(hbp{F}b-S6SKWwb*p*D=mS?n5p|UX6SLxf8hvxfuC0ayN1*@^W-)yi?=$TGmz^ z&^mT>)j1Z+^n&NZ^5>b2FFLEwd~6c!c?Ip%TAO9+vsk93%xewH#P@#%p0=CzOf1t@ zo^uet3y1L4;BcXb@Y&ERpAChuL<`qt9ipvmrLEOk?2ei1vRY|t+vK-l7W%+Bk`E%| z2Z?;|oWV7)1D*0evW4SDz6X9l{E>7v9lMZcB8wrQ-8OCZlKgN-1NUx5p3b=$TuXc1 zQ3uCFd)!x)VC60LqK*dc6Zg?ceLD@4kWmosn#oTb6Kri{ZQpU~B#g+#Sq0&D<`m%H z4<0tZz;I>qD|2B{LHM^z$e(@pww&qwDEr>HY(GdIi(#6T*kbaW_H+=#bbxp7m#-V! z57Iu~vzK;7evpn>K5#BWqjAl z*XYOAlNZ=M%aK=0-hhk`q#|VatAp&za7eb#Qsm{5@qt928zP@o&JVH9|F4#x^bZ~M z6OsI+-{{zm?Bpl?MSy-o{fGJy<)s)br!K0FTK8Jkn1^6ZEZm+u_+>H;Z zh+dm~4wBDe{Q`f1yf$+%@^hBME-8R2CxpIgxkr5fmg}oji^3OXRuy3mN}M zl!s2rMa2J6R9-8e`>C@f_q!JN(J%cLf4uL|ZuGemcLq+h@_nr^B(zmiNUzfzPp8c~ z2GdgnmvNl)?S!Rrej?|Oah$?hPR4VW)Bna|Y-Sa*N7Kj_!~cly=^ItO63;%&`8JLdxjr75@z*itE|qCHnizthv0@nc@$# zXRyX&#)n`b*KK6nv59fWLXI04vo*pLWx!0$;W>GP)pB0U$t;fHP?WwN@k{OAmQbJN zH^|5MUwiVFuy(B<2I2}f<}<9T>&CwPGIPtoM*2$D5_FX&`_rDKKWo4z&sfIO*h2eQ za~s;im<66A2+NW7EORB8D{)O1@gH;r|3P8=2Z{Me`*3B}dHe`nI1n2?ga4rJ^cyoh zq+e*`aN=V5+xax@hUr7a6iw$FX0*~Tw_3h~rf{6jaTPppD(5C@FQ+>!-$B?3S(`Sn zms2w5Q(7svb?6$NpWVyYvX8dJ`4-jXAaz;aqCL^{EzUQn%?eWAL-I$cZ<)znO{}-R z!g}j)UOa6r&*6Kd55KU8y~UQqhr8Q8ZGFo=_EEFHB}96ufB(XF;EGmSzJrv8Im~C$ z(33=%+UfWKno$K~3tyC>|F+o?o;DT#K@+RsX)%+4168wnS)vz>pK9nCo% zzCoPR1#Fxe*WW`q_-mz6q%GT0MSPTgFi+d7{(qfzVyv9BE16E66{}Qxlf^2X)qD(} zK(!MrR;dOqO{`MwIEz)P!I#qz=4pq`QU%Zl8y$J9>$V-T%Q1)D%3Rj5>y4T?s{Uo! z`LGvmML!}NkB2bXIk&>R6h6S7EYyJkw#xGTWSA&ex)O9Iz0wQS!o=0$ALuM|%Y}+B zEL^Qvsv>@{RJF`MVX1;O_>!uD$q}EX`KFjU=9?jGfMdStxfHBnZ=x#37X>u4iv3)am## zC*7Gbv>^fJmaeLA&i)9xgZVMn`4gH(H|e_$p&yTop|P*ds4@0!%TEKk%zkv48l#6a z_h!u3&%9h?@nHMF_#rY6U`}4l{l-rN>2?cz1U}xF6Ard-?--AL8~xeRuVuGPMvtBA z8qf3Z@Sj32>CCr{9gwkS2lLww#-E+c$KPgN-pM@vZN{J{nb)3TetVL!>M6#f(syZ& z5<9*!%YD78Ic{tWd(O(now{=aHskDN12*p8k-x6t^P1h?xU;!q?>fc{>#|~>g&o_! zE^8RJ#kiN)gM{&Mka6+wXXiFwck`Xi@}+Tl_qwcjY>YSj1m8%TI8Xepe>S&y%!0gT z*))3?SH~=1u0|Yth-1uyIn85{Q&?jspBfi6uHMTyY+nt`7J0v)xjkdGleERZ-^JK$ zH*ei8=NZ$TVoZ0T26l`#UAn!5HTcKH)@t(Bw(Cew=^;F{mVNnX_y0iO5S^d< ztMQGrmodP;Hs+x zbn7MS@r`8b7fRNTYSubRr(9@$Sg~zH=Bixm(66)aQMf+^hc)2~#lxDUV+n4g>^S2U z<_>1OGM%xx#w)fy#u=~luO5bP^I_o-<3BOX8n0+hVAi%By3HTjTiBv;yT&io>Kx-cjXy5NXNNz99A@3)TkrO#JoznbpfBcxU!wlsm~Qzwe{BS;Wb9*MR<)< zIqz?4*zf_o#sS`e{?po@CDyhdx83l*_T#PEo8_aQ@zb{Kad^V7escnQmoh#}e=^gV zZ-^%}*TNIJ$uI4(HcWQr?3w-!^a{D?HJ0K->yzJtSK?mj#ADEbpLrgB(2<$npF&pt zne)gU$l`}o_I$+oa~mz2gwpC)=%DRH0rXd&S`=45g>x(H_bR_sj~3X^SZx14$bSjHVp|^C zr#W1r(qt+5JM{d$+@~?2-an831@`+?h7_jnlHXAiKckO}_n+&6NxaqO3irY!?z5T1 zn%h`wI&Xk0WPWbS8S`1?;a#)|74zWp=G*u7z$EtCOk&Lxe@9;wlQ`eLmpPi+vB%gC zPmIHdiQk9#rSqF?$2Gth;NOUo(oy+)lO2AY9dCvEUN5v5#oUqp|75+5iC4$)H7d)O z?z3cPyexlQ-~SA@OvX^JFrU@65x-uE+2P;fr%kM2EbobN;viPgZUdKM8y%lF*antH zdHkR@>pQnvZI;Gus!zM+H;i|yo{If@jJkf3`uivG81Cy0k0BN#Ouk&w{yvp9kHNY| z`8#<-{!Z3M@fh>afxl?;7^DIL!_CP6+*t>(zha+lTr)neumfl4=fr@7@OiRg+e1z458U+hwxXuc5?6S|o1bfXa@)g% zB{Z#h>+?2W$p95IswA-yz>8uoI8s|DJqn&=0Xzx*PGCM*SKG9JIEp{1 z;{Wm3B)>0qVW!@B7w`1Kj;#81PWXB_4C4c3C;p8yvcvs6voFy_JYYBAP1bI+_5kW; zTp{j5e28y!ZusAAej`TQ$6Gn!#3*@HuEmTzJ$Zop(B4GY?!zP8787$Q&b7FdW5ZyS zjE`_0(}YFFdOm6*Eur%)pf`t9hvhZkx2{det3>P^-WRoFwVP>85r!; zo<{orjs1Vd{{Nl*Kf+_3pTR$U>F;x+So!oii%k&=GMN2H+4=d(Yp@@zYZ}ZM-iD6B z;tb!#rWm4~lOMavQOp6?GR~|(|HN2YHbRX%Ww&$IK16i%tGTY6a}`{-mh(l(#mJ?| z%aNBOmm;r3E<^Xv8d-c0om&d~5oE1wpyD;=_pdQ$OTtdh7&MVFG5X#hdfq_oD16Iu zjJ`Km!#G&FV062|nvu;uXRkoMDZpAS+ymMhRqsV7=~@nx`S}| zZLJ6n_}j!%8#5dbt0EyfJ-xoIja(z8%GS z$WM+~50xoB_x)Ip0-igDYoDVWiS;n|kpCg#qW6lia99tW6YHV>l5HdW8%Ph0q1JM* z!o+%*`=jC+VLeFCu7|Ajyflw->T^-7M|Prr6Yo*lK5duz657+mhx;3zMAor~W8XZ+ z$cG%(WB&gv>(LtPKS&%jzVxlPSdT{(=k=CvpF#abNB{Tbb4R{?Hgxna?q^Ma@8gzl zpC{0BXnYEg^lE4UzCvvK)Of;F2gP-~F#-F1p#N3lJ0*|(=~!DJzdIkJ&3GKH#PP?4 z-r4x}sm8BQ=*O0_aV>NfIST-*6iAToy zr)r$=m2sI<(?~1%7U~%AEp%y-D|~7T_7cv^zmSiJ$|;J@FNM4Z*QI3BR%$e?4MU)EBRUO{vHom+6}~&OeQJC19KOjlHR^o3^HV zx~Hj|_T~(JPD1#7pG3PnNq&ZCQv$RNpJ6Ra#r$!ZT?;9*@=e4&U0mPAd*vHt&^^>+ zPfVP-?-ROj9{0f?OdUIZ;J!tJ?)#Z}m+s3+H1}OW-}z+NQ!l$$09{?^2==bdm~ilD z8$KfvEgwaV`QZ@z0R{KbcA_^6mDA3`TtCW~pd;z?&3X9C@Vycf&Q5SOui6PG#F!y8 zlXR~hm8o&ns(-fmp7oLGVlruGTz;{K`Z6=rM*`AIF5<)1lq(yU!_k}bo+9<5P%nLP-JU&t;4{cYqwd%A`w2VImM%Z_U0|66b2 z$H+Y|d?B8_w<7$H<;UpdIE(+;HiEu}x_W?kou{q6K>vAB`AxdjzB8&mjdjD5miq56_+Bk9Zy~%jBE+M>BdrA=x=>YZo`}mH)e#$9jwd4u(>IblGw{iSbRo1HNvHoSx z@Z7qBurJn){*v>IEwt9MG7j5P8OJMijE%=0hroR{SH!u)=KCCfM|OUgurH7F|EpM` z=sclrl}sLo4~g6S7qOZB)5g04X`9Nr}>M>%e4m?HbD6rDj9Jo>k;^u z0Jg?c==cINTeD8dezy|292tAqDePj}*ZS0Qp0fyk2YclTwKHpng;$KorCrDkpV>4l zd}i(3@R{ym;m%SRonqov#J*%psIGxhgtm>rL z=E``|VmbD-GQw99Uf!B@rh9JqQFxu|B+?T-dx`1K7-`Gz#~m@A0O z3b-209mFpA@I_RKZ+^!%T!}A!*@nMSMEr~5I7eC~*I>V^$*M#b@7Rbdm2R^6#w(n1 zn8J|HwO>YU~5B`9k>noFtQst9(gY^y6Fqpj@6e~Y)_&; z_M?^eew4A+g-zH38d)2}xliwh?ZHoybPa(F?w`s1MciLZ8&^(UH*L*qe~{}txc<#q zusvLF>82Ce!z|Vxqzz2Vf$gEL86QLH7hsiEbdVM?m07-59KMJ8K$zO*AZ_!7GK=jA ztYEIIzUYhbmY<>`>hNlwu^+bQD0TQ4&n+Z<7Ls1ak!7=3guDcqdL5)*JHE{VhmnsU z=W#xN9k!h@em{B%aXlA16Po0s=xS~B+Hus)a@y!3o9o#h;d=I1K8kMhKM9lc4(-$y z+B)N(2%ig+w7*$8@0x-?BK$N=mY;^{*gIxOZbgRcAGIb=zIRTPjDI59 z&<^swll4rt}QHKrRLw?D(hM1Y)Li`W0 z$Jr$9akdC~iR2B)*xzO$&yie>jQuSSIbSk-596v3`K_`(i9OEJ{#yB3j?HK_adq-_ zEpi32ldq*5FDI-F8`4US$y4pi=F~^k(@WHoarpRk`h4{*zuKfRAAApe`8%2mujD?> zd&zIHQvvcm@Mq-t8S?yU`EBXj$z%AQ(DY$V#y^qrI;tFaqWu$*e~ynNCto9c5BVM> z{|(!@Oe_?`Y#4 zn+ZF?`3BB!;<%mj$C2sd@76r?5u54h;e0RW<2j$m`96-5cut?#AZ%paoIgt#46pHD zbedzB-cVg(O9D)a#}0bT6RvH;HxXkx`64oV zkgXf3i*@J8)=gT<{w;U*|%JQ%W*(Gd99{DC}&u@VVY%y~? z<{JTYjcYz@u|#KP+Ix_(FRb?4l3y43HVV$+Srr`T@h&&)%}UOdBWG}Krt*P)YYsM+ zjqpO7V2K*oZ)`IxkyxWLu3J=gig zacvs5{ZKdliQsuARecM_2LD8`F7jOz;fNS_o}tZ(d<$(xkT%173+=|BZ=r1r(yoL$ zY2)-Qr{lsGy75DF7Js!p_$=z>IrG(qVz7RAt4;N6~csw-Nr@Y`6NnWEdj&pjg`0z(lS~ zt;%xI|HWz!;YN;^3`3MuMZ3ojF39XHwwJts{}EFpZYYpUI9yO<53-5KsmSm`W)Ctq zay;@T(h*{B7TeHp9tn>FXQR%O2%LD{xsS|Ymco&Ymco`?h{KB zpJ1^xZu}Y5-jB>4T{TPaTQsmoSD>5c%!Jv)X7tjxM&P$-esiVqTU5yZhS}9(cS{du zRccQzx0f*b_M`&-*Uheh)veN=T=DtHl^j=bJ#0_kVrSaGyjtt}BFqiC7uF&9?|lk=xtY(?KchG9 z-@-VXv2jRqUgp02%!eJW*y+=w$LH1DZ6Z8ues(qn48nQr+Zyiwfr@mU6-|vx$XLI!`vJvynS8P zv+L(Jzi+goSA&x!A)@4;`KQiLjLmaCf%4vQH zxq)?MLE?CkxN5yj$42H|+K+4#%njqGleAk}L(^Fcb3+?=j`r_77o6T zj&;LRw0)fkVUy3c?N0h)6Fwd0hBopKw4=_rO8NQL8kn0p=0qFC$-ozG;{O%&Ueoi# zKGwoHwhhDC)Noy`u7l07^TBX7Q5DHks0suhzHGgr03 z+`Q=uZ^kZf*+SBPgK5(mcpvRpgc&)T-841E#rpIC-%UHvX?4;6DO}h3 z+}3}W&6kK55%22gqz_TOb+rStmF zGiIVrp^JUhs^7-Mr@$pQf^UFyPbF#-}F(>#o zFwDuG2y=qHVk!5%^y~!VtH6a`I|imi`mVcpmTVKb8+njvmkJ&k!aP5;L z-}?jSEMHc)aW2B9@Lk_uZ`n|M==L_mxV|rr#}mu{Rnq;?7%SbUlI~(@qJ5(nPNR}+NpFt zj}Cl0=Q~L&bB)?b%J*a9*i3xJ?0hY=zajb^0qI+$ms|qpQg`ir>zwCrEXDcqQ2XveUc)*Q9^71+pKBy-OuOL-~|n zSf)U_H{$ziEa6J$=rncG*yI=X_mm(^3-9vHb9{JF9+o@)ztCN=w_3!97jtE$rRJ8J zvjtgmAU&k-QTyH+SeshM|JR579d%Kx4LVD6FLNi^qyCQl5oN=i&-WJaQ(extzdb-c zoC{d-lHD)I4p%%?Mt$oSSey-Wq*2%c&2wAh)@bfB|8D$wkv^gAxlLj;0*yH^AMhFT z9x#kW5N;+!IoP3e3jLXzm?uk44 z8!nZNXu3o_)7b61*j#;&SkKaX4)I>S)5{jALZJw*v}-t z2R#$tZ;IRB>N>_{R$3D`#$Nl_H(c%H*&3Jyex|G&mdNTGmlC%)#-d7Vr#~A-8}~u| zS>4T6e>PR^C2b#d?5gc%IdM{d_3O`B&wP=!`X+v~zhbr))6PY=rOUbAJn!AXZRt{l z)0R%9Eq#Z!bU)wnCvi$`NoGH$aNeiCE)uf`~$w{(2d9OC(X?vXpAIi)X= zWn;F!y^3#d4VG{&N+!(;K-a0BH!uAuu4Be&WVzLg`9<~`a0TXky7pd zY4-oe?0>j1bKRHu9~kqDH{+p8RTJu`^PD662D3^x?#x*IURKFR8y~70!YWaBG%geq zkpo{4su|F-U9Mn77uTV`DDRhyA0Ibym!mf{f_{?S!8|&!RCs_QAkuwtZ_bqd=$ADxs>zAk&hu`3o!iDe&hql3y~Lb z{xEVIauMyIQb1@vL!bM>V zbkcx1T#z}QNrOK0R8AT&Pc!;1Ck>eI1)28+oHSU1%-k=M2F&eb&(fL+lLq<7g~(1C zEJ9w$d(yF?Q$F@yZ}V8l7LR4^oq1tqZiL60eEa*)OF~?Gt$B&KsJ>KqEIZ$;V6mLE z*+bfdNQWTh*32&~?(7BmPJ?Ox*}A|4e+O|q#9ZQ;YU)3%mg<%Kxawc;4Gr3!_hjUTy|(YP6!IjAaF2aXzSDG#^64h>N#~NdS7BlR^>4;t2Z#9+ zV1u1+QePY(zyBFuv&!qbEXEPf%^UEY<{II@m3JxM#b{aYi1UAk@zg40F|AIENwVihiWwv(waDdtJUY*&ByeFF3 zn#Ow${^07&);D>NVYV1Un0?>GY%vx!%vQVSz04M4j6a3hdg|LlcrC^i-P#8(ir2ch zvY=@#yjC=;rMZUB=CxKZE)g>=W=s3k_42#KdWx&^Thz^N_KEA>h#r0udi4gwZ@plc zD$2atkpDPi@mpu66f}9^x6W|S8LsaddcEx4hlZJZ4(T4TTg1z-TinydJ(sU`PYgOE z-gAXH$cW#=ZPB&`+R;t19xSvUMhjbL=yZb3ZDHFyOjzSQ-~esn9Xf%EP4;O zwYGYc-!NM||4(AJ7-uoh7|d+#@-}sKyG;I`X|(sCgV&OM$?#fm^_LjKU1VIZv22KU zsm!DKAUpxW=?kpasJ6j|2M>K6{4$NXt=Ex47ZgJx0QzuoA;Qup0@iEc7<_^;kJ18 zhI;Ak@U=x=nQ@M7vk7hHo#jKgEjw<8+bXrWE#eU*K6?J?4!)0XGW%0eUJbjo3w~iY z$I zGyNm~e0IyWxx9znDvx5fm`j-b&>VIv9qwUD6uXs-Z9K(hx8Sl2uVok{j!fwsNemkcX9tw6VkK_E-td2q$t%XtS)*`}}5MD%hG3-{`Ux3|8 zV%(ODJwWVMip_3i*z8t6-{lsg1-li`b%{EL%Q{PVPqoEv!4GJEx%aSJ6S+R!X159% zcP3H3l4*zf33oGgPT@G7|3t#$IqoC8w`Qvq-f9Ar25 z?MB{<3kG%_N59u2wQP;$6{U7E&7s{|Fm44E+`@8o>aa&@@(s`ae zt_>AZ?@W6$%OB)=jTe2NjN-P4o8h)-C%-onZi{*rm`MFozmRtoZcBBcL)_MlJIgcS zw(=})%jIxeA7-4a{pIp`#zLO432qBMAPAckm`UB9MOw8XizAqWoQF)E4pOHBQ;?@4 z??r|y2+TmvSZBDcbaYR~h6&qyiT+}##csW)tsa>)s($O&Xsh9QOk2IlVz+X{R5M;y zyOIEJrgl*6-9ercVSJK!Uvdm&abaV>MP%Ue9*a1VRSiQOuG zEvuuHwAoC(-9r6qgu{TnC;1sve%kdh!fmw; zv-c4m<_}UPw?AQXTlD9b>CYV>RN6x@NM0Kj{V$Z?hTS4hGhw$P`5aXS260>DU4T3k zpB1w6G{S9>=Rxw`a9fmzPRd1u+ltC-hucc?x)z5SSBKH7b*o?B+{(AL!XNOQPTteV z@oC;u2*)JE%IvQ z1IYW4%aKGr)&i7Q&zE=@X zj{D$(ErGFY5eip0kAO=2T_%)xdPsavk=MP~I4ueHu<&ERM_ggQC6~j_Wwj zZ$FgPapI8W59%1lM>&>1sKcB)f{!Y$H5?b~;zKi{IIaVnZ;Rr%7=vD>4U2q_^iZ@R z=6h&I27M20rO{FCr_Iy%uj9s$oyL_{GThL2}=REI&vO5{Cby<6NH+#b(ur zyMn#06QgCbS;aP+g-;~IW^ELs6~$)N&O?r3v*P~*HY>wov%2Q9FZ$B)7Mq2SwB7jc z+yDNl%~+c8Z%Ff6=C}RKc?0MXf{dk{emi;$p8A;0 zW>If`ZRvlfl(x1lSJ*a-Hnqn&4*2anaUpYb1a z)VB*^vl?Nuw!>yIk3GeF_T+BZEauABX0vYGIrol~`h!tymTdYFHtQJgIc~FA?NMx2 z8{vne*sLS4Sx2MTEIWP?Hj6m+9I)9e;@CqR2eDbi@gi{ztY-YPmN}N#tP0pH#z-e= zi+;b7F;O{e7VX+O+O+eGrA{%Hy1>||hc+$3X6?TQn+22F%lPUKw2h9=MESXz{B-O! zhRv#Iv)C;Bt{OILIb*Og!sG*KCCBADrf%5!0mEjI2U=5Z*eqLDVAw2MpAccQ>~i56 z!e$i@VY6cBpTuUpj_rONc_I7L26zqqceyPFYlDtym;30?jGY=8dvm7395%~gwYpNQ zdxkPv58VI3HtjdZUY*fuO|)&&*m0uyo*ygxDy+~C2v>UFOqs_RcZSMip4hS_y$_B7GEc%d#H3(W+*oy(_90e)k(b)$yS&1Wt6x@9x@ zQ~0b0?KD4#?O`aNb+4U&L;0+`?ED+bXH6Z#XT2Q7XFWu^XToA_Cf$r32bSVtIFwHj zCV42EmBBlL%vG?ZzZzh^qJ0l_oz|j9b6L~4&N&xAuNg$I`TLLcH%N~rz2SNE+uBd@ z>&|;=BO57SPeyTBpZ^4V;lV6Lo?|$t5&jqNj;jxq!euSD{SUcQVS5Jr4@JM@Mc(lR z`yIW7=$U! z`x~X7i3@3WJLP2P`9{vaY+uu4|6gkNHa!t_{20eK*>TqQzK7GoHuDDUglsg?oYr?o zU^j=;kW)wu8U^07}JfKp?7M%yDKb4%Ztr8!e~+E4)H8KCz{cktLF@5w62lA znYuQb(IT%0J(G1L`i2?0E}GF|40iXU7NfPEGZZI$Gg^O4xH_YCN#XQ|4x@E1-*Tz=$MC{2aKo`p z@2+(>z1!wu5441zpSSn%@}$kply9VF(qH}pf-pxV&sqJv7q+PUIp*fXDU>%HUFw*f zQ{f{*yBM$HD@W<8e%{CLA1Q;nPkz$^wRbbt9>%zzaTV*u1GU=cC6;mc0>_RR?j%f}t&Mc9lUY4%g-KB=Um8R54!wMw8gNu(Ab@Q@Mi(H%l{&K zoQWX_CDK<9qYNhTKipFn^V_FQd3}}in8111Bm5bqMi`}Ek}g4h@<*rkR_hn^o`ZbP zzE&5k&Dfnqyz2t><1+8k^Sx>}hCKftc>eR;e`(Ex`l0Fc7B*!kohnDL*VAt5UHk%* z4uN>359ttJXwo4Nuk>N9ID6UzYKJ!~4dA%&b;EjY`F52(pjLAlYyr$^0$Rge8{ho+ zuNO8cUjlh<|HBU@n*F(hl8L{@_wB@8>ADqvL!l{So6PgrW6C@)9-l&b9{Wm}=dq_$ z5I?U$cT)4JHy1WdB~K4DW;S`St$AEO{@M=rO_z2w#{8W5%g?4&ebRrR@zYIBHK~^Z zyzk|_n4fDl21vMxeY3JlZRzemKk&9QND92=Q(ik zuNfYman#RTUr5t9>Sv{CpVBz$XX~;v{M!z@ejbdgy!SWcnZ`Od*!i!qugZbm4SVvc z^X_!s?X};fZ}3nTbzRAN(tdh>!~ezF+s8*yo(umoyGeHQ%1a<2pt4C+f+(nfxFuUQ z2`_;NScsz1mJO*Iq}5ur*3y>UtRxGlII_wq^fbZr6aw9Y6rzAu{MWxEAw&gr^ zH$12ACR!^gkU=!R?=?FU0;0$E`Ta4UnS17*`~7;ouj{%c2AyjDn{M8>25;>P(4S`e zZGB?%J)AP6-+w_bB>jGpe#`%V;Qzs8f5@7=op$wiI^O78HirIOM87TuZZB#5IOxzU zm_6BP(>@PwOPGg&^+;ZU+nMaa#+QB?ZdcJ}fm?~46m6W#S^#dBSa3Usw7_kp3Adbg zX~6Al17?Y3^@hN&$gV+wSzt0kA7va2m{TqqfH{GY6#7@sH^yef`R%)CQ2YGIB>zZT z2ICMH_KOMHAuzO+Ha+lX=7}+IasFlEhiW)ZETR}`Ypwkm7_ruq@J!tf^iLBqTU~2_ zIefiJ)VY1GHNYEwUWEbt!SVAd4B+!)2M+NcY{!>N;@iYq6g{yETa14Mc4&vdP80h) z3Uk(8|LW(%4*72~*HFqAgq{0{-(kUyz{|(0zRsHZ8f)vTz{=8A)|w{%BmWz`4E=)e zvV{5uujx|e+=7>jz978Jri>_k9c}jYK!RL`Z?{>rIv5a@( z^H|RPVa|zJ!}%rR^XMh*=Q&WCU`+Sp_ZU9{TumablE5)@6J;(h|A7g|k~V3^t0o*z zk$I6ADWV&cJ$6Gkn53i9rlf8#Nk?Ox`y{%-e+Xu&Q(*R4VuvJQ_O;K4S@PF0CxZ9$ zS;t?5-Ze0%gJHJ6GvlA4amB#K7ol-?QQu&gUC27IV0O|KUyR1xN*Th3TxIt4zr|h_ z8aI~z2bX<4W&h&A(c#l~J`es;!9zCi5q#;Yl-7^!s@5MIau#mw8QQ7NRP7dg$wn!E zJN|hz&v_2bOY*9(2u*n&SW`#!42I#YtPz3Xi@6i`mNldh4<=Q!75Nuwv`_fabnJu2 zs_8vZc*2CE>{;X4q;V6$OA;Tj8JpM-iR(8&@7mA8TPb5-$tC_qty}}}Mm>UGS_ZXE z;3mphOEJz^>XI{-GKtq;FaGF$PmD8`x;R_un4GOdOrb8$W$F?hn)8*qq`^6!IKrLp1`iJ1ApZQ{vxzl_|**U!LMe9OW?0%9xRyN zJ%~1+g=^x#3tTt)(fJEpXM=wPu1$WnF_W~wb=DxbzJ3rNJEm{@vB7+-8$Nb)pPW&> zHK@MvAKsj>%iv@G09c2ts&tr*0|lK(r*y})%LYyFGB_2X&h!F5pdg)>?I z6~I9`@KAA9W6fzgt+77HnTX{4W|X9Y#keF`bh7jLftCX+`uuo{L;9bQk@$<+pYb?*$JC{`g>45)VYt*D9`y z2l(DEF;BC(K23L%{puXlFISeFyVe2h>`$JpwmvP=0qnSpX@@39*U#o&Purl~lqa;i19~m;qtN;e=zKI+-b3pRTE3=K_6XuT zq2c`sFyB!6ztGxeE+kvNJtHYw{;&Ko?SGVc5ST1wjeZfB+?je7CjSB1@)=XMe8!Y5 z@u5B|Th0Ooz6fkSLfwPm=U&!{1)ErI=+rLd{_5-4n!>C4(i9_JfsCd6e?R}%u~+o*sxt80egn7l z+toJ)>!YL{8Lslyv1&$7J^n<_bVWW!-7{VS_}VCEjlHk#Vd-GR@pCz5?97& z!_FNVSeK#bmQI7QGUT)Ei~;Aw>oLmnkAg?xUm5Ga0H-C)fzG|ZQ$=rJhnA!;)~U>M z8hQg2y@9er#(3l{-d2Hcv56FUB8xo_nKNUZ*p$|M+VK>+56R;k;l2LtH02Hd*OgYM zO_?ITRVsax_!^=|{TQ94_mlo#y;G!oxR&?mc~C#L|LLX6l{a==u4wD%R|$2flv#JV zLR)6jrdhOYCUmX>xii_XsKg`iPtrP9&?njJt|>{z4IM|l)YIQj{M1bN7jW#$>7&EH zr=RjZzD%JnoR`9X{dU_MCzqsBKK)(gK*#yneLhUPrOz^c%u%cGfY+fr+@9yX{$=|6 zByHVp_P2w6#e>2h5+iskb7(Jb9bxc=BYG6pm7FIKx7%71*el9BN6EW%vmIXmFKc;3 zPxK6Vm`~X|G1o-v3S(~P(AL?E#jIA^Zp^PW4uMaNgUuWVd#l(*N*#@i!|!CigQ;(v zxo0@#vI8&5h%hebd9kK&Ae zbeR^O7aMfZo4)lqIHSzO8TI7-8~++OgR^m8PU4Kc8R_k}y_BcC(VC}dYX{+sbXlW2 zl<_NUO56X2JNBI4-wWW5-_YM9^p|-Zz#Tv5zy1or9chdwcw?0l8PxWfYop!lyM;Ss z?~!=o=im;fi8})HFWQ1!3Hk2-@)_dTlQN74$h|$ zCH5o?1Pt9zzCmB^H|Kkkj8U4`{c;AhAp_a~j(y3589#Iz-=k-ou}eM^@6X5>9gfm= z!6U}HfTv(xz*BraO__N9xLjaeOkrGJmT?KHtOGk^j2>bYw6o%~X~>t)TL&X#OwL;e zA+vv5;lbnfBn=5R2@Ua{vknsQ0iUK1XXE_Pu5;#Ezw;EzHb-@D-F7GSk>4LYCw*9yCxkBdgT%A%b zZ5H~wnzISYSZ^id9dC|dW%sf}n{woIMQxs$>yWiuaJc~zp z`lp%U!7@GVF~>uN2UFp_&K-|J=_B$=U4~bey$CsnX$0+&*cQq9H;dc26C+ z%C9+IiSL&%>YpMeL*fo*D2Q9krsT^1u04 zD`rJZseZ5p|Dcxp-S^uahOB)89>i+rl{XP1BdSb&U||{cq2n9$&4;a~kG)QxV>VYd z7d(k0gG*wZXL7-lIGkJ(<2;=UJj~wDiu=6!RP^hs4^A=aR8pm!+=y~byT{k!_oS~N zW>S@^E2&c6FwO{&@`iJl@`iAi@`iGk@^T^%Eacn;`mnlXihK38DQ;A=b7!!H`_fj;@hX{D}uB; zIE5H(Nm;M1af-WH+CL`XiDARuEPcR^eY^Cb%BD9xi9NL%SX# zc4}Si6fKTV`|8>$#M?x-BK_M<8=nh!+NFQb2RtuH|5n-gM*mv)hOKzJ^lvB6yX2Yv zZRB~AJk!T5JY!qlP9F_Bacs&5)_-u6_Q5z{cIk`w09!%<0Cpoxog%3Jl`uGr9I@Z>p!R+rLC?V<#xf( z`7-UqhEC!xYrJJ2t$KV;xFlF<_-zZ1UI*NSh&A{kv2da?RudXLD~5CKhCR0}@pg6F z_{ph;|2Fb2aitQJZKsMq;9hWer|A#4ey-uWU4o6K_-#j*;v2DyYnbJ`eXW+*nX1Qk zaberwjEzn5Pqi6(;?4}>c4nY!zlu1Xr0?Nb@NA&S^o7pV)B^=!op^0$mdRO3;BbR} z6c{!d0q7~?v8Nv1L}EmBDcRw~;v0zX%QX(3aw&KCN^2~)9mx)#0dMPqw^@V6x;xl_ zUrB?p4x@*;%lZ_Y-pTuY4W1@^8Vj#iszb>C&RKcdc=6#5X6yZp**Z2Re;Xeo=Fe)L zS7i^>15d0e?GvxJX2677)$WK`Fsq2og$b{! zJvCy%sw(?D`wjqO2RsULLi8ZdhYsMobHH=#$N`Uy{U8Mya_kmGH^#9hOIsnj5pxX~ z?_SQ+){39_;C0Y3LGvBE$n@3C)&BlLR`>_~_#w&oD!Irk#7G_KVpsyBs+;*U0w*?|v|Y7~8e@d*R#WE3OB}G8ac?>UH>L*HwT^(NC|gnBsnD z4*vM8OW{*&m-`p}ihsX1eWva!-p@b43_i@UaY0WVKHTxeX}b6=8)r>mlOMw-U(TKo zyZtCW%rShKC62ztiZ;%bz~@@%;L`( z!>->axOy7T)8!dlJ%i^8c?MTc;(2n=^Zk}0ZH8TWDAtKTGiMJ;``6I^)gPqj-|J1$ ze{d?r=!XwqL?3r1?hg$ACX>0dMW8sqj<{9qFPEHTXW~R``}f{C60#EE4V91KgIyUY52 zr3k-s{SB!*1~_XZfF6Xk*Totv3cOHS9AKZDwRwy+T120V z1DrL&S~|v>ia$3`?^<$@ZwFbk4d8A1we%omkzPo8G3hy^s}3^HJWuD{j0VrK3VG(; z4DwB)|C1R<^eyq7S;)hjRlOujPb|(d)(ZAt+C0^zLH`W7VQ#T3Hw})e z*h=V#D`}_n?@Qc?1^)PW&MNN(Puxq4Dw#{6ThUy~&p+U?=F1gmV6O0k8^imt2k?)^ zmp#Bfo}IKq()h9m*!RmMJw(zEm!5&okToH&R2bk4lK-FQdtk1i&t1^xfw_i0cR{BI z<{J7Og+2>iJ_darm}?W>1rHc&75*nCa14x>t;CNV+#r0-8R2VA-Jn}@UsX2C-NX2K z1Fx2r1zsyH=j<1Wq1SaR=qck|nAp2=KU8YO)_XhX>46{WZsZ!L=-unNqtET$z#Sf` zdn0%DFS<8zAA&A!A>+Tk!PDJx1M!$_t=-#rk51z~+Vu$STQ{s~Z+CA&TlbP%+j@An zvSXZf7jta1jqmd~o5s7QJW~EBHV=nr(_wtojs!gc+FDOrgS55ldEV^{dg^Jb#Ov$o z#K(>H%K1ui&XVXcICIvJ%`LuI_O%2*i7v9ljJus+?^d2e@_zE5_t>M!dx_C4{|w~E zUQM1)R3zWmbxv`Myq|&WE-=*09&+o`O6v}rqW9Cc{)%bXKb+NdogdRW`c5Y}4LU}g zk67`;&?}zDaX-rYw|O4J`+U;t8PnW{J>9*xwslV*+IAP`ro30-(boMkXK!>jd7taV zZxMgReO#v)k6y;12b%r?_fEbaOne*@a%gJ(Nse?-3iprMDb^dSM^@5e%? zieKDdU_+ zi|_VH`~~FdF63&T#9n|0KZeZgBlbc!vQKvlbr0dbjXS!lyE<&{Zszf>VVQf^F^}C3 zj%-Un3j_~}-(x~}Y-FdzbKKb*Ozh6kYl-1dL#&78#CM1yugBp3eZ+030k22zB#n&V zBW^^E;C$r%81ldGFwe+JUC1`RZT#C}#``&Pm3zgzc@NdifSYhv0SM1~4zFGM9qMHE5gdY)J#QFD(a2#Gl{5E87LSQoN6>kf%vGlTV8%>61sa!F zJ)iMWWNftYv`1)FJ9)%6p@z1|x{LE&aLGj0l&tNobI=)PR_G(B!%AB`bY17S+`@~? zT7PdMdgwXS#X0j=P?u{B{Q5!oyhCd|C2B=qd`qTLuIy6{{x+U(3BDP4l{R_dQ_A2^ zqNWeB7d|D54|3u#ZO6~o3!hR3eO zafFycCOODXsHxs=QIPVmJ+-c?Y}9Lh0yVe9NT87mc?wZv7C^Pi*eLNVcm zh?f%&=IGz1UjyGd8z`%Rbw=JLFL=)Ot&z53o3r!<+6_&w;QJhT4)Pw@t0IlRuow7? zi@eQR7TH_sNIXwH8UK{c;dO7HwE;?%T4~0IL$q%~Ve@nEb zHe2|d_wd=i;_+II-4?DJG7G)J0nUOG`bL~4%1vb6zXulGDhIp(@`$@<7eet4eu#n>erB;N$~zDcN=_V)6%wX=uahdyF{DExl%*ggg3V6N5>fA%TT81(g%2zX%8baK_`L>&?!0% zT-?n(EMu=G#{36}byxT*zW>rc_<&~Q{37D1-lN&WXDrIU4gZjtQS+(jBcVI zjr5`FwzhcY@HXe}SxKG=I$L>7+TIc=7rG?;Nwfl4068JLg?={ybI1$P7VgLgG312k zCf;u(-3YvGpv=rgoT)o|@7!yg#PJz!%;nZK#C4fN`!>BmUV)uJX>&tZHN!Sw%5Y z6}1zIp$2aOKeA$mbU9?VhDO8K0ycaI~QZRH0?U1K12b;OHIEkFvr( z=+232)$nTQkhF2&T($MU(FXXbeT>;g?ztRx){^!S^_c zizM>`UguoIq|7357*0d4E>20(0biy;C+_vV++SVCx??X@uRC_P;j{QH>?MUZ#BM&j z*1lIU33_you^;s+|Grd!EPZU2F7eHc`Lg7|^We?m6O;IZeG=wSWeyD=TDQ z(!i;#sk!iOiNy=s67X~hfv45UbApXC8>hVhk8Rd>0T@fHPQsai|A1v5aN#0Wm=D-+ z1%svCLB1nT$a#e#PsEWWWPi~o_=k4HktyQH67eR<1O7pl5d0Hg2>%Oym}ji{A$#jg zd{iemh<3(n!RNG7VroVwF+UTSACpggjJ-9{FVz*_?-sq3(DFxEm)nWY{{wWywI3zv zaP)iq$#oCTSE9MvhHnzmuX8#&l{BXk)EAQKch5Xp)DkhJ)o3lq;DbpWh+hjb4Y(_ zQ2IvF*O8X7+R9iN|0$Pg9^PMVvxK8xK_lskyc*P6G#smlvnn5Q@pDnuh@E?Vb7TLV%+ERPSWS&kKdh6;*bBiMh#by z=L+WdA`?y|f0VVWC@$@>3^gpWMG@bnPWg5#@fr$G{pd&(9-tgt@t>3>c9Zh$zVpj~ zC%9#-8lFTQ!ze@YJVc&`LHT6-dwDPKuI7^GfQj#{eUG0}M-19pI0PLSIs%ECA^Cn} z-UXLeA`9Vf)GG4MzmWfK^P8N769aC3pQ?se@a_ZFYM%M+K`Re>_B~G3=!cY>?0>Fy zsx*x=;AiTwgVuR2mup>z&c+G2iT{sMp4g43T-F$govZbnEGtV(xjHQzMR)oy+{M20 zHU6{mhz{^8Q&c0Sy3{Y_%Kc{ZUTNNE45X9$V^c|=ov$M8_JhuF-MIVR(AMkXOXt(? z`MPr$@(=SlzT*n5t9Jg`b8OJLR0_^Vk1e|I-;Pra8)!@K5C!*t_X_CCoGI?Qs{7qe zDYJsHoMWAfLu^oDg$|sHQ)QON-h%8${BevL?j`<#*yTS#Up21Bxi)Z}9pfzRdfF`O zcCGoo&T)&Iy|rmZ+w55nMX__eINxlWsqc{ZtOb4PivJ0xx}p!5{;&r8vCnP) zeOC%G0}dwbDZJ1(N%Q-3Z=1YIyalGX2 z&f|60oH{-hIbLj!wnx^#S@*}^91o?wa=h+`?;RKUUiitU@N<4Eqwl#NV;^u5d#>&C z*+VqrNncOd($_-nU3ylyne!1&u`a}3RQe$GRbKzEZ*C7idpz{ik>e%h38TIm%8g&r z^k!Z3-;S4j?Umz|-|02#6Wka#_KQaBn9*K9+;(Ne;QHPI$4i~<+@;PJsZ&Wy)>%i) z9H)MXmX17|uD}=8c>A0_rBD7zqnv3*TREGXwbUhT1}~jFnxdb2Cq+MbECu`AA)4%A zy$Nh?7h4th8R>)gqHi_*%%3)FX-4eWPQCG-GCkT0kHq=Q@g?xn&^=#^U2B`JhW}M` z8Q4^GUZsZD$uniQ^X%tY^eC&ptcJhM^C+j+5A;?S#f+FKEQ5 z*$O_h>Rm^@^lijnuxtGvu0L}fLeTt4F7_>QIO!b7dDnB?}oi@sUp4O543>Vu5renvh% ztLVVu$o0aX8oFxq*w%hid?PZ`HomdvWbh+~d~M3lEy$?b8a#=`+2_bw2~*bc3Xjv& zaITCs?yQUzN46^2?bur>Jk83{ZK696yUKa+I^D<(ve)8e9f};JieKF>WE|Q1L2irX zukj?<`$T9C#b+LSSyVbNQh)#C$Jao0$x}_hDuIAq$|DvyrZQy(6d~{OTy1}=J zJj*$^#xs14p|{FsAHklLw67DoYtl2v3^m-!x~OBV%KnegfjY+eLUL0FZI*9N&Zw_r zF6!W2l|pO=!KZ`g!o~XS6MYW-MW*C)+kv-9I$Ix}VWDf^jcNe;D*~2M9-xCkc(fdTNgAS(}O3?>BQ>b8TB{+p~`N{op2%a!W(m;^nSE3QpP`rdD>7O(ILaw_3;l%1YQ}mr z_5qUmi4Ty!PxM9g2fsUI^8fHo z-$(x-dmpC_dOUi^;hqfW(dZp2c0ghS{33Zp#~^x#%VVy-IW&|Lr8NwYR&AXVLSw@V<#>b8k1gg=h8$;!778d%Mob za|ZTy1?OTv>sdqR0L;X^V5Z$ zjNnI`=*uR^v*1R5X|LEYZD4-0-nuGW5&c@b28~^q_NkG zVXrCkw3T^sUd(yF(273v|CP1QEvK-_i(`{#;4`t)7M=$A`owF_aLG7D>%;Ej40eC| z%6as8o<7#@?5QCJPaiParzpQl+NI06O-Z}-!zZ)Cx$tW~`%uk2Ne!PyR`UgOv|IAj zFhm2nqhLn@*{d5^`jX7uQrfwUcCMnGt7&&F&q4Zih<;($8Li^`Lf)<9`#pSLOnM3F z`$#_+@JKylsYmLVK^-Ei4U{Rdi={kb7aQem;e2eXJc(g!mF38f7;uPu*Hi^fatgfU z?kJ&sr?EFYzmHGRN2yn(UXewmZWnc5Wb`kWzKy~cAb-b6`k0`YOz<||{7~jR_Z2Ot4u$TA*arhSL%PI6ieb|3k`TpQi!*5Z~;694asMWvEll_k= zj-(AA@_v)8pvQIclj^@8&EiZ_`t?qBYhO=JlCKarEVgT7XI|J}qWQa@RKIx=nN(t+ z{p@nlvp!xMwTqth@rPY@)6NasLE@loMxGQsn(zh+_)>)*{L1Y~|Me=~&*Pe6%8+qe z*|P&aY!5*%4cRv7>-EPIS>aAIpRD(9j8wyWNnbcBAYZZ6x|9f!h#yRWq;X)}(w(FIBhFF|EcddkuF>r$#FLMcxxV#YFNLeP$gA{=9m$sarDlr0NdRZ$-II_^MUt8icQse(wK73D+GmzrizI ze>vaGaSD;&T6cTNxB4*Scf`yK-?TvT!Z(#r_hIJrbuPmfhJJk0Y`f?;1Hyx`j%5t) zWDKk_FJmn)AYVKGeX+BC^9&!NKJ-)KLlmzCKIreMdYh(KOxI3u?!uYiW!gtAg_^_w ziL-_eqK62hm)Y1rO!TL3HTG?85IWSOOkJI!w1xO)t+_&clKsTN2ob|g>}A$IU4S3a zW2N!c3if!MVTYdP7Zt$7$~k)XJ#%#N9g5r6ZSKi$8tuzY$=Uk#c8~Hi*Cagn7b@GM z3(D0yf9k!c=5EPX^O*P;-SJaw3O;P#pj79hAC|qPvUip0C+lfj{jKh`HoKNUCnP%f zN7!46|3#S^YVhj*+3lV)OT7A}%(M9C_|sA%0sI*1bJ{%tTdLus<4?0kLN~J~i!aVv z^i2u&ngh0W&(_=g9zQWZT){x;+C1!LhWI_}iuk_Tfi0Osmoe~9Z1)sz^hUZ{6#f5Z zrbl8!oROc2g#?>eJF9>xzc9`e*w+(%z=}0{2?RG{e=r=n8C&Lr*CB z+NV>rfW6&QsQNu?+0$G5Q$-IDGbpf#^mj?`AkXqtE%0SCPd)E`jSte-@o{61SK2P) z?o<ARGVH`M@`G`-zE)e^}LIvLs!LJ>eCS4e& z_2Q3x;1XLn&RmTx#6DK!=BFff2z#W#xq3R~#h+8q5h=Rpt&M%Yqe}H7%bAPi%*E45 zzb`3AY)jt5CaMqHsjSi1o*Y%C`bU@PoA}QqaY)keqg^#O8P{d?+=2KlzxaEWfp0^P z6}Uq`ul}d|5+2kKRpeEpAH*)R`f-qcJgs`2ciK`S9U1nBtSRx|a$$!a%2V|YTScUhGa_Yu z`A4gIh_x4Ioi!~lF!-0y-39JVcNA!ApZ+?rlbx+U?poHmF|AC0GNVi{aj|}F%0oZN zDbqI(FVnYlIkl(q;J?uQ_bpcR)A*J>^pG>$L>c|$3w32`qKoLBRN1=zN2;i2(W0Q`2Tsbmpz2J=QNzT^pdmMTX^AhKb3qwz2@sa^zP=HIeA#XIzD{%K# zv5v4st;=(+@8#cK{yVvteq88Z!8iQdhupM@|34C%gMDk$>;ktl-?_ez|NHn~WRNo# z`d^hZXQpfKyh(f{!C$mRc@kc|#Cb&Ab(5pW_M$R!^b&fwAYuH^W`xeaUiA>fI^rM^p z&0{RQPx_N*oVE;YOT4=P8=2(!rV0M>$~Xo6rHPgs+Y&3CZ72EXE%<=B=pR;~e-V6s zin-`@D7x$=_=4@FC&<&Bv#xY|x#EtmtZduPd8c*gR^rbMZ9`}IjI}?dKyy@JeR?l@ zQ~$>Kz-HOa&{M-tfw^!xvB!e;7`}6I{t#ym#fOnL&OM!~B^I-{u_RT0Nn*}ezH_XH z1nZ%Hm7KG3g>mLeLe5;Fe1mo|PLuZ*giky_TkqXBTd#vRfoIzz@{{Z*)tLK9%Z>e{ zkvm4vzCQ5$322V27tu}1SRZ}y?763gPK$NwT9X-Z1+o9Q-S6p!CdM~$Rb>pEed=11 z5fL5WGIXLfRqPSK+dCf^qpc9XIp}QvB=Byi0~gj{b7Gvmi;q?l>+2`1FTbNKBJ=R8{h3;GLuMp&61c6%&;!IC*;=1L?3U@; zPTIeg4Bz6J5kLNO%~wDR zh?gk7#D3zGZUuJ-@SkhOf6I^W+*Vr|Y2a?6P4@*mO8ukJ4Fva>`Y+)OUVP2gmfQ3V z%k#9R<$3N8m?wW@MWlXQyQc?!wIG1e|j6Zq79Il+m9qMeZ?8xn@8IiSDl1WnMea<`j5OVq=We^!&BWpH6wsm_~ttB;)l@KP4GBA;avvt zJ{$iewD^|RC&4FMyOZZFq#S3BLz`bBc8A0m7Ct#9d+CSKy+|y=BWGg~ioL_w0_DRx z_)nRWlERlZC!GF8#QE%Q=bsq=7;+x}h@AKShgo6au|n(2^5M@0%HL;}-}w)e&p$@_ z{3GT6Udlg^_0W@dEorSp#vP0&%S@TRJQF=Wxbqds`$U2J$zOZ*U$HM9de*CtE=>9t z+*V7BFJkjY=|h?6U*M%YspCKRPy7o)|DHVa!_R+4{QnPsn2i6=_a}FlW&Zq&mATC- z^J%k8{u^9ola%>Wv&_w3tjs5@GM_TbznuLD?AqmQ$LH)S z`y#}he`MYT?L}@rla`F@p02b>86jli{wt7Suf!J&-aNqCbD|@j%Qwz=7-7I8>r{N} zEIJ;a1b=cL=WG+Z!n%KHr!0ZCCMaPo8xU0lc?@d;^+)#3pfdSW-U{W+7qW7lu+j$?)BR=LI*2oouaA{TO^^sD6Q4cv116_$ztlPfOa-3LjaV%3q;=zgNa zkCA=6BY#7mgr4t#KlcCXHEcsqLF0vIw{WcR?S0U9WB&#m9G{zsEsX!o__%qx#4MCG z+>QRmi~hz~udLm&)N}PX%WY@%IMI9itLI`fChI*>Y=@6@z(b)^K-Xl|ahUZeI#0oq z$vo_f1|Kbr245v6*K4KmTF%FVUT!9j$eXgxt+{fose<0a%iPWw5PLOV#rR`yXPrqR`~o@UA&~o7)=jtQ z#@K86lLf0nJ0ER_hw^(|YZk&IHUJNetj!yFPM$aHS~H*L3Vb+ z_d~pUm3K*a5;zk3jt=%jgqA19C2@6#=k9T{TPwla@?P+_;PLM1Li7BKV$o$^VSoL@2eXcL$2h-D9-`{0#eGlGLaDorqcM_gW;^_Ope-ew=2M%m! zPek}ziPtOqt;FjU*-G?kWx<7vcZl)EA1L@0o*&_PJ$~MW^ zqFbFXn?1@jUF5KruH_u#o~pL^M_Fz0-dU`zG`&XPhP|wB7OLUU9eKvScRMl5C2p}7 zIFXpdUV)R{lmnbt@r}K#mv(fyvfjM`>iOt~wwJH<;$s2K053k^&>L7s+h6Ctp8H|$ zk07s5PD=_r{L7>pc>fCbM(&5Whq!|Sv3c=9Gra62`=A-(*CgW}g0~mhTI5cFvD5Go zA9aq>MD`K6r=HlwHS5zO@uTd?a=vjO(;HbHbg~v+FZDG#B9+%H*ju+-+6PRJaU|(2 z^1Ae2^uH-NYItlW_=>gBGZx*|iq!N-;aB{g8qOAVWfQlF z^L9@b)1I-MWn9Gt?-*Zb*H0|A>)lK2`g=?5dSQ*<)4R;BpI&L#d+xF8?+3@Y>#&`Q zznexo=Csx2X6}_eGm*^_jHfH`N~zG0Le_8*Ygk=thu?mgeRW`!J!KbjCN@nj=GTRN zii`Oc8z>iRLH3IWu?*cWHZ*LqE}i zPG_4#e{Uzaei!&>oZoZ$dGtH`9QynAFDKjHIK*gs32l!v2g1k4zvT>{8pC*ut?0FFb&q_XkRg)}*kG_m?hV z-V5os=;rILgpR#Zrtf4=Lu9?s@|z8rSM*!I7^_rUa;)hBdHjO) zOWm?IYgm^?d@g3k{I@)^D@@%(^(Jo z!(+MrPk;6D_3g;lshW@TqLejx#Phl_qWq`dqo$AIc|Pw(a9_ZkcwL+^rK}kqsj=S> z>Ej3+oYkvt$mW{El@(DrgTQXD;&}+yT&^6hSzJRo51MmUv8#EDeQz0y0DBM$ zV`|S_03T`RTxfL1!4%p(Ka!Gp1Mk$xNt1sm+(7J|jnL(d$il4M+X~e1DZw$wYulf2 zOluXJMdrl?UM&Q!6vtP1euU>oc@`R-q~lVbMaLD+0ki11)G2gaXtz-h`Wlgugnv2- z%t^m{MQ8brLv&cbbH=``#g94ItD#N6bARm&cL%zyLi}2!eP6w;f0M)(6g_@=Dsaj> zi3|6gM^eM_BMaID2AZ)qKgqt?DRh8={n(Y4D_R%w+0X|vI15eLfgEY*x-R}hUKrb+ zDI&WqSezezTT!MNe1E_}JP_na-Fv)-vf9y)UH9#R@J7mt6RTEY-uRcNYLOGn`)9~( zbN))q5nHPEGs*Mxg=MfWOCI*Jwn(1Okg2AUN5*J7GIu_FXoUF?9(XH$N&ZjD^iJ$! zt+ePvLghCbx)vD+(Tj)<=v8D+3n#?0!3j^7>wCZ*1~1K?hn+IxwX57Oac(Pn?S@ZN zCv#DYPtyzBAGUm&+A|HGrhQ)@9ll@u(BLOeqQ_Qfm-se4@U_w5yLmtO-M4v1jMEWu z<|Dy;$iAAzGp83S=hhcZN!F)KF!%O{8TGYL-z}8!)@`H1&ApCkG9E7#Dele4%1UMaB+W*8#-Ma2>FHM5|7GnoZJ0JF zZRh)B(jsffSZ`&FsrwnlJ5Kw6yjNOzN%xUP&yj2!eo^m|zSK&$57&;7Ca&qg_xDI& zWTp8YCq2qaJgm)< ziR3v?Kd^~BE3G`T#;+vLd3uS*$m28fi0y&IRNs}NhG+3^lG%peaKDmE_B*6L!Iwj_ z)v(wS{5NZ3@cVS$pPAs*CH~Cs`6l^)XO{ElL1jpuO!8R&N;;LatULMV*XBRK^S~OF z_vh=izfSvO@ba-y-~;%1iD^B>{8!pwt#A4F5BXwaF$#Hbq+w&Rkbm3GD?f@pJ%&Dg zU7r$umTy0!53cj`@c+>>ig9-F;PMS!A-cad{F~wx_)N{Qe5N>Cwd$@T6ihnzh{p5FV4#=Iuacl zj74TW^4+R0VLlt}2S5CjeBzHJdr^|dc#q!kUwDsRZQ#B5p2_#U++`nBo<*NlSfK2& z^l2yG%L>29_ujXaRv9bFQwi+H!G*UC`p?>X_Yo6BXhhDxJHy-gK9l}fWm|co=#eB( zDtUfJp6M6J<1_P|i8#Z}KYhA^22K>Q9&Xm52ye544>`Smmy(7;Z zy371``Yg`w#lOP%cRYIES!e%6=WhIqoFKZlf}v_y&fisNOaE6#hd<%^m}{U9%+Jqh zm*^5s@qX~S3^go3=2NZ{x&N}sNn4*#x#OWIvd3xs8{_OJ#Fr9F5g0UdLNmCtCl}x5 zZA~oZ&VJizWR&<2F6J;aJ82uk7*>NDj5B$o{3AM+?=#=Brx}`;%yXKu&&daTOTKSQ zKKRMx_+UE&A9(z<67Fr8*(!CMX{l(HJzPI~)&J!Z-t26h{~@{^&H=XS{F;h;nt z@gHPg@9}@cmv18U`Q#Y8ehS(6WU*bB`Xr`l6nXK_te5TZm#l+5(w7VQ^X;MT`0iP{ z??>3b+8;$Hrsxj%H-EjVHDjAA^Hz7O@&zdG5AduP^5y$J-^7=%20V3`y8esn2-lljZ*YAf+r8iwhV7o%1Q@n^xx{us zFXawis-3DJ-gk?l{Woz!|AjGkR@4}};a?!1S6(OazDMmyU*p}|nyOrf%v9lkMz|2wJENgJINg@(RhobX}T zYp`DQlf<4oz2yeISNxMCR>TnOIMAgG?5AK;ScopAa4~xb=u!suQ-(N@dC{eC=B*1| zii`NQ@elalfvqs@xfy>~%f7Rab3miR>pd=P5~F$bp03e6FJ=rbsrMAwXGfwo(nIF3 zZ(Q#=mVqBh4tYLF`Za{$OX{$b-CpE#%lt)IS9K0$>Q>fTp+mt%9veeoNxpRyE7dZ_ zPJ4}8#$V?47mP#b@BLG({wC##tF@y72aJQE=a+Q@?-xbieAFx}R;X0V_&bmJ+%i8> z);G}sZ0|j%EaEIE+DnwxPFdS+$u=T)R9D()Betk2d$CUJFq-eG>yv%Sr@FJkVh1ek zRgM!c!<+|W?NQc#%8F1{^L|B3Wel6p8J1z&dUCN-KfT1M_p)9Ly1$J0P{Z+=VT~z; z_}%2;!*Ut-(cH&#zl8f$+-=;4aZlqul6waC0`587FXsM9hv)B7MmEpJda`K~v4t*? zwPUWC5YGZvQkMl&YbwmWn1%SXuottMK1q9`Vv|o>qGFRzTcVulDs72!#-p?)D)#xb zC5kRu+7gwsU1>{H&V!{bQFPW)x03B#AnP1TOD)`V6XG+6N(`j8rA{DF552x(`ZW|CEbW$gG}^u~EBT*k3)Po^1~`>HvZv(B zaV}64zh|tI`ONg{x$rb6mN{CZ6|8@7ol#$Evc7KqYZe%TzRCGaN(%Ol@MP&jv8VJZ zS}yoxE@jFZwd|+^X`jZ`u8Wo%cGMkj_E%eW)E)2(QSb)7bER>3O@%!*;guzp-lz6I zu($fWSda=hKxOW)xE23+$}rN5+2y2VuWZEf0?t;EeaGbd81%=bwBiGi-b8|CEgkUl<3y}vZ;PJXv(zrmN&YP;3PKM;pl zo`rVF{7t?2JpLHm{dxTH`7thBO66%kZTnmvmwlNF^0@qG=-C370_!7oY}{2~jG@HK zxY^P7TmU@5*zA$BT;O{z7&BueFr}D0ulSdYU@Qjb6(0F|`rFQ3c;s~Q`%{uUa^>g5 zyAas1;#~+Ya0hhcBzWM|rY!yBmMnd{-S&nxpLyVs|BXL>FHRo&t$i+Z)Iyc1&2sv1IoA;n+p+6~8*Pg`g@K5FX z`ahR*{u67nYmBC<*iAkg@F?jO5&y3Pp8DSeJT_>X|7qT3sSKfOn9Y3(}<4@KSE zMNX!E>+It9-$ma-{ZGDGuK)P0a=iq4QfJ80Nn7SZc&`BIB4~`zoS5WCr}89YV%X?0 zJ_V+Yp1by}jo$e&fRFH>VWan#a{VRB^Yhf?^@cLz=oil_Q%0L zGB);!HuPcmPf!=WUGBAA<($`+JeO)Ld#J{lRjha4n0C&M@Oyj?_|HZ=d%tDuC3B{{ z;2p-(_V4~h!Y|0Y#<$ICU5gEH=(jd~(|()&B(|(#8yvu1+V=r4oWXfKy_~gkis#Xk zOFRL82IU^(9cK?cIXh1)aT)t;4{hGBYBfFBeq-;oADf?j__atMeIIZROE2fCoDz7= zjMRL@9bciEW4z-WqQJWJNKKExEB56(XSJ>?8r{0-t}(6FST#L8(p{+1p8Jp?(`nCx z#6(`ja{=w)tPNMXHzMQcyOZ}T>peC1)EoZMp`VX*#~07i$9@eMWS&B-3E~AAXL`nu zWa~mtle8YVh5!6J=lV7APd8&yIWm8J_XOe>O~Ma&GXBBSvUT=Te^+Svr4aMSptaud zn$qD6D~;HNAzKE}cPMv)AH|mGqxrhhh+P+wh!7L*9_cX7NR`rQ<(|pN}ow zz4;Q;M!E8h8TQ=LAM#)4h83keqO+g0rEAK|>h3I@a8F_|adWGdVQ@zs?r7=C|Xo_Y}T^ zxpGF*sJ6too3Y_Z`hc{Ow;eyYD0W8)`z>vWl{toePlE3P3xdDI?<0y0P&=~HOXbMt zD;KoAgwIDDJD_;}sJ6j8lVZv_zx@kxUz4(@UGyc$IB~|(36JkI&XDAsBzz{~3p4bW zhAGb&z8>^xeA#efWg|}#ZzHT*u_ zX05WWt$K|0>7S@Ay#n74%4U`B@q-hh*oMWh3yY7TuEh?$iFM;oy9xV68$1B(hIQyq zTWr`f25i-a-$ZhJCTdqo+l@7wioXN429wE4nJ$N&d}WbB>;u){Jnjni7&k=h>#@J3 z+~Q0%GGnEp8|}CJJ3v;=&64>e(KCkp?8$_%I~2Smz3$^Pf~;r z#-;fck;}){X$6rGep*p{f&I1saI?SEpC-O3bM&>t;f?A?66*wbuOI0?H37X?aAu@< zJvKx+sgdH16%p5_^2qHu_Q*HzJub{GixhA2Ms6RjMlRh{78y5&Z=-FI%f@&kR|B)R zk5(dUY~bF!H2j9Se+mD{yjhXudD)TW*S33>e@D_4q%$M8XUycvifn#*sJ1+>DpH=0 zebrO*BjuY?Be!q9Au?-AN@V%+c29XReQg-2ts9O%%OR(}4twF6;pve(Z5feo=QtxX zpigtK6)nqEBR3Ag_vc6OU-i(P2KYGI;-3v&p)LM-0nb{>SSx-k%jt7IeO@ko#{Z0U z@T>CSS_uCZFZ0lx#<=6tAwDNw=1crjyqx3M%ouo0pCd18ReX-TtkGutRt(yC$4Iw- zHuPp*2mV6%_H4#q)ttqy=)`f$WtP zqsNrFvFfqmSCDvTKK^If#+j1s4MXVjOvcsk>Bx|CG0S+)=3dS{Cn9xRO{`W!k6e^x z_z~2w9}VvRl)vAM|3R+)Hn`vNBOq3s;C^`U#|=LM!QqVk^iers!KH#XU6kcVhaG?) zYj4Pi1mMZ)u^;S!4+(&S>%qYt>zt8#aBvX&!Tpb=^W4sJ2hWa3d|8#gKc_0vo{<-6 zXPtN2@_C*c>428DFKYMfw~dUnubacW+(-hwdIEky;)%#y#n5xMH&laflei|al=y+m z7#q$LXa~PqcsN0P)C6b2B<|!6oiJh)BBOTSGhc82jY&gS@$WXJ)re^i-A_1{wh1jw z&#l^<$mD!N`aT|dH6FW91zXudY@K}#oHvU7tcuNHO}*F}RzzxSoJop3qH(SP@%5KK zhP|HHCNdWS8#i+ae+ulmMK30_x@M(Py%v5WWSi?2enk8R60{-m<)q(02Y2BoLd)m6 zg}*TL=wF9tSgB0?5^}}6_zj%E=Tvwkqn%q7Y*d5zGbDK>7xuZrC%FOvgJ&Y96mjb6 zOZ&$<_5Lx?ZE&m;ztIx>OXIs2w8bY3ZS!}f8|(NgVu@}1QkmX|oUX&q?q&}zbX}P~ z(v(epwOrBeGyR9Q)+f&=X@-7_p8gmA*OX1J#ZUPnXe0j(mQ8-f_gr{J858)1XAB#C z=4C4BlZ??jjE}5EKeqYp4GW>;4Xm?9=KMyULp-nLc|OneJj+^Gz%%<{tlJYJLju16 z_{9I0^(kx9k8QrJ%^o(qw9RL&SafyXP1xtNUQb#) z3+q^Ey%#nB| zzT>Os>p7j}ZYS$C&U%fre&ej)?OkVW^Ox5Ti`2kRCSxm72kTa4{rUulu%>;F$$CD- zyX1N`WJK2KJJ`jFowe|&5)Vx961@H*;hDO}%{<38U-F1;h{%>9bTU##C2%GAE77m^ z14sS#sh_Khet&vOtHhh=nE=c}lZ|m*K2(ch_ukByMX`NvmOT(`-Tl#Z$!FBmFXVY0V~-ts+M-CTenV*u>nvK2oxJ!L;g2gk z@^;2Ap1Bx1>Je>*e{m*pnBZ5$-)1{DVIkobguwN~tTAcx&~XJ5`S#MQS?F$i(&7o2NRGcDwL0GDkv>1b%z(ENf*fb&=Tx z?kbrR!9@aZ=fj}YAK_iSfn;pia%|VtO!g?ND#00PoLADpISl(tZJep;g)S-h30Hzg zoWzffPvAVJF`Pv}*~n7p8S;1R!RF)Cv5DF{*aG)VC})nb;h#RUwUGTt@g22i&Wgmh zaqi%UoL&9y1Wl3qxGOc4yK0{qiH|ei-8n(C^G+vzYrJzddwFTVI`UO+n%<32A^ zbZfguZ2OB+v1=CF{?tnF%cJ0$$DnK2^rr&**d7P4JGR+rweYPy~wED6`6X^oJ{?_s!U`b@D;ZFy-PFo_m^erk9FFTZ9SN0v^6BQ z{EVN)+x)%889w>WEL|stt&FJ(jP`OSfWX85N88)SM|GC@|7S8GlMo<4C;?JRLZC^d ziWMnN$w-m`k`mgqB^E2TOh{WoW35URk#(8L02zo%kC~QMwg!wY1e_nOsE`-yk}$Ni z(iJVcqRXzFNvKScR;&TSA^SDo_jMj71EQDuF0!Tv+Wy;2TeWzR8B4R>*@;tr15mSfz*Ix4cN71uc$ehcwU#BZ1Qk&#v0+mV93 zGPVe`d4@Ue-yXSM)~sD;hpLrl;9<;eK!?6E;sal?2JA&SH~GL{tO0vb!FI$4wqs4U z_?JX{;4apH!RQE9M0}aVHDOl{*5fKC@h&hK;TfgJu-#+d&ZE6UPG#<8;)K`pGIZA7 zd+1l>)xulK^9?6>j zK8OCZq`j*wMSTZ*f}_73>$dyZH~ScOMK^eS;4J!<;ex^FTaF73qi+Q+SdYGyxLLSf z+-%%(T(BK|mAGI<`l@ge`Rxx-FWjBD%W+$9SKzkduEgcuYM&Rk3AY?~J8mUzGj0{`4%`K} zjkt4g!8i2H!v*8eHy;;_Lt|}Xuk!8h^!UyZ--vqvw+VjQcFt|h=KaLAN9q3~0Z+{# z-W}xG$@>=Gx0?4G*Pi12N#38}U6co`LEmXy@CJQnaKRh&o#o64Z!nj;U8E0pGj?>= zgnrfp-#OBYk{f5LZOI`pH*(QWdPrXPC=-)V8N`8p%+*NS~-#r=A*kFL7%yAXou*th2XztkKn$7G6i{m>92QXA{VTk9DW`f=pQw> zRN)heEkr3;VUx+HZdHl9E>oEs_(PfQYY^LtoPF(eBg2vweB>X>9`yQ2+qNQS-@xLW z@JnJ_VWs0Boeuml@@OUvX-~t(K8Ytk(V}~Q3EgYk&39UKuly@?@9$!NnJ52S-U|<2 z>?Urr>?BIXZsG%_`hXR#Askx8`oQ@-wCWRX;Sb3A@HNhd=s<#tM%!367xHgC{!l@Q zVJlI>o!@f*ODpXvwi4gPP1s7nPpv^N|LjBPQW^SL$o=7U-TB~@a86RVh;TMxkt<$_ zPY!DgBcRPvuNpc)^6I+Qpd_$Z{9A~WwR~fsFEP3G4`{t|G_igSe-yGTLR^Z+$1>sOA3^ z?sUulp5^947uTTUZ_DHUk2WfN!g?o|xqC=o;0c2>tyf{#|U9EgydhkKHE=u1j~k`piUhMc`pMbJD^e zS?^?w%YUJ?dkxvDpRu1c-O?*+NL?@W{_-Gl)qnhiAy1C6#>D58m~!IQMQyg6xR!Bd z)C-zbbS`G}C}BTxzPG^n7JCd?pZ?sx)%+{=7@;K(oAO=nboIY(rCpXJ+h|PK_easS zPU!iks{Qf}dz)a>{H64ZC4EcxpE-ZG|Lrn8fGqpVedzkL$NQ1{-#&x1ljO@TaARd} zGwNi?mvi3#%kt&_)0-9!jeN{($LUklD`1|4(jIfCi_U+_WAGZt8(oF~x(ttycZns7 z7JS^4`-XL1Bv14-{-Q3^ZuF0C)MrY*vu9$`ojveK6Id&vPb6z+KJMjn=zpLKD0GFa zpF-FDIbDBrcy6i(wOhu6oaOlUp?@^*>`Bh=MjfVKk!K0_2uYsEb6)vd^!z`{UUKE! z2z`L_@)fyr2EKwu-tW-Ad!bqC4BF`CI{rt;krvo<4AMy`~WFWR5+Mf z^qdT=t*A>i`0U3N>?pvv?q;8&eM8VacrM5zFu;5+RP&NNU*CHI7ar# zdBBfOL&)+x}xj?DDHP?YWMCyV4Il5MXAol3!R|SHj zBmQaNdpaqLv&emkJ0FcST}5t@8w!4V1!az(7C9p2!G^w+|6|Tv+>*#k&I}cLDH3PT zc;a#Rxcv9La}+$7Pt$I>k@#tN+fl)M{}kcL{I`Pkn}YiY?xe^|C%_WzE>v5(3*G(j zGI zSFtCPyGG=0RE@K2jB{=mcZhV$9jTm&yEzY^-+0{f4rAo}+JNVsbpg+Bxo`DC({ayl zISXIl931w7N7#55 z{@LP3rkagENBp#VZou+hTmvX?v>jpEkd#pQ8bRlvr`4@GO zd$UibflF0Zew`jf9W=;P#_{FTBic0TpfzpwtPvfEev!jG)NbP2WPx>Q>Ox@0?be!J zGw$N(>0j2~bJhh`CU=Rp-pV(bhCYO$3o(ek+7Nd`8}vbzT2!jI<&KS_ap*+wZTemC z&Rr8kFCww-+jJ4qT6ptNm!WN z9seg-n3MNCNcje`EA`7cm0+(_nrYF-lV0V{X4Z>KvR=^lF}a_na0_>nZsGnFSwCIbQiwP`xJQ5j>xpNhCan}>9#(F)o(_-TxM)> zZoaPXD2u;ff+_c*|GxAu=u>2s=^1O`17f2i{Ou9h3nQ*vZ)BXeERtPW8o6azN#rv1 zyF~r^sn;K<*ZZ``?`e+WF2f^{nOx0cEP{&mlLk! zAJ)Op5a|weGM0#E-3zep^<;uCnvMQzw9wSyh!(o9ajw~VqEJ;D7oj7wFw!M_?k4!T z^E#LV_?zMJHerv^ToyUMjyi3iejBl!3KE}H8c6{U{`_jf^$i|pb7>?khwq+g@Vv9O z!IPR(5^jJfiRM zQtKr3{0Y8~9`nr1PK}&DivNiCossir@ShfcTIBpG{3pdfB62%2%ls@yq%ad5kw&M! zt;wl}wmZ>>f**I1wVXQmPtkvre`_mk8syFnbpKj{)7@Jer>o@KzO!|@nuol`$Nb8h z4}X2W-;;-4h>v-d?_7jF3I)Ex4}n36~T05-ulPNw|t|CE+T<3kc6Aynyih&7SM@ zSy&^CwbGxhF8-dS&%!#LUIWcDi~nY`KB3d1&A~rU{9w@*;4c)v66rt0I&SR`hJ3jr zUrm_GvCd_`o>))gv(S^2J;+!`v#fQCb2H&G z)-P>nba*TO+UsmW$A$Ze?-((Ldv8h0xdr<`XWbQNTc zT9Esx$|c`SJ#nYpTH1S^v_JLqQnn3*Hxgz|kFmCEwS-p_w$^*Cp71l9JyK4gHJ+6F zi;x@TXHmu^J8zo?Soa^CA2zV31z$610MYq_28fB?sy4;K42j2_FM*D_R_5Ty-(7rU$^?MCRJXxawwH38rWP zGS@D~R5xSm_f_}mUCUqN-D}*b#y|V1+ltpni|_%$2ML!Gu6)fC+kt;4aV`AYihn+F z3;1q3Woag@`b_;^`lTP;OwpT_@nXs@R%mVM+rSrH53)`LJ(r+42g;#8E1^HDD)sl4RqDT6Ua4ybXy?Ao zo{P1W`unRZ^>-N~UnBo*<0=pLuFYxhJ@at8amQ=tRP`z7c_VM$FF_7pvbii$_H}P0 zHj8{`2R+?$f}Q~7X`nno%F~rg+_a#lf%0gDd{Yqg_$gB?CkVY0^vFH4OIT+X2t6w{ z&oXA=+ll_lHF$SM7~ZmkL-GzDpZM+dsb{|VjUCr>rrf}(G-O8ZBKj=(Ts^9lI+AhvdX?qX8hTOr3U8zUQVeI5Gmbjx)n})lA_;vWRiO(Xu z7JnwR_z`p|a>urZUcH~Y6^m85>r&ddG0n2wkhP+UbZILM9C@vAVdSzG**1DQyJLSUDVCTJYL28mAd(uw{pku!0ZhD@|+C)$~f*I2&^FPHGwi?vUd-6h_c4Y8gq$r;`>z@ z`o+o&J;-?~FbG|oNjlK-F=%;zR)Z&yO&Gd82L0|YAUusQ^n47u-k*ymi=RDJ96RBY!LwOxXT9a_E+Y&Ccn z);=%i_=;bQ49D5yr`^K-36Is7Pu5(!oqmlkX06XG)89q!LFn{QbhTT~5YlI&<7MCi zlq1(1D$~cYA6%LPZ*2j0y^_Zr&`k9A`yHfMGo)PI5+{4_9W6yes>4& zdU$8@AM(-lI>FlbMzNN)8MxvN(0z_#_Kgy#@*%KO*&{&nuwb_O`?Gt%8x|f!%t>4;@AvTD z#rK(nxl=X9eX7z{4(Kc`8YNxEF!VwUdLiCij_&M8{YmPTcqeCm_yO8MzC9E*?;fGO z1@pBu5HjvM7Q9!jmG^rX)6AJtnKSzdbKh!-=(oWKxCB2y((lPf>#{mgbyjJvdb)K#IM z2fXa(?CDq7)8p*vav!5l>c)EC%lu z`$8NHv7QCcNwd&j+|Jl(ih4v2dkK0|+d+6Ig0%E`l#9ZIpJnh%{N>44Omp(ofLp+93Tj#GHm^*PNS3k9cTx zZGiZG;xEun7fH9N3LfWT@SM{R$M_tQ3Z-9n_Zgn2V zzo~eTGL$k$2C%WYv;!L@+QpAd%Flilu!P__GP*ZNg-<+~<@~`2)vNwHbEb>M6Dk+t zh%qI4*P+&0x9lTd=MG-kcVhoww)wZ5GdR0GZpeAw<=q<-Ik#?DsQWjj>d%ti#rcl5 z_vWOu_0b-(|NObRZqszh^U*=S#pf*6wUyL~_A`0g#qhSX4)>g1+TO$b>XA9a{OXbU z#axOpr|fcxAf zg#U^2lI+KZ-VygM-)v3=-WjUiX0=-Y8qB|Op?){vx`Gn7$qUDhHIU-YWBsyplU}iO zlU_;aCiy2B`a<`SXA5~MtZky3G@@ckcxO`BL3jsYql_INQQP^xIVpUM@OHv-W;MPk zDO6t}ZkzoLVfkkZVL7An&2viLY;_ND0rMLpEdPAf{zpOXM0kBtcrW2E5|*|Ud9IPp zu0r*B;-9h8A^dH^^@J1cif+)?hZt`u2_)l2zNo9CN z@r_rX<=y?fGtwpeRl-XM%bpvG@AAf~Yk23i(lO%b_s5C*xcxuhJWcqX1A1z?D9-zn^H8S8V-7M_j(SzU-6t^`Ak1iG4Q)R+7fvE3$0)uF-Pm zNj$P_!Jrl0r3-xjto2Sqwi83PGoxDxi=NKMDG&N}#{ZY97Phe-8-CGqs6a2ou9I00 zm-_NF^p6I;dThvR;cZSs=Wby_=S5^OkCH|a>Du~6Qa>r*OyX_7k)D#GJ~&$RjwQ})Yzt4JChHIx&K^usC z&u&jM?@8+Szl$!=p4D#7+IPoumx4cv-El&fCl3tLrHOh8ze3Up!6O#D$GxLWUXOjY z7yX{siEB9l5BcP36Vr4SxTLc!Tv9K(iQEU4R|CC+EUo3Fl^${fY3nNVcI>l`=vV!! z9Q+@iU-JALkJQ`jgDmy$DYvwFD(^F0Uwto{#W7Wjrj2 zD`BILkuU!u6Z)36tGMEtC-P+D9^-wA6+=CQz7y2@cu`7Gha&5n}K)w za~mTwS#PG0v0q|gZ~c$-W`bY?Q2$LYn|d?J`Q4~DGm<=aS$Z=?e*ya^jsCN-e`1Uu z1OJD$>`Hd3K9G}&Ocj13<60x{9M+frPH*PDU!pg|eel{z_#GB5jojbuuT4>Z4`%Mm zoQXAb8V;hjy$!$cEPJpYSc~7%p}7tp=;MpQ;X)=ZV{bR>=WfMo@)A6#4>A5e z$a6c-ENd)EJBcpMqKh(CChq&Ocevkgrb|=0b{He*pGfxw%6v17pday0#^*n@5&)?PFRyCIt< zW6p@Ipre*M&|9H1_dsJF<-aKZ?ZT~Oi0}^l2T8ATaeMqoT6?;Yp6jp% zzoPas7_rc|=pa^aRFz;HD{R$b%B5eP9&{w>))2q*c zo)Ntp2}@ov$*U0?F3G0~o|si8N6-}+IKdqyC&6Vs<Uw{Ml z@8-Ueg3`9W3;4a$-05?$YdYhi{)^iy)RBj;w0QMv$kYa);jixZ>gN9z&!TY}He2v3 zTmjGE0Wf{~c(PN5c^2GPk>FRLBT~c~A$-t{A5h*eSw2+#2z<}UV0~zfDXk^ruW6#bIIKp zR$8v{rri>2{>CNPEiE0YE~0FM=t|sJuQOmYNS$k@EfIx#>yYLx2|YvDE8OV*tbU2OHs& zDBhuJqi?x)#U4uv{49s?v!dXd2tP~iU}26sgqP*weiisw{gmSp<+wr_u2F^oL)|sd0F)`S7+R-yyMWfrlX&C+XzK`${!4rQ2edR( zXRctv`i&`*`?Pz8s{7B5YP)uBblcU7V@#YT>Y#C7+tPxRu&uXvGo3>JPySf#)ZveE z7q0T%+r^&bxmwLB_8re{%5z$BV&ukY%&A3F!XLrLL&ixwrSu12ZM`j6Thy&uXeyij zEoA%_Ft+78nUg=bq=Y{Y4|XH}+i?-%K11ABthl%FujYA@$NuKKd{ayK^L!&1r7}-s z?#mu0boOXto@A(B$#58S))mIEL7)D}b@wOvuhvTYQUN;IR=UE2+ks!sjgrrgt$3mD z1G2u*Ka%#9e`W78)+U$w!y)K6(vbh|Crz!7eeNQAn+twTCj6Ry{8_@cA-)^GllY+q zk9H3KAo@`CmF@Af!j~xFK0Ed+=35TB?ICnmgg>IWILl{pmbYc1S@=aJ>Lh-MG^!d5 znW#31znt{Wk{&YAI`#rv9%{@FXxl;f^f_Su+2a3pAAUUvfFNN;#UQyF=Soxhv)> z^T0GV#$e42_1b9FD@?s!;+tPXCreu2v%U}GnrjMtWZF~CH5n&In)(eB;k%Ahs)dhi z$gI&juysn}%is^MUJ74xRFeF_w5t{!ikNGQrzab%$t0fgAUx#~;kOPUQ-GHohnE~L zgogw_S$N6jdNfrndewEfLintGIqkBx%G_H5|Fv(HqfOeRgtNZTKQ)2}W$S>zpN`d{ z3ptB&orG^Ba|ixXtQH>AIe3`e@YGLM=)EU1b&<`999269FR~k6B=X$YMR|{`xEuRr z=0ZI@eBrr^46XMJ_hUy#>I)p{eFjdb%oWb=a;91j?JF`Q8H4_{@W(cw?*s3w#W}+* zys|d>u8#cVoMiJxWxVVq?lY`KA^y3MpDXWoKM0SGcj@R{hDcM+WFh!(NR~I5}J1@!SA@b3j=#04Nzj@5p`S4q_X>;!5(}t*j?iNqH55De-NeS6? z-K*t?>qI7Nx3ATPhK>zwSY*}d#x{)8hH=_Zo5y^fAGPRF&ZX9VCHL`Zxs+poF|gv3 z?N1>SeCpK^hkH)uw2N#wb`jl$ZqfkPS!7e9<0L$5X_HT2OK6UfeDoTQp|=39+mb!y z!RyW!UbiK?%0ss#U-;caj0(ZvvoJGg7W?A_v ze#+`kDytv5-#?tM;-{?s;d~YUaK4H^RGi}9TAZyQ10nD9YDIVWw-iIeJSX>N+wJkR z=s~fUNSl?S?=P~N7W{sZ)$O1!cQUqY-P{)ZqMM8CCWaiu*3A`}OhQivnMDj;HbYMa zc|}4`M&uccfzym*$s>`rmwAg`ktS)2%)(CFl366ndj^sB^oV?C8EyeG9_FynGm5N7 z$TfPA`DC!h^cFhW(q-)t83*zoQ}%DlHjtC*6>?@^4N|%|%l$vdI7GHlgq))YIfr(U zy$}9(e1DapYhdP8!Mm)(BIk%9=Sb))Am=dj6)ahZ%?tO#`aPJ4xi7y{3d3SD{ma4HJ30 z$yfGS**gpV1G}gu>m7UOOLDJ@wMT^nuhXJ2Ci7j(cJ{7j>s$8H1M)3gAwE)m!JQ*Sc?4uR8P8D^90@%{v!9%1)8d zcvl%Rj?c*X?H9`2x^iR*&?#%67ZxCQ&WGOf1v`rCtUD^!c#+d!a~@yG+>kL;3f5+8 ziaI49JC-K)m+ck$f*bCt*!=})^zY`)X4k4x_GgYZmla=FU^j#i(R}=I`YBSMS#DKi62n(eCjN1sKgjtB%pkGx z*T4-DEC9KSRZp5NCKyoYjwrO3w1t!< zegTZ4_fLWK;smP&9HPbvk@#w-5$8L=*>Zq!SL@K@7r<^ezDu#b8_##vzkBRB?iych zeYeM9eK#)RTTR#>EY>&{o@9;%Jq`R<+qWNNg9^i>V}r{GlyUsU>P_hI_V`nImS#>h{;mvR05 zPb<|$hn2bObI^C;?2(*~_J4+|*VK+t^RZ!)e#{fRY5K8&KFni`Ngqzfu1WeZPjIK{ z!yx?^pzoyr8>H`Ko_1PxDD>ZJmq$UfDY_4=EwQ7h`BI0+Q9!?l+#fxmnr+}w>;p{=ri96T>8of&!z@`jo`BSuo0-K5mJ0`yu7CK@(LzG#XrYo5J6#nAivo<90d@L5C1 zExybd*N^VMsRJ}hEqU6)XRXa@?QaoM+xg>9{m!JdfebnwHGy~AFkjW7+;sw4$bl>Hb~2V0nM^o`C(r0M6sgK{ztGo zNB1&thm)4=PvVjMk zF1tMkT8HsieOpXCRv);Cvi`@BH^sp~^3xW9Ah<TB2_O+#0iIb-Kz?w6BPIbU3vfDMwQ|Ge@;KjW%|@m|VUkMAUIFje2k znD8y@WISPez?k-}z-3I=9f3b~I$ig{H>-hX=65+5SNN;MpTfAp4`0oXErXFS^W-S? z`wDtW@zWLhn%Ze<-Mmy?Y%B9dI1L-gynH|3mlAehBM2TbI{i|nJoNc}TPnfMB#$ji zaY=v65?m#+aek_9)ZMl{vii)3+nuAf36^Vezflff)Y5ID@0NFr3a<}ltIyV#=_S}u z()wJX^3~8%Be%+JrkU4b0h+$fjGIkr}z*sPOwEjJ znR;(z%gf^9Mv;8}A5 zedCK|dc6xf9q_{XoQw6oooV`}!01Te>tiAf&yO-NRcpAbpk_zFQ@bE!@lM#ty9&FtyA64?t#Y-?G-~$Jtg1&&Rpc7c&v z2R~o12RXe0^zb$n)j48GF zfas4oQ-ATt7c;_QgDSSOf~D%`-t1khp?>bmzBI?OH(^Z0SRe8`CaEcR!;_?ZmzsrF z%U%J0Q^QsGCj7ayun&2|M#{Zw3wUWVPb!&nvewAAofh7(FU7)AO*Q80qW;n0HT-AS zW!Tnal=_XUqr<+3JFK(uC{^*W_7$-Apx-C>N_7XFy6jK(zdkQIOswJeT^k)1z4R8& zAMmacb|+4FIM*o4r=pY8GS(gQj690HhBWKZ+mv~*c_ibXdGaWCc4dq*=fY<0s+YO4 zIfH#?s`~Hn7BAP%Q{@cj7)SayS+jdjA%Fam@lhy?$*jV@Ig53%1D)luk&>qSA|)APBBC!FUkCpNyk6j zY_5t3-r{b-sBB%L_w8YQM-Q)L#Qnqvh-Y2hFS?5Sd%#-z!S;=369&gb_V5x_bmXBe zqJ(EFZSfPhnY`ceiFUzRtQ(K*?b*@oMmq(v4IDlnxQ7mKRxh!Z_@TdiU?SFl5f^B< z1w1}4_Tt>f4*p@BGj6;uO>g*TFz>-a^lzD9$WuNgXRs`Vc{bI30J`cD<&*W+NH2{w z_etoX@$>~}>UeMj@4%7=!+2=<2=0?&-?YYSIy(0ibH*Hw&jAZ^=g4*+>uN^6!@w?; zbDro0%3PIt_OeDwzF=KFXW*IA2Aa^;R$9{kewW{)Y!=*l6VFuHEZFuYo~g1~Fa}LL zQ)TnL_@T=fE0@@>Wez3dnf||w2^kN9XDZ`B@JwYK2%f2o1Hm&bX#`J|IV*Gc5@ilI zK!Zuy=@VoAGsk~-4>T}i;~M*YT=sj$jBiURVnM;yFF=q6e?}+GCn?gtjwJl7uGllbq(X0_AoA{2XZ3$uhECr81OMZY8WSZ zn{Q!kfSdVs88;`110!>@IWA;8tjq#~&9({2HFYpU^jq(qKgBbx zkHUlh-62QYyUdF|8B6S`GFAm&w4e3fNBau4sE;-lY*8O=ESRD`+Ep+`eau6_6!kIB z0u9x)cZmLI#Q!kx8dIk{`n^(yTLvU{Ij$@*r({|#`nAQy08p5!i^lNq7tKKgDgtJ&7B_ zeG7Lh?g?CJlQ(cT8*({l61TKn|LT%9q4nfk*D#(vFcZw_;3CS0eFOJwq&T6A*hj@~ zyyC9=!7k09OiP&O>Fvh;D`yX6su#hXxm$-<42vk9(C%y zCkQhh_5I|it&H{Ij8}PI! ztzj=Q>9wC03#Ms4c2U!@of16LeB}NHo+*4>Ke&Iw>-7h}fh%Wxa82P23qD{T{9(Zd zwCgpDZMw+BHm#%`(S^7MZ8{+9lhor#x~?C^Mj}dB>Tx1nfA3_v-gk<%s}O9{v+4S~ z=h7`~Q|fSHoKXh@+m!aT>4={!Mb3+T#y~T)1bB&d{dV7u-Xi0wx}KaoPC=agP^weo5TdiaWm|?(4;!+?}+WaoPFVfT#1Dot|Ud za}?#Cqm=ELkz?F*l+rjV()k7AzeN03Bt9c@jQfsKz$iKPS$Ut1P5IKuu`vNpN;BBy z+u#9k57Tk(6Nru^Zu`BwyDgHk9Q<o(I$Cyq}$KB+avNF<$+>ZpnJbyIOF_G|?$08k50-j4dyvF_lKfoQmjsK_f&3NA5&G%2?-j4ez z+z;SBhWjDhRk$C)eG+#f?h@Q7xcB4UhWiliblit=$Kx)BUiFSv?@V)qebG#H>3d3e z8SA0&Iy%5=?EDn%@fhy5(UHzo_@5O2m`LXm{P&ALGt&7G{)fd+`z^+Q5AFAHTrl5{ zmEm%>Gv*ZQ=`r?N!LILwXVCeLaXghgVqx6+Z{Eh4wW+v6?)G4w z1ei-5;7Qy2x|Ge{*E`Y#v)sZdr+l)n%U*7jiL?%opz&+97;t;jv8^QKCOzrf|nV>96zhlpoHlnjHQl zHqDcQ*qXzu72M2D>`rpXD+F#Pd-&X%oKoH2Ah?+m_w_9sX~;c0j5GhleOG^M<7Q6W zcgII^1Z!`eolbrpbCR~pCXZ)HL)uj8BfLnXzu7xAc&|C<*f;iY_hpi_fQ%Xjsj>!jSDVe|Akh1#Q_Whc9_rX6y2UY$t?wcZCgP&>N|7MMy zi9a)SjD^>8vwNxH&lphaO+v{G(mX(oC*1JyDyH3`-PS(3l*1OJak4BEM&K>*4W07O5Z&B8_ z=(bNsWQ{xa%@vVj_pr8poOSAUzGYpEmJ!d|cTCnk*1b+y+y30z_gAcW7r8H7*1Rk* z9*-jrssLYg{pvEk8+p$fcpG)mN8Q3p5#DPLG}$QOtMkpX{bl-b%WfhDR)H^CreC!1 zTO}-K`?}Ug;oVL$?pZN-w~Y6Y{L9`JgO*CMFkF>wL)Cufv)EjG(=#O;=ZqREuxuwd zGZ%HHiS5L5VmlG!JF%VEggb0Ik!{#c{IPgS_}Bcah&&71i6755@k~YMZPV$=;XhKp z54gd4RTN|1*J(o^z04TjQJ`F(zLsjHU-H4kIlTrf*WZ$UXHxp#CVjy(y@fQjb0)TH zXqDprFY+Qo`R&3NInN z%MSbJt8T*okQ6Q>{32m#@7=UF>5|S&bvE(ew7(<#F~Z+4!#`KB$tWbe%?^XrT0nS< z9p?R=gd6NI?~4fky&b0CatMEguwX~N%-SRFKFjU2Tp4FygqHj$;WFA%zUgOeybK@T z#(BMQ-}(2Gqr&pdzw(d6O2@V-(7P1l-D_5S4EKXPcUs{WEO!I0>|2uG_32OEcZ~F7 zoaG$Z$iq3$A;&hpv&+?Lg{AC^DZ9u!v#qipvcE;&!mjhLk*mkx35)Kr=u7P*{ebnI z20u9lKl#EhmGIvY=OCRKb{f>NIms{f7Dh!l{)&t0WldE- znU@xh_bt?87tse9hkOLvg|7Z#y9nVA*N{dRW7kNZvX3Wh+ek=Uo}C9gxlBh|Sc4DN zf;)xyf3^M-9?&D`G~Hr-YqwW*Quyg4|0gVe1#Kd-1eo|n{nlBoL6<1m>Y5kR*(V=0 zZ6W4kBeEbF*OYteu^X{%7vvl+>B*T^&SulELDQU=>aIKasA>0*Nqc9ZlVG&Nht;m^ z#l!!ewEpF+Bs~1*eupj_Z6kHuNgcn%^AgXCR()-{X%_Y>qG#9t!-?TtieS7>+&AOH zImS2?-9BlDeB5pJf3)F8sZ&4gEVetFta!V<>Q*l^*d^~VkaSC zdry&ZpYbat?DJ--L3HoxT&vt6#)QzR#(&V3GVWf;afIs%SGnV3d1s9sk*WKj^=hE? z${Bw`qtwk_<*v)(8)y~df1y>-YkwD+`(L6}e*SN1;kruFAEnHzD<=&}+x3aIyChv` z7&EPL)M3)TU(XxXxtI9=4x{u&d{Vh@*(drn)a%dTjOIfN-|W6+L#`<2D*pYLIyrm? z?f(L@n};*59(oCy?Z@1;T#O5oJDHJDJomTY zla6BDyaIn*&cauAaNc#!<^JAV)t|6#>`l<*H^(P!Cg1q}#ps)TK+XFey2wuS<0}>Y z+wfA5>#3jrSNf6uDYEcMHS`%iL)<3x%rs=w4~^$6VU3TXi>`SaBp%uBQsV3Ji!DY2 z`)o3v=~?!=Jnm{1T6;Hb$$pry#dwDDjHInj-ZLe9oaarRH+W9)$oJ9@VviAH-IjUt zP}11AnLS1zGHj3WNz$&PUN^JHc#wB8Za>C)`hD{H9?xH;58|A89hRxw*=*{Bj8aYA zVD4rH-{(iry9SnN^a(@%L$FNu-sTv_GX37nKaXV^orw+z{G4at_ZoCNIw0sDzcdLQ z5Ru2VAY)jDzK(@u8hgsbGX1z^Pa4a0RBvsaiS6nW?iZaVmg!Qk`uFBK=Du{aL>HSm zk*oQUaf#f`kBrNY49ky z!PNJzxT%fT|M#zHroMOg`1PzU#{H{;70~fj_=@~1{!;D=8#vAVGG{W)_Ak9fy?T~A zY0jaup0AkaNB?bVYA1*5n@+~c_LhJ&x+ZpM8bcZ-4hvW@!2&)w2?xqD*Um80;| zIiHGth_r*`moGT3&QZuqr7uTE;ulKvyv-t~8WYJM$C-aE`Wwz^ZBoXT;7s>b=7Bwi zuPrcn^P$F>-0er7HBO4`LKdc-@_Y8mT`jE+@K@=x#)-(hO2K(J&_Uj|4N79Xc(c_r?{b%f;5gX2xvTlU9<0~Z;J7>k z&TAF;uFRe8<>0-p0OxfD_^#m9y;BR`>&k#21o%c`gxSh|q(kQp!=^41L1>m}tKL}5F_--{Nmo$DG5AR(Vx)Hc6zjvn>=-8iaWldyuD8Dw&fcG$8}zIJNs3_4pHGO zD&l{Gv;AD9rn9y$jSH!L%Dl6&;G_5;_#f zVtQK8q1Z2c&q6icN_Y=`sXz0}pp`mO)uFGWL(x~RU%ptLbg!+cLm_(ybg{K}Krg?6 z4h3?wLFV9Pk)K&@xo79-a6fBCudI{wZ%l9i`qAY?Cs-4G?Ll1n+`uSAFFS^Qww%3V zi&z81=J7|P)iu<=hdDpQoHuz(Bh)zSK@aPKosUsw)`2~v(48Q^x<1;8elpTM$GGc8 z$BDH{c+)M61HY@&6UYP?LTseaC+|X^Jb*adDf`8I*u z)GtscdrTXct&C@7j-UBq<|leaMqR0w138t3o^uR+XV#>MHi#cR>@F}iy8B;4Z^*)H zt>>O%sc+3Fbq#$j@-pcoBQAf8`liGs_Y>vt*N(U3+NoH~f!BJjlrIv{LtO+M!GI>#4Iw zoiEW2{j`H!H?5DhyvW>=KBGUo=+AEYv3rPlJ;=KO-u3g)Cb4?nKf}AVJm5QZf%g;> z>?km!v~|4S!26Bhv|+JgX2{#`xxP42F7ZDHA2h9&pNRcT__C< z)tHO07u^QdD8XBeWf5kr60B9NpS~PG*JTc2)+ud}@DSnogclI*BYctYEW)$FW<{?` zJ4akMajZW9)~cS9V0xbBu37I)RrJ(ayffVn?$%A&4sK^H^;vCVtfp+YuvoEk=>q#N zwvu@4ToPEUUc%V7I4vyJcd&aoUpb7$`pyEv^BX*yYQbS$4G!xw4F*>0`C70~SA(b8 zN_Y?7)Z^cei=FB_*r}dxCVmIum4vZXJ>NojXM^XZ)`{x*X5w}n^UUB*-t+r$8K39( z5Z7vAsh;17zeV1sMz)sERJWbxZr;9BeH%JNu^{Db1h=(`zSs_K>jvtz(Zp@N4uf?8 z7_44!x5}NmpR)V+1i;9}-A^Bp-qsahuzK^<9^`>7-aK%+@=OfY+B`5=xt|!?CeOxV zh4%3=Z}QMv@Im|JF^+xc@8m(N_?RPk&?Y`)yCLi>{CmiQHudkvrCqnKpr4vk_2&!N zy9#EyuOYJx?MT&q;OJ$V>IAbTV;+L>srZJb-{KUZ#C7pKUhOwJcgdQ zG6K9+7ioeMql`$QoW!F~u8dG3*Os&9vJNY(<%ay5^-=B;KF1m0+ICC-rPI=X;hPC- z(!%~7;H^?W?JVomIrcH;e~kGbkD_NF`-QCQ0ZR|2!_tG{-%Y*Xt@5w={xuC4A z@Es(rW$>wlHZtVaQSdpTSwgi>7_^S?&Ax^{%NxhQY-=gif5w@^PFulFM5`kIbCN%O zVcW@w4FUEAS|)Zg*uZGm8N|fKfb}^hSV*%8&mnBB-P%0D;3P>|(;bem$m2`7OZaAc z_T&@XN#8De5o^8Z&Y*)LdXMPNypqtJ=}c8`LElIAEzzAZb$U`&KWXM6=QMCv8AGvx zB;3_P@K9$Z;jS{Cy1;Qu;I1+f+|*sGkq;s?;Z*+0@4KhjU8?#_7C z&|hIc8(=@X%pP_XTH^|1Nk8zXG{<-D$PD+0K28!XzW^O$-}6J&Taj%D2BQzXR71w$ zO>rB#S)B0_X933IZ)kJDL@?wV@=XhZ z$}O~~=syVk+QS_~?|sPBfpDPNFLYz5w#qGZq>Q)E%!M!hs)^h9G~?|uIwiwnhy7p< z>nLMKn}=)B0@^I%3mZH`<>0}3q0w5)+v6M3+YK5JJlG!er;F}V4&TB#DAZr7PjlST zcgZ~Ww zvDV3W>u0%w--z>vkR%)pSvK2~gHFNrSDIq2W+C3^1# z9>zd#A8}xX^#}fV15<`^WqE%c zuIvzdGWNLL*y>(~D|?Z>yT8H2l^x`p0rpA3mF;8fU1%_HWx;thaAj+39U^o=MCK)H zY!AGA@rT5Z9MF!haAMO~U*0C)*l|7ZC2W5vI`cYASw37ppp6kG6&VGNj)ygw!HE!^7EgwHT%Ec#g6 zLHawvr5yy@6P!}*EaUFnaj;&9Z(>e&=be9c)x-7rwN}SypeD) z3Ac7flyq4Sptl4k*T4fs*ZT?DK7kc_k$3Pw1iM+VM2G8U;nr@Kb%4Eh9q%`o>w|$? zyOD6vTqEM}J}wDQ6zs$v(S7WLA5v)I);?cw|9ZdkRyA^b7_%0Ao9FU<^s&(Io#R!% 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%0DqrPu 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

    &|jKYm~s=Nawwh20)i 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