From 5ce57cb747e5869a8c024433be8c9f31dbbd56e8 Mon Sep 17 00:00:00 2001 From: Nasr Date: Mon, 27 Oct 2025 16:42:44 -0500 Subject: [PATCH 1/5] feat: add search bindings --- Cargo.lock | 12 ++-- Cargo.toml | 6 +- bindings/c/dojo.h | 88 ++++++++++++++++++++++++ crates/c/src/lib.rs | 22 ++++++ crates/c/src/types.rs | 79 +++++++++++++++++++++ crates/uniffi/src/uniffi/client.rs | 15 ++++ crates/uniffi/src/uniffi/types/mod.rs | 2 + crates/uniffi/src/uniffi/types/search.rs | 57 +++++++++++++++ crates/wasm/src/lib.rs | 41 +++++++++-- crates/wasm/src/types.rs | 59 ++++++++++++++++ 10 files changed, 368 insertions(+), 13 deletions(-) create mode 100644 crates/uniffi/src/uniffi/types/search.rs diff --git a/Cargo.lock b/Cargo.lock index 745fe12..507ed25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4523,8 +4523,8 @@ dependencies = [ [[package]] name = "torii-client" -version = "1.8.2" -source = "git+https://github.com/dojoengine/torii?rev=8378c63#8378c636a6904f17ce04a011d2aee1bc3d84751a" +version = "1.8.7" +source = "git+https://github.com/dojoengine/torii?rev=ffd7139#ffd71390e0a71c06892a9681d155515f36efa988" dependencies = [ "async-trait", "crypto-bigint", @@ -4547,8 +4547,8 @@ dependencies = [ [[package]] name = "torii-grpc-client" -version = "1.8.2" -source = "git+https://github.com/dojoengine/torii?rev=8378c63#8378c636a6904f17ce04a011d2aee1bc3d84751a" +version = "1.8.7" +source = "git+https://github.com/dojoengine/torii?rev=ffd7139#ffd71390e0a71c06892a9681d155515f36efa988" dependencies = [ "crypto-bigint", "dojo-types", @@ -4573,8 +4573,8 @@ dependencies = [ [[package]] name = "torii-proto" -version = "1.8.2" -source = "git+https://github.com/dojoengine/torii?rev=8378c63#8378c636a6904f17ce04a011d2aee1bc3d84751a" +version = "1.8.7" +source = "git+https://github.com/dojoengine/torii?rev=ffd7139#ffd71390e0a71c06892a9681d155515f36efa988" dependencies = [ "chrono", "crypto-bigint", diff --git a/Cargo.toml b/Cargo.toml index c4d5ce3..1377b32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,9 +15,9 @@ version = "1.8.3" # Dojo dependencies dojo-world = { git = "https://github.com/dojoengine/dojo", rev = "0afeb1bc" } dojo-types = { git = "https://github.com/dojoengine/dojo", rev = "0afeb1bc" } -torii-proto = { git = "https://github.com/dojoengine/torii", rev = "8378c63" } -torii-client = { git = "https://github.com/dojoengine/torii", rev = "8378c63" } -torii-grpc-client = { git = "https://github.com/dojoengine/torii", rev = "8378c63" } +torii-proto = { git = "https://github.com/dojoengine/torii", rev = "ffd7139" } +torii-client = { git = "https://github.com/dojoengine/torii", rev = "ffd7139" } +torii-grpc-client = { git = "https://github.com/dojoengine/torii", rev = "ffd7139" } # Starknet dependencies starknet = "0.17.0" diff --git a/bindings/c/dojo.h b/bindings/c/dojo.h index ecb85d3..83d8d9e 100644 --- a/bindings/c/dojo.h +++ b/bindings/c/dojo.h @@ -29,6 +29,7 @@ struct TokenBalance; struct TokenContract; struct Contract; struct TokenTransfer; +struct TableSearchResults; struct Provider; struct Account; struct Ty; @@ -36,8 +37,10 @@ struct Model; struct Member; struct AchievementTask; struct PlayerAchievementProgress; +struct SearchMatch; struct EnumOption; struct TaskProgress; +struct SearchMatchField; typedef enum BlockTag { Latest, @@ -1052,6 +1055,38 @@ typedef struct TokenTransfer { struct COptionc_char event_id; } TokenTransfer; +typedef struct CArrayTableSearchResults { + struct TableSearchResults *data; + uintptr_t data_len; +} CArrayTableSearchResults; + +typedef struct SearchResponse { + uint32_t total; + struct CArrayTableSearchResults results; +} SearchResponse; + +typedef enum ResultSearchResponse_Tag { + OkSearchResponse, + ErrSearchResponse, +} ResultSearchResponse_Tag; + +typedef struct ResultSearchResponse { + ResultSearchResponse_Tag tag; + union { + struct { + struct SearchResponse ok; + }; + struct { + struct Error err; + }; + }; +} ResultSearchResponse; + +typedef struct SearchQuery { + const char *query; + uint32_t limit; +} SearchQuery; + typedef enum ResultCArrayFieldElement_Tag { OkCArrayFieldElement, ErrCArrayFieldElement, @@ -1285,6 +1320,17 @@ typedef struct TokenContract { struct COptionU256 total_supply; } TokenContract; +typedef struct CArraySearchMatch { + struct SearchMatch *data; + uintptr_t data_len; +} CArraySearchMatch; + +typedef struct TableSearchResults { + const char *table; + uint32_t count; + struct CArraySearchMatch matches; +} TableSearchResults; + typedef struct CArrayEnumOption { struct EnumOption *data; uintptr_t data_len; @@ -1384,6 +1430,31 @@ typedef struct PlayerAchievementProgress { double progress_percentage; } PlayerAchievementProgress; +typedef struct CArraySearchMatchField { + struct SearchMatchField *data; + uintptr_t data_len; +} CArraySearchMatchField; + +typedef enum COptionf64_Tag { + Somef64, + Nonef64, +} COptionf64_Tag; + +typedef struct COptionf64 { + COptionf64_Tag tag; + union { + struct { + double some; + }; + }; +} COptionf64; + +typedef struct SearchMatch { + const char *id; + struct CArraySearchMatchField fields; + struct COptionf64 score; +} SearchMatch; + typedef struct EnumOption { const char *name; struct Ty *ty; @@ -1395,6 +1466,11 @@ typedef struct TaskProgress { bool completed; } TaskProgress; +typedef struct SearchMatchField { + const char *key; + const char *value; +} SearchMatchField; + #ifdef __cplusplus extern "C" { #endif // __cplusplus @@ -2034,6 +2110,18 @@ struct Resultbool client_update_token_transfer_subscription(struct ToriiClient * const struct U256 *token_ids, uintptr_t token_ids_len); +/** + * Performs a full-text search across indexed entities using FTS5 + * + * # Parameters + * * `client` - Pointer to ToriiClient instance + * * `query` - Search query containing the search text and limit + * + * # Returns + * Result containing SearchResponse with results grouped by table or error + */ +struct ResultSearchResponse client_search(struct ToriiClient *client, struct SearchQuery query); + /** * Serializes a string into a byte array * diff --git a/crates/c/src/lib.rs b/crates/c/src/lib.rs index ce54217..d476450 100644 --- a/crates/c/src/lib.rs +++ b/crates/c/src/lib.rs @@ -1893,6 +1893,28 @@ mod ffi { } } + /// Performs a full-text search across indexed entities using FTS5 + /// + /// # Parameters + /// * `client` - Pointer to ToriiClient instance + /// * `query` - Search query containing the search text and limit + /// + /// # Returns + /// Result containing SearchResponse with results grouped by table or error + #[no_mangle] + pub unsafe extern "C" fn client_search( + client: *mut ToriiClient, + query: types::SearchQuery, + ) -> Result { + let query = query.into(); + let search_future = unsafe { (*client).inner.search(query) }; + + match RUNTIME.block_on(search_future) { + Ok(response) => Result::Ok(response.into()), + Err(e) => Result::Err(e.into()), + } + } + /// Serializes a string into a byte array /// /// # Parameters diff --git a/crates/c/src/types.rs b/crates/c/src/types.rs index b12bea9..c1ff062 100644 --- a/crates/c/src/types.rs +++ b/crates/c/src/types.rs @@ -2094,6 +2094,85 @@ impl From for AchievementProgression { } } +// Search types +#[derive(Clone, Debug)] +#[repr(C)] +pub struct SearchQuery { + pub query: *const c_char, + pub limit: u32, +} + +impl From for torii_proto::SearchQuery { + fn from(val: SearchQuery) -> Self { + let query = unsafe { CStr::from_ptr(val.query).to_string_lossy().to_string() }; + Self { query, limit: val.limit } + } +} + +#[derive(Clone, Debug)] +#[repr(C)] +pub struct SearchMatchField { + pub key: *const c_char, + pub value: *const c_char, +} + +#[derive(Clone, Debug)] +#[repr(C)] +pub struct SearchMatch { + pub id: *const c_char, + pub fields: CArray, + pub score: COption, +} + +impl From for SearchMatch { + fn from(val: torii_proto::SearchMatch) -> Self { + let fields: Vec = val + .fields + .into_iter() + .map(|(k, v)| SearchMatchField { + key: CString::new(k).unwrap().into_raw(), + value: CString::new(v).unwrap().into_raw(), + }) + .collect(); + Self { + id: CString::new(val.id).unwrap().into_raw(), + fields: fields.into(), + score: val.score.into(), + } + } +} + +#[derive(Clone, Debug)] +#[repr(C)] +pub struct TableSearchResults { + pub table: *const c_char, + pub count: u32, + pub matches: CArray, +} + +impl From for TableSearchResults { + fn from(val: torii_proto::TableSearchResults) -> Self { + Self { + table: CString::new(val.table).unwrap().into_raw(), + count: val.count, + matches: val.matches.into(), + } + } +} + +#[derive(Clone, Debug)] +#[repr(C)] +pub struct SearchResponse { + pub total: u32, + pub results: CArray, +} + +impl From for SearchResponse { + fn from(val: torii_proto::SearchResponse) -> Self { + Self { total: val.total, results: val.results.into() } + } +} + // C-specific types for accounts and providers pub struct Provider( pub(crate) std::sync::Arc< diff --git a/crates/uniffi/src/uniffi/client.rs b/crates/uniffi/src/uniffi/client.rs index afd17ca..35b06ff 100644 --- a/crates/uniffi/src/uniffi/client.rs +++ b/crates/uniffi/src/uniffi/client.rs @@ -318,6 +318,21 @@ impl ToriiClient { rows.into_iter().map(|r| r.try_into()).collect() } + /// Perform a full-text search across indexed entities using FTS5. + /// + /// # Arguments + /// * `query` - Search query containing the search text and limit + /// + /// # Returns + /// A `SearchResponse` containing results grouped by table with relevance scores + pub fn search(&self, query: SearchQuery) -> Result { + let inner = self.inner.clone(); + runtime() + .block_on(inner.search(query.into())) + .map(Into::into) + .map_err(|e| DojoError::QueryError { message: e.to_string() }) + } + /// Subscribe to entity updates pub fn subscribe_entity_updates( &self, diff --git a/crates/uniffi/src/uniffi/types/mod.rs b/crates/uniffi/src/uniffi/types/mod.rs index 3352270..b5b0238 100644 --- a/crates/uniffi/src/uniffi/types/mod.rs +++ b/crates/uniffi/src/uniffi/types/mod.rs @@ -11,6 +11,7 @@ pub mod entity; pub mod event; pub mod query; pub mod schema; +pub mod search; pub mod token; pub mod transaction; @@ -26,5 +27,6 @@ pub use entity::*; pub use event::*; pub use query::*; pub use schema::*; +pub use search::*; pub use token::*; pub use transaction::*; diff --git a/crates/uniffi/src/uniffi/types/search.rs b/crates/uniffi/src/uniffi/types/search.rs new file mode 100644 index 0000000..9c4abfb --- /dev/null +++ b/crates/uniffi/src/uniffi/types/search.rs @@ -0,0 +1,57 @@ +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SearchQuery { + pub query: String, + pub limit: u32, +} + +impl From for torii_proto::SearchQuery { + fn from(val: SearchQuery) -> Self { + Self { query: val.query, limit: val.limit } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SearchMatch { + pub id: String, + pub fields: HashMap, + pub score: Option, +} + +impl From for SearchMatch { + fn from(val: torii_proto::SearchMatch) -> Self { + Self { id: val.id, fields: val.fields, score: val.score } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct TableSearchResults { + pub table: String, + pub count: u32, + pub matches: Vec, +} + +impl From for TableSearchResults { + fn from(val: torii_proto::TableSearchResults) -> Self { + Self { + table: val.table, + count: val.count, + matches: val.matches.into_iter().map(Into::into).collect(), + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SearchResponse { + pub total: u32, + pub results: Vec, +} + +impl From for SearchResponse { + fn from(val: torii_proto::SearchResponse) -> Self { + Self { total: val.total, results: val.results.into_iter().map(Into::into).collect() } + } +} + diff --git a/crates/wasm/src/lib.rs b/crates/wasm/src/lib.rs index d401a76..7c1d353 100644 --- a/crates/wasm/src/lib.rs +++ b/crates/wasm/src/lib.rs @@ -34,10 +34,10 @@ use types::{ 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, + SearchQuery, SearchResponse, 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 = @@ -2163,6 +2163,39 @@ impl ToriiClient { .map_err(|err| JsValue::from(format!("failed to update subscription: {err}"))) } + /// Perform a full-text search across indexed entities using FTS5. + /// + /// # Parameters + /// * `query` - Search query containing the search text and limit + /// + /// # Returns + /// A `SearchResponse` containing results grouped by table with relevance scores + /// + /// # Example + /// ```javascript + /// const results = await client.search({ query: "dragon", limit: 10 }); + /// console.log(`Found ${results.total} total matches`); + /// for (const tableResults of results.results) { + /// console.log(`Table ${tableResults.table}: ${tableResults.count} matches`); + /// for (const match of tableResults.matches) { + /// console.log(` ID: ${match.id}, Score: ${match.score}`); + /// for (const [field, value] of Object.entries(match.fields)) { + /// console.log(` ${field}: ${value}`); + /// } + /// } + /// } + /// ``` + #[wasm_bindgen(js_name = search)] + pub async fn search(&self, query: SearchQuery) -> Result { + let response = self + .inner + .search(query.into()) + .await + .map_err(|err| JsValue::from(err.to_string()))?; + + Ok(response.into()) + } + /// Publishes a message to the network /// /// # Parameters diff --git a/crates/wasm/src/types.rs b/crates/wasm/src/types.rs index eaef1ac..5aefe76 100644 --- a/crates/wasm/src/types.rs +++ b/crates/wasm/src/types.rs @@ -1455,6 +1455,65 @@ pub struct Achievements(pub Page); #[tsify(into_wasm_abi, from_wasm_abi)] pub struct PlayerAchievements(pub Page); +// Search types +#[derive(Tsify, Serialize, Deserialize, Debug)] +#[tsify(into_wasm_abi, from_wasm_abi)] +pub struct SearchQuery { + pub query: String, + pub limit: u32, +} + +impl From for torii_proto::SearchQuery { + fn from(value: SearchQuery) -> Self { + Self { query: value.query, limit: value.limit } + } +} + +#[derive(Tsify, Serialize, Deserialize, Debug)] +#[tsify(into_wasm_abi, from_wasm_abi, hashmap_as_object)] +pub struct SearchMatch { + pub id: String, + pub fields: HashMap, + pub score: Option, +} + +impl From for SearchMatch { + fn from(value: torii_proto::SearchMatch) -> Self { + Self { id: value.id, fields: value.fields, score: value.score } + } +} + +#[derive(Tsify, Serialize, Deserialize, Debug)] +#[tsify(into_wasm_abi, from_wasm_abi)] +pub struct TableSearchResults { + pub table: String, + pub count: u32, + pub matches: Vec, +} + +impl From for TableSearchResults { + fn from(value: torii_proto::TableSearchResults) -> Self { + Self { + table: value.table, + count: value.count, + matches: value.matches.into_iter().map(Into::into).collect(), + } + } +} + +#[derive(Tsify, Serialize, Deserialize, Debug)] +#[tsify(into_wasm_abi, from_wasm_abi)] +pub struct SearchResponse { + pub total: u32, + pub results: Vec, +} + +impl From for SearchResponse { + fn from(value: torii_proto::SearchResponse) -> Self { + Self { total: value.total, results: value.results.into_iter().map(Into::into).collect() } + } +} + // WASM-specific client types #[wasm_bindgen] pub struct ToriiClient { From 5f3bb1bb562fdbe049c40f5a12dabdda94e0a297 Mon Sep 17 00:00:00 2001 From: Nasr Date: Mon, 27 Oct 2025 16:44:55 -0500 Subject: [PATCH 2/5] add types to udl --- src/dojo.udl | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/dojo.udl b/src/dojo.udl index 9f3070f..a71ac11 100644 --- a/src/dojo.udl +++ b/src/dojo.udl @@ -637,6 +637,29 @@ dictionary PageEvent { string? next_cursor; }; +// Search types +dictionary SearchQuery { + string query; + u32 limit; +}; + +dictionary SearchMatch { + string id; + record fields; + f64? score; +}; + +dictionary TableSearchResults { + string table; + u32 count; + sequence matches; +}; + +dictionary SearchResponse { + u32 total; + sequence results; +}; + // Main Dojo client interface interface ToriiClient { // Constructor - create a new client with default config (4MB max message size) @@ -719,6 +742,10 @@ interface ToriiClient { [Async, Throws=DojoError] sequence sql(string query); + // Perform full-text search across indexed entities + [Async, Throws=DojoError] + SearchResponse search(SearchQuery query); + // Subscription methods // Subscribe to entity updates [Async, Throws=DojoError] From 5d22a40e402f95cbf989965af1239793659899f0 Mon Sep 17 00:00:00 2001 From: Nasr Date: Mon, 27 Oct 2025 16:47:23 -0500 Subject: [PATCH 3/5] fmt --- crates/uniffi/src/uniffi/types/search.rs | 4 ++-- crates/wasm/src/lib.rs | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/crates/uniffi/src/uniffi/types/search.rs b/crates/uniffi/src/uniffi/types/search.rs index 9c4abfb..39a66e4 100644 --- a/crates/uniffi/src/uniffi/types/search.rs +++ b/crates/uniffi/src/uniffi/types/search.rs @@ -1,6 +1,7 @@ -use serde::{Deserialize, Serialize}; use std::collections::HashMap; +use serde::{Deserialize, Serialize}; + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SearchQuery { pub query: String, @@ -54,4 +55,3 @@ impl From for SearchResponse { Self { total: val.total, results: val.results.into_iter().map(Into::into).collect() } } } - diff --git a/crates/wasm/src/lib.rs b/crates/wasm/src/lib.rs index 7c1d353..e7af454 100644 --- a/crates/wasm/src/lib.rs +++ b/crates/wasm/src/lib.rs @@ -2187,11 +2187,8 @@ impl ToriiClient { /// ``` #[wasm_bindgen(js_name = search)] pub async fn search(&self, query: SearchQuery) -> Result { - let response = self - .inner - .search(query.into()) - .await - .map_err(|err| JsValue::from(err.to_string()))?; + let response = + self.inner.search(query.into()).await.map_err(|err| JsValue::from(err.to_string()))?; Ok(response.into()) } From 77b0ba428dd2226e16facb2568d6c287ef69dbb4 Mon Sep 17 00:00:00 2001 From: Nasr Date: Mon, 27 Oct 2025 16:54:55 -0500 Subject: [PATCH 4/5] all bindings --- bindings/csharp/dojo.cs | 354 +++++++++ bindings/go/dojo.go | 403 +++++++++- bindings/go/dojo.h | 11 + bindings/kotlin/com/dojoengine/dojo/dojo.kt | 329 +++++++++ bindings/python/dojo.py | 319 ++++++++ bindings/swift/DojoEngine.swift | 381 ++++++++++ crates/uniffi/src/dojo.udl | 32 + crates/uniffi/src/uniffi/types/search.rs | 17 +- scripts/build_everything.sh | 49 ++ src/bin/uniffi-bindgen-kotlin.rs | 55 -- src/bin/uniffi-bindgen-python.rs | 65 -- src/bin/uniffi-bindgen-swift.rs | 71 -- src/dojo.udl | 773 -------------------- src/lib.rs | 7 - src/uniffi/README.md | 93 --- src/uniffi/client.rs | 537 -------------- src/uniffi/mod.rs | 14 - 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 | 329 --------- src/uniffi/types/entity.rs | 130 ---- src/uniffi/types/event.rs | 65 -- src/uniffi/types/mod.rs | 30 - src/uniffi/types/query.rs | 310 -------- src/uniffi/types/schema.rs | 331 --------- src/uniffi/types/token.rs | 209 ------ src/uniffi/types/transaction.rs | 128 ---- 30 files changed, 1889 insertions(+), 3643 deletions(-) create mode 100755 scripts/build_everything.sh delete mode 100644 src/bin/uniffi-bindgen-kotlin.rs delete mode 100644 src/bin/uniffi-bindgen-python.rs delete mode 100644 src/bin/uniffi-bindgen-swift.rs delete mode 100644 src/dojo.udl delete mode 100644 src/lib.rs delete mode 100644 src/uniffi/README.md delete mode 100644 src/uniffi/client.rs delete mode 100644 src/uniffi/mod.rs delete mode 100644 src/uniffi/types/achievement.rs delete mode 100644 src/uniffi/types/activity.rs delete mode 100644 src/uniffi/types/aggregation.rs delete mode 100644 src/uniffi/types/contract.rs delete mode 100644 src/uniffi/types/controller.rs delete mode 100644 src/uniffi/types/core.rs delete mode 100644 src/uniffi/types/entity.rs delete mode 100644 src/uniffi/types/event.rs delete mode 100644 src/uniffi/types/mod.rs delete mode 100644 src/uniffi/types/query.rs delete mode 100644 src/uniffi/types/schema.rs delete mode 100644 src/uniffi/types/token.rs delete mode 100644 src/uniffi/types/transaction.rs diff --git a/bindings/csharp/dojo.cs b/bindings/csharp/dojo.cs index 4b08e7f..42541f3 100644 --- a/bindings/csharp/dojo.cs +++ b/bindings/csharp/dojo.cs @@ -888,6 +888,8 @@ public struct UniffiVTableCallbackInterfaceTransactionUpdateCallback + + @@ -963,6 +965,10 @@ public static extern RustBuffer uniffi_dojo_uniffi_fn_method_toriiclient_publish public static extern RustBuffer uniffi_dojo_uniffi_fn_method_toriiclient_publish_message_batch(IntPtr @ptr,RustBuffer @messages,ref UniffiRustCallStatus _uniffi_out_err ); + [DllImport("dojo_uniffi", CallingConvention = CallingConvention.Cdecl)] + public static extern RustBuffer uniffi_dojo_uniffi_fn_method_toriiclient_search(IntPtr @ptr,RustBuffer @query,ref UniffiRustCallStatus _uniffi_out_err + ); + [DllImport("dojo_uniffi", CallingConvention = CallingConvention.Cdecl)] public static extern RustBuffer uniffi_dojo_uniffi_fn_method_toriiclient_sql(IntPtr @ptr,RustBuffer @query,ref UniffiRustCallStatus _uniffi_out_err ); @@ -1303,6 +1309,10 @@ public static extern ushort uniffi_dojo_uniffi_checksum_method_toriiclient_publi public static extern ushort uniffi_dojo_uniffi_checksum_method_toriiclient_publish_message_batch( ); + [DllImport("dojo_uniffi", CallingConvention = CallingConvention.Cdecl)] + public static extern ushort uniffi_dojo_uniffi_checksum_method_toriiclient_search( + ); + [DllImport("dojo_uniffi", CallingConvention = CallingConvention.Cdecl)] public static extern ushort uniffi_dojo_uniffi_checksum_method_toriiclient_sql( ); @@ -1483,6 +1493,12 @@ static void uniffiCheckApiChecksums() { throw new UniffiContractChecksumException($"uniffi.dojo: uniffi bindings expected function `uniffi_dojo_uniffi_checksum_method_toriiclient_publish_message_batch` checksum `50961`, library returned `{checksum}`"); } } + { + var checksum = _UniFFILib.uniffi_dojo_uniffi_checksum_method_toriiclient_search(); + if (checksum != 24059) { + throw new UniffiContractChecksumException($"uniffi.dojo: uniffi bindings expected function `uniffi_dojo_uniffi_checksum_method_toriiclient_search` checksum `24059`, library returned `{checksum}`"); + } + } { var checksum = _UniFFILib.uniffi_dojo_uniffi_checksum_method_toriiclient_sql(); if (checksum != 59851) { @@ -1974,6 +1990,8 @@ internal interface IToriiClient { /// string[] PublishMessageBatch(Message[] @messages); /// + SearchResponse Search(SearchQuery @query); + /// SqlRow[] Sql(string @query); /// PageEvent StarknetEvents(EventQuery @query); @@ -2194,6 +2212,15 @@ public string[] PublishMessageBatch(Message[] @messages) { } + /// + public SearchResponse Search(SearchQuery @query) { + return CallWithPointer(thisPtr => FfiConverterTypeSearchResponse.INSTANCE.Lift( + _UniffiHelpers.RustCallWithError(FfiConverterTypeDojoError.INSTANCE, (ref UniffiRustCallStatus _status) => + _UniFFILib.uniffi_dojo_uniffi_fn_method_toriiclient_search(thisPtr, FfiConverterTypeSearchQuery.INSTANCE.Lower(@query), ref _status) +))); + } + + /// public SqlRow[] Sql(string @query) { return CallWithPointer(thisPtr => FfiConverterSequenceTypeSqlRow.INSTANCE.Lift( @@ -4080,6 +4107,130 @@ public override void Write(Query value, BigEndianStream stream) { +internal record SearchField ( + string @key, + string @value +) { +} + +class FfiConverterTypeSearchField: FfiConverterRustBuffer { + public static FfiConverterTypeSearchField INSTANCE = new FfiConverterTypeSearchField(); + + public override SearchField Read(BigEndianStream stream) { + return new SearchField( + @key: FfiConverterString.INSTANCE.Read(stream), + @value: FfiConverterString.INSTANCE.Read(stream) + ); + } + + public override int AllocationSize(SearchField value) { + return 0 + + FfiConverterString.INSTANCE.AllocationSize(value.@key) + + FfiConverterString.INSTANCE.AllocationSize(value.@value); + } + + public override void Write(SearchField value, BigEndianStream stream) { + FfiConverterString.INSTANCE.Write(value.@key, stream); + FfiConverterString.INSTANCE.Write(value.@value, stream); + } +} + + + +internal record SearchMatch ( + string @id, + SearchField[] @fields, + double? @score +) { +} + +class FfiConverterTypeSearchMatch: FfiConverterRustBuffer { + public static FfiConverterTypeSearchMatch INSTANCE = new FfiConverterTypeSearchMatch(); + + public override SearchMatch Read(BigEndianStream stream) { + return new SearchMatch( + @id: FfiConverterString.INSTANCE.Read(stream), + @fields: FfiConverterSequenceTypeSearchField.INSTANCE.Read(stream), + @score: FfiConverterOptionalDouble.INSTANCE.Read(stream) + ); + } + + public override int AllocationSize(SearchMatch value) { + return 0 + + FfiConverterString.INSTANCE.AllocationSize(value.@id) + + FfiConverterSequenceTypeSearchField.INSTANCE.AllocationSize(value.@fields) + + FfiConverterOptionalDouble.INSTANCE.AllocationSize(value.@score); + } + + public override void Write(SearchMatch value, BigEndianStream stream) { + FfiConverterString.INSTANCE.Write(value.@id, stream); + FfiConverterSequenceTypeSearchField.INSTANCE.Write(value.@fields, stream); + FfiConverterOptionalDouble.INSTANCE.Write(value.@score, stream); + } +} + + + +internal record SearchQuery ( + string @query, + uint @limit +) { +} + +class FfiConverterTypeSearchQuery: FfiConverterRustBuffer { + public static FfiConverterTypeSearchQuery INSTANCE = new FfiConverterTypeSearchQuery(); + + public override SearchQuery Read(BigEndianStream stream) { + return new SearchQuery( + @query: FfiConverterString.INSTANCE.Read(stream), + @limit: FfiConverterUInt32.INSTANCE.Read(stream) + ); + } + + public override int AllocationSize(SearchQuery value) { + return 0 + + FfiConverterString.INSTANCE.AllocationSize(value.@query) + + FfiConverterUInt32.INSTANCE.AllocationSize(value.@limit); + } + + public override void Write(SearchQuery value, BigEndianStream stream) { + FfiConverterString.INSTANCE.Write(value.@query, stream); + FfiConverterUInt32.INSTANCE.Write(value.@limit, stream); + } +} + + + +internal record SearchResponse ( + uint @total, + TableSearchResults[] @results +) { +} + +class FfiConverterTypeSearchResponse: FfiConverterRustBuffer { + public static FfiConverterTypeSearchResponse INSTANCE = new FfiConverterTypeSearchResponse(); + + public override SearchResponse Read(BigEndianStream stream) { + return new SearchResponse( + @total: FfiConverterUInt32.INSTANCE.Read(stream), + @results: FfiConverterSequenceTypeTableSearchResults.INSTANCE.Read(stream) + ); + } + + public override int AllocationSize(SearchResponse value) { + return 0 + + FfiConverterUInt32.INSTANCE.AllocationSize(value.@total) + + FfiConverterSequenceTypeTableSearchResults.INSTANCE.AllocationSize(value.@results); + } + + public override void Write(SearchResponse value, BigEndianStream stream) { + FfiConverterUInt32.INSTANCE.Write(value.@total, stream); + FfiConverterSequenceTypeTableSearchResults.INSTANCE.Write(value.@results, stream); + } +} + + + internal record Signature ( FieldElement @r, FieldElement @s @@ -4196,6 +4347,40 @@ public override void Write(Struct value, BigEndianStream stream) { +internal record TableSearchResults ( + string @table, + uint @count, + SearchMatch[] @matches +) { +} + +class FfiConverterTypeTableSearchResults: FfiConverterRustBuffer { + public static FfiConverterTypeTableSearchResults INSTANCE = new FfiConverterTypeTableSearchResults(); + + public override TableSearchResults Read(BigEndianStream stream) { + return new TableSearchResults( + @table: FfiConverterString.INSTANCE.Read(stream), + @count: FfiConverterUInt32.INSTANCE.Read(stream), + @matches: FfiConverterSequenceTypeSearchMatch.INSTANCE.Read(stream) + ); + } + + public override int AllocationSize(TableSearchResults value) { + return 0 + + FfiConverterString.INSTANCE.AllocationSize(value.@table) + + FfiConverterUInt32.INSTANCE.AllocationSize(value.@count) + + FfiConverterSequenceTypeSearchMatch.INSTANCE.AllocationSize(value.@matches); + } + + public override void Write(TableSearchResults value, BigEndianStream stream) { + FfiConverterString.INSTANCE.Write(value.@table, stream); + FfiConverterUInt32.INSTANCE.Write(value.@count, stream); + FfiConverterSequenceTypeSearchMatch.INSTANCE.Write(value.@matches, stream); + } +} + + + internal record TaskProgress ( string @taskId, uint @count, @@ -6467,6 +6652,37 @@ public override void Write(ulong? value, BigEndianStream stream) { +class FfiConverterOptionalDouble: FfiConverterRustBuffer { + public static FfiConverterOptionalDouble INSTANCE = new FfiConverterOptionalDouble(); + + public override double? Read(BigEndianStream stream) { + if (stream.ReadByte() == 0) { + return null; + } + return FfiConverterDouble.INSTANCE.Read(stream); + } + + public override int AllocationSize(double? value) { + if (value == null) { + return 1; + } else { + return 1 + FfiConverterDouble.INSTANCE.AllocationSize((double)value); + } + } + + public override void Write(double? value, BigEndianStream stream) { + if (value == null) { + stream.WriteByte(0); + } else { + stream.WriteByte(1); + FfiConverterDouble.INSTANCE.Write((double)value, stream); + } + } +} + + + + class FfiConverterOptionalBoolean: FfiConverterRustBuffer { public static FfiConverterOptionalBoolean INSTANCE = new FfiConverterOptionalBoolean(); @@ -7604,6 +7820,98 @@ public override void Write(PlayerAchievementProgress[] value, BigEndianStream st +class FfiConverterSequenceTypeSearchField: FfiConverterRustBuffer { + public static FfiConverterSequenceTypeSearchField INSTANCE = new FfiConverterSequenceTypeSearchField(); + + public override SearchField[] Read(BigEndianStream stream) { + var length = stream.ReadInt(); + if (length == 0) { + return []; + } + + var result = new SearchField[(length)]; + var readFn = FfiConverterTypeSearchField.INSTANCE.Read; + for (int i = 0; i < length; i++) { + result[i] = readFn(stream); + } + return result; + } + + public override int AllocationSize(SearchField[] value) { + var sizeForLength = 4; + + // details/1-empty-list-as-default-method-parameter.md + if (value == null) { + return sizeForLength; + } + + var allocationSizeFn = FfiConverterTypeSearchField.INSTANCE.AllocationSize; + var sizeForItems = value.Sum(item => allocationSizeFn(item)); + return sizeForLength + sizeForItems; + } + + public override void Write(SearchField[] value, BigEndianStream stream) { + // details/1-empty-list-as-default-method-parameter.md + if (value == null) { + stream.WriteInt(0); + return; + } + + stream.WriteInt(value.Length); + var writerFn = FfiConverterTypeSearchField.INSTANCE.Write; + value.ForEach(item => writerFn(item, stream)); + } +} + + + + +class FfiConverterSequenceTypeSearchMatch: FfiConverterRustBuffer { + public static FfiConverterSequenceTypeSearchMatch INSTANCE = new FfiConverterSequenceTypeSearchMatch(); + + public override SearchMatch[] Read(BigEndianStream stream) { + var length = stream.ReadInt(); + if (length == 0) { + return []; + } + + var result = new SearchMatch[(length)]; + var readFn = FfiConverterTypeSearchMatch.INSTANCE.Read; + for (int i = 0; i < length; i++) { + result[i] = readFn(stream); + } + return result; + } + + public override int AllocationSize(SearchMatch[] value) { + var sizeForLength = 4; + + // details/1-empty-list-as-default-method-parameter.md + if (value == null) { + return sizeForLength; + } + + var allocationSizeFn = FfiConverterTypeSearchMatch.INSTANCE.AllocationSize; + var sizeForItems = value.Sum(item => allocationSizeFn(item)); + return sizeForLength + sizeForItems; + } + + public override void Write(SearchMatch[] value, BigEndianStream stream) { + // details/1-empty-list-as-default-method-parameter.md + if (value == null) { + stream.WriteInt(0); + return; + } + + stream.WriteInt(value.Length); + var writerFn = FfiConverterTypeSearchMatch.INSTANCE.Write; + value.ForEach(item => writerFn(item, stream)); + } +} + + + + class FfiConverterSequenceTypeSqlField: FfiConverterRustBuffer { public static FfiConverterSequenceTypeSqlField INSTANCE = new FfiConverterSequenceTypeSqlField(); @@ -7742,6 +8050,52 @@ public override void Write(Struct[] value, BigEndianStream stream) { +class FfiConverterSequenceTypeTableSearchResults: FfiConverterRustBuffer { + public static FfiConverterSequenceTypeTableSearchResults INSTANCE = new FfiConverterSequenceTypeTableSearchResults(); + + public override TableSearchResults[] Read(BigEndianStream stream) { + var length = stream.ReadInt(); + if (length == 0) { + return []; + } + + var result = new TableSearchResults[(length)]; + var readFn = FfiConverterTypeTableSearchResults.INSTANCE.Read; + for (int i = 0; i < length; i++) { + result[i] = readFn(stream); + } + return result; + } + + public override int AllocationSize(TableSearchResults[] value) { + var sizeForLength = 4; + + // details/1-empty-list-as-default-method-parameter.md + if (value == null) { + return sizeForLength; + } + + var allocationSizeFn = FfiConverterTypeTableSearchResults.INSTANCE.AllocationSize; + var sizeForItems = value.Sum(item => allocationSizeFn(item)); + return sizeForLength + sizeForItems; + } + + public override void Write(TableSearchResults[] value, BigEndianStream stream) { + // details/1-empty-list-as-default-method-parameter.md + if (value == null) { + stream.WriteInt(0); + return; + } + + stream.WriteInt(value.Length); + var writerFn = FfiConverterTypeTableSearchResults.INSTANCE.Write; + value.ForEach(item => writerFn(item, stream)); + } +} + + + + class FfiConverterSequenceTypeTaskProgress: FfiConverterRustBuffer { public static FfiConverterSequenceTypeTaskProgress INSTANCE = new FfiConverterSequenceTypeTaskProgress(); diff --git a/bindings/go/dojo.go b/bindings/go/dojo.go index 626cfe3..b242e04 100644 --- a/bindings/go/dojo.go +++ b/bindings/go/dojo.go @@ -1,7 +1,5 @@ package dojo -// #cgo CFLAGS: -I${SRCDIR} -// #cgo LDFLAGS: -L${SRCDIR}/../../target/release -ldojo_uniffi // #include import "C" @@ -453,6 +451,15 @@ func uniffiCheckChecksums() { panic("dojo: uniffi_dojo_uniffi_checksum_method_toriiclient_publish_message_batch: UniFFI API checksum mismatch") } } + { + checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_dojo_uniffi_checksum_method_toriiclient_search() + }) + if checksum != 24059 { + // If this happens try cleaning and rebuilding your project + panic("dojo: uniffi_dojo_uniffi_checksum_method_toriiclient_search: UniFFI API checksum mismatch") + } + } { checksum := rustCall(func(_uniffiStatus *C.RustCallStatus) C.uint16_t { return C.uniffi_dojo_uniffi_checksum_method_toriiclient_sql() @@ -1052,6 +1059,7 @@ type ToriiClientInterface interface { PlayerAchievements(query PlayerAchievementQuery) (PagePlayerAchievement, error) PublishMessage(message Message) (string, error) PublishMessageBatch(messages []Message) ([]string, error) + Search(query SearchQuery) (SearchResponse, error) Sql(query string) ([]SqlRow, error) StarknetEvents(query EventQuery) (PageEvent, error) SubscribeEntityUpdates(clause *Clause, worldAddresses []FieldElement, callback EntityUpdateCallback) (uint64, error) @@ -1275,6 +1283,23 @@ func (_self *ToriiClient) PublishMessageBatch(messages []Message) ([]string, err } } +func (_self *ToriiClient) Search(query SearchQuery) (SearchResponse, error) { + _pointer := _self.ffiObject.incrementPointer("*ToriiClient") + defer _self.ffiObject.decrementPointer() + _uniffiRV, _uniffiErr := rustCallWithError[DojoError](FfiConverterDojoError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return GoRustBuffer{ + inner: C.uniffi_dojo_uniffi_fn_method_toriiclient_search( + _pointer, FfiConverterSearchQueryINSTANCE.Lower(query), _uniffiStatus), + } + }) + if _uniffiErr != nil { + var _uniffiDefaultValue SearchResponse + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterSearchResponseINSTANCE.Lift(_uniffiRV), nil + } +} + func (_self *ToriiClient) Sql(query string) ([]SqlRow, error) { _pointer := _self.ffiObject.incrementPointer("*ToriiClient") defer _self.ffiObject.decrementPointer() @@ -3714,6 +3739,170 @@ func (_ FfiDestroyerQuery) Destroy(value Query) { value.Destroy() } +type SearchField struct { + Key string + Value string +} + +func (r *SearchField) Destroy() { + FfiDestroyerString{}.Destroy(r.Key) + FfiDestroyerString{}.Destroy(r.Value) +} + +type FfiConverterSearchField struct{} + +var FfiConverterSearchFieldINSTANCE = FfiConverterSearchField{} + +func (c FfiConverterSearchField) Lift(rb RustBufferI) SearchField { + return LiftFromRustBuffer[SearchField](c, rb) +} + +func (c FfiConverterSearchField) Read(reader io.Reader) SearchField { + return SearchField{ + FfiConverterStringINSTANCE.Read(reader), + FfiConverterStringINSTANCE.Read(reader), + } +} + +func (c FfiConverterSearchField) Lower(value SearchField) C.RustBuffer { + return LowerIntoRustBuffer[SearchField](c, value) +} + +func (c FfiConverterSearchField) Write(writer io.Writer, value SearchField) { + FfiConverterStringINSTANCE.Write(writer, value.Key) + FfiConverterStringINSTANCE.Write(writer, value.Value) +} + +type FfiDestroyerSearchField struct{} + +func (_ FfiDestroyerSearchField) Destroy(value SearchField) { + value.Destroy() +} + +type SearchMatch struct { + Id string + Fields []SearchField + Score *float64 +} + +func (r *SearchMatch) Destroy() { + FfiDestroyerString{}.Destroy(r.Id) + FfiDestroyerSequenceSearchField{}.Destroy(r.Fields) + FfiDestroyerOptionalFloat64{}.Destroy(r.Score) +} + +type FfiConverterSearchMatch struct{} + +var FfiConverterSearchMatchINSTANCE = FfiConverterSearchMatch{} + +func (c FfiConverterSearchMatch) Lift(rb RustBufferI) SearchMatch { + return LiftFromRustBuffer[SearchMatch](c, rb) +} + +func (c FfiConverterSearchMatch) Read(reader io.Reader) SearchMatch { + return SearchMatch{ + FfiConverterStringINSTANCE.Read(reader), + FfiConverterSequenceSearchFieldINSTANCE.Read(reader), + FfiConverterOptionalFloat64INSTANCE.Read(reader), + } +} + +func (c FfiConverterSearchMatch) Lower(value SearchMatch) C.RustBuffer { + return LowerIntoRustBuffer[SearchMatch](c, value) +} + +func (c FfiConverterSearchMatch) Write(writer io.Writer, value SearchMatch) { + FfiConverterStringINSTANCE.Write(writer, value.Id) + FfiConverterSequenceSearchFieldINSTANCE.Write(writer, value.Fields) + FfiConverterOptionalFloat64INSTANCE.Write(writer, value.Score) +} + +type FfiDestroyerSearchMatch struct{} + +func (_ FfiDestroyerSearchMatch) Destroy(value SearchMatch) { + value.Destroy() +} + +type SearchQuery struct { + Query string + Limit uint32 +} + +func (r *SearchQuery) Destroy() { + FfiDestroyerString{}.Destroy(r.Query) + FfiDestroyerUint32{}.Destroy(r.Limit) +} + +type FfiConverterSearchQuery struct{} + +var FfiConverterSearchQueryINSTANCE = FfiConverterSearchQuery{} + +func (c FfiConverterSearchQuery) Lift(rb RustBufferI) SearchQuery { + return LiftFromRustBuffer[SearchQuery](c, rb) +} + +func (c FfiConverterSearchQuery) Read(reader io.Reader) SearchQuery { + return SearchQuery{ + FfiConverterStringINSTANCE.Read(reader), + FfiConverterUint32INSTANCE.Read(reader), + } +} + +func (c FfiConverterSearchQuery) Lower(value SearchQuery) C.RustBuffer { + return LowerIntoRustBuffer[SearchQuery](c, value) +} + +func (c FfiConverterSearchQuery) Write(writer io.Writer, value SearchQuery) { + FfiConverterStringINSTANCE.Write(writer, value.Query) + FfiConverterUint32INSTANCE.Write(writer, value.Limit) +} + +type FfiDestroyerSearchQuery struct{} + +func (_ FfiDestroyerSearchQuery) Destroy(value SearchQuery) { + value.Destroy() +} + +type SearchResponse struct { + Total uint32 + Results []TableSearchResults +} + +func (r *SearchResponse) Destroy() { + FfiDestroyerUint32{}.Destroy(r.Total) + FfiDestroyerSequenceTableSearchResults{}.Destroy(r.Results) +} + +type FfiConverterSearchResponse struct{} + +var FfiConverterSearchResponseINSTANCE = FfiConverterSearchResponse{} + +func (c FfiConverterSearchResponse) Lift(rb RustBufferI) SearchResponse { + return LiftFromRustBuffer[SearchResponse](c, rb) +} + +func (c FfiConverterSearchResponse) Read(reader io.Reader) SearchResponse { + return SearchResponse{ + FfiConverterUint32INSTANCE.Read(reader), + FfiConverterSequenceTableSearchResultsINSTANCE.Read(reader), + } +} + +func (c FfiConverterSearchResponse) Lower(value SearchResponse) C.RustBuffer { + return LowerIntoRustBuffer[SearchResponse](c, value) +} + +func (c FfiConverterSearchResponse) Write(writer io.Writer, value SearchResponse) { + FfiConverterUint32INSTANCE.Write(writer, value.Total) + FfiConverterSequenceTableSearchResultsINSTANCE.Write(writer, value.Results) +} + +type FfiDestroyerSearchResponse struct{} + +func (_ FfiDestroyerSearchResponse) Destroy(value SearchResponse) { + value.Destroy() +} + type Signature struct { R FieldElement S FieldElement @@ -3870,6 +4059,50 @@ func (_ FfiDestroyerStruct) Destroy(value Struct) { value.Destroy() } +type TableSearchResults struct { + Table string + Count uint32 + Matches []SearchMatch +} + +func (r *TableSearchResults) Destroy() { + FfiDestroyerString{}.Destroy(r.Table) + FfiDestroyerUint32{}.Destroy(r.Count) + FfiDestroyerSequenceSearchMatch{}.Destroy(r.Matches) +} + +type FfiConverterTableSearchResults struct{} + +var FfiConverterTableSearchResultsINSTANCE = FfiConverterTableSearchResults{} + +func (c FfiConverterTableSearchResults) Lift(rb RustBufferI) TableSearchResults { + return LiftFromRustBuffer[TableSearchResults](c, rb) +} + +func (c FfiConverterTableSearchResults) Read(reader io.Reader) TableSearchResults { + return TableSearchResults{ + FfiConverterStringINSTANCE.Read(reader), + FfiConverterUint32INSTANCE.Read(reader), + FfiConverterSequenceSearchMatchINSTANCE.Read(reader), + } +} + +func (c FfiConverterTableSearchResults) Lower(value TableSearchResults) C.RustBuffer { + return LowerIntoRustBuffer[TableSearchResults](c, value) +} + +func (c FfiConverterTableSearchResults) Write(writer io.Writer, value TableSearchResults) { + FfiConverterStringINSTANCE.Write(writer, value.Table) + FfiConverterUint32INSTANCE.Write(writer, value.Count) + FfiConverterSequenceSearchMatchINSTANCE.Write(writer, value.Matches) +} + +type FfiDestroyerTableSearchResults struct{} + +func (_ FfiDestroyerTableSearchResults) Destroy(value TableSearchResults) { + value.Destroy() +} + type TaskProgress struct { TaskId string Count uint32 @@ -6479,6 +6712,43 @@ func (_ FfiDestroyerOptionalUint64) Destroy(value *uint64) { } } +type FfiConverterOptionalFloat64 struct{} + +var FfiConverterOptionalFloat64INSTANCE = FfiConverterOptionalFloat64{} + +func (c FfiConverterOptionalFloat64) Lift(rb RustBufferI) *float64 { + return LiftFromRustBuffer[*float64](c, rb) +} + +func (_ FfiConverterOptionalFloat64) Read(reader io.Reader) *float64 { + if readInt8(reader) == 0 { + return nil + } + temp := FfiConverterFloat64INSTANCE.Read(reader) + return &temp +} + +func (c FfiConverterOptionalFloat64) Lower(value *float64) C.RustBuffer { + return LowerIntoRustBuffer[*float64](c, value) +} + +func (_ FfiConverterOptionalFloat64) Write(writer io.Writer, value *float64) { + if value == nil { + writeInt8(writer, 0) + } else { + writeInt8(writer, 1) + FfiConverterFloat64INSTANCE.Write(writer, *value) + } +} + +type FfiDestroyerOptionalFloat64 struct{} + +func (_ FfiDestroyerOptionalFloat64) Destroy(value *float64) { + if value != nil { + FfiDestroyerFloat64{}.Destroy(*value) + } +} + type FfiConverterOptionalBool struct{} var FfiConverterOptionalBoolINSTANCE = FfiConverterOptionalBool{} @@ -7598,6 +7868,92 @@ func (FfiDestroyerSequencePlayerAchievementProgress) Destroy(sequence []PlayerAc } } +type FfiConverterSequenceSearchField struct{} + +var FfiConverterSequenceSearchFieldINSTANCE = FfiConverterSequenceSearchField{} + +func (c FfiConverterSequenceSearchField) Lift(rb RustBufferI) []SearchField { + return LiftFromRustBuffer[[]SearchField](c, rb) +} + +func (c FfiConverterSequenceSearchField) Read(reader io.Reader) []SearchField { + length := readInt32(reader) + if length == 0 { + return nil + } + result := make([]SearchField, 0, length) + for i := int32(0); i < length; i++ { + result = append(result, FfiConverterSearchFieldINSTANCE.Read(reader)) + } + return result +} + +func (c FfiConverterSequenceSearchField) Lower(value []SearchField) C.RustBuffer { + return LowerIntoRustBuffer[[]SearchField](c, value) +} + +func (c FfiConverterSequenceSearchField) Write(writer io.Writer, value []SearchField) { + if len(value) > math.MaxInt32 { + panic("[]SearchField is too large to fit into Int32") + } + + writeInt32(writer, int32(len(value))) + for _, item := range value { + FfiConverterSearchFieldINSTANCE.Write(writer, item) + } +} + +type FfiDestroyerSequenceSearchField struct{} + +func (FfiDestroyerSequenceSearchField) Destroy(sequence []SearchField) { + for _, value := range sequence { + FfiDestroyerSearchField{}.Destroy(value) + } +} + +type FfiConverterSequenceSearchMatch struct{} + +var FfiConverterSequenceSearchMatchINSTANCE = FfiConverterSequenceSearchMatch{} + +func (c FfiConverterSequenceSearchMatch) Lift(rb RustBufferI) []SearchMatch { + return LiftFromRustBuffer[[]SearchMatch](c, rb) +} + +func (c FfiConverterSequenceSearchMatch) Read(reader io.Reader) []SearchMatch { + length := readInt32(reader) + if length == 0 { + return nil + } + result := make([]SearchMatch, 0, length) + for i := int32(0); i < length; i++ { + result = append(result, FfiConverterSearchMatchINSTANCE.Read(reader)) + } + return result +} + +func (c FfiConverterSequenceSearchMatch) Lower(value []SearchMatch) C.RustBuffer { + return LowerIntoRustBuffer[[]SearchMatch](c, value) +} + +func (c FfiConverterSequenceSearchMatch) Write(writer io.Writer, value []SearchMatch) { + if len(value) > math.MaxInt32 { + panic("[]SearchMatch is too large to fit into Int32") + } + + writeInt32(writer, int32(len(value))) + for _, item := range value { + FfiConverterSearchMatchINSTANCE.Write(writer, item) + } +} + +type FfiDestroyerSequenceSearchMatch struct{} + +func (FfiDestroyerSequenceSearchMatch) Destroy(sequence []SearchMatch) { + for _, value := range sequence { + FfiDestroyerSearchMatch{}.Destroy(value) + } +} + type FfiConverterSequenceSqlField struct{} var FfiConverterSequenceSqlFieldINSTANCE = FfiConverterSequenceSqlField{} @@ -7727,6 +8083,49 @@ func (FfiDestroyerSequenceStruct) Destroy(sequence []Struct) { } } +type FfiConverterSequenceTableSearchResults struct{} + +var FfiConverterSequenceTableSearchResultsINSTANCE = FfiConverterSequenceTableSearchResults{} + +func (c FfiConverterSequenceTableSearchResults) Lift(rb RustBufferI) []TableSearchResults { + return LiftFromRustBuffer[[]TableSearchResults](c, rb) +} + +func (c FfiConverterSequenceTableSearchResults) Read(reader io.Reader) []TableSearchResults { + length := readInt32(reader) + if length == 0 { + return nil + } + result := make([]TableSearchResults, 0, length) + for i := int32(0); i < length; i++ { + result = append(result, FfiConverterTableSearchResultsINSTANCE.Read(reader)) + } + return result +} + +func (c FfiConverterSequenceTableSearchResults) Lower(value []TableSearchResults) C.RustBuffer { + return LowerIntoRustBuffer[[]TableSearchResults](c, value) +} + +func (c FfiConverterSequenceTableSearchResults) Write(writer io.Writer, value []TableSearchResults) { + if len(value) > math.MaxInt32 { + panic("[]TableSearchResults is too large to fit into Int32") + } + + writeInt32(writer, int32(len(value))) + for _, item := range value { + FfiConverterTableSearchResultsINSTANCE.Write(writer, item) + } +} + +type FfiDestroyerSequenceTableSearchResults struct{} + +func (FfiDestroyerSequenceTableSearchResults) Destroy(sequence []TableSearchResults) { + for _, value := range sequence { + FfiDestroyerTableSearchResults{}.Destroy(value) + } +} + type FfiConverterSequenceTaskProgress struct{} var FfiConverterSequenceTaskProgressINSTANCE = FfiConverterSequenceTaskProgress{} diff --git a/bindings/go/dojo.h b/bindings/go/dojo.h index 7b3198a..370b7b5 100644 --- a/bindings/go/dojo.h +++ b/bindings/go/dojo.h @@ -638,6 +638,11 @@ RustBuffer uniffi_dojo_uniffi_fn_method_toriiclient_publish_message(void* ptr, R RustBuffer uniffi_dojo_uniffi_fn_method_toriiclient_publish_message_batch(void* ptr, RustBuffer messages, RustCallStatus *out_status ); #endif +#ifndef UNIFFI_FFIDEF_UNIFFI_DOJO_UNIFFI_FN_METHOD_TORIICLIENT_SEARCH +#define UNIFFI_FFIDEF_UNIFFI_DOJO_UNIFFI_FN_METHOD_TORIICLIENT_SEARCH +RustBuffer uniffi_dojo_uniffi_fn_method_toriiclient_search(void* ptr, RustBuffer query, RustCallStatus *out_status +); +#endif #ifndef UNIFFI_FFIDEF_UNIFFI_DOJO_UNIFFI_FN_METHOD_TORIICLIENT_SQL #define UNIFFI_FFIDEF_UNIFFI_DOJO_UNIFFI_FN_METHOD_TORIICLIENT_SQL RustBuffer uniffi_dojo_uniffi_fn_method_toriiclient_sql(void* ptr, RustBuffer query, RustCallStatus *out_status @@ -1072,6 +1077,12 @@ uint16_t uniffi_dojo_uniffi_checksum_method_toriiclient_publish_message(void #define UNIFFI_FFIDEF_UNIFFI_DOJO_UNIFFI_CHECKSUM_METHOD_TORIICLIENT_PUBLISH_MESSAGE_BATCH uint16_t uniffi_dojo_uniffi_checksum_method_toriiclient_publish_message_batch(void +); +#endif +#ifndef UNIFFI_FFIDEF_UNIFFI_DOJO_UNIFFI_CHECKSUM_METHOD_TORIICLIENT_SEARCH +#define UNIFFI_FFIDEF_UNIFFI_DOJO_UNIFFI_CHECKSUM_METHOD_TORIICLIENT_SEARCH +uint16_t uniffi_dojo_uniffi_checksum_method_toriiclient_search(void + ); #endif #ifndef UNIFFI_FFIDEF_UNIFFI_DOJO_UNIFFI_CHECKSUM_METHOD_TORIICLIENT_SQL diff --git a/bindings/kotlin/com/dojoengine/dojo/dojo.kt b/bindings/kotlin/com/dojoengine/dojo/dojo.kt index 360551d..31f6776 100644 --- a/bindings/kotlin/com/dojoengine/dojo/dojo.kt +++ b/bindings/kotlin/com/dojoengine/dojo/dojo.kt @@ -796,6 +796,8 @@ internal object IntegrityCheckingUniffiLib { ): Short external fun uniffi_dojo_uniffi_checksum_method_toriiclient_publish_message_batch( ): Short + external fun uniffi_dojo_uniffi_checksum_method_toriiclient_search( + ): Short external fun uniffi_dojo_uniffi_checksum_method_toriiclient_sql( ): Short external fun uniffi_dojo_uniffi_checksum_method_toriiclient_starknet_events( @@ -899,6 +901,8 @@ external fun uniffi_dojo_uniffi_fn_method_toriiclient_publish_message(`ptr`: Lon ): RustBuffer.ByValue external fun uniffi_dojo_uniffi_fn_method_toriiclient_publish_message_batch(`ptr`: Long,`messages`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue +external fun uniffi_dojo_uniffi_fn_method_toriiclient_search(`ptr`: Long,`query`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, +): RustBuffer.ByValue external fun uniffi_dojo_uniffi_fn_method_toriiclient_sql(`ptr`: Long,`query`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, ): RustBuffer.ByValue external fun uniffi_dojo_uniffi_fn_method_toriiclient_starknet_events(`ptr`: Long,`query`: RustBuffer.ByValue,uniffi_out_err: UniffiRustCallStatus, @@ -1087,6 +1091,9 @@ private fun uniffiCheckApiChecksums(lib: IntegrityCheckingUniffiLib) { if (lib.uniffi_dojo_uniffi_checksum_method_toriiclient_publish_message_batch() != 2146.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } + if (lib.uniffi_dojo_uniffi_checksum_method_toriiclient_search() != 20622.toShort()) { + throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + } if (lib.uniffi_dojo_uniffi_checksum_method_toriiclient_sql() != 38286.toShort()) { throw RuntimeException("UniFFI API checksum mismatch: try cleaning and rebuilding your project") } @@ -1758,6 +1765,8 @@ public interface ToriiClientInterface { fun `publishMessageBatch`(`messages`: List): List + fun `search`(`query`: SearchQuery): SearchResponse + fun `sql`(`query`: kotlin.String): List fun `starknetEvents`(`query`: EventQuery): PageEvent @@ -2045,6 +2054,20 @@ open class ToriiClient: Disposable, AutoCloseable, ToriiClientInterface + @Throws(DojoException::class)override fun `search`(`query`: SearchQuery): SearchResponse { + return FfiConverterTypeSearchResponse.lift( + callWithHandle { + uniffiRustCallWithError(DojoException) { _status -> + UniffiLib.uniffi_dojo_uniffi_fn_method_toriiclient_search( + it, + FfiConverterTypeSearchQuery.lower(`query`),_status) +} + } + ) + } + + + @Throws(DojoException::class)override fun `sql`(`query`: kotlin.String): List { return FfiConverterSequenceTypeSqlRow.lift( callWithHandle { @@ -4371,6 +4394,155 @@ public object FfiConverterTypeQuery: FfiConverterRustBuffer { +data class SearchField ( + val `key`: kotlin.String + , + val `value`: kotlin.String + +){ + + + + companion object +} + +/** + * @suppress + */ +public object FfiConverterTypeSearchField: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): SearchField { + return SearchField( + FfiConverterString.read(buf), + FfiConverterString.read(buf), + ) + } + + override fun allocationSize(value: SearchField) = ( + FfiConverterString.allocationSize(value.`key`) + + FfiConverterString.allocationSize(value.`value`) + ) + + override fun write(value: SearchField, buf: ByteBuffer) { + FfiConverterString.write(value.`key`, buf) + FfiConverterString.write(value.`value`, buf) + } +} + + + +data class SearchMatch ( + val `id`: kotlin.String + , + val `fields`: List + , + val `score`: kotlin.Double? + +){ + + + + companion object +} + +/** + * @suppress + */ +public object FfiConverterTypeSearchMatch: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): SearchMatch { + return SearchMatch( + FfiConverterString.read(buf), + FfiConverterSequenceTypeSearchField.read(buf), + FfiConverterOptionalDouble.read(buf), + ) + } + + override fun allocationSize(value: SearchMatch) = ( + FfiConverterString.allocationSize(value.`id`) + + FfiConverterSequenceTypeSearchField.allocationSize(value.`fields`) + + FfiConverterOptionalDouble.allocationSize(value.`score`) + ) + + override fun write(value: SearchMatch, buf: ByteBuffer) { + FfiConverterString.write(value.`id`, buf) + FfiConverterSequenceTypeSearchField.write(value.`fields`, buf) + FfiConverterOptionalDouble.write(value.`score`, buf) + } +} + + + +data class SearchQuery ( + val `query`: kotlin.String + , + val `limit`: kotlin.UInt + +){ + + + + companion object +} + +/** + * @suppress + */ +public object FfiConverterTypeSearchQuery: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): SearchQuery { + return SearchQuery( + FfiConverterString.read(buf), + FfiConverterUInt.read(buf), + ) + } + + override fun allocationSize(value: SearchQuery) = ( + FfiConverterString.allocationSize(value.`query`) + + FfiConverterUInt.allocationSize(value.`limit`) + ) + + override fun write(value: SearchQuery, buf: ByteBuffer) { + FfiConverterString.write(value.`query`, buf) + FfiConverterUInt.write(value.`limit`, buf) + } +} + + + +data class SearchResponse ( + val `total`: kotlin.UInt + , + val `results`: List + +){ + + + + companion object +} + +/** + * @suppress + */ +public object FfiConverterTypeSearchResponse: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): SearchResponse { + return SearchResponse( + FfiConverterUInt.read(buf), + FfiConverterSequenceTypeTableSearchResults.read(buf), + ) + } + + override fun allocationSize(value: SearchResponse) = ( + FfiConverterUInt.allocationSize(value.`total`) + + FfiConverterSequenceTypeTableSearchResults.allocationSize(value.`results`) + ) + + override fun write(value: SearchResponse, buf: ByteBuffer) { + FfiConverterUInt.write(value.`total`, buf) + FfiConverterSequenceTypeTableSearchResults.write(value.`results`, buf) + } +} + + + data class Signature ( val `r`: FieldElement , @@ -4510,6 +4682,47 @@ public object FfiConverterTypeStruct: FfiConverterRustBuffer { +data class TableSearchResults ( + val `table`: kotlin.String + , + val `count`: kotlin.UInt + , + val `matches`: List + +){ + + + + companion object +} + +/** + * @suppress + */ +public object FfiConverterTypeTableSearchResults: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): TableSearchResults { + return TableSearchResults( + FfiConverterString.read(buf), + FfiConverterUInt.read(buf), + FfiConverterSequenceTypeSearchMatch.read(buf), + ) + } + + override fun allocationSize(value: TableSearchResults) = ( + FfiConverterString.allocationSize(value.`table`) + + FfiConverterUInt.allocationSize(value.`count`) + + FfiConverterSequenceTypeSearchMatch.allocationSize(value.`matches`) + ) + + override fun write(value: TableSearchResults, buf: ByteBuffer) { + FfiConverterString.write(value.`table`, buf) + FfiConverterUInt.write(value.`count`, buf) + FfiConverterSequenceTypeSearchMatch.write(value.`matches`, buf) + } +} + + + data class TaskProgress ( val `taskId`: kotlin.String , @@ -7116,6 +7329,38 @@ public object FfiConverterOptionalULong: FfiConverterRustBuffer { +/** + * @suppress + */ +public object FfiConverterOptionalDouble: FfiConverterRustBuffer { + override fun read(buf: ByteBuffer): kotlin.Double? { + if (buf.get().toInt() == 0) { + return null + } + return FfiConverterDouble.read(buf) + } + + override fun allocationSize(value: kotlin.Double?): ULong { + if (value == null) { + return 1UL + } else { + return 1UL + FfiConverterDouble.allocationSize(value) + } + } + + override fun write(value: kotlin.Double?, buf: ByteBuffer) { + if (value == null) { + buf.put(0) + } else { + buf.put(1) + FfiConverterDouble.write(value, buf) + } + } +} + + + + /** * @suppress */ @@ -7900,6 +8145,62 @@ public object FfiConverterSequenceTypePlayerAchievementProgress: FfiConverterRus +/** + * @suppress + */ +public object FfiConverterSequenceTypeSearchField: FfiConverterRustBuffer> { + override fun read(buf: ByteBuffer): List { + val len = buf.getInt() + return List(len) { + FfiConverterTypeSearchField.read(buf) + } + } + + override fun allocationSize(value: List): ULong { + val sizeForLength = 4UL + val sizeForItems = value.map { FfiConverterTypeSearchField.allocationSize(it) }.sum() + return sizeForLength + sizeForItems + } + + override fun write(value: List, buf: ByteBuffer) { + buf.putInt(value.size) + value.iterator().forEach { + FfiConverterTypeSearchField.write(it, buf) + } + } +} + + + + +/** + * @suppress + */ +public object FfiConverterSequenceTypeSearchMatch: FfiConverterRustBuffer> { + override fun read(buf: ByteBuffer): List { + val len = buf.getInt() + return List(len) { + FfiConverterTypeSearchMatch.read(buf) + } + } + + override fun allocationSize(value: List): ULong { + val sizeForLength = 4UL + val sizeForItems = value.map { FfiConverterTypeSearchMatch.allocationSize(it) }.sum() + return sizeForLength + sizeForItems + } + + override fun write(value: List, buf: ByteBuffer) { + buf.putInt(value.size) + value.iterator().forEach { + FfiConverterTypeSearchMatch.write(it, buf) + } + } +} + + + + /** * @suppress */ @@ -7984,6 +8285,34 @@ public object FfiConverterSequenceTypeStruct: FfiConverterRustBuffer> { + override fun read(buf: ByteBuffer): List { + val len = buf.getInt() + return List(len) { + FfiConverterTypeTableSearchResults.read(buf) + } + } + + override fun allocationSize(value: List): ULong { + val sizeForLength = 4UL + val sizeForItems = value.map { FfiConverterTypeTableSearchResults.allocationSize(it) }.sum() + return sizeForLength + sizeForItems + } + + override fun write(value: List, buf: ByteBuffer) { + buf.putInt(value.size) + value.iterator().forEach { + FfiConverterTypeTableSearchResults.write(it, buf) + } + } +} + + + + /** * @suppress */ diff --git a/bindings/python/dojo.py b/bindings/python/dojo.py index bf62c91..3d002b7 100644 --- a/bindings/python/dojo.py +++ b/bindings/python/dojo.py @@ -535,6 +535,8 @@ def _uniffi_check_api_checksums(lib): raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_dojo_uniffi_checksum_method_toriiclient_publish_message_batch() != 10937: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") + if lib.uniffi_dojo_uniffi_checksum_method_toriiclient_search() != 24151: + raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_dojo_uniffi_checksum_method_toriiclient_sql() != 38880: raise InternalError("UniFFI API checksum mismatch: try cleaning and rebuilding your project") if lib.uniffi_dojo_uniffi_checksum_method_toriiclient_starknet_events() != 49963: @@ -1016,6 +1018,12 @@ class _UniffiVTableCallbackInterfaceDojoTransactionUpdateCallback(ctypes.Structu ctypes.POINTER(_UniffiRustCallStatus), ) _UniffiLib.uniffi_dojo_uniffi_fn_method_toriiclient_publish_message_batch.restype = _UniffiRustBuffer +_UniffiLib.uniffi_dojo_uniffi_fn_method_toriiclient_search.argtypes = ( + ctypes.c_uint64, + _UniffiRustBuffer, + ctypes.POINTER(_UniffiRustCallStatus), +) +_UniffiLib.uniffi_dojo_uniffi_fn_method_toriiclient_search.restype = _UniffiRustBuffer _UniffiLib.uniffi_dojo_uniffi_fn_method_toriiclient_sql.argtypes = ( ctypes.c_uint64, _UniffiRustBuffer, @@ -1145,6 +1153,9 @@ class _UniffiVTableCallbackInterfaceDojoTransactionUpdateCallback(ctypes.Structu _UniffiLib.uniffi_dojo_uniffi_checksum_method_toriiclient_publish_message_batch.argtypes = ( ) _UniffiLib.uniffi_dojo_uniffi_checksum_method_toriiclient_publish_message_batch.restype = ctypes.c_uint16 +_UniffiLib.uniffi_dojo_uniffi_checksum_method_toriiclient_search.argtypes = ( +) +_UniffiLib.uniffi_dojo_uniffi_checksum_method_toriiclient_search.restype = ctypes.c_uint16 _UniffiLib.uniffi_dojo_uniffi_checksum_method_toriiclient_sql.argtypes = ( ) _UniffiLib.uniffi_dojo_uniffi_checksum_method_toriiclient_sql.restype = ctypes.c_uint16 @@ -6610,6 +6621,292 @@ def write(value, buf): _UniffiFfiConverterSequenceString.write(value.models, buf) _UniffiFfiConverterBoolean.write(value.historical, buf) +@dataclass +class SearchField: + def __init__(self, *, key:str, value:str): + self.key = key + self.value = value + + + + + def __str__(self): + return "SearchField(key={}, value={})".format(self.key, self.value) + def __eq__(self, other): + if self.key != other.key: + return False + if self.value != other.value: + return False + return True + +class _UniffiFfiConverterTypeSearchField(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return SearchField( + key=_UniffiFfiConverterString.read(buf), + value=_UniffiFfiConverterString.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.key) + _UniffiFfiConverterString.check_lower(value.value) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.key, buf) + _UniffiFfiConverterString.write(value.value, buf) + +class _UniffiFfiConverterSequenceTypeSearchField(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeSearchField.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeSearchField.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeSearchField.read(buf) for i in range(count) + ] + +class _UniffiFfiConverterOptionalFloat64(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + if value is not None: + _UniffiFfiConverterFloat64.check_lower(value) + + @classmethod + def write(cls, value, buf): + if value is None: + buf.write_u8(0) + return + + buf.write_u8(1) + _UniffiFfiConverterFloat64.write(value, buf) + + @classmethod + def read(cls, buf): + flag = buf.read_u8() + if flag == 0: + return None + elif flag == 1: + return _UniffiFfiConverterFloat64.read(buf) + else: + raise InternalError("Unexpected flag byte for optional type") + +@dataclass +class SearchMatch: + def __init__(self, *, id:str, fields:typing.List[SearchField], score:typing.Optional[float]): + self.id = id + self.fields = fields + self.score = score + + + + + def __str__(self): + return "SearchMatch(id={}, fields={}, score={})".format(self.id, self.fields, self.score) + def __eq__(self, other): + if self.id != other.id: + return False + if self.fields != other.fields: + return False + if self.score != other.score: + return False + return True + +class _UniffiFfiConverterTypeSearchMatch(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return SearchMatch( + id=_UniffiFfiConverterString.read(buf), + fields=_UniffiFfiConverterSequenceTypeSearchField.read(buf), + score=_UniffiFfiConverterOptionalFloat64.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.id) + _UniffiFfiConverterSequenceTypeSearchField.check_lower(value.fields) + _UniffiFfiConverterOptionalFloat64.check_lower(value.score) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.id, buf) + _UniffiFfiConverterSequenceTypeSearchField.write(value.fields, buf) + _UniffiFfiConverterOptionalFloat64.write(value.score, buf) + +@dataclass +class SearchQuery: + def __init__(self, *, query:str, limit:int): + self.query = query + self.limit = limit + + + + + def __str__(self): + return "SearchQuery(query={}, limit={})".format(self.query, self.limit) + def __eq__(self, other): + if self.query != other.query: + return False + if self.limit != other.limit: + return False + return True + +class _UniffiFfiConverterTypeSearchQuery(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return SearchQuery( + query=_UniffiFfiConverterString.read(buf), + limit=_UniffiFfiConverterUInt32.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.query) + _UniffiFfiConverterUInt32.check_lower(value.limit) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.query, buf) + _UniffiFfiConverterUInt32.write(value.limit, buf) + +class _UniffiFfiConverterSequenceTypeSearchMatch(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeSearchMatch.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeSearchMatch.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeSearchMatch.read(buf) for i in range(count) + ] + +@dataclass +class TableSearchResults: + def __init__(self, *, table:str, count:int, matches:typing.List[SearchMatch]): + self.table = table + self.count = count + self.matches = matches + + + + + def __str__(self): + return "TableSearchResults(table={}, count={}, matches={})".format(self.table, self.count, self.matches) + def __eq__(self, other): + if self.table != other.table: + return False + if self.count != other.count: + return False + if self.matches != other.matches: + return False + return True + +class _UniffiFfiConverterTypeTableSearchResults(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return TableSearchResults( + table=_UniffiFfiConverterString.read(buf), + count=_UniffiFfiConverterUInt32.read(buf), + matches=_UniffiFfiConverterSequenceTypeSearchMatch.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterString.check_lower(value.table) + _UniffiFfiConverterUInt32.check_lower(value.count) + _UniffiFfiConverterSequenceTypeSearchMatch.check_lower(value.matches) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterString.write(value.table, buf) + _UniffiFfiConverterUInt32.write(value.count, buf) + _UniffiFfiConverterSequenceTypeSearchMatch.write(value.matches, buf) + +class _UniffiFfiConverterSequenceTypeTableSearchResults(_UniffiConverterRustBuffer): + @classmethod + def check_lower(cls, value): + for item in value: + _UniffiFfiConverterTypeTableSearchResults.check_lower(item) + + @classmethod + def write(cls, value, buf): + items = len(value) + buf.write_i32(items) + for item in value: + _UniffiFfiConverterTypeTableSearchResults.write(item, buf) + + @classmethod + def read(cls, buf): + count = buf.read_i32() + if count < 0: + raise InternalError("Unexpected negative sequence length") + + return [ + _UniffiFfiConverterTypeTableSearchResults.read(buf) for i in range(count) + ] + +@dataclass +class SearchResponse: + def __init__(self, *, total:int, results:typing.List[TableSearchResults]): + self.total = total + self.results = results + + + + + def __str__(self): + return "SearchResponse(total={}, results={})".format(self.total, self.results) + def __eq__(self, other): + if self.total != other.total: + return False + if self.results != other.results: + return False + return True + +class _UniffiFfiConverterTypeSearchResponse(_UniffiConverterRustBuffer): + @staticmethod + def read(buf): + return SearchResponse( + total=_UniffiFfiConverterUInt32.read(buf), + results=_UniffiFfiConverterSequenceTypeTableSearchResults.read(buf), + ) + + @staticmethod + def check_lower(value): + _UniffiFfiConverterUInt32.check_lower(value.total) + _UniffiFfiConverterSequenceTypeTableSearchResults.check_lower(value.results) + + @staticmethod + def write(value, buf): + _UniffiFfiConverterUInt32.write(value.total, buf) + _UniffiFfiConverterSequenceTypeTableSearchResults.write(value.results, buf) + @dataclass class Signature: def __init__(self, *, r:FieldElement, s:FieldElement): @@ -8224,6 +8521,8 @@ def publish_message(self, message: Message) -> str: raise NotImplementedError def publish_message_batch(self, messages: typing.List[Message]) -> typing.List[str]: raise NotImplementedError + def search(self, query: SearchQuery) -> SearchResponse: + raise NotImplementedError def sql(self, query: str) -> typing.List[SqlRow]: raise NotImplementedError def starknet_events(self, query: EventQuery) -> PageEvent: @@ -8469,6 +8768,21 @@ def publish_message_batch(self, messages: typing.List[Message]) -> typing.List[s *_uniffi_lowered_args, ) return _uniffi_lift_return(_uniffi_ffi_result) + def search(self, query: SearchQuery) -> SearchResponse: + + _UniffiFfiConverterTypeSearchQuery.check_lower(query) + _uniffi_lowered_args = ( + self._uniffi_clone_handle(), + _UniffiFfiConverterTypeSearchQuery.lower(query), + ) + _uniffi_lift_return = _UniffiFfiConverterTypeSearchResponse.lift + _uniffi_error_converter = _UniffiFfiConverterTypeDojoError + _uniffi_ffi_result = _uniffi_rust_call_with_error( + _uniffi_error_converter, + _UniffiLib.uniffi_dojo_uniffi_fn_method_toriiclient_search, + *_uniffi_lowered_args, + ) + return _uniffi_lift_return(_uniffi_ffi_result) def sql(self, query: str) -> typing.List[SqlRow]: _UniffiFfiConverterString.check_lower(query) @@ -8790,6 +9104,11 @@ def write(cls, value: ToriiClient, buf: _UniffiRustBuffer): "PageTransaction", "PlayerAchievementQuery", "Query", + "SearchField", + "SearchMatch", + "SearchQuery", + "TableSearchResults", + "SearchResponse", "Signature", "SqlField", "SqlRow", diff --git a/bindings/swift/DojoEngine.swift b/bindings/swift/DojoEngine.swift index 56a1a5e..f53c70d 100644 --- a/bindings/swift/DojoEngine.swift +++ b/bindings/swift/DojoEngine.swift @@ -658,6 +658,8 @@ public protocol ToriiClientProtocol: AnyObject, Sendable { func publishMessageBatch(messages: [Message]) throws -> [String] + func search(query: SearchQuery) throws -> SearchResponse + func sql(query: String) throws -> [SqlRow] func starknetEvents(query: EventQuery) throws -> PageEvent @@ -848,6 +850,15 @@ open func publishMessageBatch(messages: [Message])throws -> [String] { }) } +open func search(query: SearchQuery)throws -> SearchResponse { + return try FfiConverterTypeSearchResponse_lift(try rustCallWithError(FfiConverterTypeDojoError_lift) { + uniffi_dojo_uniffi_fn_method_toriiclient_search( + self.uniffiCloneHandle(), + FfiConverterTypeSearchQuery_lower(query),$0 + ) +}) +} + open func sql(query: String)throws -> [SqlRow] { return try FfiConverterSequenceTypeSqlRow.lift(try rustCallWithError(FfiConverterTypeDojoError_lift) { uniffi_dojo_uniffi_fn_method_toriiclient_sql( @@ -3742,6 +3753,218 @@ public func FfiConverterTypeQuery_lower(_ value: Query) -> RustBuffer { } +public struct SearchField: Equatable, Hashable { + public let key: String + public let value: String + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(key: String, value: String) { + self.key = key + self.value = value + } + + +} + +#if compiler(>=6) +extension SearchField: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeSearchField: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SearchField { + return + try SearchField( + key: FfiConverterString.read(from: &buf), + value: FfiConverterString.read(from: &buf) + ) + } + + public static func write(_ value: SearchField, into buf: inout [UInt8]) { + FfiConverterString.write(value.key, into: &buf) + FfiConverterString.write(value.value, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSearchField_lift(_ buf: RustBuffer) throws -> SearchField { + return try FfiConverterTypeSearchField.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSearchField_lower(_ value: SearchField) -> RustBuffer { + return FfiConverterTypeSearchField.lower(value) +} + + +public struct SearchMatch: Equatable, Hashable { + public let id: String + public let fields: [SearchField] + public let score: Double? + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(id: String, fields: [SearchField], score: Double?) { + self.id = id + self.fields = fields + self.score = score + } + + +} + +#if compiler(>=6) +extension SearchMatch: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeSearchMatch: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SearchMatch { + return + try SearchMatch( + id: FfiConverterString.read(from: &buf), + fields: FfiConverterSequenceTypeSearchField.read(from: &buf), + score: FfiConverterOptionDouble.read(from: &buf) + ) + } + + public static func write(_ value: SearchMatch, into buf: inout [UInt8]) { + FfiConverterString.write(value.id, into: &buf) + FfiConverterSequenceTypeSearchField.write(value.fields, into: &buf) + FfiConverterOptionDouble.write(value.score, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSearchMatch_lift(_ buf: RustBuffer) throws -> SearchMatch { + return try FfiConverterTypeSearchMatch.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSearchMatch_lower(_ value: SearchMatch) -> RustBuffer { + return FfiConverterTypeSearchMatch.lower(value) +} + + +public struct SearchQuery: Equatable, Hashable { + public let query: String + public let limit: UInt32 + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(query: String, limit: UInt32) { + self.query = query + self.limit = limit + } + + +} + +#if compiler(>=6) +extension SearchQuery: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeSearchQuery: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SearchQuery { + return + try SearchQuery( + query: FfiConverterString.read(from: &buf), + limit: FfiConverterUInt32.read(from: &buf) + ) + } + + public static func write(_ value: SearchQuery, into buf: inout [UInt8]) { + FfiConverterString.write(value.query, into: &buf) + FfiConverterUInt32.write(value.limit, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSearchQuery_lift(_ buf: RustBuffer) throws -> SearchQuery { + return try FfiConverterTypeSearchQuery.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSearchQuery_lower(_ value: SearchQuery) -> RustBuffer { + return FfiConverterTypeSearchQuery.lower(value) +} + + +public struct SearchResponse: Equatable, Hashable { + public let total: UInt32 + public let results: [TableSearchResults] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(total: UInt32, results: [TableSearchResults]) { + self.total = total + self.results = results + } + + +} + +#if compiler(>=6) +extension SearchResponse: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeSearchResponse: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SearchResponse { + return + try SearchResponse( + total: FfiConverterUInt32.read(from: &buf), + results: FfiConverterSequenceTypeTableSearchResults.read(from: &buf) + ) + } + + public static func write(_ value: SearchResponse, into buf: inout [UInt8]) { + FfiConverterUInt32.write(value.total, into: &buf) + FfiConverterSequenceTypeTableSearchResults.write(value.results, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSearchResponse_lift(_ buf: RustBuffer) throws -> SearchResponse { + return try FfiConverterTypeSearchResponse.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeSearchResponse_lower(_ value: SearchResponse) -> RustBuffer { + return FfiConverterTypeSearchResponse.lower(value) +} + + public struct Signature: Equatable, Hashable { public let r: FieldElement public let s: FieldElement @@ -3946,6 +4169,62 @@ public func FfiConverterTypeStruct_lower(_ value: Struct) -> RustBuffer { } +public struct TableSearchResults: Equatable, Hashable { + public let table: String + public let count: UInt32 + public let matches: [SearchMatch] + + // Default memberwise initializers are never public by default, so we + // declare one manually. + public init(table: String, count: UInt32, matches: [SearchMatch]) { + self.table = table + self.count = count + self.matches = matches + } + + +} + +#if compiler(>=6) +extension TableSearchResults: Sendable {} +#endif + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public struct FfiConverterTypeTableSearchResults: FfiConverterRustBuffer { + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> TableSearchResults { + return + try TableSearchResults( + table: FfiConverterString.read(from: &buf), + count: FfiConverterUInt32.read(from: &buf), + matches: FfiConverterSequenceTypeSearchMatch.read(from: &buf) + ) + } + + public static func write(_ value: TableSearchResults, into buf: inout [UInt8]) { + FfiConverterString.write(value.table, into: &buf) + FfiConverterUInt32.write(value.count, into: &buf) + FfiConverterSequenceTypeSearchMatch.write(value.matches, into: &buf) + } +} + + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTableSearchResults_lift(_ buf: RustBuffer) throws -> TableSearchResults { + return try FfiConverterTypeTableSearchResults.lift(buf) +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +public func FfiConverterTypeTableSearchResults_lower(_ value: TableSearchResults) -> RustBuffer { + return FfiConverterTypeTableSearchResults.lower(value) +} + + public struct TaskProgress: Equatable, Hashable { public let taskId: String public let count: UInt32 @@ -7041,6 +7320,30 @@ fileprivate struct FfiConverterOptionUInt64: FfiConverterRustBuffer { } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterOptionDouble: FfiConverterRustBuffer { + typealias SwiftType = Double? + + public static func write(_ value: SwiftType, into buf: inout [UInt8]) { + guard let value = value else { + writeInt(&buf, Int8(0)) + return + } + writeInt(&buf, Int8(1)) + FfiConverterDouble.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 FfiConverterDouble.read(from: &buf) + default: throw UniffiInternalError.unexpectedOptionalTag + } + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -7709,6 +8012,56 @@ fileprivate struct FfiConverterSequenceTypePlayerAchievementProgress: FfiConvert } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeSearchField: FfiConverterRustBuffer { + typealias SwiftType = [SearchField] + + public static func write(_ value: [SearchField], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeSearchField.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [SearchField] { + let len: Int32 = try readInt(&buf) + var seq = [SearchField]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeSearchField.read(from: &buf)) + } + return seq + } +} + +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeSearchMatch: FfiConverterRustBuffer { + typealias SwiftType = [SearchMatch] + + public static func write(_ value: [SearchMatch], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeSearchMatch.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [SearchMatch] { + let len: Int32 = try readInt(&buf) + var seq = [SearchMatch]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeSearchMatch.read(from: &buf)) + } + return seq + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -7784,6 +8137,31 @@ fileprivate struct FfiConverterSequenceTypeStruct: FfiConverterRustBuffer { } } +#if swift(>=5.8) +@_documentation(visibility: private) +#endif +fileprivate struct FfiConverterSequenceTypeTableSearchResults: FfiConverterRustBuffer { + typealias SwiftType = [TableSearchResults] + + public static func write(_ value: [TableSearchResults], into buf: inout [UInt8]) { + let len = Int32(value.count) + writeInt(&buf, len) + for item in value { + FfiConverterTypeTableSearchResults.write(item, into: &buf) + } + } + + public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> [TableSearchResults] { + let len: Int32 = try readInt(&buf) + var seq = [TableSearchResults]() + seq.reserveCapacity(Int(len)) + for _ in 0 ..< len { + seq.append(try FfiConverterTypeTableSearchResults.read(from: &buf)) + } + return seq + } +} + #if swift(>=5.8) @_documentation(visibility: private) #endif @@ -8295,6 +8673,9 @@ private let initializationResult: InitializationResult = { if (uniffi_dojo_uniffi_checksum_method_toriiclient_publish_message_batch() != 2146) { return InitializationResult.apiChecksumMismatch } + if (uniffi_dojo_uniffi_checksum_method_toriiclient_search() != 20622) { + return InitializationResult.apiChecksumMismatch + } if (uniffi_dojo_uniffi_checksum_method_toriiclient_sql() != 38286) { return InitializationResult.apiChecksumMismatch } diff --git a/crates/uniffi/src/dojo.udl b/crates/uniffi/src/dojo.udl index 3d6a654..69a9e57 100644 --- a/crates/uniffi/src/dojo.udl +++ b/crates/uniffi/src/dojo.udl @@ -637,6 +637,34 @@ dictionary PageEvent { string? next_cursor; }; +// Search types +dictionary SearchQuery { + string query; + u32 limit; +}; + +dictionary SearchField { + string key; + string value; +}; + +dictionary SearchMatch { + string id; + sequence fields; + f64? score; +}; + +dictionary TableSearchResults { + string table; + u32 count; + sequence matches; +}; + +dictionary SearchResponse { + u32 total; + sequence results; +}; + // Main Dojo client interface interface ToriiClient { // Constructor - create a new client with default config (4MB max message size) @@ -719,6 +747,10 @@ interface ToriiClient { [Throws=DojoError] sequence sql(string query); + // Perform full-text search across indexed entities + [Throws=DojoError] + SearchResponse search(SearchQuery query); + // Subscription methods // Subscribe to entity updates [Throws=DojoError] diff --git a/crates/uniffi/src/uniffi/types/search.rs b/crates/uniffi/src/uniffi/types/search.rs index 39a66e4..eb61b02 100644 --- a/crates/uniffi/src/uniffi/types/search.rs +++ b/crates/uniffi/src/uniffi/types/search.rs @@ -1,5 +1,3 @@ -use std::collections::HashMap; - use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -14,16 +12,27 @@ impl From for torii_proto::SearchQuery { } } +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct SearchField { + pub key: String, + pub value: String, +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct SearchMatch { pub id: String, - pub fields: HashMap, + pub fields: Vec, pub score: Option, } impl From for SearchMatch { fn from(val: torii_proto::SearchMatch) -> Self { - Self { id: val.id, fields: val.fields, score: val.score } + let fields = val + .fields + .into_iter() + .map(|(key, value)| SearchField { key, value }) + .collect(); + Self { id: val.id, fields, score: val.score } } } diff --git a/scripts/build_everything.sh b/scripts/build_everything.sh new file mode 100755 index 0000000..0e987e1 --- /dev/null +++ b/scripts/build_everything.sh @@ -0,0 +1,49 @@ +#!/bin/bash +# Master script to build ALL Dojo bindings (UniFFI, C, and WASM) + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR/.." + +echo "========================================" +echo "Building ALL Dojo Bindings" +echo "========================================" +echo "" + +# Build UniFFI bindings (Swift, Kotlin, Python, C#, Go) +echo "🔧 Building UniFFI bindings..." +./scripts/build_all_bindings.sh +echo "" + +# Build C bindings +echo "🔧 Building C bindings..." +./scripts/build_c.sh +echo "" + +# Build C++ bindings +echo "🔧 Building C++ bindings..." +./scripts/build_cpp.sh +echo "" + +# Build WASM bindings +echo "🔧 Building WASM bindings..." +./scripts/build_wasm.sh +echo "" + +echo "✅ ALL BINDINGS GENERATED SUCCESSFULLY!" +echo "" +echo "Generated bindings:" +echo " 📁 UniFFI bindings:" +echo " - bindings/swift/" +echo " - bindings/kotlin/" +echo " - bindings/python/" +echo " - bindings/csharp/" +echo " - bindings/go/" +echo " 📁 C/C++ bindings:" +echo " - bindings/c/dojo.h" +echo " - bindings/cpp/" +echo " 📁 WASM bindings:" +echo " - pkg/" +echo "" + diff --git a/src/bin/uniffi-bindgen-kotlin.rs b/src/bin/uniffi-bindgen-kotlin.rs deleted file mode 100644 index f9a2f4d..0000000 --- a/src/bin/uniffi-bindgen-kotlin.rs +++ /dev/null @@ -1,55 +0,0 @@ -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 deleted file mode 100644 index e4f37bb..0000000 --- a/src/bin/uniffi-bindgen-python.rs +++ /dev/null @@ -1,65 +0,0 @@ -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 deleted file mode 100644 index 5396425..0000000 --- a/src/bin/uniffi-bindgen-swift.rs +++ /dev/null @@ -1,71 +0,0 @@ -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/dojo.udl b/src/dojo.udl deleted file mode 100644 index a71ac11..0000000 --- a/src/dojo.udl +++ /dev/null @@ -1,773 +0,0 @@ -// 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; -}; - -// 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; - 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); -}; - -// 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 { - "ClientError", - "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; -}; - -// Search types -dictionary SearchQuery { - string query; - u32 limit; -}; - -dictionary SearchMatch { - string id; - record fields; - f64? score; -}; - -dictionary TableSearchResults { - string table; - u32 count; - sequence matches; -}; - -dictionary SearchResponse { - u32 total; - sequence results; -}; - -// 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); - - // Perform full-text search across indexed entities - [Async, Throws=DojoError] - SearchResponse search(SearchQuery 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/lib.rs b/src/lib.rs deleted file mode 100644 index c57aca1..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,7 +0,0 @@ -// Re-export the appropriate crate based on compilation target - -#[cfg(not(target_arch = "wasm32"))] -pub use c::*; - -#[cfg(target_arch = "wasm32")] -pub use wasm::*; diff --git a/src/uniffi/README.md b/src/uniffi/README.md deleted file mode 100644 index 74dfd3d..0000000 --- a/src/uniffi/README.md +++ /dev/null @@ -1,93 +0,0 @@ -# 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 deleted file mode 100644 index 0f97cad..0000000 --- a/src/uniffi/client.rs +++ /dev/null @@ -1,537 +0,0 @@ -// Client wrapper for UniFFI - exposes torii_client functionality - -use super::types::*; -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: Arc, - 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: Arc::new(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: Arc::new(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 addrs = addrs?; - - let worlds = self.inner - .worlds(addrs) - .await - .map_err(|e| DojoError::QueryError(e.to_string()))?; - - 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(|e| DojoError::QueryError(e.to_string()))?; - - 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(|e| DojoError::QueryError(e.to_string()))?; - - 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(|e| DojoError::QueryError(e.to_string()))?; - - 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(|e| DojoError::QueryError(e.to_string()))?; - - 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(|e| DojoError::QueryError(e.to_string()))?; - - 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(|e| DojoError::QueryError(e.to_string()))?; - - 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(|e| DojoError::QueryError(e.to_string()))?; - - 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(|e| DojoError::QueryError(e.to_string()))?; - - 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(|e| DojoError::QueryError(e.to_string()))?; - - 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(|e| DojoError::QueryError(e.to_string()))?; - - 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(|e| DojoError::QueryError(e.to_string()))?; - - 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(|e| DojoError::QueryError(e.to_string()))?; - - 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(|e| DojoError::QueryError(e.to_string()))?; - - 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(|e| DojoError::QueryError(e.to_string()))?; - - 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(|e| DojoError::QueryError(e.to_string()))?; - - 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/mod.rs b/src/uniffi/mod.rs deleted file mode 100644 index c422a6d..0000000 --- a/src/uniffi/mod.rs +++ /dev/null @@ -1,14 +0,0 @@ -// UniFFI bindings for Dojo -// -// This module provides foreign function interface bindings for multiple languages -// (Swift, Kotlin, Python) using Mozilla's UniFFI framework. - -// Type definitions organized by domain -pub mod types; - -// Client implementation -pub mod client; - -// Re-export everything for convenience -pub use client::*; -pub use types::*; diff --git a/src/uniffi/types/achievement.rs b/src/uniffi/types/achievement.rs deleted file mode 100644 index ae67098..0000000 --- a/src/uniffi/types/achievement.rs +++ /dev/null @@ -1,239 +0,0 @@ -// 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 deleted file mode 100644 index 29c37e3..0000000 --- a/src/uniffi/types/activity.rs +++ /dev/null @@ -1,76 +0,0 @@ -// 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 deleted file mode 100644 index 1d964bb..0000000 --- a/src/uniffi/types/aggregation.rs +++ /dev/null @@ -1,49 +0,0 @@ -// 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 deleted file mode 100644 index 4f88575..0000000 --- a/src/uniffi/types/contract.rs +++ /dev/null @@ -1,85 +0,0 @@ -// 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 deleted file mode 100644 index 6951fce..0000000 --- a/src/uniffi/types/controller.rs +++ /dev/null @@ -1,41 +0,0 @@ -// 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/types/core.rs b/src/uniffi/types/core.rs deleted file mode 100644 index 6be9a51..0000000 --- a/src/uniffi/types/core.rs +++ /dev/null @@ -1,329 +0,0 @@ -// 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 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 { - 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, - #[error("Connection error")] - ConnectionError, - #[error("Publish error")] - PublishError, - #[error("Query error: {0}")] - QueryError(String), - #[error("Subscription error")] - SubscriptionError, -} - -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()), - } - } -} - -// 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/types/entity.rs b/src/uniffi/types/entity.rs deleted file mode 100644 index 5e7c7cb..0000000 --- a/src/uniffi/types/entity.rs +++ /dev/null @@ -1,130 +0,0 @@ -// 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/types/event.rs b/src/uniffi/types/event.rs deleted file mode 100644 index 96a91f3..0000000 --- a/src/uniffi/types/event.rs +++ /dev/null @@ -1,65 +0,0 @@ -// Event and Message types -use super::core::*; -use super::query::*; - -#[derive(Debug, Clone)] -pub struct Event { - pub keys: Vec, - pub data: Vec, - 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 { - 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(), - } - } -} - -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/types/mod.rs b/src/uniffi/types/mod.rs deleted file mode 100644 index 4b669d8..0000000 --- a/src/uniffi/types/mod.rs +++ /dev/null @@ -1,30 +0,0 @@ -// 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/types/query.rs b/src/uniffi/types/query.rs deleted file mode 100644 index 30a5512..0000000 --- a/src/uniffi/types/query.rs +++ /dev/null @@ -1,310 +0,0 @@ -// Query types - Query, Clause, KeysClause, MemberClause, CompositeClause -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, - 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/types/schema.rs b/src/uniffi/types/schema.rs deleted file mode 100644 index bc88eff..0000000 --- a/src/uniffi/types/schema.rs +++ /dev/null @@ -1,331 +0,0 @@ -// 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 deleted file mode 100644 index 439a513..0000000 --- a/src/uniffi/types/token.rs +++ /dev/null @@ -1,209 +0,0 @@ -// 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 deleted file mode 100644 index 8d0657a..0000000 --- a/src/uniffi/types/transaction.rs +++ /dev/null @@ -1,128 +0,0 @@ -// 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 bea1ef0cac0c1b6a206d646adbcaf01b13b56213 Mon Sep 17 00:00:00 2001 From: Nasr Date: Mon, 27 Oct 2025 16:55:31 -0500 Subject: [PATCH 5/5] fmt --- crates/uniffi/src/uniffi/types/search.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/crates/uniffi/src/uniffi/types/search.rs b/crates/uniffi/src/uniffi/types/search.rs index eb61b02..5e79b37 100644 --- a/crates/uniffi/src/uniffi/types/search.rs +++ b/crates/uniffi/src/uniffi/types/search.rs @@ -27,11 +27,8 @@ pub struct SearchMatch { impl From for SearchMatch { fn from(val: torii_proto::SearchMatch) -> Self { - let fields = val - .fields - .into_iter() - .map(|(key, value)| SearchField { key, value }) - .collect(); + let fields = + val.fields.into_iter().map(|(key, value)| SearchField { key, value }).collect(); Self { id: val.id, fields, score: val.score } } }