diff --git a/FULL_HELP_DOCS.md b/FULL_HELP_DOCS.md index 27fb7bead..55e093acc 100644 --- a/FULL_HELP_DOCS.md +++ b/FULL_HELP_DOCS.md @@ -1663,7 +1663,7 @@ Creates and funds a new account with the specified starting balance * `--destination ` — Account Id to create, e.g. `GBX...` * `--starting-balance ` — Initial balance in stroops of the account, default 1 XLM - Default value: `10000000` + Default value: `10_000_000` @@ -1722,7 +1722,7 @@ Sends an amount in a specific asset to a destination account * `--asset ` — Asset to send, default native, e.i. XLM Default value: `native` -* `--amount ` — Amount of the aforementioned asset to send +* `--amount ` — Amount of the aforementioned asset to send. e.g. `10_000_000` (1 XLM) diff --git a/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs b/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs index 0a0a103e8..9988b2cdd 100644 --- a/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs +++ b/cmd/crates/soroban-test/tests/it/integration/tx/operations.rs @@ -93,7 +93,7 @@ async fn payment() { "--destination", test1.as_str(), "--amount", - ONE_XLM.to_string().as_str(), + "10_000_000", ]) .assert() .success(); diff --git a/cmd/soroban-cli/src/commands/tx/new/create_account.rs b/cmd/soroban-cli/src/commands/tx/new/create_account.rs index 9cc3a62ff..2826439e9 100644 --- a/cmd/soroban-cli/src/commands/tx/new/create_account.rs +++ b/cmd/soroban-cli/src/commands/tx/new/create_account.rs @@ -1,6 +1,6 @@ use clap::{command, Parser}; -use crate::{commands::tx, xdr}; +use crate::{commands::tx, tx::builder, xdr}; #[derive(Parser, Debug, Clone)] #[group(skip)] @@ -11,15 +11,15 @@ pub struct Cmd { #[arg(long)] pub destination: xdr::AccountId, /// Initial balance in stroops of the account, default 1 XLM - #[arg(long, default_value = "10000000")] - pub starting_balance: i64, + #[arg(long, default_value = "10_000_000")] + pub starting_balance: builder::Amount, } impl From<&Cmd> for xdr::OperationBody { fn from(cmd: &Cmd) -> Self { xdr::OperationBody::CreateAccount(xdr::CreateAccountOp { destination: cmd.destination.clone(), - starting_balance: cmd.starting_balance, + starting_balance: cmd.starting_balance.into(), }) } } diff --git a/cmd/soroban-cli/src/commands/tx/new/payment.rs b/cmd/soroban-cli/src/commands/tx/new/payment.rs index c626d9ca8..3cebfa532 100644 --- a/cmd/soroban-cli/src/commands/tx/new/payment.rs +++ b/cmd/soroban-cli/src/commands/tx/new/payment.rs @@ -13,9 +13,9 @@ pub struct Cmd { /// Asset to send, default native, e.i. XLM #[arg(long, default_value = "native")] pub asset: builder::Asset, - /// Amount of the aforementioned asset to send. + /// Amount of the aforementioned asset to send. e.g. `10_000_000` (1 XLM) #[arg(long)] - pub amount: i64, + pub amount: builder::Amount, } impl From<&Cmd> for xdr::OperationBody { @@ -23,7 +23,7 @@ impl From<&Cmd> for xdr::OperationBody { xdr::OperationBody::Payment(xdr::PaymentOp { destination: cmd.destination.clone(), asset: cmd.asset.clone().into(), - amount: cmd.amount, + amount: cmd.amount.into(), }) } } diff --git a/cmd/soroban-cli/src/tx/builder.rs b/cmd/soroban-cli/src/tx/builder.rs index ad22737ea..c84bb7124 100644 --- a/cmd/soroban-cli/src/tx/builder.rs +++ b/cmd/soroban-cli/src/tx/builder.rs @@ -1,6 +1,8 @@ +pub mod amount; pub mod asset; pub mod transaction; +pub use amount::Amount; pub use asset::Asset; pub use transaction::TxExt; diff --git a/cmd/soroban-cli/src/tx/builder/amount.rs b/cmd/soroban-cli/src/tx/builder/amount.rs new file mode 100644 index 000000000..d3c204f50 --- /dev/null +++ b/cmd/soroban-cli/src/tx/builder/amount.rs @@ -0,0 +1,35 @@ +use std::str::FromStr; + +#[derive(Clone, Debug, Copy)] +pub struct Amount(i64); + +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("cannot start or end with `_`: {0}")] + CannotStartOrEndWithUnderscore(String), + #[error(transparent)] + IntParse(#[from] std::num::ParseIntError), +} + +impl FromStr for Amount { + type Err = Error; + + fn from_str(value: &str) -> Result { + if value.starts_with('_') || value.ends_with('_') { + return Err(Error::CannotStartOrEndWithUnderscore(value.to_string())); + } + Ok(Self(value.replace('_', "").parse::()?)) + } +} + +impl From for i64 { + fn from(builder: Amount) -> Self { + builder.0 + } +} + +impl From<&Amount> for i64 { + fn from(builder: &Amount) -> Self { + (*builder).into() + } +}