fix(cli): aiken address
This commit is contained in:
parent
8b4985498b
commit
a311531508
|
@ -7,7 +7,7 @@ use aiken_lang::uplc::CodeGenerator;
|
||||||
use error::Error;
|
use error::Error;
|
||||||
use schema::Schema;
|
use schema::Schema;
|
||||||
use std::fmt::{self, Debug, Display};
|
use std::fmt::{self, Debug, Display};
|
||||||
use validator::{Purpose, Validator};
|
use validator::Validator;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct Blueprint<T: Default> {
|
pub struct Blueprint<T: Default> {
|
||||||
|
@ -57,16 +57,13 @@ impl<T> Blueprint<T>
|
||||||
where
|
where
|
||||||
T: Clone + Default,
|
T: Clone + Default,
|
||||||
{
|
{
|
||||||
pub fn lookup(
|
pub fn lookup(&self, title: Option<&String>) -> Option<LookupResult<Validator<T>>> {
|
||||||
&self,
|
|
||||||
title: Option<&String>,
|
|
||||||
purpose: Option<&Purpose>,
|
|
||||||
) -> Option<LookupResult<Validator<T>>> {
|
|
||||||
let mut validator = None;
|
let mut validator = None;
|
||||||
|
|
||||||
for v in self.validators.iter() {
|
for v in self.validators.iter() {
|
||||||
let match_title = Some(&v.title) == title.or(Some(&v.title));
|
let match_title = title.map(|t| v.title.contains(t)).unwrap_or(false);
|
||||||
let match_purpose = v.purpose.as_ref() == purpose.or(v.purpose.as_ref());
|
|
||||||
if match_title && match_purpose {
|
if match_title {
|
||||||
validator = Some(if validator.is_none() {
|
validator = Some(if validator.is_none() {
|
||||||
LookupResult::One(v)
|
LookupResult::One(v)
|
||||||
} else {
|
} else {
|
||||||
|
@ -74,47 +71,27 @@ where
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
validator
|
validator
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_validator<F, A, E>(
|
pub fn with_validator<F, A, E>(
|
||||||
&self,
|
&self,
|
||||||
title: Option<&String>,
|
title: Option<&String>,
|
||||||
purpose: Option<&Purpose>,
|
when_missing: fn(Vec<String>) -> E,
|
||||||
when_missing: fn(Vec<(String, String)>) -> E,
|
when_too_many: fn(Vec<String>) -> E,
|
||||||
when_too_many: fn(Vec<(String, String)>) -> E,
|
|
||||||
action: F,
|
action: F,
|
||||||
) -> Result<A, E>
|
) -> Result<A, E>
|
||||||
where
|
where
|
||||||
F: Fn(Validator<T>) -> Result<A, E>,
|
F: Fn(Validator<T>) -> Result<A, E>,
|
||||||
{
|
{
|
||||||
match self.lookup(title, purpose) {
|
match self.lookup(title) {
|
||||||
Some(LookupResult::One(validator)) => action(validator.to_owned()),
|
Some(LookupResult::One(validator)) => action(validator.to_owned()),
|
||||||
Some(LookupResult::Many) => Err(when_too_many(
|
Some(LookupResult::Many) => Err(when_too_many(
|
||||||
self.validators
|
self.validators.iter().map(|v| v.title.clone()).collect(),
|
||||||
.iter()
|
|
||||||
.map(|v| {
|
|
||||||
let mut title = v.title.split('.');
|
|
||||||
|
|
||||||
(
|
|
||||||
title.next().unwrap().to_string(),
|
|
||||||
title.next().unwrap().to_string(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
)),
|
)),
|
||||||
None => Err(when_missing(
|
None => Err(when_missing(
|
||||||
self.validators
|
self.validators.iter().map(|v| v.title.clone()).collect(),
|
||||||
.iter()
|
|
||||||
.map(|v| {
|
|
||||||
let mut title = v.title.split('-');
|
|
||||||
|
|
||||||
(
|
|
||||||
title.next().unwrap().to_string(),
|
|
||||||
title.next().unwrap().to_string(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect(),
|
|
||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,14 +132,10 @@ pub enum Error {
|
||||||
},
|
},
|
||||||
|
|
||||||
#[error("I didn't find any validator matching your criteria.")]
|
#[error("I didn't find any validator matching your criteria.")]
|
||||||
NoValidatorNotFound {
|
NoValidatorNotFound { known_validators: Vec<String> },
|
||||||
known_validators: Vec<(String, String)>,
|
|
||||||
},
|
|
||||||
|
|
||||||
#[error("I found multiple suitable validators and I need you to tell me which one to pick.")]
|
#[error("I found multiple suitable validators and I need you to tell me which one to pick.")]
|
||||||
MoreThanOneValidatorFound {
|
MoreThanOneValidatorFound { known_validators: Vec<String> },
|
||||||
known_validators: Vec<(String, String)>,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Error {
|
impl Error {
|
||||||
|
@ -374,13 +370,13 @@ impl Diagnostic for Error {
|
||||||
Error::NoValidatorNotFound { known_validators } => {
|
Error::NoValidatorNotFound { known_validators } => {
|
||||||
Some(Box::new(format!(
|
Some(Box::new(format!(
|
||||||
"Here's a list of all validators (and their purpose) I've found in your project. Please double-check this list against the options that you've provided:\n\n{}",
|
"Here's a list of all validators (and their purpose) I've found in your project. Please double-check this list against the options that you've provided:\n\n{}",
|
||||||
known_validators.iter().map(|(name, purpose)| format!("→ {name} (purpose = {purpose})", name = name.purple().bold(), purpose = purpose.bright_blue())).collect::<Vec<String>>().join("\n")
|
known_validators.iter().map(|title| format!("→ {title}", title = title.purple().bold())).collect::<Vec<String>>().join("\n")
|
||||||
)))
|
)))
|
||||||
},
|
},
|
||||||
Error::MoreThanOneValidatorFound { known_validators } => {
|
Error::MoreThanOneValidatorFound { known_validators } => {
|
||||||
Some(Box::new(format!(
|
Some(Box::new(format!(
|
||||||
"Here's a list of all validators (and their purpose) I've found in your project. Select one of them using the appropriate options:\n\n{}",
|
"Here's a list of all validators (and their purpose) I've found in your project. Select one of them using the appropriate options:\n\n{}",
|
||||||
known_validators.iter().map(|(name, purpose)| format!("→ {name} (purpose = {purpose})", name = name.purple().bold(), purpose = purpose.bright_blue())).collect::<Vec<String>>().join("\n")
|
known_validators.iter().map(|title| format!("→ {title}", title = title.purple().bold())).collect::<Vec<String>>().join("\n")
|
||||||
)))
|
)))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub mod pretty;
|
||||||
pub mod script;
|
pub mod script;
|
||||||
pub mod telemetry;
|
pub mod telemetry;
|
||||||
|
|
||||||
use crate::blueprint::{schema::Schema, validator, Blueprint};
|
use crate::blueprint::{schema::Schema, Blueprint};
|
||||||
use aiken_lang::{
|
use aiken_lang::{
|
||||||
ast::{Definition, Function, ModuleKind, TypedDataType, TypedFunction},
|
ast::{Definition, Function, ModuleKind, TypedDataType, TypedFunction},
|
||||||
builder::{DataTypeKey, FunctionAccessKey},
|
builder::{DataTypeKey, FunctionAccessKey},
|
||||||
|
@ -287,7 +287,6 @@ where
|
||||||
pub fn address(
|
pub fn address(
|
||||||
&self,
|
&self,
|
||||||
title: Option<&String>,
|
title: Option<&String>,
|
||||||
purpose: Option<&validator::Purpose>,
|
|
||||||
stake_address: Option<&String>,
|
stake_address: Option<&String>,
|
||||||
) -> Result<ShelleyAddress, Error> {
|
) -> Result<ShelleyAddress, Error> {
|
||||||
// Parse stake address
|
// Parse stake address
|
||||||
|
@ -318,7 +317,8 @@ where
|
||||||
let when_too_many =
|
let when_too_many =
|
||||||
|known_validators| Error::MoreThanOneValidatorFound { known_validators };
|
|known_validators| Error::MoreThanOneValidatorFound { known_validators };
|
||||||
let when_missing = |known_validators| Error::NoValidatorNotFound { known_validators };
|
let when_missing = |known_validators| Error::NoValidatorNotFound { known_validators };
|
||||||
blueprint.with_validator(title, purpose, when_too_many, when_missing, |validator| {
|
|
||||||
|
blueprint.with_validator(title, when_too_many, when_missing, |validator| {
|
||||||
let n = validator.parameters.len();
|
let n = validator.parameters.len();
|
||||||
if n > 0 {
|
if n > 0 {
|
||||||
Err(blueprint::error::Error::ParameterizedValidator { n }.into())
|
Err(blueprint::error::Error::ParameterizedValidator { n }.into())
|
||||||
|
@ -333,7 +333,6 @@ where
|
||||||
pub fn apply_parameter(
|
pub fn apply_parameter(
|
||||||
&self,
|
&self,
|
||||||
title: Option<&String>,
|
title: Option<&String>,
|
||||||
purpose: Option<&validator::Purpose>,
|
|
||||||
param: &Term<DeBruijn>,
|
param: &Term<DeBruijn>,
|
||||||
) -> Result<Blueprint<serde_json::Value>, Error> {
|
) -> Result<Blueprint<serde_json::Value>, Error> {
|
||||||
// Read blueprint
|
// Read blueprint
|
||||||
|
@ -346,8 +345,9 @@ where
|
||||||
let when_too_many =
|
let when_too_many =
|
||||||
|known_validators| Error::MoreThanOneValidatorFound { known_validators };
|
|known_validators| Error::MoreThanOneValidatorFound { known_validators };
|
||||||
let when_missing = |known_validators| Error::NoValidatorNotFound { known_validators };
|
let when_missing = |known_validators| Error::NoValidatorNotFound { known_validators };
|
||||||
|
|
||||||
let applied_validator =
|
let applied_validator =
|
||||||
blueprint.with_validator(title, purpose, when_too_many, when_missing, |validator| {
|
blueprint.with_validator(title, when_too_many, when_missing, |validator| {
|
||||||
validator.apply(param).map_err(|e| e.into())
|
validator.apply(param).map_err(|e| e.into())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::with_project;
|
use crate::with_project;
|
||||||
use aiken_lang::VALIDATOR_NAMES;
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(clap::Args)]
|
#[derive(clap::Args)]
|
||||||
|
@ -11,11 +10,11 @@ pub struct Args {
|
||||||
|
|
||||||
/// Name of the validator's module within the project. Optional if there's only one validator.
|
/// Name of the validator's module within the project. Optional if there's only one validator.
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
validator: Option<String>,
|
module: Option<String>,
|
||||||
|
|
||||||
/// Purpose of the validator within the module. Optional if there's only one validator.
|
/// Name of the validator within the module. Optional if there's only one validator.
|
||||||
#[clap(short, long, possible_values=&VALIDATOR_NAMES)]
|
#[clap(short, long)]
|
||||||
purpose: Option<String>,
|
validator: Option<String>,
|
||||||
|
|
||||||
/// Stake address to attach, if any.
|
/// Stake address to attach, if any.
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
|
@ -29,8 +28,8 @@ pub struct Args {
|
||||||
pub fn exec(
|
pub fn exec(
|
||||||
Args {
|
Args {
|
||||||
directory,
|
directory,
|
||||||
|
module,
|
||||||
validator,
|
validator,
|
||||||
purpose,
|
|
||||||
delegated_to,
|
delegated_to,
|
||||||
rebuild,
|
rebuild,
|
||||||
}: Args,
|
}: Args,
|
||||||
|
@ -39,15 +38,23 @@ pub fn exec(
|
||||||
if rebuild {
|
if rebuild {
|
||||||
p.build(false)?;
|
p.build(false)?;
|
||||||
}
|
}
|
||||||
let address = p.address(
|
|
||||||
validator.as_ref(),
|
let title = module.as_ref().map(|m| {
|
||||||
purpose
|
format!(
|
||||||
.as_ref()
|
"{m}{}",
|
||||||
.map(|p| p.clone().try_into().unwrap())
|
validator
|
||||||
.as_ref(),
|
.as_ref()
|
||||||
delegated_to.as_ref(),
|
.map(|v| format!(".{v}"))
|
||||||
)?;
|
.unwrap_or("".to_string())
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
let title = title.as_ref().or(validator.as_ref());
|
||||||
|
|
||||||
|
let address = p.address(title, delegated_to.as_ref())?;
|
||||||
|
|
||||||
println!("{}", address.to_bech32().unwrap());
|
println!("{}", address.to_bech32().unwrap());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::with_project;
|
use crate::with_project;
|
||||||
use aiken_lang::VALIDATOR_NAMES;
|
|
||||||
use aiken_project::error::Error;
|
use aiken_project::error::Error;
|
||||||
use miette::IntoDiagnostic;
|
use miette::IntoDiagnostic;
|
||||||
use std::{fs, path::PathBuf};
|
use std::{fs, path::PathBuf};
|
||||||
|
@ -17,11 +16,11 @@ pub struct Args {
|
||||||
|
|
||||||
/// Name of the validator's module within the project. Optional if there's only one validator.
|
/// Name of the validator's module within the project. Optional if there's only one validator.
|
||||||
#[clap(short, long)]
|
#[clap(short, long)]
|
||||||
validator: Option<String>,
|
module: Option<String>,
|
||||||
|
|
||||||
/// Purpose of the validator within the module. Optional if there's only one validator.
|
/// Name of the validator within the module. Optional if there's only one validator.
|
||||||
#[clap(short, long, possible_values=&VALIDATOR_NAMES)]
|
#[clap(short, long)]
|
||||||
purpose: Option<String>,
|
validator: Option<String>,
|
||||||
|
|
||||||
/// The parameter, using high-level UPLC-syntax
|
/// The parameter, using high-level UPLC-syntax
|
||||||
parameter: String,
|
parameter: String,
|
||||||
|
@ -30,8 +29,8 @@ pub struct Args {
|
||||||
pub fn exec(
|
pub fn exec(
|
||||||
Args {
|
Args {
|
||||||
directory,
|
directory,
|
||||||
|
module,
|
||||||
validator,
|
validator,
|
||||||
purpose,
|
|
||||||
parameter,
|
parameter,
|
||||||
}: Args,
|
}: Args,
|
||||||
) -> miette::Result<()> {
|
) -> miette::Result<()> {
|
||||||
|
@ -41,16 +40,22 @@ pub fn exec(
|
||||||
.into_diagnostic()?;
|
.into_diagnostic()?;
|
||||||
|
|
||||||
with_project(directory, |p| {
|
with_project(directory, |p| {
|
||||||
let blueprint = p.apply_parameter(
|
let title = module.as_ref().map(|m| {
|
||||||
validator.as_ref(),
|
format!(
|
||||||
purpose
|
"{m}{}",
|
||||||
.as_ref()
|
validator
|
||||||
.map(|p| p.clone().try_into().unwrap())
|
.as_ref()
|
||||||
.as_ref(),
|
.map(|v| format!(".{v}"))
|
||||||
&term,
|
.unwrap_or("".to_string())
|
||||||
)?;
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
let title = title.as_ref().or(validator.as_ref());
|
||||||
|
|
||||||
|
let blueprint = p.apply_parameter(title, &term)?;
|
||||||
|
|
||||||
let json = serde_json::to_string_pretty(&blueprint).unwrap();
|
let json = serde_json::to_string_pretty(&blueprint).unwrap();
|
||||||
|
|
||||||
fs::write(p.blueprint_path(), json).map_err(|error| Error::FileIo {
|
fs::write(p.blueprint_path(), json).map_err(|error| Error::FileIo {
|
||||||
error,
|
error,
|
||||||
path: p.blueprint_path(),
|
path: p.blueprint_path(),
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
},
|
},
|
||||||
"validators": [
|
"validators": [
|
||||||
{
|
{
|
||||||
"title": "hello_world-spend",
|
"title": "hello_world.spend",
|
||||||
"datum": {
|
"datum": {
|
||||||
"title": "Datum",
|
"title": "Datum",
|
||||||
"anyOf": [
|
"anyOf": [
|
||||||
|
|
Loading…
Reference in New Issue