From e2dc4ec6c85b37841341a0529ff7d0d19ee93f86 Mon Sep 17 00:00:00 2001 From: rvcas Date: Fri, 3 Mar 2023 00:13:35 -0500 Subject: [PATCH] feat: implement convert command --- crates/aiken-project/src/blueprint/error.rs | 4 + crates/aiken/src/cmd/blueprint/convert.rs | 89 ++++++++++++++++++++- 2 files changed, 91 insertions(+), 2 deletions(-) diff --git a/crates/aiken-project/src/blueprint/error.rs b/crates/aiken-project/src/blueprint/error.rs index 1c8877fd..c506fcca 100644 --- a/crates/aiken-project/src/blueprint/error.rs +++ b/crates/aiken-project/src/blueprint/error.rs @@ -41,3 +41,7 @@ pub enum Error { keyword_spend = "spend".if_supports_color(Stdout, |s| s.purple())))] ParameterizedValidator { n: usize }, } + +unsafe impl Send for Error {} + +unsafe impl Sync for Error {} diff --git a/crates/aiken/src/cmd/blueprint/convert.rs b/crates/aiken/src/cmd/blueprint/convert.rs index 3108726d..cb5a4c76 100644 --- a/crates/aiken/src/cmd/blueprint/convert.rs +++ b/crates/aiken/src/cmd/blueprint/convert.rs @@ -1,4 +1,12 @@ -use std::path::PathBuf; +use clap::clap_derive::ArgEnum; +use miette::IntoDiagnostic; +use serde_json::json; +use std::{env, fs::File, io::BufReader, path::PathBuf, process}; + +use aiken_project::{ + blueprint::{error::Error as BlueprintError, Blueprint}, + error::Error as ProjectError, +}; /// Convert a blueprint into other formats. #[derive(clap::Args)] @@ -14,6 +22,15 @@ pub struct Args { /// Name of the validator within the module. Optional if there's only one validator. #[clap(short, long)] validator: Option, + + // Format to convert to + #[clap(long, arg_enum, default_value = "cardano-cli")] + to: Format, +} + +#[derive(Copy, Clone, ArgEnum)] +pub enum Format { + CardanoCli, } pub fn exec( @@ -21,7 +38,75 @@ pub fn exec( directory, module, validator, + to, }: Args, ) -> miette::Result<()> { - Ok(()) + let title = module.as_ref().map(|m| { + format!( + "{m}{}", + validator + .as_ref() + .map(|v| format!(".{v}")) + .unwrap_or_default() + ) + }); + + let title = title.as_ref().or(validator.as_ref()); + + let project_path = if let Some(d) = directory { + d + } else { + env::current_dir().into_diagnostic()? + }; + + let blueprint_path = project_path.join("plutus.json"); + + // Read blueprint + let blueprint = File::open(blueprint_path) + .map_err(|_| BlueprintError::InvalidOrMissingFile) + .into_diagnostic()?; + + let blueprint: Blueprint = + serde_json::from_reader(BufReader::new(blueprint)).into_diagnostic()?; + + // Calculate the address + let when_too_many = + |known_validators| ProjectError::MoreThanOneValidatorFound { known_validators }; + let when_missing = |known_validators| ProjectError::NoValidatorNotFound { known_validators }; + + let result = + blueprint.with_validator(title, when_too_many, when_missing, |validator| match to { + Format::CardanoCli => { + let cbor_bytes = validator.program.to_cbor().unwrap(); + + let mut double_cbor_bytes = Vec::new(); + + let mut cbor_encoder = pallas_codec::minicbor::Encoder::new(&mut double_cbor_bytes); + + cbor_encoder.bytes(&cbor_bytes).unwrap(); + + let cbor_hex = hex::encode(double_cbor_bytes); + + Ok(json!({ + "type": "PlutusScriptV2", + "description": "Generated by Aiken", + "cborHex": cbor_hex + })) + } + }); + + match result { + Ok(value) => { + let json = serde_json::to_string_pretty(&value).unwrap(); + + println!("{json}"); + + Ok(()) + } + Err(err) => { + err.report(); + + process::exit(1) + } + } }