diff --git a/Cargo.lock b/Cargo.lock index 0f11dbb35f1..83884bbf57a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2166,10 +2166,12 @@ dependencies = [ "build-data", "console_error_panic_hook", "gloo-utils", + "log", "noirc_driver", "noirc_frontend", "serde", "wasm-bindgen", + "wasm-logger", ] [[package]] @@ -3682,6 +3684,17 @@ dependencies = [ "leb128", ] +[[package]] +name = "wasm-logger" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "074649a66bb306c8f2068c9016395fa65d8e08d2affcbf95acf3c24c3ab19718" +dependencies = [ + "log", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "wasmer" version = "2.3.0" diff --git a/crates/fm/src/file_reader.rs b/crates/fm/src/file_reader.rs index 6b45d990633..f0a5fe625aa 100644 --- a/crates/fm/src/file_reader.rs +++ b/crates/fm/src/file_reader.rs @@ -26,7 +26,8 @@ cfg_if::cfg_if! { pub(crate) fn read_file_to_string(path_to_file: &Path) -> Result { use std::io::ErrorKind; - match StdLibAssets::get(path_to_file.to_str().unwrap()) { + let path_str = path_to_file.to_str().unwrap(); + match StdLibAssets::get(path_str) { Some(std_lib_asset) => { Ok(std::str::from_utf8(std_lib_asset.data.as_ref()).unwrap().to_string()) diff --git a/crates/wasm/Cargo.toml b/crates/wasm/Cargo.toml index 6f390ad46ae..bbcabe12e0a 100644 --- a/crates/wasm/Cargo.toml +++ b/crates/wasm/Cargo.toml @@ -17,7 +17,8 @@ noirc_driver.workspace = true noirc_frontend.workspace = true wasm-bindgen.workspace = true serde.workspace = true - +log = "0.4.17" +wasm-logger = "0.2.0" console_error_panic_hook = "0.1.7" gloo-utils = { version = "0.1", features = ["serde"] } diff --git a/crates/wasm/build-wasm b/crates/wasm/build-wasm index c7c0de14c7a..0762d12fff3 100755 --- a/crates/wasm/build-wasm +++ b/crates/wasm/build-wasm @@ -18,7 +18,7 @@ else VERSION_APPENDIX="-NOGIT" fi -jq -s '.[0] * .[1]' pkg/nodejs/package.json pkg/web/package.json | jq '.files = ["nodejs", "web", "package.json"]' | jq ".version += \"$VERSION_APPENDIX\"" | jq '.main = "./nodejs/" + .main | .module = "./web/" + .module | .types = "./web/" + .types | .peerDependencies = { "@noir-lang/noir-source-resolver": "1.0.0" }' | tee ./pkg/package.json +jq -s '.[0] * .[1]' pkg/nodejs/package.json pkg/web/package.json | jq '.files = ["nodejs", "web", "package.json"]' | jq ".version += \"$VERSION_APPENDIX\"" | jq '.main = "./nodejs/" + .main | .module = "./web/" + .module | .types = "./web/" + .types | .peerDependencies = { "@noir-lang/noir-source-resolver": "1.1.1" }' | tee ./pkg/package.json rm pkg/nodejs/package.json pkg/nodejs/README.md pkg/nodejs/.gitignore diff --git a/crates/wasm/src/lib.rs b/crates/wasm/src/lib.rs index 9d5c5c11337..61212dbaacd 100644 --- a/crates/wasm/src/lib.rs +++ b/crates/wasm/src/lib.rs @@ -1,13 +1,13 @@ #![forbid(unsafe_code)] #![warn(unused_crate_dependencies, unused_extern_crates)] #![warn(unreachable_pub)] - use acvm::acir::circuit::Circuit; use gloo_utils::format::JsValueSerdeExt; +use log::{debug, Level}; use noirc_driver::{CompileOptions, Driver}; use noirc_frontend::graph::{CrateName, CrateType}; use serde::{Deserialize, Serialize}; -use std::path::PathBuf; +use std::{path::PathBuf, str::FromStr}; use wasm_bindgen::prelude::*; #[derive(Serialize, Deserialize)] @@ -17,8 +17,14 @@ pub struct BuildInfo { dirty: &'static str, } -#[derive(Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct WASMCompileOptions { + #[serde(default = "default_entry_point")] + entry_point: String, + + #[serde(default = "default_circuit_name")] + circuit_name: String, + // Compile each contract function used within the program #[serde(default = "bool::default")] contracts: bool, @@ -28,14 +34,52 @@ pub struct WASMCompileOptions { #[serde(default)] optional_dependencies_set: Vec, + + #[serde(default = "default_log_level")] + log_level: String, +} + +fn default_log_level() -> String { + String::from("info") +} + +fn default_circuit_name() -> String { + String::from("contract") +} + +fn default_entry_point() -> String { + String::from("main.nr") } +impl Default for WASMCompileOptions { + fn default() -> Self { + Self { + entry_point: default_entry_point(), + circuit_name: default_circuit_name(), + log_level: default_log_level(), + contracts: false, + compile_options: CompileOptions::default(), + optional_dependencies_set: vec![], + } + } +} + +#[wasm_bindgen] +pub fn init_log_level(level: String) { + // Set the static variable from Rust + use std::sync::Once; + + let log_level = Level::from_str(&level).unwrap_or(Level::Error); + static SET_HOOK: Once = Once::new(); + SET_HOOK.call_once(|| { + wasm_logger::init(wasm_logger::Config::new(log_level)); + }); +} const BUILD_INFO: BuildInfo = BuildInfo { git_hash: env!("GIT_COMMIT"), version: env!("CARGO_PKG_VERSION"), dirty: env!("GIT_DIRTY"), }; - pub fn add_noir_lib(driver: &mut Driver, crate_name: &str) { let path_to_lib = PathBuf::from(&crate_name).join("lib.nr"); let library_crate = driver.create_non_local_crate(path_to_lib, CrateType::Library); @@ -46,12 +90,22 @@ pub fn add_noir_lib(driver: &mut Driver, crate_name: &str) { #[wasm_bindgen] pub fn compile(args: JsValue) -> JsValue { console_error_panic_hook::set_once(); - let options: WASMCompileOptions = JsValueSerdeExt::into_serde(&args).unwrap(); + + let options: WASMCompileOptions = if args.is_undefined() || args.is_null() { + debug!("Initializing compiler with default values."); + WASMCompileOptions::default() + } else { + JsValueSerdeExt::into_serde(&args) + .unwrap_or_else(|_| panic!("Could not deserialize compile arguments")) + }; + + debug!("Compiler configuration {:?}", &options); + // For now we default to plonk width = 3, though we can add it as a parameter let language = acvm::Language::PLONKCSat { width: 3 }; - let path = PathBuf::from("main.nr"); let mut driver = noirc_driver::Driver::new(&language); + let path = PathBuf::from(&options.entry_point); driver.create_local_crate(path, CrateType::Binary); // We are always adding std lib implicitly. It comes bundled with binary. @@ -72,8 +126,9 @@ pub fn compile(args: JsValue) -> JsValue { let collected_compiled_programs: Vec<_> = compiled_contracts .into_iter() .flat_map(|contract| { + let contract_id = format!("{}-{}", options.circuit_name, &contract.name); contract.functions.into_iter().map(move |(function, program)| { - let program_name = format!("{}-{}", &contract.name, function); + let program_name = format!("{}-{}", contract_id, function); (program_name, program) }) })