Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,14 @@ impl TemplateProgram {
debug_symbols: self.simfony.debug_symbols(self.file.as_ref()),
simplicity: commit,
witness_types: self.simfony.witness_types().shallow_clone(),
parameter_types: self.simfony.parameters().shallow_clone(),
})
}

pub fn generate_abi_meta(&self) -> Result<AbiMeta, String> {
Ok(AbiMeta {
witness_types: self.simfony.witness_types().shallow_clone(),
param_types: self.parameters().shallow_clone(),
})
}
}
Expand All @@ -99,6 +107,7 @@ pub struct CompiledProgram {
simplicity: Arc<named::CommitNode<Elements>>,
witness_types: WitnessTypes,
debug_symbols: DebugSymbols,
parameter_types: Parameters,
}

impl CompiledProgram {
Expand Down Expand Up @@ -162,6 +171,19 @@ impl CompiledProgram {
debug_symbols: self.debug_symbols.clone(),
})
}

pub fn generate_abi_meta(&self) -> Result<AbiMeta, String> {
Ok(AbiMeta {
witness_types: self.witness_types.shallow_clone(),
param_types: self.parameter_types.shallow_clone(),
})
}
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct AbiMeta {
pub witness_types: WitnessTypes,
pub param_types: Parameters,
}

/// A SimplicityHL program, compiled to Simplicity and satisfied with witness data.
Expand Down
21 changes: 20 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use base64::display::Base64Display;
use base64::engine::general_purpose::STANDARD;
use clap::{Arg, ArgAction, Command};

use simplicityhl::{Arguments, CompiledProgram};
use simplicityhl::{AbiMeta, Arguments, CompiledProgram};
use std::{env, fmt};

#[cfg_attr(feature = "serde", derive(serde::Serialize))]
Expand All @@ -12,6 +12,8 @@ struct Output {
program: String,
/// Simplicity witness result, base64 encoded, if the .wit file was provided.
witness: Option<String>,
/// Simplicity program ABI metadata to the program which the user provides.
abi_meta: Option<AbiMeta>,
}

impl fmt::Display for Output {
Expand All @@ -20,6 +22,9 @@ impl fmt::Display for Output {
if let Some(witness) = &self.witness {
writeln!(f, "Witness:\n{}", witness)?;
}
if let Some(witness) = &self.abi_meta {
writeln!(f, "ABI meta:\n{:?}", witness)?;
}
Ok(())
}
}
Expand Down Expand Up @@ -59,6 +64,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
.action(ArgAction::SetTrue)
.help("Output in JSON"),
)
.arg(
Arg::new("abi")
.long("abi")
.action(ArgAction::SetTrue)
.help("Additional ABI .simf contract types"),
)
};

let matches = command.get_matches();
Expand All @@ -68,6 +79,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let prog_text = std::fs::read_to_string(prog_path).map_err(|e| e.to_string())?;
let include_debug_symbols = matches.get_flag("debug");
let output_json = matches.get_flag("json");
let abi_param = matches.get_flag("abi");

let compiled = CompiledProgram::new(prog_text, Arguments::default(), include_debug_symbols)?;

Expand Down Expand Up @@ -103,9 +115,16 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
}
};

let abi_opt = if abi_param {
Some(compiled.generate_abi_meta()?)
} else {
None
};

let output = Output {
program: Base64Display::new(&program_bytes, &STANDARD).to_string(),
witness: witness_bytes.map(|bytes| Base64Display::new(&bytes, &STANDARD).to_string()),
abi_meta: abi_opt,
};

if output_json {
Expand Down
64 changes: 62 additions & 2 deletions src/serde.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use std::collections::HashMap;
use std::fmt;

use serde::{de, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};

use crate::parse::ParseFromStr;
use crate::str::WitnessName;
use crate::types::ResolvedType;
use crate::value::Value;
use crate::witness::{Arguments, WitnessValues};
use crate::{AbiMeta, Parameters, WitnessTypes};
use serde::{de, ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer};

struct WitnessMapVisitor;

Expand Down Expand Up @@ -43,6 +43,66 @@ impl<'de> Deserialize<'de> for WitnessValues {
}
}

impl Serialize for ResolvedType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(&self.to_string())
}
}

impl Serialize for WitnessName {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self.as_ref())
}
}

impl Serialize for AbiMeta {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: ::serde::Serializer,
{
use ::serde::ser::SerializeStruct;

let mut state = serializer.serialize_struct("AbiMeta", 2)?;
state.serialize_field("witness_types", &self.witness_types)?;
state.serialize_field("parameter_types", &self.param_types)?;
state.end()
}
}

impl Serialize for Parameters {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let map_ref = self.as_ref();
let mut map = serializer.serialize_map(Some(map_ref.len()))?;
for (key, value) in map_ref {
map.serialize_entry(key, value)?;
}
map.end()
}
}

impl Serialize for WitnessTypes {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let map_ref = self.as_ref();
let mut map = serializer.serialize_map(Some(map_ref.len()))?;
for (key, value) in map_ref {
map.serialize_entry(key, value)?;
}
map.end()
}
}

impl<'de> Deserialize<'de> for Arguments {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
Expand Down
6 changes: 6 additions & 0 deletions src/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ pub struct WitnessName(Arc<str>);
wrapped_string!(WitnessName, "witness name");
impl_arbitrary_lowercase_alpha!(WitnessName);

impl AsRef<str> for WitnessName {
fn as_ref(&self) -> &str {
self.0.as_ref()
}
}

/// The name of a jet.
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct JetName(Arc<str>);
Expand Down
12 changes: 12 additions & 0 deletions src/witness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,12 @@ pub struct WitnessTypes(Arc<HashMap<WitnessName, ResolvedType>>);

impl_name_type_map!(WitnessTypes);

impl AsRef<HashMap<WitnessName, ResolvedType>> for WitnessTypes {
fn as_ref(&self) -> &HashMap<WitnessName, ResolvedType> {
self.0.as_ref()
}
}

/// Map of witness values.
#[derive(Clone, Debug, Eq, PartialEq, Default)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
Expand Down Expand Up @@ -151,6 +157,12 @@ pub struct Parameters(Arc<HashMap<WitnessName, ResolvedType>>);

impl_name_type_map!(Parameters);

impl AsRef<HashMap<WitnessName, ResolvedType>> for Parameters {
fn as_ref(&self) -> &HashMap<WitnessName, ResolvedType> {
self.0.as_ref()
}
}

/// Map of arguments.
///
/// An argument is the value of a parameter.
Expand Down