-
Notifications
You must be signed in to change notification settings - Fork 5.4k
/
main.rs
105 lines (95 loc) · 2.71 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//! A `forc` plugin for converting a given string or path to their hash.
use anyhow::Result;
use atty::Stream;
use clap::Parser;
use forc_tracing::{init_tracing_subscriber, println_error};
use std::{
default::Default,
io::{stdin, stdout, Read, Write},
};
use termion::screen::IntoAlternateScreen;
mod address;
mod args;
mod keccak256;
mod keys;
mod sha256;
fn help() -> &'static str {
Box::leak(
format!(
"EXAMPLES:\n{}{}{}{}{}",
args::examples(),
address::examples(),
keys::new_key::examples(),
keys::parse_secret::examples(),
keys::get_public_key::examples(),
)
.into_boxed_str(),
)
}
/// Forc plugin for hashing arbitrary data
#[derive(Debug, Parser)]
#[clap(
name = "forc-crypto",
after_help = help(),
version
)]
pub enum Command {
Keccak256(args::HashArgs),
Sha256(args::HashArgs),
Address(address::Args),
GetPublicKey(keys::get_public_key::Arg),
NewKey(keys::new_key::Arg),
ParseSecret(keys::parse_secret::Arg),
}
fn main() {
init_tracing_subscriber(Default::default());
if let Err(err) = run() {
println_error(&format!("{}", err));
std::process::exit(1);
}
}
fn run() -> Result<()> {
let app = Command::parse();
let content = match app {
Command::Keccak256(arg) => keccak256::hash(arg)?,
Command::GetPublicKey(arg) => keys::get_public_key::handler(arg)?,
Command::Sha256(arg) => sha256::hash(arg)?,
Command::Address(arg) => address::dump_address(arg.address)?,
Command::NewKey(arg) => keys::new_key::handler(arg)?,
Command::ParseSecret(arg) => keys::parse_secret::handler(arg)?,
};
display_output(content)
}
fn wait_for_keypress() {
let mut single_key = [0u8];
stdin().read_exact(&mut single_key).unwrap();
}
fn has_sensible_info<T>(message: &T) -> bool
where
T: serde::Serialize,
{
match serde_json::to_value(message) {
Ok(serde_json::Value::Object(map)) => map.get("secret").is_some(),
_ => false,
}
}
pub(crate) fn display_output<T>(message: T) -> anyhow::Result<()>
where
T: serde::Serialize,
{
if atty::is(Stream::Stdout) {
let text = serde_yaml::to_string(&message).expect("valid string");
if has_sensible_info(&message) {
let mut screen = stdout().into_alternate_screen()?;
writeln!(screen, "{text}",)?;
screen.flush()?;
println!("### Do not share or lose this private key! Press any key to exit. ###");
wait_for_keypress();
} else {
println!("{text}");
}
} else {
print!("{}", serde_json::to_string(&message).expect("valid json"));
}
Ok(())
}