Skip to content

Commit

Permalink
[CLI] --json output (#2153)
Browse files Browse the repository at this point in the history
Closes #2146 

### Checklist
- [x] Relevant issue is linked
- [ ] Docs updated/issue for docs created
- [ ] Added relevant tests


## Declare
--json

```
{
  "class_hash": "0x8448a68b5ea1affc45e3fd4b8b480ea36a51dc34e337a16d2567d32d0c6f8a",
  "command": "Declare",
  "transaction_hash": "0x41753d391e9b238a608a3866f22191a6a956cb42fb4e3857f0af9197a0d3b82"
}
```

--int-format

```
command: Declare
class_hash: 233725228316200119834039379114988415372286690470331219113395524995289739146
transaction_hash: 1850467425684918101618529434157632339580094806406252409582129610526565415810
```

## Deploy
--json

```
{
  "command": "Deploy",
  "contract_address": "0x1ceadaa5f34ace657469c74c1eacc02295faec59dc58f814538fd626cbee1db",
  "transaction_hash": "0x6ee128bd8db9361cdfbf245e92660663d2f7a44093d0593fb13ca58c39fe013"
}
```

--int-format --json

```
{
  "command": "Deploy",
  "contract_address": "817481939262878850386591849661418498787336656885023715447744806500308017627",
  "transaction_hash": "3134514694621465973511654855236921494481584513720403914416829849016788312083"
}
```
  • Loading branch information
war-in authored Jun 30, 2023
1 parent dd711b2 commit 5502362
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 27 deletions.
1 change: 1 addition & 0 deletions cast/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cast/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ starknet = { git = "https://github.com/xJonathanLEI/starknet-rs" }
tokio = { version = "1.28.2", features = ["full"] }
url = "2.2.2"
rand = "0.8.5"
primitive-types = "0.12.1"
shellexpand = "3.1.0"

[dev-dependencies]
Expand Down
48 changes: 40 additions & 8 deletions cast/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use anyhow::{anyhow, Context, Error, Result};
use camino::Utf8PathBuf;
use primitive_types::U256;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use starknet::core::types::{
BlockId,
BlockTag::{Latest, Pending},
Expand Down Expand Up @@ -220,15 +222,45 @@ pub async fn handle_wait_for_tx_result<T>(
}
}

pub fn print_formatted(text: &str, value: FieldElement, int_format: bool) {
println!(
"{text}{}",
if int_format {
format!("{value}")
} else {
format!("{value:#x}")
pub fn print_formatted(
mut output: Vec<(&str, String)>,
int_format: bool,
json: bool,
error: bool,
) -> Result<()> {
if !int_format {
output = output
.into_iter()
.map(|(key, value)| {
if let Ok(int_value) = U256::from_dec_str(&value) {
(key, format!("{int_value:#x}"))
} else {
(key, value)
}
})
.collect();
}

if json {
let json_output: HashMap<&str, String> = output.into_iter().collect();
let json_value: Value = serde_json::to_value(json_output)?;

write_to_output(serde_json::to_string_pretty(&json_value)?, error);
} else {
for (key, value) in &output {
write_to_output(format!("{key}: {value}"), error);
}
);
}

Ok(())
}

fn write_to_output<T: std::fmt::Display>(value: T, error: bool) {
if error {
eprintln!("{value}");
} else {
println!("{value}");
}
}

#[cfg(test)]
Expand Down
117 changes: 98 additions & 19 deletions cast/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ struct Cli {
#[clap(short, long)]
int_format: bool,

/// If passed, output will be displayed in json format
#[clap(short, long)]
json: bool,

#[command(subcommand)]
command: Commands,
}
Expand All @@ -55,6 +59,7 @@ enum Commands {
}

#[tokio::main]
#[allow(clippy::too_many_lines)]
async fn main() -> Result<()> {
let cli = Cli::parse();

Expand All @@ -74,26 +79,44 @@ async fn main() -> Result<()> {
let mut account =
get_account(&cli.account, &cli.accounts_file_path, &provider, &network)?;

let declared_contract = starknet_commands::declare::declare(
let result = starknet_commands::declare::declare(
&declare.sierra_contract_path,
&declare.casm_contract_path,
declare.max_fee,
&mut account,
)
.await?;

print_formatted("Class hash: ", declared_contract.class_hash, cli.int_format);
print_formatted(
"Transaction hash: ",
declared_contract.transaction_hash,
cli.int_format,
);
.await;

match result {
Ok(declared_contract) => print_formatted(
vec![
("command", "Declare".to_string()),
("class_hash", format!("{}", declared_contract.class_hash)),
(
"transaction_hash",
format!("{}", declared_contract.transaction_hash),
),
],
cli.int_format,
cli.json,
false,
)?,
Err(error) => {
print_formatted(
vec![("error", error.to_string())],
cli.int_format,
cli.json,
true,
)?;
}
}

Ok(())
}
Commands::Deploy(deploy) => {
let account = get_account(&cli.account, &cli.accounts_file_path, &provider, &network)?;

let (transaction_hash, contract_address) = starknet_commands::deploy::deploy(
let result = starknet_commands::deploy::deploy(
&deploy.class_hash,
deploy
.constructor_calldata
Expand All @@ -105,10 +128,28 @@ async fn main() -> Result<()> {
deploy.max_fee,
&account,
)
.await?;

print_formatted("Contract address: ", contract_address, cli.int_format);
print_formatted("Transaction hash: ", transaction_hash, cli.int_format);
.await;

match result {
Ok((transaction_hash, contract_address)) => print_formatted(
vec![
("command", "Deploy".to_string()),
("contract_address", format!("{contract_address}")),
("transaction_hash", format!("{transaction_hash}")),
],
cli.int_format,
cli.json,
false,
)?,
Err(error) => {
print_formatted(
vec![("error", error.to_string())],
cli.int_format,
cli.json,
true,
)?;
}
}

Ok(())
}
Expand All @@ -122,24 +163,62 @@ async fn main() -> Result<()> {
&provider,
block_id.as_ref(),
)
.await?;
.await;

match result {
Ok(response) => print_formatted(
vec![
("command", "Call".to_string()),
("response", format!("{response:?}")),
],
cli.int_format,
cli.json,
false,
)?,
Err(error) => {
print_formatted(
vec![("error", error.to_string())],
cli.int_format,
cli.json,
true,
)?;
}
}

println!("Call response: {result:?}");
Ok(())
}
Commands::Invoke(invoke) => {
let mut account =
get_account(&cli.account, &cli.accounts_file_path, &provider, &network)?;
let transaction_hash = starknet_commands::invoke::invoke(
let result = starknet_commands::invoke::invoke(
&invoke.contract_address,
&invoke.entry_point_name,
invoke.calldata.iter().map(AsRef::as_ref).collect(),
invoke.max_fee,
&mut account,
)
.await?;
.await;

match result {
Ok(transaction_hash) => print_formatted(
vec![
("command", "Invoke".to_string()),
("transaction_hash", format!("{transaction_hash}")),
],
cli.int_format,
cli.json,
false,
)?,
Err(error) => {
print_formatted(
vec![("error", error.to_string())],
cli.int_format,
cli.json,
true,
)?;
}
}

print_formatted("Transaction hash: ", transaction_hash, cli.int_format);
Ok(())
}
}
Expand Down

0 comments on commit 5502362

Please sign in to comment.