use crate::DEFAULT_KEY_COL_WIDTH;
use anyhow::{
Context,
Result,
};
use clap::{
Args,
Subcommand,
};
use colored::Colorize as _;
use contract_build::{
CrateMetadata,
util,
};
use contract_transcode::ContractMessageTranscoder;
#[derive(Debug, Args)]
pub struct DecodeCommand {
#[clap(subcommand)]
commands: DecodeCommands,
}
#[derive(Debug, Subcommand)]
pub enum DecodeCommands {
#[clap(name = "message")]
Message(DecodeMessage),
#[clap(name = "constructor")]
Constructor(DecodeConstructor),
#[clap(name = "event")]
Event(DecodeEvent),
}
#[derive(Debug, Clone, Args)]
pub struct DecodeMessage {
#[clap(short, long)]
data: String,
}
#[derive(Debug, Clone, Args)]
pub struct DecodeConstructor {
#[clap(short, long)]
data: String,
}
#[derive(Debug, Clone, Args)]
pub struct DecodeEvent {
#[clap(short, long)]
signature_topic: String,
#[clap(short, long)]
data: String,
}
impl DecodeCommand {
pub fn run(&self) -> Result<()> {
let crate_metadata = CrateMetadata::from_manifest_path(None)?;
let transcoder = ContractMessageTranscoder::load(crate_metadata.metadata_path())?;
const ERR_MSG: &str = "Failed to decode specified data as a hex value";
let decoded_data = match &self.commands {
DecodeCommands::Event(event) => {
let signature_topic_data =
util::decode_hex(&event.signature_topic).context(ERR_MSG)?;
let signature_topic =
primitive_types::H256::from_slice(&signature_topic_data);
transcoder.decode_contract_event(
&signature_topic,
&mut &util::decode_hex(&event.data).context(ERR_MSG)?[..],
)?
}
DecodeCommands::Message(message) => {
transcoder.decode_contract_message(
&mut &util::decode_hex(&message.data).context(ERR_MSG)?[..],
)?
}
DecodeCommands::Constructor(constructor) => {
transcoder.decode_contract_constructor(
&mut &util::decode_hex(&constructor.data).context(ERR_MSG)?[..],
)?
}
};
println!(
"{:>width$} {}",
"Decoded data:".bright_green().bold(),
decoded_data,
width = DEFAULT_KEY_COL_WIDTH
);
Ok(())
}
}