stylus_tools/core/
check.rs1use std::{env, path::Path};
5
6use alloy::{primitives::Address, providers::Provider};
7use bytesize::ByteSize;
8
9use crate::{
10 core::{
11 activation::{self, ActivationConfig},
12 build::{build_contract, BuildConfig},
13 project::{
14 contract::{Contract, ContractStatus},
15 hash_project, ProjectConfig, ProjectHash,
16 },
17 },
18 utils::format_file_size,
19 wasm::process_wasm_file,
20};
21
22#[derive(Debug, Default)]
23pub struct CheckConfig {
24 pub activation: ActivationConfig,
25 pub build: BuildConfig,
26 pub project: ProjectConfig,
27}
28
29#[derive(Debug, thiserror::Error)]
30pub enum CheckError {
31 #[error("io error: {0}")]
32 Io(#[from] std::io::Error),
33 #[error("cargo metadata error: {0}")]
34 CargoMetadata(#[from] cargo_metadata::Error),
35
36 #[error("{0}")]
37 Activation(#[from] crate::core::activation::ActivationError),
38 #[error("{0}")]
39 Build(#[from] crate::core::build::BuildError),
40 #[error("{0}")]
41 Contract(#[from] crate::core::project::contract::ContractError),
42 #[error("{0}")]
43 Project(#[from] crate::core::project::ProjectError),
44 #[error("{0}")]
45 ProcessWasm(#[from] crate::wasm::ProcessWasmFileError),
46}
47
48pub async fn check_contract(
52 contract: &Contract,
53 address: Option<Address>,
54 config: &CheckConfig,
55 provider: &impl Provider,
56) -> Result<ContractStatus, CheckError> {
57 let wasm_file = build_contract(contract, &config.build)?;
58 let dir = env::current_dir()?;
59 let project_hash = hash_project(dir, &config.project, &config.build)?;
60 let status = check_wasm_file(&wasm_file, project_hash, address, config, provider).await?;
61 Ok(status)
62}
63
64pub async fn check_wasm_file(
65 wasm_file: impl AsRef<Path>,
66 project_hash: ProjectHash,
67 contract_address: Option<Address>,
68 config: &CheckConfig,
69 provider: &impl Provider,
70) -> Result<ContractStatus, CheckError> {
71 debug!(@grey, "reading wasm file at {}", wasm_file.as_ref().to_string_lossy().lavender());
72 let processed = process_wasm_file(wasm_file, project_hash)?;
73 info!(@grey, "contract size: {}", format_file_size(ByteSize::b(processed.code.len() as u64), ByteSize::kib(16), ByteSize::kib(24)));
74 debug!(@grey, "wasm size: {}", format_file_size(ByteSize::b(processed.wasm.len() as u64), ByteSize::kib(96), ByteSize::kib(128)));
75
76 debug!(@grey, "connecting to RPC: {:?}", provider.root());
79 let codehash = processed.codehash();
80 if Contract::exists(codehash, &provider).await? {
81 return Ok(ContractStatus::Active {
82 code: processed.code,
83 });
84 }
85
86 let contract_address = contract_address.unwrap_or_else(Address::random);
87 let fee = activation::data_fee(
88 processed.code.clone(),
89 contract_address,
90 &config.activation,
91 provider,
92 )
93 .await?;
94 Ok(ContractStatus::Ready {
95 code: processed.code,
96 fee,
97 })
98}