Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rusk-wallet: Add stdout_format flag to binary #2700

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 99 additions & 7 deletions rusk-wallet/src/bin/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use rusk_wallet::{
},
Address, Error, Profile, Wallet, EPOCH, MAX_PROFILES,
};
use serde_json::json;
use wallet_core::BalanceInfo;

use crate::io::prompt;
Expand Down Expand Up @@ -638,7 +639,7 @@ impl Command {
let contract_id =
wallet.get_contract_id(profile_idx, code, deploy_nonce)?;

Ok(RunResult::ContractId(contract_id))
Ok(RunResult::ContractId((contract_id, deploy_nonce)))
}
Command::Create { .. } => Ok(RunResult::Create()),
Command::Restore { .. } => Ok(RunResult::Restore()),
Expand All @@ -655,17 +656,109 @@ pub enum RunResult<'a> {
StakeInfo(StakeData, bool),
Profile((u8, &'a Profile)),
Profiles(&'a Vec<Profile>),
ContractId([u8; CONTRACT_ID_BYTES]),
ContractId(([u8; CONTRACT_ID_BYTES], u64)),
ExportedKeys(PathBuf, PathBuf),
Create(),
Restore(),
Settings(),
PhoenixHistory(Vec<TransactionHistory>),
}

impl fmt::Display for RunResult<'_> {
impl<'a> RunResult<'a> {
/// Convert the ran result into json
pub fn to_json(&self) -> String {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why don't you implement serde::Serialize for RunResult?

use RunResult::*;

match self {
PhoenixBalance(bal, _) => {
json!({
"total": bal.value,
"spendable": bal.spendable
})
}
MoonlightBalance(bal) => {
let bal = bal.to_string();

json!({
"total": bal,
})
}
Profile((_, profile)) => profile.to_json(),
Profiles(addrs) => {
let addrs = addrs.iter().map(|a| a.to_json()).collect();

serde_json::Value::Array(addrs)
}
Tx(hash) => {
let hex = hex::encode(hash.to_bytes());

json!({
"hash": hex
})
}
StakeInfo(data, _) => {
let faults = data.faults.to_string();
let hard_faults = data.hard_faults.to_string();
let rewards = Dusk::from(data.reward).to_string();

match data.amount {
Some(amt) => {
let amount = Dusk::from(amt.value).to_string();
let locked = Dusk::from(amt.locked).to_string();
let eligibility = amt.eligibility.to_string();
let epoch = (amt.eligibility / EPOCH).to_string();

json!({
"rewards": rewards,
"amount": amount,
"locked": locked,
"eligibility": eligibility,
"epoch": epoch,
"hard_faults": hard_faults,
"faults": faults,
})
}
None => {
json!({
"rewards": rewards,
"faults": faults,
"hard_faults": hard_faults
})
}
}
}
ExportedKeys(pk, kp) => {
let pk = pk.as_os_str();
let kp = kp.as_os_str();

json!({
"pk_export_location": pk,
"key_pair_export_location": kp
})
}
PhoenixHistory(txns) => {
let txns = txns.iter().map(|his| his.to_json()).collect();

serde_json::Value::Array(txns)
}
ContractId((bytes, nonce)) => {
let contract_id = hex::encode(bytes);

json!({
"contract_id": contract_id,
"deploy_nonce": nonce
})
}
Create() | Restore() | Settings() => serde_json::Value::Null,
}
.to_string()
}
}

impl<'a> fmt::Display for RunResult<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use RunResult::*;

match self {
PhoenixBalance(balance, _) => {
let total = Dusk::from(balance.value);
Expand Down Expand Up @@ -719,8 +812,6 @@ impl fmt::Display for RunResult<'_> {
writeln!(f, "> Eligible stake: {amount} DUSK")?;
writeln!(f, "> Reclaimable slashed stake: {locked} DUSK")?;
writeln!(f, "> Stake active from block #{eligibility} (Epoch {epoch})")?;
} else {
writeln!(f, "> No active stake found for this key")?;
Comment on lines -722 to -723
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this has been removed?

}
let faults = data.faults;
let hard_faults = data.hard_faults;
Expand All @@ -730,8 +821,9 @@ impl fmt::Display for RunResult<'_> {
writeln!(f, "> Hard Slashes: {hard_faults}")?;
write!(f, "> Accumulated rewards is: {rewards} DUSK")
}
ContractId(bytes) => {
write!(f, "> Contract ID: {}", hex::encode(bytes))
ContractId((bytes, nonce)) => {
write!(f, "> Contract ID: {}", hex::encode(bytes))?;
write!(f, "> Deploy nonce: {}", nonce)
}
ExportedKeys(pk, kp) => {
let pk = pk.display();
Expand Down
29 changes: 29 additions & 0 deletions rusk-wallet/src/bin/command/history.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use std::fmt::{self, Display};
use rusk_wallet::{BlockTransaction, DecodedNote, GraphQL};

use execution_core::{dusk, from_dusk, transfer::Transaction};
use serde_json::json;

use crate::io::{self};
use crate::settings::Settings;
Expand All @@ -31,6 +32,34 @@ impl TransactionHistory {
"BLOCK", "TX_ID", "METHOD", "AMOUNT", "FEE"
)
}

pub fn to_json(&self) -> serde_json::Value {
let dusk = self.amount / dusk(1.0) as f64;
let contract = match self.tx.call() {
None => "transfer",
Some(call) => &call.fn_name,
};

let fee = match self.direction {
TransactionDirection::In => "".into(),
TransactionDirection::Out => {
let fee = self.fee;
let fee = from_dusk(fee);
format!("{: >12.9}", fee)
}
};

let tx_id = &self.id;
let heigth = self.height;

json!({
"block": heigth,
"tx_id": tx_id,
"contract": contract,
"amount": dusk,
"fee": fee,
})
}
}

impl Display for TransactionHistory {
Expand Down
2 changes: 1 addition & 1 deletion rusk-wallet/src/bin/interactive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use rusk_wallet::{
};

use crate::{
io::{self, prompt},
io::{self, prompt, GraphQL},
settings::Settings,
Command, GraphQL, RunResult, WalletFile,
};
Expand Down
5 changes: 5 additions & 0 deletions rusk-wallet/src/bin/io/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ pub(crate) struct WalletArgs {
#[arg(long, value_enum, default_value_t = LogFormat::Coloured)]
pub log_type: LogFormat,

/// format of the result messages written to stdout after a wallet
/// operation
#[clap(long, value_enum, default_value_t = LogFormat::Plain)]
pub stdout_format: LogFormat,

/// Command
#[command(subcommand)]
pub command: Option<Command>,
Expand Down
95 changes: 10 additions & 85 deletions rusk-wallet/src/bin/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,9 @@ use inquire::InquireError;
use rocksdb::ErrorKind;
use tracing::{error, info, warn, Level};

use crate::command::TransactionHistory;
use crate::settings::{LogFormat, Settings};

use rusk_wallet::{
currency::Dusk,
dat::{self, LATEST_VERSION},
Error, GraphQL, Profile, SecureWalletFile, Wallet, WalletPath, EPOCH,
};
Expand Down Expand Up @@ -318,93 +316,20 @@ async fn exec() -> anyhow::Result<()> {
match cmd {
// if there is no command we are in interactive mode and need to run the
// interactive loop
None => {
wallet.register_sync().await?;
interactive::run_loop(&mut wallet, &settings).await?;
}
// else we run the given command and print the result
Some(cmd) => {
match cmd.run(&mut wallet, &settings).await? {
RunResult::PhoenixBalance(balance, spendable) => {
if spendable {
println!("{}", Dusk::from(balance.spendable));
} else {
println!("{}", Dusk::from(balance.value));
}
}
RunResult::MoonlightBalance(balance) => {
println!("Total: {}", balance);
}
RunResult::Profile((profile_idx, profile)) => {
println!(
"> {}\n> {}\n> {}\n",
Profile::index_string(profile_idx),
profile.shielded_address_string(),
profile.public_account_string(),
);
}
RunResult::Profiles(addrs) => {
for (profile_idx, profile) in addrs.iter().enumerate() {
println!(
"> {}\n> {}\n> {}\n\n",
Profile::index_string(profile_idx as u8),
profile.shielded_address_string(),
profile.public_account_string(),
);
}
}
RunResult::Tx(hash) => {
let tx_id = hex::encode(hash.to_bytes());
let run_res = cmd.run(&mut wallet, &settings).await?;

// Wait for transaction confirmation from network
let gql = GraphQL::new(settings.state, status::headless)?;
gql.wait_for(&tx_id).await?;
let mut stdout_res = run_res.to_string();

println!("{tx_id}");
}
RunResult::StakeInfo(info, reward) => {
let rewards = Dusk::from(info.reward);
if reward {
println!("{rewards}");
} else {
if let Some(amt) = info.amount {
let amount = Dusk::from(amt.value);
let locked = Dusk::from(amt.locked);
let eligibility = amt.eligibility;
let epoch = amt.eligibility / EPOCH;

println!("Eligible stake: {amount} DUSK");
println!(
"Reclaimable slashed stake: {locked} DUSK"
);
println!("Stake active from block #{eligibility} (Epoch {epoch})");
} else {
println!("No active stake found for this key");
}
let faults = info.faults;
let hard_faults = info.hard_faults;
let rewards = Dusk::from(info.reward);

println!("Slashes: {faults}");
println!("Hard Slashes: {hard_faults}");
println!("Accumulated rewards is: {rewards} DUSK");
}
}
RunResult::ExportedKeys(pub_key, key_pair) => {
println!("{},{}", pub_key.display(), key_pair.display())
}
RunResult::PhoenixHistory(transactions) => {
println!("{}", TransactionHistory::header());
for th in transactions {
println!("{th}");
}
}
RunResult::ContractId(id) => {
println!("Contract ID: {:?}", id);
}
RunResult::Settings() => {}
RunResult::Create() | RunResult::Restore() => {}
if want_json {
stdout_res = run_res.to_json();
Comment on lines +324 to +325
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put an if else and avoid to "run_res.to_string()"?

}

println!("{stdout_res}");
}
None => {
wallet.register_sync().await?;
interactive::run_loop(&mut wallet, &settings).await?;
}
}

Expand Down
9 changes: 9 additions & 0 deletions rusk-wallet/src/wallet/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use super::*;
use crate::Error;

use dusk_bytes::{DeserializableSlice, Serializable};
use serde_json::json;

/// Address to perform a transaction with.
#[derive(Clone, Eq)]
Expand Down Expand Up @@ -225,6 +226,14 @@ impl Profile {

index_string
}

/// format the profile into a json value
pub fn to_json(&self) -> serde_json::Value {
json!({
"shielded": String::from(&Address::Shielded(self.shielded_addr)),
"public": String::from(&Address::Public(self.public_addr)),
})
}
}

fn shielded_address_prefix() -> String {
Expand Down
Loading