Skip to content

Commit

Permalink
update sozo model + sozo register commands with namespace
Browse files Browse the repository at this point in the history
  • Loading branch information
remybar committed Jun 3, 2024
1 parent e812370 commit 547fa48
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 28 deletions.
56 changes: 46 additions & 10 deletions bin/sozo/src/commands/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ pub enum ModelCommand {
#[arg(help = "The name of the model")]
name: String,

#[arg(short, long)]
#[arg(help = "The model namespace. If not set, the main package ID is used.")]
namespace: Option<String>,

#[command(flatten)]
world: WorldOptions,

Expand All @@ -34,6 +38,10 @@ pub enum ModelCommand {
#[arg(help = "The name of the model")]
name: String,

#[arg(short, long)]
#[arg(help = "The model namespace. If not set, the main package ID is used.")]
namespace: Option<String>,

#[command(flatten)]
world: WorldOptions,

Expand Down Expand Up @@ -65,6 +73,10 @@ hashes, called 'hash' in the following documentation.
#[arg(help = "The name of the model")]
name: String,

#[arg(short, long)]
#[arg(help = "The model namespace. If not set, the main package ID is used.")]
namespace: Option<String>,

#[command(flatten)]
world: WorldOptions,

Expand All @@ -77,6 +89,10 @@ hashes, called 'hash' in the following documentation.
#[arg(help = "The name of the model")]
name: String,

#[arg(short, long)]
#[arg(help = "The model namespace. If not set, the main package ID is used.")]
namespace: Option<String>,

#[command(flatten)]
world: WorldOptions,

Expand All @@ -93,6 +109,10 @@ hashes, called 'hash' in the following documentation.
#[arg(help = "The name of the model")]
name: String,

#[arg(short, long)]
#[arg(help = "The model namespace. If not set, the main package ID is used.")]
namespace: Option<String>,

#[arg(value_name = "KEYS")]
#[arg(value_delimiter = ',')]
#[arg(help = "Comma seperated values e.g., 0x12345,0x69420,...")]
Expand All @@ -109,34 +129,50 @@ hashes, called 'hash' in the following documentation.
impl ModelArgs {
pub fn run(self, config: &Config) -> Result<()> {
trace!(args = ?self);
let ws = scarb::ops::read_workspace(config.manifest_path(), config)?;
let env_metadata = utils::load_metadata_from_config(config)?;
let get_namespace = |ns: Option<String>| -> String {
match ns {
Some(x) => x,
None => {
let default_namespace = ws.current_package().unwrap().id.name.to_string();
println!("[default namespace: {}]", default_namespace);
default_namespace
}
}
};

config.tokio_handle().block_on(async {
match self.command {
ModelCommand::ClassHash { name, starknet, world } => {
ModelCommand::ClassHash { name, namespace, starknet, world } => {
let namespace = get_namespace(namespace);
let world_address = world.address(env_metadata.as_ref()).unwrap();
let provider = starknet.provider(env_metadata.as_ref()).unwrap();
model::model_class_hash(name, world_address, provider).await
model::model_class_hash(namespace, name, world_address, provider).await
}
ModelCommand::ContractAddress { name, starknet, world } => {
ModelCommand::ContractAddress { name, namespace, starknet, world } => {
let namespace = get_namespace(namespace);
let world_address = world.address(env_metadata.as_ref()).unwrap();
let provider = starknet.provider(env_metadata.as_ref()).unwrap();
model::model_contract_address(name, world_address, provider).await
model::model_contract_address(namespace, name, world_address, provider).await
}
ModelCommand::Layout { name, starknet, world } => {
ModelCommand::Layout { name, namespace, starknet, world } => {
let namespace = get_namespace(namespace);
let world_address = world.address(env_metadata.as_ref()).unwrap();
let provider = starknet.provider(env_metadata.as_ref()).unwrap();
model::model_layout(name, world_address, provider).await
model::model_layout(namespace, name, world_address, provider).await
}
ModelCommand::Schema { name, to_json, starknet, world } => {
ModelCommand::Schema { name, namespace, to_json, starknet, world } => {
let namespace = get_namespace(namespace);
let world_address = world.address(env_metadata.as_ref()).unwrap();
let provider = starknet.provider(env_metadata.as_ref()).unwrap();
model::model_schema(name, world_address, provider, to_json).await
model::model_schema(namespace, name, world_address, provider, to_json).await
}
ModelCommand::Get { name, keys, starknet, world } => {
ModelCommand::Get { name, namespace, keys, starknet, world } => {
let namespace = get_namespace(namespace);
let world_address = world.address(env_metadata.as_ref()).unwrap();
let provider = starknet.provider(env_metadata.as_ref()).unwrap();
model::model_get(name, keys, world_address, provider).await
model::model_get(namespace, name, keys, world_address, provider).await
}
}
})
Expand Down
18 changes: 15 additions & 3 deletions bin/sozo/src/commands/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ pub enum RegisterCommand {
#[arg(help = "The class hash of the models to register.")]
models: Vec<FieldElement>,

#[arg(short, long)]
#[arg(help = "The namespace to use to register these models. If not set, the main \
package ID is used.")]
namespace: Option<String>,

#[command(flatten)]
world: WorldOptions,

Expand All @@ -47,14 +52,20 @@ impl RegisterArgs {
pub fn run(self, config: &Config) -> Result<()> {
trace!(args = ?self);
let env_metadata = utils::load_metadata_from_config(config)?;
let ws = scarb::ops::read_workspace(config.manifest_path(), config)?;

let (starknet, world, account, transaction, models) = match self.command {
RegisterCommand::Model { starknet, world, account, transaction, models } => {
let (namespace, starknet, world, account, transaction, models) = match self.command {
RegisterCommand::Model { namespace, starknet, world, account, transaction, models } => {
trace!(?models, "Registering models.");
(starknet, world, account, transaction, models)
(namespace, starknet, world, account, transaction, models)
}
};

let namespace = match namespace {
Some(x) => x,
None => ws.current_package().unwrap().id.name.to_string(),
};

let world_address = world.world_address.unwrap_or_default();
trace!(?world_address, "Using world address.");

Expand All @@ -66,6 +77,7 @@ impl RegisterArgs {
world_reader.set_block(BlockId::Tag(BlockTag::Pending));

register::model_register(
namespace,
models,
&world,
transaction.into(),
Expand Down
11 changes: 8 additions & 3 deletions crates/dojo-world/src/contracts/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use cainome::cairo_serde::{CairoSerde as _, ContractAddress, Error as CainomeErr
use dojo_types::packing::{PackingError, ParseError};
use dojo_types::primitive::{Primitive, PrimitiveError};
use dojo_types::schema::{Enum, EnumOption, Member, Struct, Ty};
use starknet::core::crypto::compute_hash_on_elements;
use starknet::core::types::FieldElement;
use starknet::core::utils::{
cairo_short_string_to_felt, get_selector_from_name, parse_cairo_short_string,
Expand Down Expand Up @@ -82,13 +83,17 @@ where
P: Provider + Sync + Send,
{
pub async fn new(
namespace: &str,
name: &str,
world: &'a WorldContractReader<P>,
) -> Result<ModelRPCReader<'a, P>, ModelError> {
let name = get_selector_from_name(name)?;
let model_selector = get_selector_from_name(name)?;
let namespace_selector = get_selector_from_name(namespace)?;

let model_selector = compute_hash_on_elements(&[namespace_selector, model_selector]);

let (class_hash, contract_address) =
world.model(&name).block_id(world.block_id).call().await?;
world.model(&model_selector).block_id(world.block_id).call().await?;

// World Cairo contract won't raise an error in case of unknown/unregistered
// model so raise an error here in case of zero address.
Expand All @@ -102,7 +107,7 @@ where
world_reader: world,
class_hash: class_hash.into(),
contract_address: contract_address.into(),
name,
name: model_selector,
model_reader,
})
}
Expand Down
4 changes: 2 additions & 2 deletions crates/dojo-world/src/contracts/model_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ async fn test_model() {
let world_address = deploy_world(&runner, &manifest_dir.into(), &target_dir).await;

let world = WorldContractReader::new(world_address, provider);
let position = world.model_reader("Position").await.unwrap();
let position = world.model_reader("Dojo", "Position").await.unwrap();
let schema = position.schema().await.unwrap();

assert_eq!(
Expand Down Expand Up @@ -68,7 +68,7 @@ async fn test_model() {
felt!("0x027942375b09862291ece780c573e8c625df4ba41fd7524e0658ca75fff014ff")
);

let moves = world.model_reader("Moves").await.unwrap();
let moves = world.model_reader("Dojo", "Moves").await.unwrap();
let schema = moves.schema().await.unwrap();

assert_eq!(
Expand Down
8 changes: 6 additions & 2 deletions crates/dojo-world/src/contracts/world.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ impl<P> WorldContractReader<P>
where
P: Provider + Sync + Send,
{
pub async fn model_reader(&self, name: &str) -> Result<ModelRPCReader<'_, P>, ModelError> {
ModelRPCReader::new(name, self).await
pub async fn model_reader(
&self,
namespace: &str,
name: &str,
) -> Result<ModelRPCReader<'_, P>, ModelError> {
ModelRPCReader::new(namespace, name, self).await
}
}
4 changes: 2 additions & 2 deletions crates/sozo/ops/src/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ where
let model_name = parse_cairo_short_string(&mc.model)?;
let model_selector = get_selector_from_name(&model_name)?;

match world_reader.model_reader(&model_name).await {
match world_reader.model_reader("TODO", &model_name).await {
Ok(_) => {
let contract = utils::get_contract_address(world, mc.contract).await?;
calls.push(world.grant_writer_getcall(&model_selector, &contract.into()));
Expand Down Expand Up @@ -215,7 +215,7 @@ where
let model_name = parse_cairo_short_string(&mc.model)?;
let model_selector = get_selector_from_name(&model_name)?;

match world_reader.model_reader(&model_name).await {
match world_reader.model_reader("TODO", &model_name).await {
Ok(_) => {
let contract = utils::get_contract_address(world, mc.contract).await?;
calls.push(world.revoke_writer_getcall(&model_selector, &contract.into()));
Expand Down
15 changes: 10 additions & 5 deletions crates/sozo/ops/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,44 +11,47 @@ use starknet::providers::JsonRpcClient;
const INDENT: &str = " ";

pub async fn model_class_hash(
namespace: String,
name: String,
world_address: FieldElement,
provider: JsonRpcClient<HttpTransport>,
) -> Result<()> {
let mut world_reader = WorldContractReader::new(world_address, &provider);
world_reader.set_block(BlockId::Tag(BlockTag::Pending));

let model = world_reader.model_reader(&name).await?;
let model = world_reader.model_reader(&namespace, &name).await?;

println!("{:#x}", model.class_hash());

Ok(())
}

pub async fn model_contract_address(
namespace: String,
name: String,
world_address: FieldElement,
provider: JsonRpcClient<HttpTransport>,
) -> Result<()> {
let mut world_reader = WorldContractReader::new(world_address, &provider);
world_reader.set_block(BlockId::Tag(BlockTag::Pending));

let model = world_reader.model_reader(&name).await?;
let model = world_reader.model_reader(&namespace, &name).await?;

println!("{:#x}", model.contract_address());

Ok(())
}

pub async fn model_layout(
namespace: String,
name: String,
world_address: FieldElement,
provider: JsonRpcClient<HttpTransport>,
) -> Result<()> {
let mut world_reader = WorldContractReader::new(world_address, &provider);
world_reader.set_block(BlockId::Tag(BlockTag::Pending));

let model = world_reader.model_reader(&name).await?;
let model = world_reader.model_reader(&namespace, &name).await?;
let layout = match model.layout().await {
Ok(x) => x,
Err(_) => anyhow::bail!(
Expand All @@ -64,6 +67,7 @@ pub async fn model_layout(
}

pub async fn model_schema(
namespace: String,
name: String,
world_address: FieldElement,
provider: JsonRpcClient<HttpTransport>,
Expand All @@ -72,7 +76,7 @@ pub async fn model_schema(
let mut world_reader = WorldContractReader::new(world_address, &provider);
world_reader.set_block(BlockId::Tag(BlockTag::Pending));

let model = world_reader.model_reader(&name).await?;
let model = world_reader.model_reader(&namespace, &name).await?;
let schema = model.schema().await?;

if to_json {
Expand All @@ -85,6 +89,7 @@ pub async fn model_schema(
}

pub async fn model_get(
namespace: String,
name: String,
keys: Vec<FieldElement>,
world_address: FieldElement,
Expand All @@ -93,7 +98,7 @@ pub async fn model_get(
let mut world_reader = WorldContractReader::new(world_address, &provider);
world_reader.set_block(BlockId::Tag(BlockTag::Pending));

let model = world_reader.model_reader(&name).await?;
let model = world_reader.model_reader(&namespace, &name).await?;
let schema = model.schema().await?;
let values = model.entity_storage(&keys).await?;

Expand Down
3 changes: 2 additions & 1 deletion crates/sozo/ops/src/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use starknet_crypto::FieldElement;
use crate::utils::handle_transaction_result;

pub async fn model_register<A, P>(
namespace: String,
models: Vec<FieldElement>,
world: &WorldContract<A>,
txn_config: TxnConfig,
Expand All @@ -37,7 +38,7 @@ where
let registered_models_names = manifest.models.iter().map(|m| m.name.as_str());
let mut model_class_hashes = HashMap::new();
for model_name in registered_models_names {
let read_model = world_reader.model_reader(model_name).await?;
let read_model = world_reader.model_reader(&namespace, model_name).await?;
let class_hash = read_model.class_hash();
model_class_hashes.insert(class_hash, model_name);
}
Expand Down

0 comments on commit 547fa48

Please sign in to comment.