diff --git a/Cargo.lock b/Cargo.lock index fdcb05d..32752ce 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2663,6 +2663,7 @@ dependencies = [ "env_logger", "hex", "hex-literal", + "log", "num-bigint", "regex", "rpassword", diff --git a/Cargo.toml b/Cargo.toml index 7c99f2b..27b282f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ colored_json = "3.2.0" env_logger = "0.10.0" hex = "0.4.3" hex-literal = "0.4.1" +log = "0.4.19" num-bigint = "0.4.3" regex = "1.8.4" rpassword = "7.2.0" diff --git a/src/main.rs b/src/main.rs index ec8c4f5..1b3c654 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,7 @@ mod provider; mod signer; mod subcommands; mod utils; +mod verbosity; const VERSION_STRING: &str = concat!(env!("CARGO_PKG_VERSION"), " (", env!("VERGEN_GIT_SHA"), ")"); @@ -101,8 +102,6 @@ enum Subcommands { #[tokio::main] async fn main() { - env_logger::init(); - if let Err(err) = run_command(Cli::parse()).await { eprintln!("{}", format!("Error: {err}").red()); std::process::exit(1); diff --git a/src/subcommands/account/deploy.rs b/src/subcommands/account/deploy.rs index d7484f0..3f868f1 100644 --- a/src/subcommands/account/deploy.rs +++ b/src/subcommands/account/deploy.rs @@ -14,6 +14,7 @@ use crate::{ account::{AccountConfig, AccountVariant, DeployedStatus, DeploymentStatus}, signer::SignerArgs, utils::watch_tx, + verbosity::VerbosityArgs, ProviderArgs, }; @@ -30,10 +31,14 @@ pub struct Deploy { estimate_only: bool, #[clap(help = "Path to the account config file")] file: PathBuf, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl Deploy { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = Arc::new(self.provider.into_provider()); let signer = Arc::new(self.signer.into_signer()?); diff --git a/src/subcommands/account/fetch.rs b/src/subcommands/account/fetch.rs index b9e97e1..9bf9ce4 100644 --- a/src/subcommands/account/fetch.rs +++ b/src/subcommands/account/fetch.rs @@ -14,6 +14,7 @@ use crate::{ AccountConfig, AccountVariant, AccountVariantType, DeployedStatus, DeploymentStatus, OzAccountConfig, KNOWN_ACCOUNT_CLASSES, }, + verbosity::VerbosityArgs, ProviderArgs, }; @@ -27,10 +28,14 @@ pub struct Fetch { output: Option, #[clap(help = "Contract address")] address: String, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl Fetch { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + // We allow not saving the config to just identify the account contract if self.output.is_none() { eprintln!( diff --git a/src/subcommands/block.rs b/src/subcommands/block.rs index 45505b6..f6f3a3c 100644 --- a/src/subcommands/block.rs +++ b/src/subcommands/block.rs @@ -3,7 +3,7 @@ use clap::Parser; use colored_json::{ColorMode, Output}; use starknet::providers::Provider; -use crate::{utils::parse_block_id, ProviderArgs}; +use crate::{utils::parse_block_id, verbosity::VerbosityArgs, ProviderArgs}; #[derive(Debug, Parser)] pub struct Block { @@ -16,10 +16,14 @@ pub struct Block { help = "Block number, hash, or tag (latest/pending)" )] block_id: String, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl Block { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = self.provider.into_provider(); let block_id = parse_block_id(&self.block_id)?; diff --git a/src/subcommands/block_hash.rs b/src/subcommands/block_hash.rs index 3b6f569..3f8ab3e 100644 --- a/src/subcommands/block_hash.rs +++ b/src/subcommands/block_hash.rs @@ -2,16 +2,20 @@ use anyhow::Result; use clap::Parser; use starknet::providers::Provider; -use crate::ProviderArgs; +use crate::{verbosity::VerbosityArgs, ProviderArgs}; #[derive(Debug, Parser)] pub struct BlockHash { #[clap(flatten)] provider: ProviderArgs, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl BlockHash { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = self.provider.into_provider(); let block = provider.block_hash_and_number().await?; diff --git a/src/subcommands/block_number.rs b/src/subcommands/block_number.rs index 3eec518..3b6ec95 100644 --- a/src/subcommands/block_number.rs +++ b/src/subcommands/block_number.rs @@ -2,16 +2,20 @@ use anyhow::Result; use clap::Parser; use starknet::providers::Provider; -use crate::ProviderArgs; +use crate::{verbosity::VerbosityArgs, ProviderArgs}; #[derive(Debug, Parser)] pub struct BlockNumber { #[clap(flatten)] provider: ProviderArgs, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl BlockNumber { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = self.provider.into_provider(); let block = provider.block_hash_and_number().await?; diff --git a/src/subcommands/block_time.rs b/src/subcommands/block_time.rs index 10c9b4e..864720e 100644 --- a/src/subcommands/block_time.rs +++ b/src/subcommands/block_time.rs @@ -3,7 +3,7 @@ use chrono::{TimeZone, Utc}; use clap::Parser; use starknet::{core::types::MaybePendingBlockWithTxHashes, providers::Provider}; -use crate::{utils::parse_block_id, ProviderArgs}; +use crate::{utils::parse_block_id, verbosity::VerbosityArgs, ProviderArgs}; #[derive(Debug, Parser)] pub struct BlockTime { @@ -26,10 +26,14 @@ pub struct BlockTime { help = "Block number, hash, or tag (latest/pending)" )] block_id: String, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl BlockTime { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = self.provider.into_provider(); let block_id = parse_block_id(&self.block_id)?; diff --git a/src/subcommands/call.rs b/src/subcommands/call.rs index 9e02ff4..6028d73 100644 --- a/src/subcommands/call.rs +++ b/src/subcommands/call.rs @@ -10,7 +10,9 @@ use starknet::{ providers::Provider, }; -use crate::{address_book::AddressBookResolver, decode::FeltDecoder, ProviderArgs}; +use crate::{ + address_book::AddressBookResolver, decode::FeltDecoder, verbosity::VerbosityArgs, ProviderArgs, +}; #[derive(Debug, Parser)] pub struct Call { @@ -22,10 +24,14 @@ pub struct Call { selector: String, #[clap(help = "Raw function call arguments")] calldata: Vec, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl Call { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = Arc::new(self.provider.into_provider()); let felt_decoder = FeltDecoder::new(AddressBookResolver::new(provider.clone())); diff --git a/src/subcommands/chain_id.rs b/src/subcommands/chain_id.rs index 30f3e74..7fd622e 100644 --- a/src/subcommands/chain_id.rs +++ b/src/subcommands/chain_id.rs @@ -2,7 +2,7 @@ use anyhow::Result; use clap::Parser; use starknet::{core::utils::parse_cairo_short_string, providers::Provider}; -use crate::ProviderArgs; +use crate::{verbosity::VerbosityArgs, ProviderArgs}; #[derive(Debug, Parser)] pub struct ChainId { @@ -20,10 +20,14 @@ pub struct ChainId { help = "Block number, hash, or tag (latest/pending)" )] block_id: String, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl ChainId { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = self.provider.into_provider(); let raw_chain_id = provider.chain_id().await?; diff --git a/src/subcommands/class_at.rs b/src/subcommands/class_at.rs index ea96622..eaadb92 100644 --- a/src/subcommands/class_at.rs +++ b/src/subcommands/class_at.rs @@ -6,7 +6,7 @@ use starknet::{ providers::Provider, }; -use crate::ProviderArgs; +use crate::{verbosity::VerbosityArgs, ProviderArgs}; #[derive(Debug, Parser)] pub struct ClassAt { @@ -14,10 +14,14 @@ pub struct ClassAt { provider: ProviderArgs, #[clap(help = "Contract address")] address: String, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl ClassAt { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = self.provider.into_provider(); let address = FieldElement::from_hex_be(&self.address)?; diff --git a/src/subcommands/class_by_hash.rs b/src/subcommands/class_by_hash.rs index 5f51cfd..0d4b8ba 100644 --- a/src/subcommands/class_by_hash.rs +++ b/src/subcommands/class_by_hash.rs @@ -6,7 +6,7 @@ use starknet::{ providers::Provider, }; -use crate::ProviderArgs; +use crate::{verbosity::VerbosityArgs, ProviderArgs}; #[derive(Debug, Parser)] pub struct ClassByHash { @@ -14,10 +14,14 @@ pub struct ClassByHash { provider: ProviderArgs, #[clap(help = "Class hash")] hash: String, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl ClassByHash { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = self.provider.into_provider(); let class_hash = FieldElement::from_hex_be(&self.hash)?; diff --git a/src/subcommands/class_hash_at.rs b/src/subcommands/class_hash_at.rs index 0d2626e..573c2cc 100644 --- a/src/subcommands/class_hash_at.rs +++ b/src/subcommands/class_hash_at.rs @@ -5,7 +5,7 @@ use starknet::{ providers::Provider, }; -use crate::ProviderArgs; +use crate::{verbosity::VerbosityArgs, ProviderArgs}; #[derive(Debug, Parser)] pub struct ClassHashAt { @@ -13,10 +13,14 @@ pub struct ClassHashAt { provider: ProviderArgs, #[clap(help = "Contract address")] address: String, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl ClassHashAt { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = self.provider.into_provider(); let address = FieldElement::from_hex_be(&self.address)?; diff --git a/src/subcommands/declare.rs b/src/subcommands/declare.rs index 2423805..c268c45 100644 --- a/src/subcommands/declare.rs +++ b/src/subcommands/declare.rs @@ -17,6 +17,7 @@ use crate::{ casm::{CasmArgs, CasmHashSource}, signer::SignerArgs, utils::watch_tx, + verbosity::VerbosityArgs, ProviderArgs, }; @@ -43,10 +44,14 @@ pub struct Declare { watch: bool, #[clap(help = "Path to contract artifact file")] file: PathBuf, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl Declare { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = Arc::new(self.provider.into_provider()); if !self.account.exists() { diff --git a/src/subcommands/deploy.rs b/src/subcommands/deploy.rs index f1b6915..6d80859 100644 --- a/src/subcommands/deploy.rs +++ b/src/subcommands/deploy.rs @@ -20,6 +20,7 @@ use crate::{ decode::FeltDecoder, signer::SignerArgs, utils::watch_tx, + verbosity::VerbosityArgs, ProviderArgs, }; @@ -58,10 +59,14 @@ pub struct Deploy { class_hash: String, #[clap(help = "Raw constructor arguments")] ctor_args: Vec, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl Deploy { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = Arc::new(self.provider.into_provider()); let felt_decoder = FeltDecoder::new(AddressBookResolver::new(provider.clone())); diff --git a/src/subcommands/invoke.rs b/src/subcommands/invoke.rs index 20635f3..483c385 100644 --- a/src/subcommands/invoke.rs +++ b/src/subcommands/invoke.rs @@ -18,6 +18,7 @@ use crate::{ decode::FeltDecoder, signer::SignerArgs, utils::watch_tx, + verbosity::VerbosityArgs, ProviderArgs, }; @@ -42,10 +43,14 @@ pub struct Invoke { watch: bool, #[clap(help = "One or more contract calls. See documentation for more details")] calls: Vec, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl Invoke { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = Arc::new(self.provider.into_provider()); let felt_decoder = FeltDecoder::new(AddressBookResolver::new(provider.clone())); diff --git a/src/subcommands/nonce.rs b/src/subcommands/nonce.rs index 1d42001..3bbdca5 100644 --- a/src/subcommands/nonce.rs +++ b/src/subcommands/nonce.rs @@ -5,7 +5,7 @@ use starknet::{ providers::Provider, }; -use crate::ProviderArgs; +use crate::{verbosity::VerbosityArgs, ProviderArgs}; #[derive(Debug, Parser)] pub struct Nonce { @@ -13,10 +13,14 @@ pub struct Nonce { provider: ProviderArgs, #[clap(help = "Contract address")] address: String, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl Nonce { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = self.provider.into_provider(); let address = FieldElement::from_hex_be(&self.address)?; diff --git a/src/subcommands/state_update.rs b/src/subcommands/state_update.rs index f3dd1d0..3dcb450 100644 --- a/src/subcommands/state_update.rs +++ b/src/subcommands/state_update.rs @@ -3,7 +3,7 @@ use clap::Parser; use colored_json::{ColorMode, Output}; use starknet::providers::Provider; -use crate::{utils::parse_block_id, ProviderArgs}; +use crate::{utils::parse_block_id, verbosity::VerbosityArgs, ProviderArgs}; #[derive(Debug, Parser)] pub struct StateUpdate { @@ -14,10 +14,14 @@ pub struct StateUpdate { help = "Block number, hash, or tag (latest/pending)" )] block_id: String, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl StateUpdate { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = self.provider.into_provider(); let block_id = parse_block_id(&self.block_id)?; diff --git a/src/subcommands/storage.rs b/src/subcommands/storage.rs index 3c342a2..281f97b 100644 --- a/src/subcommands/storage.rs +++ b/src/subcommands/storage.rs @@ -5,7 +5,7 @@ use starknet::{ providers::Provider, }; -use crate::ProviderArgs; +use crate::{verbosity::VerbosityArgs, ProviderArgs}; #[derive(Debug, Parser)] pub struct Storage { @@ -15,10 +15,14 @@ pub struct Storage { address: String, #[clap(help = "Storage key")] key: String, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl Storage { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = self.provider.into_provider(); let address = FieldElement::from_hex_be(&self.address)?; let key = FieldElement::from_hex_be(&self.key)?; diff --git a/src/subcommands/syncing.rs b/src/subcommands/syncing.rs index f80a225..f38ced3 100644 --- a/src/subcommands/syncing.rs +++ b/src/subcommands/syncing.rs @@ -3,16 +3,20 @@ use clap::Parser; use colored_json::{ColorMode, Output}; use starknet::{core::types::SyncStatusType, providers::Provider}; -use crate::ProviderArgs; +use crate::{verbosity::VerbosityArgs, ProviderArgs}; #[derive(Debug, Parser)] pub struct Syncing { #[clap(flatten)] provider: ProviderArgs, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl Syncing { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = self.provider.into_provider(); let sync_status = provider.syncing().await?; diff --git a/src/subcommands/transaction.rs b/src/subcommands/transaction.rs index 0527d3b..8cf6cd2 100644 --- a/src/subcommands/transaction.rs +++ b/src/subcommands/transaction.rs @@ -3,7 +3,7 @@ use clap::Parser; use colored_json::{ColorMode, Output}; use starknet::{core::types::FieldElement, providers::Provider}; -use crate::ProviderArgs; +use crate::{verbosity::VerbosityArgs, ProviderArgs}; #[derive(Debug, Parser)] pub struct Transaction { @@ -11,10 +11,14 @@ pub struct Transaction { provider: ProviderArgs, #[clap(help = "Transaction hash")] hash: String, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl Transaction { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = self.provider.into_provider(); let transaction_hash = FieldElement::from_hex_be(&self.hash)?; diff --git a/src/subcommands/transaction_receipt.rs b/src/subcommands/transaction_receipt.rs index 8db8c11..1a578d9 100644 --- a/src/subcommands/transaction_receipt.rs +++ b/src/subcommands/transaction_receipt.rs @@ -3,7 +3,7 @@ use clap::Parser; use colored_json::{ColorMode, Output}; use starknet::{core::types::FieldElement, providers::Provider}; -use crate::ProviderArgs; +use crate::{verbosity::VerbosityArgs, ProviderArgs}; #[derive(Debug, Parser)] pub struct TransactionReceipt { @@ -11,10 +11,14 @@ pub struct TransactionReceipt { provider: ProviderArgs, #[clap(help = "Transaction hash")] hash: String, + #[clap(flatten)] + verbosity: VerbosityArgs, } impl TransactionReceipt { pub async fn run(self) -> Result<()> { + self.verbosity.setup_logging(); + let provider = self.provider.into_provider(); let transaction_hash = FieldElement::from_hex_be(&self.hash)?; diff --git a/src/verbosity.rs b/src/verbosity.rs new file mode 100644 index 0000000..af6a54a --- /dev/null +++ b/src/verbosity.rs @@ -0,0 +1,21 @@ +use clap::Parser; +use env_logger::Builder; +use log::LevelFilter; + +#[derive(Debug, Clone, Parser)] +pub struct VerbosityArgs { + #[clap(long, help = "Log raw request/response traffic of providers")] + log_traffic: bool, +} + +impl VerbosityArgs { + pub fn setup_logging(&self) { + let mut builder = Builder::new(); + + if self.log_traffic { + builder.filter_module("starknet_providers", LevelFilter::Trace); + } + + builder.init(); + } +}