Skip to content

Commit

Permalink
Improvements for keygen cli and crates (#1465)
Browse files Browse the repository at this point in the history
Import improvements from FuelLabs/sway#5153.

Once this PR is merged and a new release is created sway will reference
this crate instead of having its own copy
(FuelLabs/sway#5170)
  • Loading branch information
cr-fuel authored Nov 1, 2023
1 parent 3c8ab9d commit 8a323ad
Show file tree
Hide file tree
Showing 7 changed files with 301 additions and 190 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
Description of the upcoming release here.

### Added
- [#1465](https://github.com/FuelLabs/fuel-core/pull/1465): Improvements for keygen cli and crates
- [#1457](https://github.com/FuelLabs/fuel-core/pull/1457): Fixing incorrect measurement for fast(µs) opcodes.
- [#1456](https://github.com/FuelLabs/fuel-core/pull/1456): Added flushing of the RocksDB during a graceful shutdown.
- [#1456](https://github.com/FuelLabs/fuel-core/pull/1456): Added more logs to track the service lifecycle.
Expand Down
55 changes: 52 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions bin/keygen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,9 @@ description = "Command line utilities for fuel-core key management"

[dependencies]
anyhow = { workspace = true }
atty = "0.2.14"
clap = { workspace = true, features = ["derive", "env"] }
crossterm = "0.27.0"
fuel-core-keygen = { workspace = true }
serde_json = { workspace = true, features = ["raw_value"] }
termion = "2.0.1"
108 changes: 100 additions & 8 deletions bin/keygen/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,25 +1,117 @@
//! A simple keygen cli utility tool for configuring fuel-core

use atty::Stream;
use clap::Parser;
use fuel_core_keygen::keygen;
use crossterm::terminal;
use fuel_core_keygen::{
new_key,
parse_secret,
KeyType,
};
use std::io::{
stdin,
stdout,
Read,
Write,
};
use termion::screen::IntoAlternateScreen;

/// Parse a secret key to view the associated public key
#[derive(Debug, clap::Args)]
#[clap(author, version, about)]
pub struct ParseSecret {
/// A private key in hex format
secret: String,
/// Print the JSON in pretty format
#[clap(long = "pretty", short = 'p')]
pub pretty: bool,
/// Key type to generate. It can either be `block-production` or `peering`.
#[clap(
long = "key-type",
short = 'k',
value_enum,
default_value = <KeyType as std::convert::Into<&'static str>>::into(KeyType::BlockProduction),
)]
pub key_type: KeyType,
}

/// Generate a random new secret & public key in the format expected by fuel-core
#[derive(Debug, clap::Args)]
#[clap(author, version, about)]
pub struct NewKey {
/// Print the JSON in pretty format
#[clap(long = "pretty", short = 'p')]
pub pretty: bool,
/// Key type to generate. It can either be `block-production` or `peering`.
#[clap(
long = "key-type",
short = 'k',
value_enum,
default_value = <KeyType as std::convert::Into<&'static str>>::into(KeyType::BlockProduction),
)]
pub key_type: KeyType,
}

/// Key management utilities for configuring fuel-core
#[derive(Debug, Parser)]
pub(crate) enum Command {
New(keygen::NewKey),
Parse(keygen::ParseSecret),
New(NewKey),
Parse(ParseSecret),
}

impl Command {
pub(crate) fn exec(&self) -> anyhow::Result<()> {
pub(crate) fn exec(&self) -> anyhow::Result<(serde_json::Value, bool)> {
match self {
Command::New(cmd) => cmd.exec(),
Command::Parse(cmd) => cmd.exec(),
Command::New(cmd) => {
Ok((serde_json::to_value(new_key(cmd.key_type)?)?, cmd.pretty))
}
Command::Parse(cmd) => Ok((
serde_json::to_value(parse_secret(cmd.key_type, &cmd.secret)?)?,
cmd.pretty,
)),
}
}
}

fn main() -> anyhow::Result<()> {
let cmd = Command::parse();
cmd.exec()
let (result, is_pretty) = cmd.exec()?;
print_value(result, is_pretty)
}

fn wait_for_keypress() {
let mut single_key = [0u8];
terminal::enable_raw_mode().expect("enable_raw_mode failed");
stdin().read_exact(&mut single_key).unwrap();
terminal::disable_raw_mode().expect("disable_raw_mode failed");
}

fn display_string_discreetly(
discreet_string: &str,
continue_message: &str,
) -> anyhow::Result<()> {
if atty::is(Stream::Stdout) {
let mut screen = stdout().into_alternate_screen()?;
writeln!(screen, "{discreet_string}")?;
screen.flush()?;
println!("{continue_message}");
wait_for_keypress();
} else {
println!("{discreet_string}");
}
Ok(())
}

fn print_value(output: serde_json::Value, pretty: bool) -> anyhow::Result<()> {
let output = if pretty {
serde_json::to_string_pretty(&output)
} else {
serde_json::to_string(&output)
}
.map_err(anyhow::Error::msg);

let _ = display_string_discreetly(
&output?,
"### Do not share or lose this private key! Press any key to complete. ###",
);
Ok(())
}
4 changes: 1 addition & 3 deletions crates/keygen/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ description = "Create to create command line utilities for fuel-core key managem

[dependencies]
anyhow = { workspace = true }
atty = "0.2.14"
clap = { workspace = true, features = ["derive", "env"] }
fuel-core-types = { workspace = true, features = ["serde", "random"] }
libp2p-identity = { version = "0.2.4", features = ["secp256k1", "peerid"] }
serde_json = { workspace = true, features = ["raw_value"] }
termion = "2.0.1"
serde = { workspace = true, features = ["derive"] }
Loading

0 comments on commit 8a323ad

Please sign in to comment.