diff --git a/crates/dojo-world/src/contracts/model.rs b/crates/dojo-world/src/contracts/model.rs
index f6c1ec6c84..b41c63071d 100644
--- a/crates/dojo-world/src/contracts/model.rs
+++ b/crates/dojo-world/src/contracts/model.rs
@@ -1,5 +1,6 @@
use std::vec;
+use async_trait::async_trait;
use dojo_types::packing::{parse_ty, unpack, PackingError, ParseError};
use dojo_types::primitive::PrimitiveError;
use dojo_types::schema::Ty;
@@ -46,7 +47,16 @@ pub enum ModelError
{
Packing(#[from] PackingError),
}
-pub struct ModelReader<'a, P> {
+#[async_trait]
+pub trait ModelReader {
+ fn class_hash(&self) -> FieldElement;
+ async fn schema(&self) -> Result;
+ async fn packed_size(&self) -> Result;
+ async fn unpacked_size(&self) -> Result;
+ async fn layout(&self) -> Result, E>;
+}
+
+pub struct ModelRPCReader<'a, P: Sync + Send> {
/// The name of the model
name: FieldElement,
/// The class hash of the model
@@ -55,14 +65,14 @@ pub struct ModelReader<'a, P> {
world_reader: &'a WorldContractReader,
}
-impl<'a, P> ModelReader<'a, P>
+impl<'a, P> ModelRPCReader<'a, P>
where
- P: Provider,
+ P: Provider + Sync + Send,
{
pub async fn new(
name: &str,
world: &'a WorldContractReader
,
- ) -> Result, ModelError> {
+ ) -> Result, ModelError> {
let name = cairo_short_string_to_felt(name)?;
let class_hash = world
@@ -88,11 +98,59 @@ where
Ok(Self { world_reader: world, class_hash, name })
}
- pub fn class_hash(&self) -> FieldElement {
+ pub async fn entity_storage(
+ &self,
+ keys: &[FieldElement],
+ ) -> Result, ModelError> {
+ let packed_size: u8 =
+ self.packed_size().await?.try_into().map_err(ParseError::ValueOutOfRange)?;
+
+ let key = poseidon_hash_many(keys);
+ let key = poseidon_hash_many(&[short_string!("dojo_storage"), self.name, key]);
+
+ let mut packed = Vec::with_capacity(packed_size as usize);
+ for slot in 0..packed_size {
+ let value = self
+ .world_reader
+ .provider()
+ .get_storage_at(
+ self.world_reader.address(),
+ key + slot.into(),
+ self.world_reader.block_id(),
+ )
+ .await?;
+
+ packed.push(value);
+ }
+
+ Ok(packed)
+ }
+
+ pub async fn entity(&self, keys: &[FieldElement]) -> Result> {
+ let mut schema = self.schema().await?;
+
+ let layout = self.layout().await?;
+ let raw_values = self.entity_storage(keys).await?;
+
+ let unpacked = unpack(raw_values, layout)?;
+ let mut keys_and_unpacked = [keys, &unpacked].concat();
+
+ schema.deserialize(&mut keys_and_unpacked)?;
+
+ Ok(schema)
+ }
+}
+
+#[async_trait]
+impl<'a, P> ModelReader> for ModelRPCReader<'a, P>
+where
+ P: Provider + Sync + Send,
+{
+ fn class_hash(&self) -> FieldElement {
self.class_hash
}
- pub async fn schema(&self) -> Result> {
+ async fn schema(&self) -> Result> {
let entrypoint = get_selector_from_name(SCHEMA_SELECTOR_STR).unwrap();
let res = self
@@ -103,7 +161,7 @@ where
Ok(parse_ty(&res[1..])?)
}
- pub async fn packed_size(&self) -> Result> {
+ async fn packed_size(&self) -> Result> {
let entrypoint = get_selector_from_name(PACKED_SIZE_SELECTOR_STR).unwrap();
let res = self
@@ -114,7 +172,7 @@ where
Ok(res[1])
}
- pub async fn unpacked_size(&self) -> Result> {
+ async fn unpacked_size(&self) -> Result> {
let entrypoint = get_selector_from_name(UNPACKED_SIZE_SELECTOR_STR).unwrap();
let res = self
@@ -125,7 +183,7 @@ where
Ok(res[1])
}
- pub async fn layout(&self) -> Result, ModelError> {
+ async fn layout(&self) -> Result, ModelError> {
let entrypoint = get_selector_from_name(LAYOUT_SELECTOR_STR).unwrap();
let res = self
@@ -135,46 +193,4 @@ where
Ok(res[2..].into())
}
-
- pub async fn entity_storage(
- &self,
- keys: &[FieldElement],
- ) -> Result, ModelError> {
- let packed_size: u8 =
- self.packed_size().await?.try_into().map_err(ParseError::ValueOutOfRange)?;
-
- let key = poseidon_hash_many(keys);
- let key = poseidon_hash_many(&[short_string!("dojo_storage"), self.name, key]);
-
- let mut packed = Vec::with_capacity(packed_size as usize);
- for slot in 0..packed_size {
- let value = self
- .world_reader
- .provider()
- .get_storage_at(
- self.world_reader.address(),
- key + slot.into(),
- self.world_reader.block_id(),
- )
- .await?;
-
- packed.push(value);
- }
-
- Ok(packed)
- }
-
- pub async fn entity(&self, keys: &[FieldElement]) -> Result> {
- let mut schema = self.schema().await?;
-
- let layout = self.layout().await?;
- let raw_values = self.entity_storage(keys).await?;
-
- let unpacked = unpack(raw_values, layout)?;
- let mut keys_and_unpacked = [keys, &unpacked].concat();
-
- schema.deserialize(&mut keys_and_unpacked)?;
-
- Ok(schema)
- }
}
diff --git a/crates/dojo-world/src/contracts/model_test.rs b/crates/dojo-world/src/contracts/model_test.rs
index 300ac6ede2..6b4b5e1981 100644
--- a/crates/dojo-world/src/contracts/model_test.rs
+++ b/crates/dojo-world/src/contracts/model_test.rs
@@ -7,6 +7,7 @@ use dojo_types::schema::{Enum, EnumOption, Member, Struct, Ty};
use starknet::accounts::ConnectedAccount;
use starknet::core::types::FieldElement;
+use crate::contracts::model::ModelReader;
use crate::contracts::world::test::deploy_world;
use crate::contracts::world::WorldContractReader;
diff --git a/crates/dojo-world/src/contracts/world.rs b/crates/dojo-world/src/contracts/world.rs
index 1f9440ff7a..9421d97bb9 100644
--- a/crates/dojo-world/src/contracts/world.rs
+++ b/crates/dojo-world/src/contracts/world.rs
@@ -11,7 +11,7 @@ use starknet::core::utils::{
use starknet::macros::selector;
use starknet::providers::{Provider, ProviderError};
-use super::model::{ModelError, ModelReader};
+use super::model::{ModelError, ModelRPCReader};
#[cfg(test)]
#[path = "world_test.rs"]
@@ -177,7 +177,7 @@ where
pub async fn model(
&'a self,
name: &str,
- ) -> Result, ModelError<::Error>>
+ ) -> Result, ModelError<::Error>>
{
self.reader.model(name).await
}
@@ -340,9 +340,12 @@ where
impl<'a, P> WorldContractReader
where
- P: Provider,
+ P: Provider + Sync + Send,
{
- pub async fn model(&'a self, name: &str) -> Result, ModelError> {
- ModelReader::new(name, self).await
+ pub async fn model(
+ &'a self,
+ name: &str,
+ ) -> Result, ModelError> {
+ ModelRPCReader::new(name, self).await
}
}
diff --git a/crates/sozo/src/ops/model.rs b/crates/sozo/src/ops/model.rs
index aba6fa548d..d567f1b230 100644
--- a/crates/sozo/src/ops/model.rs
+++ b/crates/sozo/src/ops/model.rs
@@ -1,5 +1,5 @@
use anyhow::Result;
-use dojo_world::contracts::world::WorldContractReader;
+use dojo_world::contracts::{world::WorldContractReader, model::ModelReader};
use dojo_world::metadata::Environment;
use starknet::core::types::{BlockId, BlockTag};
diff --git a/crates/torii/core/src/processors/register_model.rs b/crates/torii/core/src/processors/register_model.rs
index 2d63014c93..f632f6e437 100644
--- a/crates/torii/core/src/processors/register_model.rs
+++ b/crates/torii/core/src/processors/register_model.rs
@@ -1,5 +1,6 @@
use anyhow::{Error, Ok, Result};
use async_trait::async_trait;
+use dojo_world::contracts::model::ModelReader;
use dojo_world::contracts::world::WorldContractReader;
use starknet::core::types::{BlockWithTxs, Event, InvokeTransactionReceipt};
use starknet::core::utils::parse_cairo_short_string;