diff --git a/src/subcommands/declare.rs b/src/subcommands/declare.rs index 7855c39..3e4bef6 100644 --- a/src/subcommands/declare.rs +++ b/src/subcommands/declare.rs @@ -7,9 +7,9 @@ use starknet::{ accounts::{Account, SingleOwnerAccount}, core::types::{ contract::{legacy::LegacyContractClass, CompiledClass, SierraClass}, - BlockId, BlockTag, FieldElement, + BlockId, BlockTag, FieldElement, StarknetError, }, - providers::Provider, + providers::{Provider, ProviderError}, }; use crate::{ @@ -68,8 +68,6 @@ impl Declare { SingleOwnerAccount::new(provider.clone(), signer, account_address, chain_id); account.set_block_id(BlockId::Tag(BlockTag::Pending)); - // TODO: check if class has already been declared - // Working around a deserialization bug in `starknet-rs`: // https://github.com/xJonathanLEI/starknet-rs/issues/392 @@ -80,6 +78,11 @@ impl Declare { // Declaring Cairo 1 class let class_hash = class.class_hash()?; + // TODO: add option to skip checking + if Self::check_already_declared(&provider, class_hash).await? { + return Ok(()); + } + let casm_source = self.casm.into_casm_hash_source(&provider).await?; if !self.estimate_only { @@ -144,6 +147,11 @@ impl Declare { // Declaring Cairo 0 class let class_hash = class.class_hash()?; + // TODO: add option to skip checking + if Self::check_already_declared(&provider, class_hash).await? { + return Ok(()); + } + if !self.estimate_only { eprintln!( "Declaring Cairo 0 (deprecated) class: {}", @@ -195,4 +203,24 @@ impl Declare { Ok(()) } + + async fn check_already_declared

(provider: P, class_hash: FieldElement) -> Result + where + P: Provider, + P::Error: 'static, + { + match provider + .get_class(BlockId::Tag(BlockTag::Pending), class_hash) + .await + { + Ok(_) => { + eprintln!("Not declaring class as it's already declared. Class hash:"); + println!("{}", format!("{:#064x}", class_hash).bright_yellow()); + + Ok(true) + } + Err(ProviderError::StarknetError(StarknetError::ClassHashNotFound)) => Ok(false), + Err(err) => Err(err.into()), + } + } }