Skip to content

Commit 32302f6

Browse files
authored
Improve output of sncast account create (#3347)
<!-- Reference any GitHub issues resolved by this PR --> Closes #3254 ## Introduced changes <!-- A brief description of the changes --> - ## 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 619793e commit 32302f6

File tree

10 files changed

+151
-43
lines changed

10 files changed

+151
-43
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2626
- OpenZeppelin account updated to v1.0.0 [preset](https://docs.openzeppelin.com/contracts-cairo/1.0.0/api/account#AccountUpgradeable)
2727
- Restored support for Braavos accounts
2828
- Accounts created with `--type braavos` use updated v1.2.0 class hash
29+
- Output of `sncast account create` is now clearer; the estimated fee is displayed in both STRK and FRI.
30+
- Renamed the field `max_fee` to `estimated_fee` in the `sncast account create` output.
2931

3032
## [0.43.1] - 2025-05-16
3133

Cargo.lock

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ license-file = "LICENSE"
2929

3030
[workspace.dependencies]
3131
blockifier = { git = "https://github.com/software-mansion-labs/sequencer.git", branch = "main-v0.13.5-modified-sierra-dep", default-features = false, features = ["testing", "tracing"] }
32+
bigdecimal = "0.4.8"
3233
starknet_api = { git = "https://github.com/software-mansion-labs/sequencer.git", branch = "main-v0.13.5-modified-sierra-dep" }
3334
cairo-lang-casm = { version = "2.11.2", features = ["serde"] }
3435
cairo-lang-sierra = "2.11.2"

crates/sncast/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ edition.workspace = true
77
[dependencies]
88
anyhow.workspace = true
99
camino.workspace = true
10+
bigdecimal.workspace = true
1011
clap.workspace = true
1112
clap_complete.workspace = true
1213
serde_json.workspace = true

crates/sncast/src/response/structs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ impl CommandResponse for DeclareResponse {}
8585
pub struct AccountCreateResponse {
8686
pub address: PaddedFelt,
8787
#[serde(serialize_with = "crate::response::structs::serialize_as_decimal")]
88-
pub max_fee: Felt,
88+
pub estimated_fee: Felt,
8989
pub add_profile: String,
9090
pub message: String,
9191
}

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

Lines changed: 74 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use crate::starknet_commands::account::{
22
generate_add_profile_message, prepare_account_json, write_account_to_accounts_file,
33
};
44
use anyhow::{Context, Result, anyhow, bail};
5+
use bigdecimal::BigDecimal;
6+
use bigdecimal::num_bigint::{BigInt, Sign};
57
use camino::Utf8PathBuf;
68
use clap::Args;
79
use conversions::IntoConv;
@@ -76,15 +78,18 @@ pub async fn create(
7678
});
7779
check_class_hash_exists(provider, class_hash).await?;
7880

79-
let (account_json, max_fee) =
81+
let (account_json, estimated_fee) =
8082
generate_account(provider, salt, class_hash, create.account_type).await?;
8183

8284
let address: Felt = account_json["address"]
8385
.as_str()
8486
.context("Invalid address")?
8587
.parse()?;
8688

87-
let mut message = "Account successfully created. Prefund generated address with at least <max_fee> STRK tokens. It is good to send more in the case of higher demand.".to_string();
89+
let mut message = format!(
90+
"Account successfully created but it needs to be deployed. The estimated deployment fee is {} STRK. Prefund the account to cover deployment transaction fee",
91+
felt_to_bigdecimal(estimated_fee, 18)
92+
);
8893

8994
if let Some(keystore) = keystore.clone() {
9095
let account_path = Utf8PathBuf::from(&account);
@@ -139,7 +144,7 @@ pub async fn create(
139144

140145
Ok(AccountCreateResponse {
141146
address: address.into_(),
142-
max_fee,
147+
estimated_fee,
143148
add_profile: add_profile_message,
144149
message: if account_json["deployed"] == json!(false) {
145150
message
@@ -352,7 +357,7 @@ fn generate_deploy_command(
352357
let network_flag = generate_network_flag(rpc_url, network);
353358

354359
format!(
355-
"\n\nAfter prefunding the address, run:\n\
360+
"\n\nAfter prefunding the account, run:\n\
356361
sncast{accounts_flag} account deploy {network_flag} --name {account}"
357362
)
358363
}
@@ -366,7 +371,71 @@ fn generate_deploy_command_with_keystore(
366371
let network_flag = generate_network_flag(rpc_url, network);
367372

368373
format!(
369-
"\n\nAfter prefunding the address, run:\n\
374+
"\n\nAfter prefunding the account, run:\n\
370375
sncast --account {account} --keystore {keystore} account deploy {network_flag}"
371376
)
372377
}
378+
379+
fn felt_to_bigdecimal<F, D>(felt: F, decimals: D) -> BigDecimal
380+
where
381+
F: AsRef<Felt>,
382+
D: Into<i64>,
383+
{
384+
BigDecimal::new(
385+
BigInt::from_bytes_be(Sign::Plus, &felt.as_ref().to_bytes_be()),
386+
decimals.into(),
387+
)
388+
}
389+
390+
#[cfg(test)]
391+
mod tests {
392+
use super::*;
393+
394+
#[test]
395+
fn test_felt_to_bigdecimal_with_zero() {
396+
let felt = Felt::ZERO;
397+
let result = felt_to_bigdecimal(felt, 18);
398+
assert_eq!(result, BigDecimal::from(0));
399+
}
400+
401+
#[test]
402+
fn test_felt_to_bigdecimal_with_one() {
403+
let felt = Felt::ONE;
404+
let result = felt_to_bigdecimal(felt, 18);
405+
assert_eq!(result, BigDecimal::new(BigInt::from(1), 18));
406+
}
407+
408+
#[test]
409+
fn test_felt_to_bigdecimal_with_large_number() {
410+
let felt = Felt::from_dec_str("1311768467463790320").unwrap();
411+
let result = felt_to_bigdecimal(felt, 18);
412+
let expected = BigDecimal::from_str("1.311768467463790320").unwrap();
413+
assert_eq!(result, expected);
414+
}
415+
416+
#[test]
417+
fn test_felt_to_bigdecimal_with_different_decimals() {
418+
let felt = Felt::from_hex("0x64").unwrap();
419+
let result_0 = felt_to_bigdecimal(felt, 0);
420+
let result_2 = felt_to_bigdecimal(felt, 2);
421+
422+
assert_eq!(result_0, BigDecimal::from(100));
423+
assert_eq!(result_2, BigDecimal::new(BigInt::from(100), 2));
424+
}
425+
#[test]
426+
fn test_felt_to_bigdecimal_common_token_value() {
427+
let felt = Felt::from(1_500_000_000_000_000_000u128);
428+
let result = felt_to_bigdecimal(felt, 18);
429+
assert_eq!(result.to_string(), "1.500000000000000000");
430+
}
431+
432+
#[test]
433+
fn test_felt_to_bigdecimal_with_different_decimal_places() {
434+
let felt = Felt::from(123_456_789);
435+
436+
assert_eq!(felt_to_bigdecimal(felt, 0).to_string(), "123456789");
437+
assert_eq!(felt_to_bigdecimal(felt, 3).to_string(), "123456.789");
438+
assert_eq!(felt_to_bigdecimal(felt, 6).to_string(), "123.456789");
439+
assert_eq!(felt_to_bigdecimal(felt, 9).to_string(), "0.123456789");
440+
}
441+
}

crates/sncast/tests/e2e/account/create.rs

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ pub async fn test_happy_case(account_type: &str) {
5050
command: account create
5151
add_profile: --add-profile flag was not set. No profile added to snfoundry.toml
5252
address: 0x0[..]
53-
max_fee: [..]
54-
message: Account successfully created. Prefund generated address with at least <max_fee> STRK tokens. It is good to send more in the case of higher demand.
53+
estimated_fee: [..]
54+
message: Account successfully created but it needs to be deployed. The estimated deployment fee is [..]
5555
56-
After prefunding the address, run:
56+
After prefunding the account, run:
5757
sncast --accounts-file accounts.json account deploy --url http://127.0.0.1:5055/rpc --name my_account
5858
5959
To see account creation details, visit:
@@ -144,10 +144,10 @@ pub async fn test_happy_case_generate_salt() {
144144
command: account create
145145
add_profile: --add-profile flag was not set. No profile added to snfoundry.toml
146146
address: 0x0[..]
147-
max_fee: [..]
148-
message: Account successfully created[..]
147+
estimated_fee: [..]
148+
message: Account successfully created but it needs to be deployed. The estimated deployment fee is [..]
149149
150-
After prefunding the address, run:
150+
After prefunding the account, run:
151151
sncast --accounts-file accounts.json account deploy --url http://127.0.0.1:5055/rpc --name my_account
152152
153153
To see account creation details, visit:
@@ -230,10 +230,10 @@ pub async fn test_happy_case_accounts_file_already_exists() {
230230
command: account create
231231
add_profile: --add-profile flag was not set. No profile added to snfoundry.toml
232232
address: 0x0[..]
233-
max_fee: [..]
234-
message: Account successfully created[..]
233+
estimated_fee: [..]
234+
message: Account successfully created but it needs to be deployed. The estimated deployment fee is [..]
235235
236-
After prefunding the address, run:
236+
After prefunding the account, run:
237237
sncast --accounts-file accounts.json account deploy --url http://127.0.0.1:5055/rpc --name my_account
238238
239239
To see account creation details, visit:
@@ -362,10 +362,10 @@ pub async fn test_happy_case_keystore(account_type: &str) {
362362
command: account create
363363
add_profile: --add-profile flag was not set. No profile added to snfoundry.toml
364364
address: 0x0[..]
365-
max_fee: [..]
366-
message: Account successfully created[..]
365+
estimated_fee: [..]
366+
message: Account successfully created but it needs to be deployed. The estimated deployment fee is [..]
367367
368-
After prefunding the address, run:
368+
After prefunding the account, run:
369369
sncast --account {} --keystore {} account deploy --url {}
370370
371371
To see account creation details, visit:
@@ -565,10 +565,10 @@ pub async fn test_happy_case_keystore_int_format() {
565565
command: account create
566566
add_profile: --add-profile flag was not set. No profile added to snfoundry.toml
567567
address: [..]
568-
max_fee: [..]
569-
message: Account successfully created[..]
568+
estimated_fee: [..]
569+
message: Account successfully created but it needs to be deployed. The estimated deployment fee is [..]
570570
571-
After prefunding the address, run:
571+
After prefunding the account, run:
572572
sncast --account {} --keystore {} account deploy --url {}
573573
574574
To see account creation details, visit:
@@ -609,10 +609,10 @@ pub async fn test_happy_case_keystore_hex_format() {
609609
command: account create
610610
add_profile: --add-profile flag was not set. No profile added to snfoundry.toml
611611
address: 0x0[..]
612-
max_fee: 0x[..]
613-
message: Account successfully created[..]
612+
estimated_fee: [..]
613+
message: Account successfully created but it needs to be deployed. The estimated deployment fee is [..]
614614
615-
After prefunding the address, run:
615+
After prefunding the account, run:
616616
sncast --account {} --keystore {} account deploy --url {}
617617
618618
To see account creation details, visit:
@@ -661,10 +661,10 @@ pub async fn test_happy_case_default_name_generation() {
661661
command: account create
662662
add_profile: --add-profile flag was not set. No profile added to snfoundry.toml
663663
address: 0x0[..]
664-
max_fee: [..]
665-
message: Account successfully created. Prefund generated address with at least <max_fee> STRK tokens. It is good to send more in the case of higher demand.
664+
estimated_fee: [..]
665+
message: Account successfully created but it needs to be deployed. The estimated deployment fee is [..]
666666
667-
After prefunding the address, run:
667+
After prefunding the account, run:
668668
sncast --accounts-file accounts.json account deploy --url http://127.0.0.1:5055/rpc --name account-{id}
669669
670670
To see account creation details, visit:
@@ -695,10 +695,10 @@ pub async fn test_happy_case_default_name_generation() {
695695
command: account create
696696
add_profile: --add-profile flag was not set. No profile added to snfoundry.toml
697697
address: 0x0[..]
698-
max_fee: [..]
699-
message: Account successfully created. Prefund generated address with at least <max_fee> STRK tokens. It is good to send more in the case of higher demand.
700-
701-
After prefunding the address, run:
698+
estimated_fee: [..]
699+
message: Account successfully created but it needs to be deployed. The estimated deployment fee is [..]
700+
701+
After prefunding the account, run:
702702
sncast --accounts-file accounts.json account deploy --url http://127.0.0.1:5055/rpc --name account-2
703703
704704
To see account creation details, visit:
@@ -864,3 +864,18 @@ fn test_old_braavos_class_hashes_disabled(class_hash: &str) {
864864
"},
865865
);
866866
}
867+
868+
#[tokio::test]
869+
pub async fn test_happy_case_deployment_fee_message() {
870+
let tempdir = tempdir().expect("Failed to create a temporary directory");
871+
872+
let args = vec!["account", "create", "--url", URL];
873+
874+
let snapbox = runner(&args).current_dir(tempdir.path());
875+
let output = snapbox.assert().success();
876+
877+
assert_stdout_contains(
878+
output,
879+
"message: Account successfully created but it needs to be deployed. The estimated deployment fee is 0.000836288000000000 STRK. Prefund the account to cover deployment transaction fee",
880+
);
881+
}

docs/src/development/shell-snippets.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ $ sncast \
2121
```shell
2222
command: account create
2323
add_profile: --add-profile flag was not set. No profile added to snfoundry.toml
24-
address: [..]
25-
max_fee: [..]
26-
message: Account successfully created. Prefund generated address with at least <max_fee> STRK tokens. It is good to send more in the case of higher demand.
27-
24+
address: 0x0[..]
25+
estimated_fee: [..]
26+
message: Account successfully created but it needs to be deployed. The estimated deployment fee is [..]
27+
2828
To see account creation details, visit:
2929
account: https://sepolia.starkscan.co/contract/[..]
3030
```

docs/src/starknet/101.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,11 @@ $ sncast account create \
2121
```shell
2222
command: account create
2323
add_profile: --add-profile flag was not set. No profile added to snfoundry.toml
24-
address: 0x[..]
25-
max_fee: [..]
26-
message: Account successfully created. Prefund generated address with at least <max_fee> STRK tokens. It is good to send more in the case of higher demand.
24+
address: 0x0[..]
25+
estimated_fee: [..]
26+
message: Account successfully created but it needs to be deployed. The estimated deployment fee is [..]
2727

28-
After prefunding the address, run:
28+
After prefunding the account, run:
2929
sncast account deploy --network sepolia --name my_account
3030
```
3131

@@ -39,7 +39,7 @@ At least `max_fee` amount of fri (1 STRK = 10<sup>18</sup> fri) should be sent.
3939
> On Sepolia, [this free faucet](https://starknet-faucet.vercel.app/) can be used to fund the account.
4040
4141

42-
Then, deploy the account using the command that was provided in output, below `After prefunding the address, run`:
42+
Then, deploy the account using the command that was provided in output, below `After prefunding the account, run`:
4343

4444
<!-- { "ignored": true } -->
4545
```shell

docs/src/starknet/account.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ $ sncast \
3737
```shell
3838
command: account create
3939
add_profile: --add-profile flag was not set. No profile added to snfoundry.toml
40-
address: [..]
41-
max_fee: [..]
42-
message: Account successfully created. Prefund generated address with at least <max_fee> STRK tokens. It is good to send more in the case of higher demand.
40+
address: 0x0[..]
41+
estimated_fee: [..]
42+
message: Account successfully created but it needs to be deployed. The estimated deployment fee is [..]
4343

4444
To see account creation details, visit:
4545
account: https://sepolia.starkscan.co/contract/[..]

0 commit comments

Comments
 (0)