From cb6c709c33d17f81810dfd06ee8811ac9c878a1d Mon Sep 17 00:00:00 2001 From: glihm Date: Fri, 5 Apr 2024 13:54:29 -0400 Subject: [PATCH] feat: add metadata section to the world contract manifest --- bin/sozo/src/commands/dev.rs | 2 +- bin/sozo/src/commands/migrate.rs | 18 ++++--- bin/sozo/src/commands/options/starknet.rs | 6 ++- crates/dojo-world/src/manifest/mod.rs | 12 ++--- crates/dojo-world/src/manifest/types.rs | 14 ++++-- crates/sozo/ops/src/migration/mod.rs | 50 +++++++++---------- .../manifests/dev/manifest.json | 6 ++- .../manifests/dev/manifest.toml | 6 ++- 8 files changed, 68 insertions(+), 46 deletions(-) diff --git a/bin/sozo/src/commands/dev.rs b/bin/sozo/src/commands/dev.rs index c702ac8599..4c03b9d749 100644 --- a/bin/sozo/src/commands/dev.rs +++ b/bin/sozo/src/commands/dev.rs @@ -216,7 +216,7 @@ impl DevArgs { let mut previous_manifest: Option = Option::None; let result = build(&mut context); - let Some((mut world_address, account, _)) = context + let Some((mut world_address, account, _, _)) = context .ws .config() .tokio_handle() diff --git a/bin/sozo/src/commands/migrate.rs b/bin/sozo/src/commands/migrate.rs index c7244a88c1..10aba17018 100644 --- a/bin/sozo/src/commands/migrate.rs +++ b/bin/sozo/src/commands/migrate.rs @@ -70,13 +70,17 @@ pub async fn setup_env<'a>( Option, SingleOwnerAccount, LocalWallet>, String, + String, )> { let ui = ws.config().ui(); let world_address = world.address(env).ok(); - let (account, chain_id) = { + let (account, chain_id, rpc_url) = { let provider = starknet.provider(env)?; + + let rpc_url = starknet.url(env)?; + let chain_id = provider.chain_id().await?; let chain_id = parse_cairo_short_string(&chain_id) .with_context(|| "Cannot parse chain_id as string")?; @@ -92,7 +96,7 @@ pub async fn setup_env<'a>( } match account.provider().get_class_hash_at(BlockId::Tag(BlockTag::Pending), address).await { - Ok(_) => Ok((account, chain_id)), + Ok(_) => Ok((account, chain_id, rpc_url)), Err(ProviderError::StarknetError(StarknetError::ContractNotFound)) => { Err(anyhow!("Account with address {:#x} doesn't exist.", account.address())) } @@ -101,7 +105,7 @@ pub async fn setup_env<'a>( } .with_context(|| "Problem initializing account for migration.")?; - Ok((world_address, account, chain_id)) + Ok((world_address, account, chain_id, rpc_url.to_string())) } impl MigrateArgs { @@ -128,7 +132,7 @@ impl MigrateArgs { }; config.tokio_handle().block_on(async { - let (world_address, account, chain_id) = setup_env( + let (world_address, account, chain_id, rpc_url) = setup_env( &ws, account, starknet, @@ -138,7 +142,7 @@ impl MigrateArgs { ) .await?; - migration::migrate(&ws, world_address, chain_id, &account, name, true).await + migration::migrate(&ws, world_address, chain_id, rpc_url, &account, name, true).await }) } MigrateCommand::Apply { mut name, world, starknet, account } => { @@ -149,7 +153,7 @@ impl MigrateArgs { }; config.tokio_handle().block_on(async { - let (world_address, account, chain_id) = setup_env( + let (world_address, account, chain_id, rpc_url) = setup_env( &ws, account, starknet, @@ -159,7 +163,7 @@ impl MigrateArgs { ) .await?; - migration::migrate(&ws, world_address, chain_id, &account, name, false).await + migration::migrate(&ws, world_address, chain_id, rpc_url,&account, name, false).await }) } } diff --git a/bin/sozo/src/commands/options/starknet.rs b/bin/sozo/src/commands/options/starknet.rs index 011b04ae9e..759cacbf70 100644 --- a/bin/sozo/src/commands/options/starknet.rs +++ b/bin/sozo/src/commands/options/starknet.rs @@ -24,8 +24,10 @@ impl StarknetOptions { Ok(JsonRpcClient::new(HttpTransport::new(self.url(env_metadata)?))) } - // we dont check the env var because that would be handled by `clap` - fn url(&self, env_metadata: Option<&Environment>) -> Result { + // We dont check the env var because that would be handled by `clap`. + // This function is made public because [`JsonRpcClient`] does not expose + // the raw rpc url. + pub fn url(&self, env_metadata: Option<&Environment>) -> Result { if let Some(url) = self.rpc_url.as_ref() { Ok(url.clone()) } else if let Some(url) = env_metadata.and_then(|env| env.rpc_url()) { diff --git a/crates/dojo-world/src/manifest/mod.rs b/crates/dojo-world/src/manifest/mod.rs index de19e77b15..d56a6a9313 100644 --- a/crates/dojo-world/src/manifest/mod.rs +++ b/crates/dojo-world/src/manifest/mod.rs @@ -29,9 +29,9 @@ mod test; mod types; pub use types::{ - AbiFormat, BaseManifest, Class, ComputedValueEntrypoint, Contract, DeploymentManifest, + AbiFormat, BaseManifest, Class, ComputedValueEntrypoint, WorldContract, DeploymentManifest, DojoContract, DojoModel, Manifest, ManifestMethods, Member, OverlayClass, OverlayContract, - OverlayDojoContract, OverlayDojoModel, OverlayManifest, + OverlayDojoContract, OverlayDojoModel, OverlayManifest, WorldMetadata, }; pub const WORLD_CONTRACT_NAME: &str = "dojo::world::world"; @@ -65,10 +65,10 @@ pub enum AbstractManifestError { Json(#[from] serde_json::Error), } -impl From> for Manifest { +impl From> for Manifest { fn from(value: Manifest) -> Self { Manifest::new( - Contract { + WorldContract { class_hash: value.inner.class_hash, abi: value.inner.abi, original_class_hash: value.inner.original_class_hash, @@ -254,7 +254,7 @@ impl DeploymentManifest { models, contracts, world: Manifest::new( - Contract { + WorldContract { address: Some(world_address), class_hash: world_class_hash, ..Default::default() @@ -607,7 +607,7 @@ impl ManifestMethods for DojoModel { } } -impl ManifestMethods for Contract { +impl ManifestMethods for WorldContract { type OverlayType = OverlayContract; fn abi(&self) -> Option<&AbiFormat> { diff --git a/crates/dojo-world/src/manifest/types.rs b/crates/dojo-world/src/manifest/types.rs index fe8c09dc5e..1ef454c202 100644 --- a/crates/dojo-world/src/manifest/types.rs +++ b/crates/dojo-world/src/manifest/types.rs @@ -30,7 +30,7 @@ pub struct BaseManifest { #[derive(Clone, Debug, Serialize, Deserialize)] #[cfg_attr(test, derive(PartialEq))] pub struct DeploymentManifest { - pub world: Manifest, + pub world: Manifest, pub base: Manifest, pub contracts: Vec>, pub models: Vec>, @@ -117,7 +117,7 @@ pub struct DojoModel { #[derive(Clone, Default, Debug, Serialize, Deserialize)] #[cfg_attr(test, derive(PartialEq))] #[serde(tag = "kind")] -pub struct Contract { +pub struct WorldContract { #[serde_as(as = "UfeHex")] pub class_hash: FieldElement, #[serde_as(as = "UfeHex")] @@ -128,8 +128,8 @@ pub struct Contract { #[serde_as(as = "Option")] pub transaction_hash: Option, pub block_number: Option, - // used by World contract pub seed: Option, + pub metadata: Option, } #[serde_as] @@ -286,3 +286,11 @@ impl PartialEq for AbiFormat { } } } + +#[serde_as] +#[derive(Clone, Default, Debug, Serialize, Deserialize)] +#[cfg_attr(test, derive(PartialEq))] +pub struct WorldMetadata { + pub profile_name: String, + pub rpc_url: String, +} diff --git a/crates/sozo/ops/src/migration/mod.rs b/crates/sozo/ops/src/migration/mod.rs index 9383298d73..2c7a1156f7 100644 --- a/crates/sozo/ops/src/migration/mod.rs +++ b/crates/sozo/ops/src/migration/mod.rs @@ -7,8 +7,8 @@ use dojo_world::contracts::abi::world::ResourceMetadata; use dojo_world::contracts::cairo_utils; use dojo_world::contracts::world::WorldContract; use dojo_world::manifest::{ - AbiFormat, AbstractManifestError, BaseManifest, Contract, DeploymentManifest, DojoContract, - DojoModel, Manifest, ManifestMethods, OverlayManifest, + AbiFormat, AbstractManifestError, BaseManifest, WorldContract as ManifestWorldContract, DeploymentManifest, DojoContract, + DojoModel, Manifest, ManifestMethods, OverlayManifest, WorldMetadata, }; use dojo_world::metadata::dojo_metadata_from_workspace; use dojo_world::migration::contract::ContractMigration; @@ -57,6 +57,7 @@ pub async fn migrate( ws: &Workspace<'_>, world_address: Option, chain_id: String, + rpc_url: String, account: &SingleOwnerAccount, name: Option, dry_run: bool, @@ -104,38 +105,20 @@ where let mut strategy = prepare_migration(&target_dir, diff, name.clone(), world_address, &ui)?; let world_address = strategy.world_address().expect("world address must exist"); - if dry_run { + let migration_output = if dry_run { print_strategy(&ui, account.provider(), &strategy).await; - - update_manifests_and_abis( - ws, - local_manifest, - &profile_dir, - &profile_name, - MigrationOutput { world_address, ..Default::default() }, - name.as_ref(), - ) - .await?; + MigrationOutput { world_address, ..Default::default() } } else { // Migrate according to the diff. match apply_diff(ws, account, None, &mut strategy).await { - Ok(migration_output) => { - update_manifests_and_abis( - ws, - local_manifest, - &profile_dir, - &profile_name, - migration_output, - name.as_ref(), - ) - .await?; - } + Ok(migration_output) => migration_output, Err(e) => { update_manifests_and_abis( ws, local_manifest, &profile_dir, &profile_name, + &rpc_url, MigrationOutput { world_address, ..Default::default() }, name.as_ref(), ) @@ -145,6 +128,17 @@ where } }; + update_manifests_and_abis( + ws, + local_manifest, + &profile_dir, + &profile_name, + &rpc_url, + migration_output, + name.as_ref(), + ) + .await?; + Ok(()) } @@ -153,6 +147,7 @@ async fn update_manifests_and_abis( local_manifest: BaseManifest, profile_dir: &Utf8PathBuf, profile_name: &str, + rpc_url: &str, migration_output: MigrationOutput, salt: Option<&String>, ) -> Result<()> { @@ -164,6 +159,11 @@ async fn update_manifests_and_abis( let mut local_manifest: DeploymentManifest = local_manifest.into(); + local_manifest.world.inner.metadata = Some(WorldMetadata { + profile_name: profile_name.to_string(), + rpc_url: rpc_url.to_string(), + }); + if deployed_path.exists() { let previous_manifest = DeploymentManifest::load_from_path(&deployed_path)?; local_manifest.merge_from_previous(previous_manifest); @@ -261,7 +261,7 @@ async fn update_manifest_abis( manifest.inner.set_abi(Some(AbiFormat::Path(deployed_relative_path))); } - inner_helper::(profile_dir, profile_name, &mut local_manifest.world).await; + inner_helper::(profile_dir, profile_name, &mut local_manifest.world).await; for contract in local_manifest.contracts.iter_mut() { inner_helper::(profile_dir, profile_name, contract).await; diff --git a/examples/spawn-and-move/manifests/dev/manifest.json b/examples/spawn-and-move/manifests/dev/manifest.json index 8870aef2b3..bb9ce0f641 100644 --- a/examples/spawn-and-move/manifests/dev/manifest.json +++ b/examples/spawn-and-move/manifests/dev/manifest.json @@ -1,6 +1,6 @@ { "world": { - "kind": "Contract", + "kind": "WorldContract", "class_hash": "0x799bc4e9da10bfb3dd88e6f223c9cfbf7745435cd14f5d69675ea448e578cd", "original_class_hash": "0x799bc4e9da10bfb3dd88e6f223c9cfbf7745435cd14f5d69675ea448e578cd", "abi": [ @@ -664,6 +664,10 @@ "transaction_hash": "0x6afefdcc49b3563a4f3657900ba71e9f9356861b15b942a73f2018f046a1048", "block_number": 3, "seed": "dojo_examples", + "metadata": { + "profile_name": "dev", + "rpc_url": "http://localhost:5050/" + }, "name": "dojo::world::world" }, "base": { diff --git a/examples/spawn-and-move/manifests/dev/manifest.toml b/examples/spawn-and-move/manifests/dev/manifest.toml index 4da19e7528..156abd3709 100644 --- a/examples/spawn-and-move/manifests/dev/manifest.toml +++ b/examples/spawn-and-move/manifests/dev/manifest.toml @@ -1,5 +1,5 @@ [world] -kind = "Contract" +kind = "WorldContract" class_hash = "0x799bc4e9da10bfb3dd88e6f223c9cfbf7745435cd14f5d69675ea448e578cd" original_class_hash = "0x799bc4e9da10bfb3dd88e6f223c9cfbf7745435cd14f5d69675ea448e578cd" abi = "abis/deployments/dojo_world_world.json" @@ -9,6 +9,10 @@ block_number = 3 seed = "dojo_examples" name = "dojo::world::world" +[world.metadata] +profile_name = "dev" +rpc_url = "http://localhost:5050/" + [base] kind = "Class" class_hash = "0x679177a2cb757694ac4f326d01052ff0963eac0bc2a17116a2b87badcdf6f76"