diff --git a/src/commands/ledger/mod.rs b/src/commands/ledger/mod.rs new file mode 100644 index 0000000..9a49ef5 --- /dev/null +++ b/src/commands/ledger/mod.rs @@ -0,0 +1,78 @@ +//! Subcommands of the `tmkms` command-line application + +use crate::chain; +use crate::config::KmsConfig; +use abscissa::{Callable, GlobalConfig}; +use std::process; +use tendermint::amino_types::vote::{SignVoteRequest, Vote}; +use tendermint::amino_types::{SignableMsg, SignedMsgType}; + +#[derive(Debug, Options)] +pub enum LedgerCommand { + #[options(help = "initialise the height/round/step")] + Initialise(InitCommand), +} + +impl_command!(LedgerCommand); + +impl Callable for LedgerCommand { + fn call(&self) { + match self { + LedgerCommand::Initialise(init) => init.call(), + } + } +} + +impl LedgerCommand { + pub(super) fn config_path(&self) -> Option<&String> { + match self { + LedgerCommand::Initialise(init) => init.config.as_ref(), + } + } +} + +#[derive(Debug, Options)] +pub struct InitCommand { + #[options(short = "c", long = "config")] + pub config: Option, + + #[options(short = "h", long = "height")] + pub height: Option, + + #[options(short = "r", long = "round")] + pub round: Option, +} + +impl Callable for InitCommand { + fn call(&self) { + let config = KmsConfig::get_global(); + + chain::load_config(&config).unwrap_or_else(|e| { + status_err!("error loading configuration: {}", e); + process::exit(1); + }); + + let chain_id = config.validator[0].chain_id; + let registry = chain::REGISTRY.get(); + let chain = registry.get_chain(&chain_id).unwrap(); + + let mut vote = Vote::default(); + vote.height = self.height.unwrap(); + vote.round = self.round.unwrap(); + vote.vote_type = SignedMsgType::Proposal.to_u32(); + println!("{:?}", vote); + let sign_vote_req = SignVoteRequest { vote: Some(vote) }; + let mut to_sign = vec![]; + sign_vote_req + .sign_bytes(config.validator[0].chain_id, &mut to_sign) + .unwrap(); + + let _sig = chain.keyring.sign_ed25519(None, &to_sign).unwrap(); + + println!( + "Successfully called the init command with height {}, and round {}", + self.height.unwrap(), + self.round.unwrap() + ); + } +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 3f38719..06ac59f 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -8,6 +8,10 @@ mod version; mod yubihsm; #[cfg(feature = "yubihsm")] pub use self::yubihsm::YubihsmCommand; +#[cfg(feature = "ledgertm")] +mod ledger; +#[cfg(feature = "ledgertm")] +pub use self::ledger::LedgerCommand; pub use self::{ help::HelpCommand, keygen::KeygenCommand, start::StartCommand, version::VersionCommand, @@ -34,6 +38,10 @@ pub enum KmsCommand { #[cfg(feature = "yubihsm")] #[options(help = "subcommands for YubiHSM2")] Yubihsm(YubihsmCommand), + + #[cfg(feature = "ledgertm")] + #[options(help = "subcommands for Ledger")] + Ledger(LedgerCommand), } // TODO: refactor abscissa internally so this is all part of the proc macro @@ -59,6 +67,8 @@ impl LoadConfig for KmsCommand { KmsCommand::Start(run) => run.config.as_ref(), #[cfg(feature = "yubihsm")] KmsCommand::Yubihsm(yubihsm) => yubihsm.config_path(), + #[cfg(feature = "ledgertm")] + KmsCommand::Ledger(ledger) => ledger.config_path(), _ => return None, }; @@ -84,6 +94,8 @@ impl Callable for KmsCommand { KmsCommand::Version(version) => version.call(), #[cfg(feature = "yubihsm")] KmsCommand::Yubihsm(yubihsm) => yubihsm.call(), + #[cfg(feature = "ledgertm")] + KmsCommand::Ledger(ledger) => ledger.call(), } } }