use std::path::PathBuf;
use anyhow::{anyhow, Context as _};
use reedline_repl_rs::clap::{Arg, ArgMatches, Command};
use reedline_repl_rs::Repl;
use s_macro::s;
use crate::{match_context, Context};
#[tracing::instrument(level = "trace", err(Debug), skip(args, context))]
fn h_cargo_generate_mnemonic_to_file(
args: ArgMatches,
context: &mut Context,
) -> anyhow::Result<Option<String>> {
let cargo = match_context!(context, cargo => Some(_))?;
let filepath = args
.get_one::<String>("filepath")
.context("filepath not provided")?;
let filepath = PathBuf::from(filepath);
if !filepath.exists() {
return Err(anyhow!("Filepath does not exist"));
}
let mnemonic = cargo
.user_api()
.generate_mnemonic()
.context("Mnemonic generation error")?;
let mut file = std::fs::File::create(filepath.clone())?;
std::io::Write::write_all(&mut file, mnemonic.stringify().as_bytes())?;
Ok(Some(format!(
"{} created or replaced",
filepath.as_path().to_str().unwrap()
)))
}
#[tracing::instrument(level = "trace", err(Debug), skip(_args, context))]
fn h_cargo_generate_mnemonic_words(
_args: ArgMatches,
context: &mut Context,
) -> anyhow::Result<Option<String>> {
let cargo = match_context!(context, cargo => Some(_))?;
let mnemonic = cargo
.user_api()
.generate_mnemonic()
.context("Mnemonic generation error")?;
Ok(Some(mnemonic.stringify()))
}
#[tracing::instrument(level = "trace", err(Debug), skip(args, context))]
fn h_cargo_create_user_mnemonic_file(
args: ArgMatches,
context: &mut Context,
) -> anyhow::Result<Option<String>> {
let cargo = match_context!(context, cargo => Some(_), cargo_user => None)?;
let devicename = args
.get_one::<String>("devicename")
.context("device name not provided")?;
let filepath = args
.get_one::<String>("filepath")
.context("mnemonic-containing file not provided")?;
let filepath = PathBuf::from(filepath);
let userapi = cargo.user_api();
let mnemonic_string = std::fs::read_to_string(filepath)?;
let mnemonic_payload = userapi
.create_mnemonic_from_string(mnemonic_string)
.context("Mnemonic creation error")?;
_ = userapi
.create_user_from_mnemonic(&mnemonic_payload, s!(devicename))
.context("User creation error")?;
context.set_cargo_user()?;
Ok(Some(format!("User created with device {devicename}")))
}
#[tracing::instrument(level = "trace", err(Debug), skip(args, context))]
fn h_cargo_create_user_mnemonic_words(
args: ArgMatches,
context: &mut Context,
) -> anyhow::Result<Option<String>> {
let cargo = match_context!(context, cargo => Some(_), cargo_user => None)?;
let devicename = args
.get_one::<String>("devicename")
.context("device name not provided")?;
let mnemonic_string = args
.get_one::<String>("words")
.context("mnemonic words not provided, remember to use \" \"")?;
let userapi = cargo.user_api();
let mnemonic_payload = userapi
.create_mnemonic_from_string(s!(mnemonic_string))
.context("Mnemonic creation error")?;
_ = userapi
.create_user_from_mnemonic(&mnemonic_payload, s!(devicename))
.context("User creation error")?;
context.set_cargo_user()?;
Ok(Some(format!("User created with device {devicename}")))
}
#[tracing::instrument(level = "trace", err(Debug), skip(args, context))]
fn h_cargo_create_user_random(
args: ArgMatches,
context: &mut Context,
) -> anyhow::Result<Option<String>> {
match_context!(context, cargo => Some(_))?;
let devicename = args
.get_one::<String>("devicename")
.context("devicename not provided")?;
let userapi = context.cargo.as_ref().unwrap().user_api();
let mnemonic_payload = userapi
.generate_mnemonic()
.context("Mnemonic generation error")?;
_ = userapi
.create_user_from_mnemonic(&mnemonic_payload, s!(devicename))
.context("User creation error")?;
context.set_cargo_user()?;
Ok(Some(format!("User created with device {devicename}")))
}
#[tracing::instrument(level = "trace", err(Debug), skip(_args, context))]
fn h_cargo_user_get(_args: ArgMatches, context: &mut Context) -> anyhow::Result<Option<String>> {
match_context!(context, cargo => Some(_), cargo_user => Some(_))?;
Ok(Some(format!(
"User: {}",
context.cargo_user.as_ref().unwrap().stringify()
)))
}
#[tracing::instrument(level = "trace", err(Debug), skip(_args, context))]
fn h_cargo_user_get_public_key(
_args: ArgMatches,
context: &mut Context,
) -> anyhow::Result<Option<String>> {
let cargo_user = match_context!(context, cargo_user => Some(_))?;
let pubkey = cargo_user.get_user_public_key();
Ok(Some(hex::encode(pubkey)))
}
pub fn extend(repl: Repl<Context, anyhow::Error>) -> Repl<Context, anyhow::Error> {
repl.with_command(
Command::new("user-mnemonic-file")
.about("generate mnemonic and save it to file")
.arg(Arg::new("filepath").required(true).index(1)),
h_cargo_generate_mnemonic_to_file,
)
.with_command(
Command::new("user-mnemonic-words").about("generate menmonic and return it to console"),
h_cargo_generate_mnemonic_words,
)
.with_command(
Command::new("user-from-mnemonic-file")
.about("create user from mnemonic-containing file")
.arg(Arg::new("devicename").required(true).index(1))
.arg(Arg::new("filepath").required(true).index(2)),
h_cargo_create_user_mnemonic_file,
)
.with_command(
Command::new("user-from-mnemonic-words")
.about("create user from mnemonic argument")
.arg(Arg::new("devicename").required(true).index(1))
.arg(Arg::new("words").required(true).index(2)),
h_cargo_create_user_mnemonic_words,
)
.with_command(
Command::new("user-show").about("get stringified representation of user"),
h_cargo_user_get,
)
.with_command(
Command::new("user-create-random")
.about("create user from random mnemonic")
.arg(Arg::new("devicename").required(true).index(1)),
h_cargo_create_user_random,
)
.with_command(
Command::new("user-public-key").about("get user public key"),
h_cargo_user_get_public_key,
)
}