Skip to content

Commit da66ee2

Browse files
authored
fix: display max_fee as int (#763)
<!-- Reference any GitHub issues resolved by this PR --> Closes #410 ## Introduced changes <!-- A brief description of the changes --> - display `max_fee` as int unless `--hex-format` is specified for it ## Breaking changes <!-- List of all breaking changes, if applicable --> ## Checklist <!-- Make sure all of these are complete --> - [x] Linked relevant issue - [x] Updated relevant documentation - [x] Added relevant tests - [x] Performed self-review of the code - [x] Added changes to `CHANGELOG.md`
1 parent c6fc7f1 commit da66ee2

File tree

7 files changed

+180
-50
lines changed

7 files changed

+180
-50
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ Read more [here](https://foundry-rs.github.io/starknet-foundry/appendix/forge.ht
2828

2929
- `show-config` subcommand to display currently used configuration
3030
- `account delete` command for removing accounts from the accounts file
31+
- `--hex-format` flag has been added
32+
33+
#### Removed
34+
- `-i` short for `--int-format` is removed, now have to use the full form `--int-format`
3135

3236
## [0.8.3] - 2023-10-17
3337

crates/cast/src/helpers/response_structs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ pub struct CallResponse {
2727
#[derive(Serialize)]
2828
pub struct AccountCreateResponse {
2929
pub address: FieldElement,
30-
pub max_fee: FieldElement,
30+
pub max_fee: u64,
3131
pub add_profile: String,
3232
}
3333

crates/cast/src/lib.rs

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use anyhow::{anyhow, bail, Context, Error, Result};
22
use camino::Utf8PathBuf;
33
use helpers::constants::{DEFAULT_RETRIES, KEYSTORE_PASSWORD_ENV_VAR, UDC_ADDRESS};
4-
use primitive_types::U256;
54
use rand::rngs::OsRng;
65
use rand::RngCore;
76
use serde::{Deserialize, Serialize};
@@ -33,6 +32,7 @@ use starknet::{
3332
providers::{MaybeUnknownErrorCode, StarknetErrorWithMessage},
3433
};
3534
use std::collections::HashMap;
35+
use std::str::FromStr;
3636
use std::thread::sleep;
3737
use std::time::Duration;
3838
use std::{env, fs};
@@ -50,6 +50,38 @@ struct Account {
5050
class_hash: Option<String>,
5151
}
5252

53+
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
54+
pub enum ValueFormat {
55+
// Addresses as hex, fees as int
56+
Default,
57+
// everything as int
58+
Int,
59+
// everything as hex
60+
Hex,
61+
}
62+
63+
impl ValueFormat {
64+
#[must_use]
65+
pub fn format_u64(&self, input: u64) -> String {
66+
match self {
67+
ValueFormat::Default | ValueFormat::Int => format!("{input}"),
68+
ValueFormat::Hex => format!("{input:#x}"),
69+
}
70+
}
71+
72+
#[must_use]
73+
pub fn format_str(&self, input: &str) -> String {
74+
if let Ok(field) = FieldElement::from_str(input) {
75+
return match self {
76+
ValueFormat::Int => format!("{field:#}"),
77+
ValueFormat::Hex | ValueFormat::Default => format!("{field:#x}"),
78+
};
79+
}
80+
81+
input.to_string()
82+
}
83+
}
84+
5385
pub fn get_provider(url: &str) -> Result<JsonRpcClient<HttpTransport>> {
5486
raise_if_empty(url, "RPC url")?;
5587
let parsed_url = Url::parse(url)?;
@@ -305,25 +337,7 @@ pub async fn handle_wait_for_tx<T>(
305337
Ok(return_value)
306338
}
307339

308-
pub fn print_formatted(
309-
mut output: Vec<(&str, String)>,
310-
int_format: bool,
311-
json: bool,
312-
error: bool,
313-
) -> Result<()> {
314-
if !int_format {
315-
output = output
316-
.into_iter()
317-
.map(|(key, value)| {
318-
if let Ok(int_value) = U256::from_dec_str(&value) {
319-
(key, format!("{int_value:#x}"))
320-
} else {
321-
(key, value)
322-
}
323-
})
324-
.collect();
325-
}
326-
340+
pub fn print_formatted(output: Vec<(&str, String)>, json: bool, error: bool) -> Result<()> {
327341
if json {
328342
let json_output: HashMap<&str, String> = output.into_iter().collect();
329343
let json_value: Value = serde_json::to_value(json_output)?;
@@ -341,7 +355,7 @@ pub fn print_formatted(
341355
pub fn print_command_result<T: Serialize>(
342356
command: &str,
343357
result: &mut Result<T>,
344-
int_format: bool,
358+
value_format: ValueFormat,
345359
json: bool,
346360
) -> Result<()> {
347361
let mut output = vec![("command", command.to_string())];
@@ -359,8 +373,16 @@ pub fn print_command_result<T: Serialize>(
359373
.expect("Invalid JSON value")
360374
.iter()
361375
.filter_map(|(k, v)| {
362-
// skip values that are not convertable to string
363-
v.as_str().map(|value| (k.as_str(), value.to_string()))
376+
let value = match v {
377+
Value::Number(n) => {
378+
let n = n.as_u64().expect("found unexpected value");
379+
value_format.format_u64(n)
380+
}
381+
Value::String(s) => value_format.format_str(s),
382+
_ => return None,
383+
};
384+
385+
Some((k.as_str(), value))
364386
})
365387
.collect::<Vec<(&str, String)>>(),
366388
);
@@ -370,7 +392,7 @@ pub fn print_command_result<T: Serialize>(
370392
error = true;
371393
}
372394
};
373-
print_formatted(output, int_format, json, error)
395+
print_formatted(output, json, error)
374396
}
375397

376398
fn write_to_output<T: std::fmt::Display>(value: T, error: bool) {

crates/cast/src/main.rs

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use cast::helpers::constants::{DEFAULT_ACCOUNTS_FILE, DEFAULT_MULTICALL_CONTENTS
1010
use cast::helpers::scarb_utils::{parse_scarb_config, CastConfig};
1111
use cast::{
1212
chain_id_to_network_name, get_account, get_block_id, get_chain_id, get_provider,
13-
print_command_result,
13+
print_command_result, ValueFormat,
1414
};
1515
use clap::{Parser, Subcommand};
1616

@@ -19,6 +19,7 @@ mod starknet_commands;
1919
#[derive(Parser)]
2020
#[command(version)]
2121
#[command(about = "Cast - a Starknet Foundry CLI", long_about = None)]
22+
#[allow(clippy::struct_excessive_bools)]
2223
struct Cli {
2324
/// Profile name in Scarb.toml config file
2425
#[clap(short, long)]
@@ -46,10 +47,14 @@ struct Cli {
4647
#[clap(short, long)]
4748
keystore: Option<Utf8PathBuf>,
4849

49-
/// If passed, values will be displayed as integers, otherwise as hexes
50-
#[clap(short, long)]
50+
/// If passed, values will be displayed as integers
51+
#[clap(long, conflicts_with = "hex_format")]
5152
int_format: bool,
5253

54+
/// If passed, values will be displayed as hex
55+
#[clap(long, conflicts_with = "int_format")]
56+
hex_format: bool,
57+
5358
/// If passed, output will be displayed in json format
5459
#[clap(short, long)]
5560
json: bool,
@@ -91,6 +96,15 @@ enum Commands {
9196
async fn main() -> Result<()> {
9297
let cli = Cli::parse();
9398

99+
// Clap validates that both are not passed at same time
100+
let value_format = if cli.hex_format {
101+
ValueFormat::Hex
102+
} else if cli.int_format {
103+
ValueFormat::Int
104+
} else {
105+
ValueFormat::Default
106+
};
107+
94108
let mut config = parse_scarb_config(&cli.profile, &cli.path_to_scarb_toml)?;
95109
update_cast_config(&mut config, &cli);
96110

@@ -114,7 +128,7 @@ async fn main() -> Result<()> {
114128
)
115129
.await;
116130

117-
print_command_result("declare", &mut result, cli.int_format, cli.json)?;
131+
print_command_result("declare", &mut result, value_format, cli.json)?;
118132
Ok(())
119133
}
120134
Commands::Deploy(deploy) => {
@@ -136,7 +150,7 @@ async fn main() -> Result<()> {
136150
)
137151
.await;
138152

139-
print_command_result("deploy", &mut result, cli.int_format, cli.json)?;
153+
print_command_result("deploy", &mut result, value_format, cli.json)?;
140154
Ok(())
141155
}
142156
Commands::Call(call) => {
@@ -151,7 +165,7 @@ async fn main() -> Result<()> {
151165
)
152166
.await;
153167

154-
print_command_result("call", &mut result, cli.int_format, cli.json)?;
168+
print_command_result("call", &mut result, value_format, cli.json)?;
155169
Ok(())
156170
}
157171
Commands::Invoke(invoke) => {
@@ -172,7 +186,7 @@ async fn main() -> Result<()> {
172186
)
173187
.await;
174188

175-
print_command_result("invoke", &mut result, cli.int_format, cli.json)?;
189+
print_command_result("invoke", &mut result, value_format, cli.json)?;
176190
Ok(())
177191
}
178192
Commands::Multicall(multicall) => {
@@ -181,12 +195,7 @@ async fn main() -> Result<()> {
181195
if let Some(output_path) = &new.output_path {
182196
let mut result =
183197
starknet_commands::multicall::new::new(output_path, new.overwrite);
184-
print_command_result(
185-
"multicall new",
186-
&mut result,
187-
cli.int_format,
188-
cli.json,
189-
)?;
198+
print_command_result("multicall new", &mut result, value_format, cli.json)?;
190199
} else {
191200
println!("{DEFAULT_MULTICALL_CONTENTS}");
192201
}
@@ -207,7 +216,7 @@ async fn main() -> Result<()> {
207216
)
208217
.await;
209218

210-
print_command_result("multicall run", &mut result, cli.int_format, cli.json)?;
219+
print_command_result("multicall run", &mut result, value_format, cli.json)?;
211220
}
212221
}
213222
Ok(())
@@ -225,7 +234,7 @@ async fn main() -> Result<()> {
225234
)
226235
.await;
227236

228-
print_command_result("account add", &mut result, cli.int_format, cli.json)?;
237+
print_command_result("account add", &mut result, value_format, cli.json)?;
229238
Ok(())
230239
}
231240
account::Commands::Create(create) => {
@@ -246,10 +255,11 @@ async fn main() -> Result<()> {
246255
create.salt,
247256
create.add_profile,
248257
create.class_hash,
258+
value_format,
249259
)
250260
.await;
251261

252-
print_command_result("account create", &mut result, cli.int_format, cli.json)?;
262+
print_command_result("account create", &mut result, value_format, cli.json)?;
253263
Ok(())
254264
}
255265
account::Commands::Deploy(deploy) => {
@@ -276,7 +286,7 @@ async fn main() -> Result<()> {
276286
)
277287
.await;
278288

279-
print_command_result("account deploy", &mut result, cli.int_format, cli.json)?;
289+
print_command_result("account deploy", &mut result, value_format, cli.json)?;
280290
Ok(())
281291
}
282292
account::Commands::Delete(delete) => {
@@ -296,7 +306,7 @@ async fn main() -> Result<()> {
296306
&network_name,
297307
);
298308

299-
print_command_result("account delete", &mut result, cli.int_format, cli.json)?;
309+
print_command_result("account delete", &mut result, value_format, cli.json)?;
300310
Ok(())
301311
}
302312
},
@@ -308,7 +318,7 @@ async fn main() -> Result<()> {
308318
cli.path_to_scarb_toml,
309319
)
310320
.await;
311-
print_command_result("show-config", &mut result, cli.int_format, cli.json)?;
321+
print_command_result("show-config", &mut result, value_format, cli.json)?;
312322
Ok(())
313323
}
314324
}

crates/cast/src/starknet_commands/account/create.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use camino::Utf8PathBuf;
66
use cast::helpers::constants::{CREATE_KEYSTORE_PASSWORD_ENV_VAR, OZ_CLASS_HASH};
77
use cast::helpers::response_structs::AccountCreateResponse;
88
use cast::helpers::scarb_utils::CastConfig;
9-
use cast::{extract_or_generate_salt, get_chain_id, get_keystore_password, parse_number};
9+
use cast::{
10+
extract_or_generate_salt, get_chain_id, get_keystore_password, parse_number, ValueFormat,
11+
};
1012
use clap::Args;
1113
use serde_json::json;
1214
use starknet::accounts::{AccountFactory, OpenZeppelinAccountFactory};
@@ -48,6 +50,7 @@ pub async fn create(
4850
salt: Option<FieldElement>,
4951
add_profile: bool,
5052
class_hash: Option<String>,
53+
value_format: ValueFormat,
5154
) -> Result<AccountCreateResponse> {
5255
let salt = extract_or_generate_salt(salt);
5356
let class_hash = {
@@ -94,7 +97,9 @@ pub async fn create(
9497
let mut output = vec![("address", format!("{address:#x}"))];
9598
if account_json["deployed"] == json!(false) {
9699
println!("Account successfully created. Prefund generated address with at least {max_fee} tokens. It is good to send more in the case of higher demand, max_fee * 2 = {}", max_fee * 2);
97-
output.push(("max_fee", format!("{max_fee:#x}")));
100+
// For default and Int it should be in int
101+
let max_fee_str = value_format.format_u64(max_fee);
102+
output.push(("max_fee", max_fee_str));
98103
}
99104

100105
if add_profile {
@@ -106,7 +111,7 @@ pub async fn create(
106111

107112
Ok(AccountCreateResponse {
108113
address,
109-
max_fee: FieldElement::from(max_fee),
114+
max_fee,
110115
add_profile: if add_profile {
111116
"Profile successfully added to Scarb.toml".to_string()
112117
} else {

0 commit comments

Comments
 (0)