diff --git a/Cargo.lock b/Cargo.lock index 1690530e1..8cb7818c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -158,9 +158,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "anymap2" @@ -170,9 +170,9 @@ checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" [[package]] name = "arrayref" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" @@ -392,9 +392,9 @@ dependencies = [ [[package]] name = "auth-git2" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51bd0e4592409df8631ca807716dc1e5caafae5d01ce0157c966c71c7e49c3c" +checksum = "3810b5af212b013fe7302b12d86616c6c39a48e18f2e4b812a5a9e5710213791" dependencies = [ "dirs", "git2", @@ -599,9 +599,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" [[package]] name = "camino" @@ -614,9 +614,8 @@ dependencies = [ [[package]] name = "cargo-component" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deedd1f20ddb574d9d198d979499f628f2865718190830523cb329e264ef1469" +version = "0.17.0-dev" +source = "git+https://github.com/greenhat/cargo-component?branch=use-as-lib#37c042e3340c25cfcb3646a2445e46321289bbfe" dependencies = [ "anyhow", "bytes", @@ -641,24 +640,23 @@ dependencies = [ "tempfile", "tokio", "tokio-util", - "toml_edit 0.22.20", + "toml_edit 0.22.21", "url", "wasi-preview1-component-adapter-provider", - "wasm-metadata 0.215.0", + "wasm-metadata 0.216.0", "wasm-pkg-client", - "wasmparser 0.215.0", + "wasmparser 0.216.0", "which", "wit-bindgen-core", "wit-bindgen-rust", - "wit-component 0.215.0", - "wit-parser 0.215.0", + "wit-component 0.216.0", + "wit-parser 0.216.0", ] [[package]] name = "cargo-component-core" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2942b6673d038ed6da6c7a5964372c540253dee1508c55b0f5f7614fb2c6c371" +version = "0.17.0-dev" +source = "git+https://github.com/greenhat/cargo-component?branch=use-as-lib#37c042e3340c25cfcb3646a2445e46321289bbfe" dependencies = [ "anyhow", "clap", @@ -672,13 +670,13 @@ dependencies = [ "serde 1.0.210", "tokio", "tokio-util", - "toml_edit 0.22.20", + "toml_edit 0.22.21", "unicode-width", "url", "wasm-pkg-client", "windows-sys 0.52.0", - "wit-component 0.215.0", - "wit-parser 0.215.0", + "wit-component 0.216.0", + "wit-parser 0.216.0", ] [[package]] @@ -690,7 +688,7 @@ dependencies = [ "home", "serde 1.0.210", "serde_derive", - "toml_edit 0.22.20", + "toml_edit 0.22.21", ] [[package]] @@ -742,6 +740,7 @@ dependencies = [ "anyhow", "cargo-component", "cargo-component-core", + "cargo-config2", "cargo-generate", "cargo_metadata", "clap", @@ -752,6 +751,7 @@ dependencies = [ "parse_arg", "path-absolutize", "semver 1.0.23", + "tokio", ] [[package]] @@ -826,9 +826,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.18" +version = "1.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" dependencies = [ "jobserver", "libc", @@ -2318,9 +2318,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.60" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -2867,18 +2867,18 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "logos" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1ceb190eb9bdeecdd8f1ad6a71d6d632a50905948771718741b5461fb01e13" +checksum = "1c6b6e02facda28ca5fb8dbe4b152496ba3b1bd5a4b40bb2b1b2d8ad74e0f39b" dependencies = [ "logos-derive", ] [[package]] name = "logos-codegen" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90be66cb7bd40cb5cc2e9cfaf2d1133b04a3d93b72344267715010a466e0915a" +checksum = "b32eb6b5f26efacd015b000bfc562186472cd9b34bdba3f6b264e2a052676d10" dependencies = [ "beef", "fnv", @@ -2891,9 +2891,9 @@ dependencies = [ [[package]] name = "logos-derive" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45154231e8e96586b39494029e58f12f8ffcb5ecf80333a603a13aa205ea8cbd" +checksum = "3e5d0c5463c911ef55624739fc353238b4e310f0144be1f875dc42fec6bfd5ec" dependencies = [ "logos-codegen", ] @@ -3022,9 +3022,9 @@ dependencies = [ [[package]] name = "miden-crypto" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6fad06fc3af260ed3c4235821daa2132813d993f96d446856036ae97e9606dd" +checksum = "8a69f8362ca496a79c88cf8e5b9b349bf9c6ed49fa867d0548e670afc1f3fca5" dependencies = [ "blake3", "cc", @@ -3130,9 +3130,9 @@ dependencies = [ [[package]] name = "miden-processor" -version = "0.10.5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01e7b212b152b69373e89b069a18cb01742ef2c3f9c328e7b24c44e44f022e52" +checksum = "04a128e20400086c9a985f4e5702e438ba781338fb0bdf9acff16d996c640087" dependencies = [ "miden-air", "miden-core", @@ -3954,9 +3954,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.12" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c73c26c01b8c87956cea613c907c9d6ecffd8d18a2a5908e5de0adfaa185cea" +checksum = "fdbef9d1d47087a895abd220ed25eb4ad973a5e26f6a4367b038c25e28dfc2d9" dependencies = [ "memchr", "thiserror", @@ -3965,9 +3965,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.12" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "664d22978e2815783adbdd2c588b455b1bd625299ce36b2a99881ac9627e6d8d" +checksum = "4d3a6e3394ec80feb3b6393c725571754c6188490265c61aaf260810d6b95aa0" dependencies = [ "pest", "pest_generator", @@ -3975,9 +3975,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.12" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2d5487022d5d33f4c30d91c22afa240ce2a644e87fe08caad974d4eab6badbe" +checksum = "94429506bde1ca69d1b5601962c73f4172ab4726571a59ea95931218cb0e930e" dependencies = [ "pest", "pest_meta", @@ -3988,9 +3988,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.12" +version = "2.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0091754bbd0ea592c4deb3a122ce8ecbb0753b738aa82bc055fcc2eccc8d8174" +checksum = "ac8a071862e93690b6e34e9a5fb8e33ff3734473ac0245b27232222c4906a33f" dependencies = [ "once_cell", "pest", @@ -4135,9 +4135,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "pretty_assertions" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" dependencies = [ "diff", "yansi", @@ -5686,7 +5686,7 @@ dependencies = [ "serde 1.0.210", "serde_spanned", "toml_datetime", - "toml_edit 0.22.20", + "toml_edit 0.22.21", ] [[package]] @@ -5711,9 +5711,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" dependencies = [ "indexmap 2.5.0", "serde 1.0.210", @@ -5922,18 +5922,18 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-truncate" @@ -5948,15 +5948,15 @@ dependencies = [ [[package]] name = "unicode-width" -version = "0.1.13" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] name = "unicode-xid" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "unsafe-libyaml" @@ -6482,7 +6482,6 @@ dependencies = [ "hashbrown 0.14.5", "indexmap 2.5.0", "semver 1.0.23", - "serde 1.0.210", ] [[package]] @@ -6496,6 +6495,7 @@ dependencies = [ "hashbrown 0.14.5", "indexmap 2.5.0", "semver 1.0.23", + "serde 1.0.210", ] [[package]] @@ -6542,9 +6542,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.5" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bd24728e5af82c6c4ec1b66ac4844bdf8156257fccda846ec58b42cd0cdbe6a" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" dependencies = [ "rustls-pki-types", ] @@ -6927,29 +6927,27 @@ checksum = "c3d71ec2c97685c7e7460a30e27f955d26b8426e7c2db0ddb55a6e0537141f53" [[package]] name = "wit-bindgen-core" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb7e3df01cd43cfa1cb52602e4fc05cb2b62217655f6705639b6953eb0a3fed2" +version = "0.31.0" +source = "git+https://github.com/greenhat/wit-bindgen.git?branch=with-type-remapping-draft#f40b35324889d614074beb529a9b0bd390bdb7c1" dependencies = [ "anyhow", "heck 0.5.0", - "wit-parser 0.215.0", + "wit-parser 0.216.0", ] [[package]] name = "wit-bindgen-rust" -version = "0.30.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61a767d1a8eb4e908bfc53febc48b87ada545703b16fe0148ee7736a29a01417" +version = "0.31.0" +source = "git+https://github.com/greenhat/wit-bindgen.git?branch=with-type-remapping-draft#f40b35324889d614074beb529a9b0bd390bdb7c1" dependencies = [ "anyhow", "heck 0.5.0", "indexmap 2.5.0", "prettyplease", "syn 2.0.77", - "wasm-metadata 0.215.0", + "wasm-metadata 0.216.0", "wit-bindgen-core", - "wit-component 0.215.0", + "wit-component 0.216.0", ] [[package]] @@ -7047,9 +7045,9 @@ dependencies = [ [[package]] name = "yansi" -version = "0.5.1" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" [[package]] name = "zbus" diff --git a/Cargo.toml b/Cargo.toml index 26bfea1f4..44b314560 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -108,6 +108,8 @@ cargo-miden = { version = "0.0.7", path = "tools/cargo-miden" } miden-integration-tests = { version = "0.0.0", path = "tests/integration" } wat = "1.0.69" blake3 = "1.5" +tokio = { version = "1.39.2", features = ["rt", "time", "macros"] } +tokio-util = "0.7.11" [profile.dev] lto = false diff --git a/frontend-wasm/src/component/types/mod.rs b/frontend-wasm/src/component/types/mod.rs index 008608e5a..8fd6d9d8b 100644 --- a/frontend-wasm/src/component/types/mod.rs +++ b/frontend-wasm/src/component/types/mod.rs @@ -1736,7 +1736,7 @@ pub fn interface_type_to_ir( InterfaceType::U32 => midenc_hir_type::Type::U32, InterfaceType::S64 => midenc_hir_type::Type::I64, InterfaceType::U64 => midenc_hir_type::Type::U64, - InterfaceType::Float32 => todo!(), + InterfaceType::Float32 => midenc_hir_type::Type::Felt, InterfaceType::Float64 => todo!(), InterfaceType::Char => todo!(), InterfaceType::String => todo!(), diff --git a/frontend-wasm/src/intrinsics/felt.rs b/frontend-wasm/src/intrinsics/felt.rs index 01e8a76ec..74e262fa3 100644 --- a/frontend-wasm/src/intrinsics/felt.rs +++ b/frontend-wasm/src/intrinsics/felt.rs @@ -4,7 +4,7 @@ use midenc_hir::{FunctionIdent, InstBuilder, SourceSpan, Type::*, Value}; use crate::module::function_builder_ext::FunctionBuilderExt; -pub(crate) const INTRINSICS_FELT_MODULE_NAME: &str = "miden:stdlib/intrinsics_felt"; +pub(crate) const MODULE_ID: &str = "miden:core-import/intrinsics-felt@1.0.0"; /// Convert a call to a felt op intrinsic function into instruction(s) pub(crate) fn convert_felt_intrinsics( diff --git a/frontend-wasm/src/intrinsics/mem.rs b/frontend-wasm/src/intrinsics/mem.rs index de6b66362..53b796393 100644 --- a/frontend-wasm/src/intrinsics/mem.rs +++ b/frontend-wasm/src/intrinsics/mem.rs @@ -2,6 +2,8 @@ use midenc_hir::{AbiParam, FunctionIdent, InstBuilder, Signature, SourceSpan, Ty use crate::module::function_builder_ext::FunctionBuilderExt; +pub const MODULE_ID: &str = "miden:core-import/intrinsics-mem@1.0.0"; + /// Convert a call to a memory intrinsic function pub(crate) fn convert_mem_intrinsics( func_id: FunctionIdent, @@ -10,7 +12,7 @@ pub(crate) fn convert_mem_intrinsics( span: SourceSpan, ) -> Vec { match func_id.function.as_symbol().as_str() { - "heap_base" => { + "heap-base" => { assert_eq!(args.len(), 0, "{} takes no arguments", func_id); if builder .data_flow_graph() diff --git a/frontend-wasm/src/intrinsics/mod.rs b/frontend-wasm/src/intrinsics/mod.rs index 73abc88ba..217ce4618 100644 --- a/frontend-wasm/src/intrinsics/mod.rs +++ b/frontend-wasm/src/intrinsics/mod.rs @@ -16,8 +16,8 @@ fn modules() -> &'static HashSet<&'static str> { static MODULES: OnceLock> = OnceLock::new(); MODULES.get_or_init(|| { let mut s = HashSet::default(); - s.insert("intrinsics::mem"); - s.insert(felt::INTRINSICS_FELT_MODULE_NAME); + s.insert(mem::MODULE_ID); + s.insert(felt::MODULE_ID); s }) } @@ -30,10 +30,8 @@ pub fn convert_intrinsics_call( span: SourceSpan, ) -> Vec { match func_id.module.as_symbol().as_str() { - "intrinsics::mem" => mem::convert_mem_intrinsics(func_id, args, builder, span), - felt::INTRINSICS_FELT_MODULE_NAME => { - felt::convert_felt_intrinsics(func_id, args, builder, span) - } + mem::MODULE_ID => mem::convert_mem_intrinsics(func_id, args, builder, span), + felt::MODULE_ID => felt::convert_felt_intrinsics(func_id, args, builder, span), _ => panic!("No intrinsics found for {}", func_id), } } diff --git a/frontend-wasm/src/miden_abi/stdlib/crypto/hashes.rs b/frontend-wasm/src/miden_abi/stdlib/crypto/hashes.rs index 83b1dd781..700810267 100644 --- a/frontend-wasm/src/miden_abi/stdlib/crypto/hashes.rs +++ b/frontend-wasm/src/miden_abi/stdlib/crypto/hashes.rs @@ -3,7 +3,9 @@ use midenc_hir_type::Type::*; use crate::miden_abi::{FunctionTypeMap, ModuleFunctionTypeMap}; -pub(crate) const BLAKE3_HASH_1TO1: &str = "hash_1to1"; +pub const MODULE_ID: &str = "miden:core-import/stdlib-crypto-hashes@1.0.0"; + +pub(crate) const BLAKE3_HASH_1TO1: &str = "blake3-hash-one-to-one"; pub(crate) const BLAKE3_HASH_2TO1: &str = "hash_2to1"; pub(crate) fn signatures() -> ModuleFunctionTypeMap { @@ -11,7 +13,6 @@ pub(crate) fn signatures() -> ModuleFunctionTypeMap { let mut blake3: FunctionTypeMap = Default::default(); blake3.insert( BLAKE3_HASH_1TO1, - //Accepts and returns a 8 Felt elements FunctionType::new( [I32, I32, I32, I32, I32, I32, I32, I32], [I32, I32, I32, I32, I32, I32, I32, I32], @@ -19,12 +20,11 @@ pub(crate) fn signatures() -> ModuleFunctionTypeMap { ); blake3.insert( BLAKE3_HASH_2TO1, - // Accepts 16 and returns a 8 Felt elements FunctionType::new( [I32, I32, I32, I32, I32, I32, I32, I32, I32, I32, I32, I32, I32, I32, I32, I32], [I32, I32, I32, I32, I32, I32, I32, I32], ), ); - m.insert("std::crypto::hashes::blake3", blake3); + m.insert(MODULE_ID, blake3); m } diff --git a/frontend-wasm/src/miden_abi/transform.rs b/frontend-wasm/src/miden_abi/transform.rs index d8f4dfd9d..5d6900be5 100644 --- a/frontend-wasm/src/miden_abi/transform.rs +++ b/frontend-wasm/src/miden_abi/transform.rs @@ -27,7 +27,7 @@ fn get_transform_strategy(module_id: &str, function_id: &str) -> TransformStrate stdlib::mem::PIPE_DOUBLE_WORDS_TO_MEMORY => return TransformStrategy::ReturnViaPointer, _ => (), }, - "std::crypto::hashes::blake3" => match function_id { + stdlib::crypto::hashes::MODULE_ID => match function_id { stdlib::crypto::hashes::BLAKE3_HASH_1TO1 => return TransformStrategy::ReturnViaPointer, stdlib::crypto::hashes::BLAKE3_HASH_2TO1 => return TransformStrategy::ReturnViaPointer, _ => (), @@ -40,13 +40,13 @@ fn get_transform_strategy(module_id: &str, function_id: &str) -> TransformStrate tx_kernel::note::GET_INPUTS => return TransformStrategy::ListReturn, _ => (), }, - "miden::account" => match function_id { + tx_kernel::account::MODULE_ID => match function_id { tx_kernel::account::ADD_ASSET => return TransformStrategy::ReturnViaPointer, tx_kernel::account::REMOVE_ASSET => return TransformStrategy::ReturnViaPointer, tx_kernel::account::GET_ID => return TransformStrategy::NoTransform, _ => (), }, - "miden::tx" => match function_id { + tx_kernel::tx::MODULE_ID => match function_id { tx_kernel::tx::CREATE_NOTE => return TransformStrategy::NoTransform, _ => (), }, diff --git a/frontend-wasm/src/miden_abi/tx_kernel/account.rs b/frontend-wasm/src/miden_abi/tx_kernel/account.rs index 97cea3277..dbe9ef0f3 100644 --- a/frontend-wasm/src/miden_abi/tx_kernel/account.rs +++ b/frontend-wasm/src/miden_abi/tx_kernel/account.rs @@ -3,8 +3,10 @@ use midenc_hir_type::Type::*; use crate::miden_abi::{FunctionTypeMap, ModuleFunctionTypeMap}; -pub const ADD_ASSET: &str = "add_asset"; -pub const REMOVE_ASSET: &str = "remove_asset"; +pub const MODULE_ID: &str = "miden:core-import/account@1.0.0"; + +pub const ADD_ASSET: &str = "add-asset"; +pub const REMOVE_ASSET: &str = "remove-asset"; pub const GET_ID: &str = "get_id"; pub(crate) fn signatures() -> ModuleFunctionTypeMap { @@ -17,6 +19,6 @@ pub(crate) fn signatures() -> ModuleFunctionTypeMap { FunctionType::new([Felt, Felt, Felt, Felt], [Felt, Felt, Felt, Felt]), ); account.insert(GET_ID, FunctionType::new([], [Felt])); - m.insert("miden::account", account); + m.insert(MODULE_ID, account); m } diff --git a/frontend-wasm/src/miden_abi/tx_kernel/tx.rs b/frontend-wasm/src/miden_abi/tx_kernel/tx.rs index c1b63815c..da9390121 100644 --- a/frontend-wasm/src/miden_abi/tx_kernel/tx.rs +++ b/frontend-wasm/src/miden_abi/tx_kernel/tx.rs @@ -3,7 +3,9 @@ use midenc_hir_type::Type::*; use crate::miden_abi::{FunctionTypeMap, ModuleFunctionTypeMap}; -pub const CREATE_NOTE: &str = "create_note"; +pub const MODULE_ID: &str = "miden:core-import/tx@1.0.0"; + +pub const CREATE_NOTE: &str = "create-note"; pub(crate) fn signatures() -> ModuleFunctionTypeMap { let mut m: ModuleFunctionTypeMap = Default::default(); @@ -12,6 +14,6 @@ pub(crate) fn signatures() -> ModuleFunctionTypeMap { CREATE_NOTE, FunctionType::new([Felt, Felt, Felt, Felt, Felt, Felt, Felt, Felt, Felt, Felt], [Felt]), ); - m.insert("miden::tx", note); + m.insert(MODULE_ID, note); m } diff --git a/midenc-debug/Cargo.toml b/midenc-debug/Cargo.toml index 72f24e0fd..024b4abb1 100644 --- a/midenc-debug/Cargo.toml +++ b/midenc-debug/Cargo.toml @@ -31,8 +31,8 @@ serde.workspace = true ratatui = "0.28.0" crossterm = { version = "0.28.1", features = ["event-stream"] } tui-input = "0.10" -tokio = { version = "1.39.2", features = ["rt", "time", "macros"] } -tokio-util = "0.7.11" +tokio.workspace = true +tokio-util.workspace = true futures = "0.3.30" signal-hook = "0.3.17" syntect = { version = "5.2.0", default-features = false, features = [ diff --git a/sdk/alloc/src/lib.rs b/sdk/alloc/src/lib.rs index 045312d64..822686a75 100644 --- a/sdk/alloc/src/lib.rs +++ b/sdk/alloc/src/lib.rs @@ -123,7 +123,8 @@ unsafe impl GlobalAlloc for BumpAlloc { } #[cfg(target_family = "wasm")] -#[link(wasm_import_module = "intrinsics::mem")] +#[link(wasm_import_module = "miden:core-import/intrinsics-mem@1.0.0")] extern "C" { + #[link_name = "heap-base"] fn heap_base() -> *mut u8; } diff --git a/sdk/base-sys/src/bindings/tx/externs.rs b/sdk/base-sys/src/bindings/tx/externs.rs index 85ee9c9ce..3b796c45f 100644 --- a/sdk/base-sys/src/bindings/tx/externs.rs +++ b/sdk/base-sys/src/bindings/tx/externs.rs @@ -2,13 +2,13 @@ use miden_stdlib_sys::Felt; use crate::bindings::tx::{AccountId, CoreAsset, NoteId, NoteType, Tag}; -#[link(wasm_import_module = "miden::account")] +#[link(wasm_import_module = "miden:core-import/account@1.0.0")] extern "C" { #[link_name = "get_id<0x0000000000000000000000000000000000000000000000000000000000000000>"] pub fn extern_account_get_id() -> AccountId; - #[link_name = "add_asset<0x0000000000000000000000000000000000000000000000000000000000000000>"] + #[link_name = "add-asset"] pub fn extern_account_add_asset(_: Felt, _: Felt, _: Felt, _: Felt, ptr: *mut CoreAsset); - #[link_name = "remove_asset<0x0000000000000000000000000000000000000000000000000000000000000000>"] + #[link_name = "remove-asset"] pub fn extern_account_remove_asset(_: Felt, _: Felt, _: Felt, _: Felt, ptr: *mut CoreAsset); } @@ -18,9 +18,9 @@ extern "C" { pub fn extern_note_get_inputs(ptr: *mut Felt) -> usize; } -#[link(wasm_import_module = "miden::tx")] +#[link(wasm_import_module = "miden:core-import/tx@1.0.0")] extern "C" { - #[link_name = "create_note<0x0000000000000000000000000000000000000000000000000000000000000000>"] + #[link_name = "create-note"] pub fn extern_tx_create_note( asset_f0: Felt, asset_f1: Felt, diff --git a/sdk/base-sys/src/bindings/tx/mod.rs b/sdk/base-sys/src/bindings/tx/mod.rs index 853ca0e07..f7b48cbc3 100644 --- a/sdk/base-sys/src/bindings/tx/mod.rs +++ b/sdk/base-sys/src/bindings/tx/mod.rs @@ -107,10 +107,10 @@ pub fn create_note( asset.inner[3], tag, note_type, - recipient.0[0], - recipient.0[1], - recipient.0[2], - recipient.0[3], + recipient.inner[0], + recipient.inner[1], + recipient.inner[2], + recipient.inner[3], ) } } diff --git a/sdk/base-sys/src/bindings/tx/types.rs b/sdk/base-sys/src/bindings/tx/types.rs index c9225e045..ded6fb46d 100644 --- a/sdk/base-sys/src/bindings/tx/types.rs +++ b/sdk/base-sys/src/bindings/tx/types.rs @@ -12,7 +12,7 @@ impl From for Felt { #[repr(transparent)] pub struct CoreAsset { - pub(crate) inner: Word, + pub inner: Word, } impl CoreAsset { @@ -26,13 +26,19 @@ impl CoreAsset { } #[repr(transparent)] -pub struct Recipient(pub(crate) Word); +pub struct Recipient { + pub inner: Word, +} #[repr(transparent)] -pub struct Tag(pub(crate) Felt); +pub struct Tag { + pub inner: Felt, +} #[repr(transparent)] pub struct NoteId(pub(crate) Felt); #[repr(transparent)] -pub struct NoteType(pub(crate) Felt); +pub struct NoteType { + pub inner: Felt, +} diff --git a/sdk/stdlib-sys/src/intrinsics/felt.rs b/sdk/stdlib-sys/src/intrinsics/felt.rs index 632eec144..910b60517 100644 --- a/sdk/stdlib-sys/src/intrinsics/felt.rs +++ b/sdk/stdlib-sys/src/intrinsics/felt.rs @@ -2,7 +2,7 @@ use core::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}; -#[link(wasm_import_module = "miden:stdlib/intrinsics_felt")] +#[link(wasm_import_module = "miden:core-import/intrinsics-felt@1.0.0")] extern "C" { #[link_name = "from_u64_unchecked"] fn extern_from_u64_unchecked(value: u64) -> Felt; @@ -80,8 +80,10 @@ pub enum FeltError { } #[repr(transparent)] -#[derive(Copy, Clone)] -pub struct Felt(f32); +#[derive(Copy, Clone, Debug)] +pub struct Felt { + pub inner: f32, +} impl Felt { /// Field modulus = 2^64 - 2^32 + 1 @@ -141,26 +143,34 @@ impl From for u64 { impl From for Felt { fn from(value: u32) -> Self { - Self(unsafe { core::mem::transmute::(value) }) + Self { + inner: unsafe { core::mem::transmute::(value) }, + } } } impl From for Felt { fn from(value: u16) -> Self { - Self(unsafe { core::mem::transmute::(value as u32) }) + Self { + inner: unsafe { core::mem::transmute::(value as u32) }, + } } } impl From for Felt { fn from(value: u8) -> Self { - Self(unsafe { core::mem::transmute::(value as u32) }) + Self { + inner: unsafe { core::mem::transmute::(value as u32) }, + } } } #[cfg(target_pointer_width = "32")] impl From for Felt { fn from(value: usize) -> Self { - Self(unsafe { core::mem::transmute(value as u32) }) + Self { + inner: unsafe { core::mem::transmute(value as u32) }, + } } } diff --git a/sdk/stdlib-sys/src/intrinsics/word.rs b/sdk/stdlib-sys/src/intrinsics/word.rs index a37278aa3..b0d336888 100644 --- a/sdk/stdlib-sys/src/intrinsics/word.rs +++ b/sdk/stdlib-sys/src/intrinsics/word.rs @@ -2,36 +2,51 @@ use core::ops::{Index, IndexMut}; use crate::Felt; -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] #[repr(C, align(32))] -pub struct Word([Felt; 4]); -impl Word { - pub const fn new(word: [Felt; 4]) -> Self { - Self(word) - } -} -impl From<[Felt; 4]> for Word { - fn from(word: [Felt; 4]) -> Self { - Self(word) - } -} -impl From for [Felt; 4] { - #[inline(always)] - fn from(word: Word) -> Self { - word.0 - } +// pub struct Word([Felt; 4]); +pub struct Word { + pub inner: (Felt, Felt, Felt, Felt), } +// impl Word { +// pub const fn new(word: [Felt; 4]) -> Self { +// Self { inner: word } +// } +// } +// impl From<[Felt; 4]> for Word { +// fn from(word: [Felt; 4]) -> Self { +// Self { inner: word } +// } +// } +// impl From for [Felt; 4] { +// #[inline(always)] +// fn from(word: Word) -> Self { +// word.inner +// } +// } impl Index for Word { type Output = Felt; #[inline(always)] fn index(&self, index: usize) -> &Self::Output { - self.0.index(index) + match index { + 0 => &self.inner.0, + 1 => &self.inner.1, + 2 => &self.inner.2, + 3 => &self.inner.3, + _ => unreachable!(), + } } } impl IndexMut for Word { #[inline(always)] fn index_mut(&mut self, index: usize) -> &mut Self::Output { - self.0.index_mut(index) + match index { + 0 => &mut self.inner.0, + 1 => &mut self.inner.1, + 2 => &mut self.inner.2, + 3 => &mut self.inner.3, + _ => unreachable!(), + } } } diff --git a/sdk/stdlib-sys/src/stdlib/crypto/hashes.rs b/sdk/stdlib-sys/src/stdlib/crypto/hashes.rs index 4994cc9b9..67aa94e8f 100644 --- a/sdk/stdlib-sys/src/stdlib/crypto/hashes.rs +++ b/sdk/stdlib-sys/src/stdlib/crypto/hashes.rs @@ -2,14 +2,14 @@ //! functions. The input and output elements are assumed to contain one 32-bit //! value per element. -#[link(wasm_import_module = "std::crypto::hashes::blake3")] +#[link(wasm_import_module = "miden:core-import/stdlib-crypto-hashes@1.0.0")] extern "C" { /// Computes BLAKE3 1-to-1 hash. /// /// Input: 32-bytes stored in the first 8 elements of the stack (32 bits per element). /// Output: A 32-byte digest stored in the first 8 elements of stack (32 bits per element). /// The output is passed back to the caller via a pointer. - #[link_name = "hash_1to1<0x0000000000000000000000000000000000000000000000000000000000000000>"] + #[link_name = "blake3-hash-one-to-one"] fn extern_blake3_hash_1to1( e1: u32, e2: u32, diff --git a/tests/integration/expected/abi_transform_stdlib_blake3_hash.wat b/tests/integration/expected/abi_transform_stdlib_blake3_hash.wat index 03b47714c..84954ea22 100644 --- a/tests/integration/expected/abi_transform_stdlib_blake3_hash.wat +++ b/tests/integration/expected/abi_transform_stdlib_blake3_hash.wat @@ -1,7 +1,7 @@ (module $abi_transform_stdlib_blake3_hash.wasm (type (;0;) (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32))) (type (;1;) (func (param i32 i32))) - (import "std::crypto::hashes::blake3" "hash_1to1<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_stdlib_sys::stdlib::crypto::hashes::extern_blake3_hash_1to1 (;0;) (type 0))) + (import "miden:core-import/stdlib-crypto-hashes@1.0.0" "blake3-hash-one-to-one" (func $miden_stdlib_sys::stdlib::crypto::hashes::extern_blake3_hash_1to1 (;0;) (type 0))) (func $entrypoint (;1;) (type 1) (param i32 i32) (local i32 i32) global.get $__stack_pointer diff --git a/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.hir b/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.hir index 16cb9a16e..8ad2d4c27 100644 --- a/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.hir +++ b/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.hir @@ -123,7 +123,7 @@ (condbr v60 (block 7 v68) (block 8))) (block 6 - (let (v38 u32) (call (#intrinsics::mem #heap_base))) + (let (v38 u32) (call (#miden:core-import/intrinsics-mem@1.0.0 #heap-base))) (let (v39 u32) (memory.size)) (let (v40 i32) (const.i32 16)) (let (v41 u32) (bitcast v40)) @@ -360,8 +360,9 @@ ) ;; Imports - (func (import #intrinsics::mem #heap_base) (result u32)) (func (import #miden::note #get_inputs) (param i32) (result i32 i32)) + (func (import #miden:core-import/intrinsics-mem@1.0.0 #heap-base) + (result u32)) ) ) diff --git a/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.wat b/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.wat index 435d4d2c0..9759c2f69 100644 --- a/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.wat +++ b/tests/integration/expected/abi_transform_tx_kernel_get_inputs_4.wat @@ -6,7 +6,7 @@ (type (;4;) (func (param i32 i32 i32) (result i32))) (type (;5;) (func (param i32 i32 i32))) (type (;6;) (func (param i32 i32))) - (import "intrinsics::mem" "heap_base" (func $miden_sdk_alloc::heap_base (;0;) (type 0))) + (import "miden:core-import/intrinsics-mem@1.0.0" "heap-base" (func $miden_sdk_alloc::heap_base (;0;) (type 0))) (import "miden::note" "get_inputs<0x0000000000000000000000000000000000000000000000000000000000000000>" (func $miden_base_sys::bindings::tx::externs::extern_note_get_inputs (;1;) (type 1))) (func $entrypoint (;2;) (type 2) (param i32) local.get 0 diff --git a/tests/integration/expected/rust_sdk/basic_wallet.hir b/tests/integration/expected/rust_sdk/basic_wallet.hir new file mode 100644 index 000000000..0b3ee37c8 --- /dev/null +++ b/tests/integration/expected/rust_sdk/basic_wallet.hir @@ -0,0 +1,1304 @@ +(component + ;; Component Imports + (lower (("miden:core-import/account@1.0.0" #add-asset) (digest 0x0000000000000000000000000000000000000000000000000000000000000000) (type (func (abi wasm) (param felt) (param felt) (param felt) (param felt) (param i32)))) (#miden:core-import/account@1.0.0 #add-asset) + (lower (("miden:core-import/account@1.0.0" #remove-asset) (digest 0x0000000000000000000000000000000000000000000000000000000000000000) (type (func (abi wasm) (param felt) (param felt) (param felt) (param felt) (param i32)))) (#miden:core-import/account@1.0.0 #remove-asset) + (lower (("miden:core-import/intrinsics-felt@1.0.0" #add) (digest 0x0000000000000000000000000000000000000000000000000000000000000000) (type (func (abi wasm) (param felt) (param felt) (result felt)))) (#miden:core-import/intrinsics-felt@1.0.0 #add) + (lower (("miden:core-import/intrinsics-mem@1.0.0" #heap-base) (digest 0x0000000000000000000000000000000000000000000000000000000000000000) (type (func (abi wasm) (result i32)))) (#miden:core-import/intrinsics-mem@1.0.0 #heap-base) + (lower (("miden:core-import/stdlib-crypto-hashes@1.0.0" #blake3-hash-one-to-one) (digest 0x0000000000000000000000000000000000000000000000000000000000000000) (type (func (abi wasm) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32)))) (#miden:core-import/stdlib-crypto-hashes@1.0.0 #blake3-hash-one-to-one) + (lower (("miden:core-import/tx@1.0.0" #create-note) (digest 0x0000000000000000000000000000000000000000000000000000000000000000) (type (func (abi wasm) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (result felt)))) (#miden:core-import/tx@1.0.0 #create-note) + + ;; Modules + (module #basic_wallet + ;; Data Segments + (data (mut) (offset 1048576) 0x010000000100000001000000010000000100000001000000010000000100000002000000) + + ;; Constants + (const (id 0) 0x00100000) + + ;; Global Variables + (global (export #__stack_pointer) (id 0) (type i32) (const 0)) + + ;; Functions + (func (export #__wasm_call_ctors) + (block 0 + (br (block 1))) + + (block 1 + (ret)) + ) + + (func (export #basic_wallet::bindings::__link_custom_section_describing_imports) + + (block 0 + (br (block 1))) + + (block 1 + (ret)) + ) + + (func (export #__rust_alloc) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 i32) (const.i32 1048620)) + (let (v4 i32) (call #::alloc v3 v1 v0)) + (br (block 1 v4))) + + (block 1 (param v2 i32) + (ret v2)) + ) + + (func (export #__rust_dealloc) (param i32) (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) + (br (block 1))) + + (block 1 + (ret)) + ) + + (func (export #__rust_realloc) + (param i32) (param i32) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) + (let (v5 i32) (const.i32 1048620)) + (let (v6 i32) (call #::alloc v5 v2 v3)) + (let (v7 i1) (eq v6 0)) + (let (v8 i32) (zext v7)) + (let (v9 i1) (neq v8 0)) + (condbr v9 (block 2 v6) (block 3))) + + (block 1 (param v4 i32) + (ret v4)) + + (block 2 (param v20 i32) + (br (block 1 v20))) + + (block 3 + (let (v10 u32) (bitcast v1)) + (let (v11 u32) (bitcast v3)) + (let (v12 i1) (lt v10 v11)) + (let (v13 i32) (sext v12)) + (let (v14 i1) (neq v13 0)) + (let (v15 i32) (select v14 v1 v3)) + (let (v16 u32) (bitcast v6)) + (let (v17 (ptr u8)) (inttoptr v16)) + (let (v18 u32) (bitcast v0)) + (let (v19 (ptr u8)) (inttoptr v18)) + (memcpy v19 v17 v15) + (br (block 2 v6))) + ) + + (func (export #__rust_alloc_zeroed) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 i32) (const.i32 1048620)) + (let (v4 i32) (call #::alloc v3 v1 v0)) + (let (v5 i1) (eq v4 0)) + (let (v6 i32) (zext v5)) + (let (v7 i1) (neq v6 0)) + (condbr v7 (block 2 v4) (block 3))) + + (block 1 (param v2 i32) + (ret v2)) + + (block 2 (param v13 i32) + (br (block 1 v13))) + + (block 3 + (let (v8 i32) (const.i32 0)) + (let (v9 u8) (trunc v8)) + (let (v10 u32) (bitcast v0)) + (let (v11 u32) (bitcast v4)) + (let (v12 (ptr u8)) (inttoptr v11)) + (memset v12 v10 v9) + (br (block 2 v4))) + ) + + (func (export #miden:basic-wallet/basic-wallet@1.0.0#receive-asset) + (param felt) (param felt) (param felt) (param felt) + (block 0 + (param v0 felt) + (param v1 felt) + (param v2 felt) + (param v3 felt) + (let (v4 i32) (const.i32 0)) + (let (v5 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v6 i32) (const.i32 64)) + (let (v7 i32) (sub.wrapping v5 v6)) + (let (v8 i32) (const.i32 -32)) + (let (v9 i32) (band v7 v8)) + (let (v10 (ptr i32)) (global.symbol #__stack_pointer)) + (store v10 v9) + (call #wit_bindgen_rt::run_ctors_once) + (let (v11 u32) (bitcast v9)) + (let (v12 u32) (add.checked v11 12)) + (let (v13 u32) (mod.unchecked v12 4)) + (assertz 250 v13) + (let (v14 (ptr felt)) (inttoptr v12)) + (store v14 v3) + (let (v15 u32) (bitcast v9)) + (let (v16 u32) (add.checked v15 8)) + (let (v17 u32) (mod.unchecked v16 4)) + (assertz 250 v17) + (let (v18 (ptr felt)) (inttoptr v16)) + (store v18 v2) + (let (v19 u32) (bitcast v9)) + (let (v20 u32) (add.checked v19 4)) + (let (v21 u32) (mod.unchecked v20 4)) + (assertz 250 v21) + (let (v22 (ptr felt)) (inttoptr v20)) + (store v22 v1) + (let (v23 u32) (bitcast v9)) + (let (v24 u32) (mod.unchecked v23 4)) + (assertz 250 v24) + (let (v25 (ptr felt)) (inttoptr v23)) + (store v25 v0) + (let (v26 i32) (const.i32 32)) + (let (v27 i32) (add.wrapping v9 v26)) + (call #miden_base_sys::bindings::tx::add_asset v27 v9) + (let (v28 (ptr i32)) (global.symbol #__stack_pointer)) + (store v28 v5) + (br (block 1))) + + (block 1 + (ret)) + ) + + (func (export #miden:basic-wallet/basic-wallet@1.0.0#send-asset) + (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) + (block 0 + (param v0 felt) + (param v1 felt) + (param v2 felt) + (param v3 felt) + (param v4 felt) + (param v5 felt) + (param v6 felt) + (param v7 felt) + (param v8 felt) + (param v9 felt) + (let (v10 i32) (const.i32 0)) + (let (v11 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v12 i32) (const.i32 96)) + (let (v13 i32) (sub.wrapping v11 v12)) + (let (v14 i32) (const.i32 -32)) + (let (v15 i32) (band v13 v14)) + (let (v16 (ptr i32)) (global.symbol #__stack_pointer)) + (store v16 v15) + (call #wit_bindgen_rt::run_ctors_once) + (let (v17 u32) (bitcast v15)) + (let (v18 u32) (add.checked v17 12)) + (let (v19 u32) (mod.unchecked v18 4)) + (assertz 250 v19) + (let (v20 (ptr felt)) (inttoptr v18)) + (store v20 v3) + (let (v21 u32) (bitcast v15)) + (let (v22 u32) (add.checked v21 8)) + (let (v23 u32) (mod.unchecked v22 4)) + (assertz 250 v23) + (let (v24 (ptr felt)) (inttoptr v22)) + (store v24 v2) + (let (v25 u32) (bitcast v15)) + (let (v26 u32) (add.checked v25 4)) + (let (v27 u32) (mod.unchecked v26 4)) + (assertz 250 v27) + (let (v28 (ptr felt)) (inttoptr v26)) + (store v28 v1) + (let (v29 u32) (bitcast v15)) + (let (v30 u32) (mod.unchecked v29 4)) + (assertz 250 v30) + (let (v31 (ptr felt)) (inttoptr v29)) + (store v31 v0) + (let (v32 u32) (bitcast v15)) + (let (v33 u32) (add.checked v32 44)) + (let (v34 u32) (mod.unchecked v33 4)) + (assertz 250 v34) + (let (v35 (ptr felt)) (inttoptr v33)) + (store v35 v9) + (let (v36 u32) (bitcast v15)) + (let (v37 u32) (add.checked v36 40)) + (let (v38 u32) (mod.unchecked v37 4)) + (assertz 250 v38) + (let (v39 (ptr felt)) (inttoptr v37)) + (store v39 v8) + (let (v40 u32) (bitcast v15)) + (let (v41 u32) (add.checked v40 36)) + (let (v42 u32) (mod.unchecked v41 4)) + (assertz 250 v42) + (let (v43 (ptr felt)) (inttoptr v41)) + (store v43 v7) + (let (v44 u32) (bitcast v15)) + (let (v45 u32) (add.checked v44 32)) + (let (v46 u32) (mod.unchecked v45 4)) + (assertz 250 v46) + (let (v47 (ptr felt)) (inttoptr v45)) + (store v47 v6) + (let (v48 i32) (const.i32 64)) + (let (v49 i32) (add.wrapping v15 v48)) + (call #miden_base_sys::bindings::tx::remove_asset v49 v15) + (let (v50 i32) (const.i32 64)) + (let (v51 i32) (add.wrapping v15 v50)) + (let (v52 i32) (const.i32 32)) + (let (v53 i32) (add.wrapping v15 v52)) + (let (v54 felt) (call #miden_base_sys::bindings::tx::create_note v51 v4 v5 v53)) + (let (v55 (ptr i32)) (global.symbol #__stack_pointer)) + (store v55 v11) + (br (block 1))) + + (block 1 + (ret)) + ) + + (func (export #miden:basic-wallet/basic-wallet@1.0.0#test-felt-intrinsics) + (param felt) (param felt) (result felt) + (block 0 (param v0 felt) (param v1 felt) + (call #wit_bindgen_rt::run_ctors_once) + (let (v3 felt) (add.unchecked v0 v1)) + (br (block 1 v3))) + + (block 1 (param v2 felt) + (ret v2)) + ) + + (func (export #miden:basic-wallet/basic-wallet@1.0.0#test-stdlib) + (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v3 i32) (const.i32 0)) + (let (v4 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v5 i32) (const.i32 96)) + (let (v6 i32) (sub.wrapping v4 v5)) + (let (v7 i32) (const.i32 -32)) + (let (v8 i32) (band v6 v7)) + (let (v9 (ptr i32)) (global.symbol #__stack_pointer)) + (store v9 v8) + (call #wit_bindgen_rt::run_ctors_once) + (let (v10 u32) (bitcast v8)) + (let (v11 u32) (add.checked v10 24)) + (let (v12 u32) (mod.unchecked v11 4)) + (assertz 250 v12) + (let (v13 (ptr i32)) (inttoptr v11)) + (store v13 v0) + (let (v14 u32) (bitcast v8)) + (let (v15 u32) (add.checked v14 20)) + (let (v16 u32) (mod.unchecked v15 4)) + (assertz 250 v16) + (let (v17 (ptr i32)) (inttoptr v15)) + (store v17 v1) + (let (v18 i32) (const.i32 32)) + (let (v19 i1) (neq v1 v18)) + (let (v20 i32) (zext v19)) + (let (v21 i1) (neq v20 0)) + (condbr v21 (block 3) (block 4))) + + (block 1 (param v2 i32)) + + (block 2 + (let (v174 u32) (bitcast v8)) + (let (v175 u32) (add.checked v174 92)) + (let (v176 u32) (mod.unchecked v175 4)) + (assertz 250 v176) + (let (v177 (ptr i32)) (inttoptr v175)) + (let (v178 i32) (load v177)) + (call #alloc::raw_vec::handle_error v96 v178) + (unreachable)) + + (block 3 + (unreachable)) + + (block 4 + (let (v22 i32) (const.i32 0)) + (let (v23 u32) (bitcast v8)) + (let (v24 u32) (add.checked v23 28)) + (let (v25 u32) (mod.unchecked v24 4)) + (assertz 250 v25) + (let (v26 (ptr i32)) (inttoptr v24)) + (store v26 v22) + (let (v27 u32) (bitcast v0)) + (let (v28 (ptr i32)) (inttoptr v27)) + (let (v29 i32) (load v28)) + (let (v30 u32) (bitcast v0)) + (let (v31 u32) (add.checked v30 4)) + (let (v32 (ptr i32)) (inttoptr v31)) + (let (v33 i32) (load v32)) + (let (v34 u32) (bitcast v0)) + (let (v35 u32) (add.checked v34 8)) + (let (v36 (ptr i32)) (inttoptr v35)) + (let (v37 i32) (load v36)) + (let (v38 u32) (bitcast v0)) + (let (v39 u32) (add.checked v38 12)) + (let (v40 (ptr i32)) (inttoptr v39)) + (let (v41 i32) (load v40)) + (let (v42 u32) (bitcast v0)) + (let (v43 u32) (add.checked v42 16)) + (let (v44 (ptr i32)) (inttoptr v43)) + (let (v45 i32) (load v44)) + (let (v46 u32) (bitcast v0)) + (let (v47 u32) (add.checked v46 20)) + (let (v48 (ptr i32)) (inttoptr v47)) + (let (v49 i32) (load v48)) + (let (v50 u32) (bitcast v0)) + (let (v51 u32) (add.checked v50 24)) + (let (v52 (ptr i32)) (inttoptr v51)) + (let (v53 i32) (load v52)) + (let (v54 u32) (bitcast v0)) + (let (v55 u32) (add.checked v54 28)) + (let (v56 (ptr i32)) (inttoptr v55)) + (let (v57 i32) (load v56)) + (let (v58 i32) (const.i32 20)) + (let (v59 i32) (add.wrapping v8 v58)) + (call # as core::ops::drop::Drop>::drop v59) + (let (v60 i32) (const.i32 20)) + (let (v61 i32) (add.wrapping v8 v60)) + (call # as core::ops::drop::Drop>::drop v61) + (let (v62 i32) (const.i32 32)) + (let (v63 i32) (add.wrapping v8 v62)) + (let [(v64 i32) (v65 i32) (v66 i32) (v67 i32) (v68 i32) (v69 i32) (v70 i32) (v71 i32)] (call (#miden:core-import/stdlib-crypto-hashes@1.0.0 #blake3-hash-one-to-one) v29 v33 v37 v41 v45 v49 v53 v57)) + (let (v72 u32) (bitcast v63)) + (let (v73 (ptr i32)) (inttoptr v72)) + (store v73 v64) + (let (v74 u32) (add.checked v72 4)) + (let (v75 (ptr i32)) (inttoptr v74)) + (store v75 v65) + (let (v76 u32) (add.checked v72 8)) + (let (v77 (ptr i32)) (inttoptr v76)) + (store v77 v66) + (let (v78 u32) (add.checked v72 12)) + (let (v79 (ptr i32)) (inttoptr v78)) + (store v79 v67) + (let (v80 u32) (add.checked v72 16)) + (let (v81 (ptr i32)) (inttoptr v80)) + (store v81 v68) + (let (v82 u32) (add.checked v72 20)) + (let (v83 (ptr i32)) (inttoptr v82)) + (store v83 v69) + (let (v84 u32) (add.checked v72 24)) + (let (v85 (ptr i32)) (inttoptr v84)) + (store v85 v70) + (let (v86 u32) (add.checked v72 28)) + (let (v87 (ptr i32)) (inttoptr v86)) + (store v87 v71) + (let (v88 i32) (const.i32 84)) + (let (v89 i32) (add.wrapping v8 v88)) + (let (v90 i32) (const.i32 32)) + (let (v91 i32) (const.i32 0)) + (call #alloc::raw_vec::RawVec::try_allocate_in v89 v90 v91) + (let (v92 u32) (bitcast v8)) + (let (v93 u32) (add.checked v92 88)) + (let (v94 u32) (mod.unchecked v93 4)) + (assertz 250 v94) + (let (v95 (ptr i32)) (inttoptr v93)) + (let (v96 i32) (load v95)) + (let (v97 u32) (bitcast v8)) + (let (v98 u32) (add.checked v97 84)) + (let (v99 u32) (mod.unchecked v98 4)) + (assertz 250 v99) + (let (v100 (ptr i32)) (inttoptr v98)) + (let (v101 i32) (load v100)) + (let (v102 i32) (const.i32 1)) + (let (v103 i1) (eq v101 v102)) + (let (v104 i32) (zext v103)) + (let (v105 i1) (neq v104 0)) + (condbr v105 (block 2) (block 5))) + + (block 5 + (let (v106 u32) (bitcast v8)) + (let (v107 u32) (add.checked v106 92)) + (let (v108 u32) (mod.unchecked v107 4)) + (assertz 250 v108) + (let (v109 (ptr i32)) (inttoptr v107)) + (let (v110 i32) (load v109)) + (let (v111 i32) (const.i32 24)) + (let (v112 i32) (add.wrapping v110 v111)) + (let (v113 u32) (bitcast v8)) + (let (v114 u32) (add.checked v113 56)) + (let (v115 u32) (mod.unchecked v114 8)) + (assertz 250 v115) + (let (v116 (ptr i64)) (inttoptr v114)) + (let (v117 i64) (load v116)) + (let (v118 u32) (bitcast v112)) + (let (v119 (ptr i64)) (inttoptr v118)) + (store v119 v117) + (let (v120 i32) (const.i32 16)) + (let (v121 i32) (add.wrapping v110 v120)) + (let (v122 u32) (bitcast v8)) + (let (v123 u32) (add.checked v122 48)) + (let (v124 u32) (mod.unchecked v123 8)) + (assertz 250 v124) + (let (v125 (ptr i64)) (inttoptr v123)) + (let (v126 i64) (load v125)) + (let (v127 u32) (bitcast v121)) + (let (v128 (ptr i64)) (inttoptr v127)) + (store v128 v126) + (let (v129 i32) (const.i32 8)) + (let (v130 i32) (add.wrapping v110 v129)) + (let (v131 u32) (bitcast v8)) + (let (v132 u32) (add.checked v131 40)) + (let (v133 u32) (mod.unchecked v132 8)) + (assertz 250 v133) + (let (v134 (ptr i64)) (inttoptr v132)) + (let (v135 i64) (load v134)) + (let (v136 u32) (bitcast v130)) + (let (v137 (ptr i64)) (inttoptr v136)) + (store v137 v135) + (let (v138 u32) (bitcast v8)) + (let (v139 u32) (add.checked v138 32)) + (let (v140 u32) (mod.unchecked v139 8)) + (assertz 250 v140) + (let (v141 (ptr i64)) (inttoptr v139)) + (let (v142 i64) (load v141)) + (let (v143 u32) (bitcast v110)) + (let (v144 (ptr i64)) (inttoptr v143)) + (store v144 v142) + (let (v145 i32) (const.i32 32)) + (let (v146 u32) (bitcast v8)) + (let (v147 u32) (add.checked v146 92)) + (let (v148 u32) (mod.unchecked v147 4)) + (assertz 250 v148) + (let (v149 (ptr i32)) (inttoptr v147)) + (store v149 v145) + (let (v150 u32) (bitcast v8)) + (let (v151 u32) (add.checked v150 88)) + (let (v152 u32) (mod.unchecked v151 4)) + (assertz 250 v152) + (let (v153 (ptr i32)) (inttoptr v151)) + (store v153 v110) + (let (v154 u32) (bitcast v8)) + (let (v155 u32) (add.checked v154 84)) + (let (v156 u32) (mod.unchecked v155 4)) + (assertz 250 v156) + (let (v157 (ptr i32)) (inttoptr v155)) + (store v157 v96) + (let (v158 i32) (const.i32 8)) + (let (v159 i32) (add.wrapping v8 v158)) + (let (v160 i32) (const.i32 84)) + (let (v161 i32) (add.wrapping v8 v160)) + (call #alloc::vec::Vec::into_boxed_slice v159 v161) + (let (v162 i32) (const.i32 0)) + (let (v163 u32) (bitcast v8)) + (let (v164 u32) (add.checked v163 8)) + (let (v165 u32) (mod.unchecked v164 8)) + (assertz 250 v165) + (let (v166 (ptr i64)) (inttoptr v164)) + (let (v167 i64) (load v166)) + (let (v168 u32) (bitcast v162)) + (let (v169 u32) (add.checked v168 1048612)) + (let (v170 u32) (mod.unchecked v169 4)) + (assertz 250 v170) + (let (v171 (ptr i64)) (inttoptr v169)) + (store v171 v167) + (let (v172 (ptr i32)) (global.symbol #__stack_pointer)) + (store v172 v4) + (let (v173 i32) (const.i32 1048612)) + (ret v173)) + ) + + (func (export #cabi_post_miden:basic-wallet/basic-wallet@1.0.0#test-stdlib) + (param i32) + (block 0 (param v0 i32) + (br (block 1))) + + (block 1 + (ret)) + ) + + (func (export #cabi_realloc_wit_bindgen_0_28_0) + (param i32) (param i32) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) + (let (v5 i32) (call #wit_bindgen_rt::cabi_realloc v0 v1 v2 v3)) + (br (block 1 v5))) + + (block 1 (param v4 i32) + (ret v4)) + ) + + (func (export #wit_bindgen_rt::cabi_realloc) + (param i32) (param i32) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) + (let (v5 i1) (neq v1 0)) + (condbr v5 (block 4) (block 5))) + + (block 1 (param v4 i32) + (ret v4)) + + (block 2 (param v19 i32) + (br (block 1 v19))) + + (block 3 (param v17 i32) + (let (v18 i1) (neq v17 0)) + (condbr v18 (block 2 v17) (block 7))) + + (block 4 + (let (v16 i32) (call #__rust_realloc v0 v1 v2 v3)) + (br (block 3 v16))) + + (block 5 + (let (v6 i1) (eq v3 0)) + (let (v7 i32) (zext v6)) + (let (v8 i1) (neq v7 0)) + (condbr v8 (block 2 v2) (block 6))) + + (block 6 + (let (v9 i32) (const.i32 0)) + (let (v10 u32) (bitcast v9)) + (let (v11 u32) (add.checked v10 1048624)) + (let (v12 (ptr u8)) (inttoptr v11)) + (let (v13 u8) (load v12)) + (let (v14 i32) (zext v13)) + (let (v15 i32) (call #__rust_alloc v3 v2)) + (br (block 3 v15))) + + (block 7 + (unreachable)) + ) + + (func (export #wit_bindgen_rt::run_ctors_once) + (block 0 + (let (v0 i32) (const.i32 0)) + (let (v1 u32) (bitcast v0)) + (let (v2 u32) (add.checked v1 1048625)) + (let (v3 (ptr u8)) (inttoptr v2)) + (let (v4 u8) (load v3)) + (let (v5 i32) (zext v4)) + (let (v6 i1) (neq v5 0)) + (condbr v6 (block 2) (block 3))) + + (block 1 + (ret)) + + (block 2 + (br (block 1))) + + (block 3 + (call #__wasm_call_ctors) + (let (v7 i32) (const.i32 0)) + (let (v8 i32) (const.i32 1)) + (let (v9 u32) (bitcast v8)) + (let (v10 u8) (trunc v9)) + (let (v11 u32) (bitcast v7)) + (let (v12 u32) (add.checked v11 1048625)) + (let (v13 (ptr u8)) (inttoptr v12)) + (store v13 v10) + (br (block 2))) + ) + + (func (export #::alloc) + (param i32) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) + (let (v4 i32) (const.i32 0)) + (let (v5 i32) (const.i32 32)) + (let (v6 i32) (const.i32 32)) + (let (v7 u32) (bitcast v1)) + (let (v8 u32) (bitcast v6)) + (let (v9 i1) (gt v7 v8)) + (let (v10 i32) (sext v9)) + (let (v11 i1) (neq v10 0)) + (let (v12 i32) (select v11 v1 v5)) + (let (v13 u32) (popcnt v12)) + (let (v14 i32) (bitcast v13)) + (let (v15 i32) (const.i32 1)) + (let (v16 i1) (neq v14 v15)) + (let (v17 i32) (zext v16)) + (let (v18 i1) (neq v17 0)) + (condbr v18 (block 2) (block 3))) + + (block 1 (param v3 i32)) + + (block 2 + (unreachable)) + + (block 3 + (let (v19 i32) (const.i32 -2147483648)) + (let (v20 i32) (sub.wrapping v19 v12)) + (let (v21 u32) (bitcast v20)) + (let (v22 u32) (bitcast v2)) + (let (v23 i1) (lt v21 v22)) + (let (v24 i32) (sext v23)) + (let (v25 i1) (neq v24 0)) + (condbr v25 (block 2) (block 4))) + + (block 4 + (let (v26 i32) (const.i32 0)) + (let (v27 i32) (add.wrapping v12 v2)) + (let (v28 i32) (const.i32 -1)) + (let (v29 i32) (add.wrapping v27 v28)) + (let (v30 i32) (const.i32 0)) + (let (v31 i32) (sub.wrapping v30 v12)) + (let (v32 i32) (band v29 v31)) + (let (v33 u32) (bitcast v0)) + (let (v34 u32) (mod.unchecked v33 4)) + (assertz 250 v34) + (let (v35 (ptr i32)) (inttoptr v33)) + (let (v36 i32) (load v35)) + (let (v37 i1) (neq v36 0)) + (condbr v37 (block 5 v0 v32 v12 v26) (block 6))) + + (block 5 + (param v49 i32) + (param v55 i32) + (param v65 i32) + (param v68 i32) + (let (v48 i32) (const.i32 268435456)) + (let (v50 u32) (bitcast v49)) + (let (v51 u32) (mod.unchecked v50 4)) + (assertz 250 v51) + (let (v52 (ptr i32)) (inttoptr v50)) + (let (v53 i32) (load v52)) + (let (v54 i32) (sub.wrapping v48 v53)) + (let (v56 u32) (bitcast v54)) + (let (v57 u32) (bitcast v55)) + (let (v58 i1) (lt v56 v57)) + (let (v59 i32) (sext v58)) + (let (v60 i1) (neq v59 0)) + (condbr v60 (block 7 v68) (block 8))) + + (block 6 + (let (v38 u32) (call (#miden:core-import/intrinsics-mem@1.0.0 #heap-base))) + (let (v39 u32) (memory.size)) + (let (v40 i32) (const.i32 16)) + (let (v41 u32) (bitcast v40)) + (let (v42 u32) (shl.wrapping v39 v41)) + (let (v43 u32) (add.wrapping v38 v42)) + (let (v44 i32) (bitcast v43)) + (let (v45 u32) (bitcast v0)) + (let (v46 u32) (mod.unchecked v45 4)) + (assertz 250 v46) + (let (v47 (ptr i32)) (inttoptr v45)) + (store v47 v44) + (br (block 5 v0 v32 v12 v26))) + + (block 7 (param v67 i32) + (ret v67)) + + (block 8 + (let (v61 i32) (add.wrapping v53 v55)) + (let (v62 u32) (bitcast v49)) + (let (v63 u32) (mod.unchecked v62 4)) + (assertz 250 v63) + (let (v64 (ptr i32)) (inttoptr v62)) + (store v64 v61) + (let (v66 i32) (add.wrapping v53 v65)) + (br (block 7 v66))) + ) + + (func (export #miden_base_sys::bindings::tx::add_asset) + (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v2 u32) (bitcast v1)) + (let (v3 u32) (mod.unchecked v2 4)) + (assertz 250 v3) + (let (v4 (ptr felt)) (inttoptr v2)) + (let (v5 felt) (load v4)) + (let (v6 u32) (bitcast v1)) + (let (v7 u32) (add.checked v6 4)) + (let (v8 u32) (mod.unchecked v7 4)) + (assertz 250 v8) + (let (v9 (ptr felt)) (inttoptr v7)) + (let (v10 felt) (load v9)) + (let (v11 u32) (bitcast v1)) + (let (v12 u32) (add.checked v11 8)) + (let (v13 u32) (mod.unchecked v12 4)) + (assertz 250 v13) + (let (v14 (ptr felt)) (inttoptr v12)) + (let (v15 felt) (load v14)) + (let (v16 u32) (bitcast v1)) + (let (v17 u32) (add.checked v16 12)) + (let (v18 u32) (mod.unchecked v17 4)) + (assertz 250 v18) + (let (v19 (ptr felt)) (inttoptr v17)) + (let (v20 felt) (load v19)) + (let [(v21 felt) (v22 felt) (v23 felt) (v24 felt)] (call (#miden:core-import/account@1.0.0 #add-asset) v5 v10 v15 v20)) + (let (v25 u32) (bitcast v0)) + (let (v26 (ptr felt)) (inttoptr v25)) + (store v26 v21) + (let (v27 u32) (add.checked v25 4)) + (let (v28 (ptr felt)) (inttoptr v27)) + (store v28 v22) + (let (v29 u32) (add.checked v25 8)) + (let (v30 (ptr felt)) (inttoptr v29)) + (store v30 v23) + (let (v31 u32) (add.checked v25 12)) + (let (v32 (ptr felt)) (inttoptr v31)) + (store v32 v24) + (br (block 1))) + + (block 1 + (ret)) + ) + + (func (export #miden_base_sys::bindings::tx::remove_asset) + (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v2 u32) (bitcast v1)) + (let (v3 u32) (mod.unchecked v2 4)) + (assertz 250 v3) + (let (v4 (ptr felt)) (inttoptr v2)) + (let (v5 felt) (load v4)) + (let (v6 u32) (bitcast v1)) + (let (v7 u32) (add.checked v6 4)) + (let (v8 u32) (mod.unchecked v7 4)) + (assertz 250 v8) + (let (v9 (ptr felt)) (inttoptr v7)) + (let (v10 felt) (load v9)) + (let (v11 u32) (bitcast v1)) + (let (v12 u32) (add.checked v11 8)) + (let (v13 u32) (mod.unchecked v12 4)) + (assertz 250 v13) + (let (v14 (ptr felt)) (inttoptr v12)) + (let (v15 felt) (load v14)) + (let (v16 u32) (bitcast v1)) + (let (v17 u32) (add.checked v16 12)) + (let (v18 u32) (mod.unchecked v17 4)) + (assertz 250 v18) + (let (v19 (ptr felt)) (inttoptr v17)) + (let (v20 felt) (load v19)) + (let [(v21 felt) (v22 felt) (v23 felt) (v24 felt)] (call (#miden:core-import/account@1.0.0 #remove-asset) v5 v10 v15 v20)) + (let (v25 u32) (bitcast v0)) + (let (v26 (ptr felt)) (inttoptr v25)) + (store v26 v21) + (let (v27 u32) (add.checked v25 4)) + (let (v28 (ptr felt)) (inttoptr v27)) + (store v28 v22) + (let (v29 u32) (add.checked v25 8)) + (let (v30 (ptr felt)) (inttoptr v29)) + (store v30 v23) + (let (v31 u32) (add.checked v25 12)) + (let (v32 (ptr felt)) (inttoptr v31)) + (store v32 v24) + (br (block 1))) + + (block 1 + (ret)) + ) + + (func (export #miden_base_sys::bindings::tx::create_note) + (param i32) (param felt) (param felt) (param i32) (result felt) + (block 0 + (param v0 i32) + (param v1 felt) + (param v2 felt) + (param v3 i32) + (let (v5 u32) (bitcast v0)) + (let (v6 u32) (mod.unchecked v5 4)) + (assertz 250 v6) + (let (v7 (ptr felt)) (inttoptr v5)) + (let (v8 felt) (load v7)) + (let (v9 u32) (bitcast v0)) + (let (v10 u32) (add.checked v9 4)) + (let (v11 u32) (mod.unchecked v10 4)) + (assertz 250 v11) + (let (v12 (ptr felt)) (inttoptr v10)) + (let (v13 felt) (load v12)) + (let (v14 u32) (bitcast v0)) + (let (v15 u32) (add.checked v14 8)) + (let (v16 u32) (mod.unchecked v15 4)) + (assertz 250 v16) + (let (v17 (ptr felt)) (inttoptr v15)) + (let (v18 felt) (load v17)) + (let (v19 u32) (bitcast v0)) + (let (v20 u32) (add.checked v19 12)) + (let (v21 u32) (mod.unchecked v20 4)) + (assertz 250 v21) + (let (v22 (ptr felt)) (inttoptr v20)) + (let (v23 felt) (load v22)) + (let (v24 u32) (bitcast v3)) + (let (v25 u32) (mod.unchecked v24 4)) + (assertz 250 v25) + (let (v26 (ptr felt)) (inttoptr v24)) + (let (v27 felt) (load v26)) + (let (v28 u32) (bitcast v3)) + (let (v29 u32) (add.checked v28 4)) + (let (v30 u32) (mod.unchecked v29 4)) + (assertz 250 v30) + (let (v31 (ptr felt)) (inttoptr v29)) + (let (v32 felt) (load v31)) + (let (v33 u32) (bitcast v3)) + (let (v34 u32) (add.checked v33 8)) + (let (v35 u32) (mod.unchecked v34 4)) + (assertz 250 v35) + (let (v36 (ptr felt)) (inttoptr v34)) + (let (v37 felt) (load v36)) + (let (v38 u32) (bitcast v3)) + (let (v39 u32) (add.checked v38 12)) + (let (v40 u32) (mod.unchecked v39 4)) + (assertz 250 v40) + (let (v41 (ptr felt)) (inttoptr v39)) + (let (v42 felt) (load v41)) + (let (v43 felt) (call (#miden:core-import/tx@1.0.0 #create-note) v8 v13 v18 v23 v1 v2 v27 v32 v37 v42)) + (br (block 1 v43))) + + (block 1 (param v4 felt) + (ret v4)) + ) + + (func (export #alloc::vec::Vec::into_boxed_slice) + (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) + (let (v2 i32) (const.i32 0)) + (let (v3 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v4 i32) (const.i32 16)) + (let (v5 i32) (sub.wrapping v3 v4)) + (let (v6 (ptr i32)) (global.symbol #__stack_pointer)) + (store v6 v5) + (let (v7 u32) (bitcast v1)) + (let (v8 u32) (mod.unchecked v7 4)) + (assertz 250 v8) + (let (v9 (ptr i32)) (inttoptr v7)) + (let (v10 i32) (load v9)) + (let (v11 u32) (bitcast v1)) + (let (v12 u32) (add.checked v11 8)) + (let (v13 u32) (mod.unchecked v12 4)) + (assertz 250 v13) + (let (v14 (ptr i32)) (inttoptr v12)) + (let (v15 i32) (load v14)) + (let (v16 u32) (bitcast v10)) + (let (v17 u32) (bitcast v15)) + (let (v18 i1) (lte v16 v17)) + (let (v19 i32) (sext v18)) + (let (v20 i1) (neq v19 0)) + (condbr v20 (block 3 v0 v15 v1 v5) (block 4))) + + (block 1) + + (block 2 + (unreachable)) + + (block 3 + (param v37 i32) + (param v38 i32) + (param v43 i32) + (param v52 i32) + (let (v39 u32) (bitcast v37)) + (let (v40 u32) (add.checked v39 4)) + (let (v41 u32) (mod.unchecked v40 4)) + (assertz 250 v41) + (let (v42 (ptr i32)) (inttoptr v40)) + (store v42 v38) + (let (v44 u32) (bitcast v43)) + (let (v45 u32) (add.checked v44 4)) + (let (v46 u32) (mod.unchecked v45 4)) + (assertz 250 v46) + (let (v47 (ptr i32)) (inttoptr v45)) + (let (v48 i32) (load v47)) + (let (v49 u32) (bitcast v37)) + (let (v50 u32) (mod.unchecked v49 4)) + (assertz 250 v50) + (let (v51 (ptr i32)) (inttoptr v49)) + (store v51 v48) + (let (v53 i32) (const.i32 16)) + (let (v54 i32) (add.wrapping v52 v53)) + (let (v55 (ptr i32)) (global.symbol #__stack_pointer)) + (store v55 v54) + (ret)) + + (block 4 + (let (v21 i32) (const.i32 8)) + (let (v22 i32) (add.wrapping v5 v21)) + (call #alloc::raw_vec::RawVec::shrink_unchecked v22 v1 v15) + (let (v23 u32) (bitcast v5)) + (let (v24 u32) (add.checked v23 8)) + (let (v25 u32) (mod.unchecked v24 4)) + (assertz 250 v25) + (let (v26 (ptr i32)) (inttoptr v24)) + (let (v27 i32) (load v26)) + (let (v28 i32) (const.i32 -2147483647)) + (let (v29 i1) (neq v27 v28)) + (let (v30 i32) (zext v29)) + (let (v31 i1) (neq v30 0)) + (condbr v31 (block 2) (block 5))) + + (block 5 + (let (v32 u32) (bitcast v1)) + (let (v33 u32) (add.checked v32 8)) + (let (v34 u32) (mod.unchecked v33 4)) + (assertz 250 v34) + (let (v35 (ptr i32)) (inttoptr v33)) + (let (v36 i32) (load v35)) + (br (block 3 v0 v36 v1 v5))) + ) + + (func (export # as core::ops::drop::Drop>::drop) + (param i32) + (block 0 (param v0 i32) + (br (block 1))) + + (block 1 + (ret)) + ) + + (func (export # as core::ops::drop::Drop>::drop) + (param i32) + (block 0 (param v0 i32) + (let (v1 i32) (const.i32 0)) + (let (v2 u32) (bitcast v0)) + (let (v3 u32) (mod.unchecked v2 4)) + (assertz 250 v3) + (let (v4 (ptr i32)) (inttoptr v2)) + (let (v5 i32) (load v4)) + (let (v6 i1) (eq v5 0)) + (let (v7 i32) (zext v6)) + (let (v8 i1) (neq v7 0)) + (condbr v8 (block 2) (block 3))) + + (block 1 + (ret)) + + (block 2 + (br (block 1))) + + (block 3 + (let (v9 u32) (bitcast v0)) + (let (v10 u32) (add.checked v9 4)) + (let (v11 u32) (mod.unchecked v10 4)) + (assertz 250 v11) + (let (v12 (ptr i32)) (inttoptr v10)) + (let (v13 i32) (load v12)) + (let (v14 i32) (const.i32 1)) + (call #::deallocate v13 v14 v5) + (br (block 2))) + ) + + (func (export #alloc::raw_vec::RawVec::try_allocate_in) + (param i32) (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) + (let (v3 i32) (const.i32 0)) + (let (v4 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v5 i32) (const.i32 16)) + (let (v6 i32) (sub.wrapping v4 v5)) + (let (v7 (ptr i32)) (global.symbol #__stack_pointer)) + (store v7 v6) + (let (v8 i1) (neq v1 0)) + (condbr v8 (block 3) (block 4))) + + (block 1 + (ret)) + + (block 2 (param v62 i32) (param v64 i32) (param v68 i32) + (let (v65 u32) (bitcast v62)) + (let (v66 u32) (mod.unchecked v65 4)) + (assertz 250 v66) + (let (v67 (ptr i32)) (inttoptr v65)) + (store v67 v64) + (let (v71 i32) (const.i32 16)) + (let (v72 i32) (add.wrapping v68 v71)) + (let (v73 (ptr i32)) (global.symbol #__stack_pointer)) + (store v73 v72) + (br (block 1))) + + (block 3 + (let (v15 i32) (const.i32 -1)) + (let (v16 i1) (gt v1 v15)) + (let (v17 i32) (zext v16)) + (let (v18 i1) (neq v17 0)) + (condbr v18 (block 6) (block 7))) + + (block 4 + (let (v9 i64) (const.i64 4294967296)) + (let (v10 u32) (bitcast v0)) + (let (v11 u32) (add.checked v10 4)) + (let (v12 u32) (mod.unchecked v11 4)) + (assertz 250 v12) + (let (v13 (ptr i64)) (inttoptr v11)) + (store v13 v9) + (let (v14 i32) (const.i32 0)) + (br (block 2 v0 v14 v6))) + + (block 5 (param v63 i32) (param v70 i32) + (let (v61 i32) (const.i32 1)) + (br (block 2 v63 v61 v70))) + + (block 6 + (let (v24 i1) (neq v2 0)) + (condbr v24 (block 9) (block 10))) + + (block 7 + (let (v19 i32) (const.i32 0)) + (let (v20 u32) (bitcast v0)) + (let (v21 u32) (add.checked v20 4)) + (let (v22 u32) (mod.unchecked v21 4)) + (assertz 250 v22) + (let (v23 (ptr i32)) (inttoptr v21)) + (store v23 v19) + (br (block 5 v0 v6))) + + (block 8 + (param v37 i32) + (param v41 i32) + (param v46 i32) + (param v56 i32) + (param v69 i32) + (let (v38 i1) (eq v37 0)) + (let (v39 i32) (zext v38)) + (let (v40 i1) (neq v39 0)) + (condbr v40 (block 11) (block 12))) + + (block 9 + (let (v32 i32) (const.i32 1)) + (call #alloc::alloc::Global::alloc_impl v6 v17 v1 v32) + (let (v33 u32) (bitcast v6)) + (let (v34 u32) (mod.unchecked v33 4)) + (assertz 250 v34) + (let (v35 (ptr i32)) (inttoptr v33)) + (let (v36 i32) (load v35)) + (br (block 8 v36 v0 v1 v17 v6))) + + (block 10 + (let (v25 i32) (const.i32 8)) + (let (v26 i32) (add.wrapping v6 v25)) + (call #::allocate v26 v17 v1) + (let (v27 u32) (bitcast v6)) + (let (v28 u32) (add.checked v27 8)) + (let (v29 u32) (mod.unchecked v28 4)) + (assertz 250 v29) + (let (v30 (ptr i32)) (inttoptr v28)) + (let (v31 i32) (load v30)) + (br (block 8 v31 v0 v1 v17 v6))) + + (block 11 + (let (v52 u32) (bitcast v41)) + (let (v53 u32) (add.checked v52 8)) + (let (v54 u32) (mod.unchecked v53 4)) + (assertz 250 v54) + (let (v55 (ptr i32)) (inttoptr v53)) + (store v55 v46) + (let (v57 u32) (bitcast v41)) + (let (v58 u32) (add.checked v57 4)) + (let (v59 u32) (mod.unchecked v58 4)) + (assertz 250 v59) + (let (v60 (ptr i32)) (inttoptr v58)) + (store v60 v56) + (br (block 5 v41 v69))) + + (block 12 + (let (v42 u32) (bitcast v41)) + (let (v43 u32) (add.checked v42 8)) + (let (v44 u32) (mod.unchecked v43 4)) + (assertz 250 v44) + (let (v45 (ptr i32)) (inttoptr v43)) + (store v45 v37) + (let (v47 u32) (bitcast v41)) + (let (v48 u32) (add.checked v47 4)) + (let (v49 u32) (mod.unchecked v48 4)) + (assertz 250 v49) + (let (v50 (ptr i32)) (inttoptr v48)) + (store v50 v46) + (let (v51 i32) (const.i32 0)) + (br (block 2 v41 v51 v69))) + ) + + (func (export #::allocate) + (param i32) (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) + (let (v3 i32) (const.i32 0)) + (let (v4 i32) (global.load i32 (global.symbol #__stack_pointer))) + (let (v5 i32) (const.i32 16)) + (let (v6 i32) (sub.wrapping v4 v5)) + (let (v7 (ptr i32)) (global.symbol #__stack_pointer)) + (store v7 v6) + (let (v8 i32) (const.i32 8)) + (let (v9 i32) (add.wrapping v6 v8)) + (let (v10 i32) (const.i32 0)) + (call #alloc::alloc::Global::alloc_impl v9 v1 v2 v10) + (let (v11 u32) (bitcast v6)) + (let (v12 u32) (add.checked v11 12)) + (let (v13 u32) (mod.unchecked v12 4)) + (assertz 250 v13) + (let (v14 (ptr i32)) (inttoptr v12)) + (let (v15 i32) (load v14)) + (let (v16 u32) (bitcast v6)) + (let (v17 u32) (add.checked v16 8)) + (let (v18 u32) (mod.unchecked v17 4)) + (assertz 250 v18) + (let (v19 (ptr i32)) (inttoptr v17)) + (let (v20 i32) (load v19)) + (let (v21 u32) (bitcast v0)) + (let (v22 u32) (mod.unchecked v21 4)) + (assertz 250 v22) + (let (v23 (ptr i32)) (inttoptr v21)) + (store v23 v20) + (let (v24 u32) (bitcast v0)) + (let (v25 u32) (add.checked v24 4)) + (let (v26 u32) (mod.unchecked v25 4)) + (assertz 250 v26) + (let (v27 (ptr i32)) (inttoptr v25)) + (store v27 v15) + (let (v28 i32) (const.i32 16)) + (let (v29 i32) (add.wrapping v6 v28)) + (let (v30 (ptr i32)) (global.symbol #__stack_pointer)) + (store v30 v29) + (br (block 1))) + + (block 1 + (ret)) + ) + + (func (export #alloc::alloc::Global::alloc_impl) + (param i32) (param i32) (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) + (let (v4 i1) (eq v2 0)) + (let (v5 i32) (zext v4)) + (let (v6 i1) (neq v5 0)) + (condbr v6 (block 2 v0 v2 v1) (block 3))) + + (block 1 + (ret)) + + (block 2 (param v16 i32) (param v17 i32) (param v22 i32) + (let (v18 u32) (bitcast v16)) + (let (v19 u32) (add.checked v18 4)) + (let (v20 u32) (mod.unchecked v19 4)) + (assertz 250 v20) + (let (v21 (ptr i32)) (inttoptr v19)) + (store v21 v17) + (let (v23 u32) (bitcast v16)) + (let (v24 u32) (mod.unchecked v23 4)) + (assertz 250 v24) + (let (v25 (ptr i32)) (inttoptr v23)) + (store v25 v22) + (br (block 1))) + + (block 3 + (let (v7 i1) (neq v3 0)) + (condbr v7 (block 4) (block 5))) + + (block 4 + (let (v15 i32) (call #__rust_alloc_zeroed v2 v1)) + (br (block 2 v0 v2 v15))) + + (block 5 + (let (v8 i32) (const.i32 0)) + (let (v9 u32) (bitcast v8)) + (let (v10 u32) (add.checked v9 1048624)) + (let (v11 (ptr u8)) (inttoptr v10)) + (let (v12 u8) (load v11)) + (let (v13 i32) (zext v12)) + (let (v14 i32) (call #__rust_alloc v2 v1)) + (br (block 2 v0 v2 v14))) + ) + + (func (export #alloc::raw_vec::RawVec::shrink_unchecked) + (param i32) (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) + (let (v3 i32) (const.i32 0)) + (let (v4 i32) (const.i32 -2147483647)) + (let (v5 u32) (bitcast v1)) + (let (v6 u32) (mod.unchecked v5 4)) + (assertz 250 v6) + (let (v7 (ptr i32)) (inttoptr v5)) + (let (v8 i32) (load v7)) + (let (v9 i1) (eq v8 0)) + (let (v10 i32) (zext v9)) + (let (v11 i1) (neq v10 0)) + (condbr v11 (block 2 v0 v2 v4) (block 3))) + + (block 1 + (ret)) + + (block 2 (param v37 i32) (param v39 i32) (param v44 i32) + (let (v40 u32) (bitcast v37)) + (let (v41 u32) (add.checked v40 4)) + (let (v42 u32) (mod.unchecked v41 4)) + (assertz 250 v42) + (let (v43 (ptr i32)) (inttoptr v41)) + (store v43 v39) + (let (v45 u32) (bitcast v37)) + (let (v46 u32) (mod.unchecked v45 4)) + (assertz 250 v46) + (let (v47 (ptr i32)) (inttoptr v45)) + (store v47 v44) + (br (block 1))) + + (block 3 + (let (v12 u32) (bitcast v1)) + (let (v13 u32) (add.checked v12 4)) + (let (v14 u32) (mod.unchecked v13 4)) + (assertz 250 v14) + (let (v15 (ptr i32)) (inttoptr v13)) + (let (v16 i32) (load v15)) + (let (v17 i1) (neq v2 0)) + (condbr v17 (block 5) (block 6))) + + (block 4 + (param v26 i32) + (param v27 i32) + (param v31 i32) + (param v38 i32) + (let (v28 u32) (bitcast v26)) + (let (v29 u32) (mod.unchecked v28 4)) + (assertz 250 v29) + (let (v30 (ptr i32)) (inttoptr v28)) + (store v30 v27) + (let (v32 u32) (bitcast v26)) + (let (v33 u32) (add.checked v32 4)) + (let (v34 u32) (mod.unchecked v33 4)) + (assertz 250 v34) + (let (v35 (ptr i32)) (inttoptr v33)) + (store v35 v31) + (let (v36 i32) (const.i32 -2147483647)) + (br (block 2 v38 v27 v36))) + + (block 5 + (let (v20 i32) (const.i32 1)) + (let (v21 i32) (const.i32 1)) + (let (v22 i32) (call #__rust_realloc v16 v8 v21 v2)) + (let (v23 i1) (eq v22 0)) + (let (v24 i32) (zext v23)) + (let (v25 i1) (neq v24 0)) + (condbr v25 (block 2 v0 v2 v20) (block 7))) + + (block 6 + (let (v18 i32) (const.i32 1)) + (let (v19 i32) (const.i32 1)) + (call #::deallocate v16 v19 v8) + (br (block 4 v1 v2 v18 v0))) + + (block 7 + (br (block 4 v1 v2 v22 v0))) + ) + + (func (export #::deallocate) + (param i32) (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) + (let (v3 i1) (eq v2 0)) + (let (v4 i32) (zext v3)) + (let (v5 i1) (neq v4 0)) + (condbr v5 (block 2) (block 3))) + + (block 1 + (ret)) + + (block 2 + (br (block 1))) + + (block 3 + (call #__rust_dealloc v0 v2 v1) + (br (block 2))) + ) + + (func (export #alloc::raw_vec::handle_error) + (param i32) (param i32) + (block 0 (param v0 i32) (param v1 i32) + (unreachable)) + + (block 1) + ) + + (func (export #cabi_realloc) + (param i32) (param i32) (param i32) (param i32) (result i32) + (block 0 (param v0 i32) (param v1 i32) (param v2 i32) (param v3 i32) + (let (v5 i32) (call #cabi_realloc_wit_bindgen_0_28_0 v0 v1 v2 v3)) + (br (block 1 v5))) + + (block 1 (param v4 i32) + (ret v4)) + ) + + ;; Imports + (func (import #miden:core-import/account@1.0.0 #add-asset) + (param felt) (param felt) (param felt) (param felt) (result felt felt felt felt)) + (func (import #miden:core-import/account@1.0.0 #remove-asset) + (param felt) (param felt) (param felt) (param felt) (result felt felt felt felt)) + (func (import #miden:core-import/intrinsics-mem@1.0.0 #heap-base) + (result u32)) + (func (import #miden:core-import/stdlib-crypto-hashes@1.0.0 #blake3-hash-one-to-one) + (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (param i32) (result i32 i32 i32 i32 i32 i32 i32 i32)) + (func (import #miden:core-import/tx@1.0.0 #create-note) + (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (param felt) (result felt)) + ) + +) diff --git a/tests/integration/expected/rust_sdk/basic_wallet.wat b/tests/integration/expected/rust_sdk/basic_wallet.wat new file mode 100644 index 000000000..dfc04f887 --- /dev/null +++ b/tests/integration/expected/rust_sdk/basic_wallet.wat @@ -0,0 +1,966 @@ +(component + (type (;0;) + (instance + (type (;0;) (record (field "inner" float32))) + (export (;1;) "felt" (type (eq 0))) + (type (;2;) (tuple 1 1 1 1)) + (type (;3;) (record (field "inner" 2))) + (export (;4;) "word" (type (eq 3))) + (type (;5;) (record (field "inner" 4))) + (export (;6;) "core-asset" (type (eq 5))) + (type (;7;) (record (field "inner" 1))) + (export (;8;) "tag" (type (eq 7))) + (type (;9;) (record (field "inner" 4))) + (export (;10;) "recipient" (type (eq 9))) + (type (;11;) (record (field "inner" 1))) + (export (;12;) "note-type" (type (eq 11))) + ) + ) + (import "miden:base/core-types@1.0.0" (instance (;0;) (type 0))) + (type (;1;) + (instance + (type (;0;) s32) + (export (;1;) "ptr" (type (eq 0))) + (type (;2;) float32) + (export (;3;) "felt" (type (eq 2))) + ) + ) + (import "miden:core-import/types@1.0.0" (instance (;1;) (type 1))) + (alias export 1 "ptr" (type (;2;))) + (type (;3;) + (instance + (alias outer 1 2 (type (;0;))) + (export (;1;) "ptr" (type (eq 0))) + (type (;2;) (func (result 1))) + (export (;0;) "heap-base" (func (type 2))) + ) + ) + (import "miden:core-import/intrinsics-mem@1.0.0" (instance (;2;) (type 3))) + (alias export 1 "felt" (type (;4;))) + (type (;5;) + (instance + (alias outer 1 4 (type (;0;))) + (export (;1;) "felt" (type (eq 0))) + (type (;2;) (func (param "a" 1) (param "b" 1) (result 1))) + (export (;0;) "add" (func (type 2))) + ) + ) + (import "miden:core-import/intrinsics-felt@1.0.0" (instance (;3;) (type 5))) + (alias export 1 "ptr" (type (;6;))) + (type (;7;) + (instance + (alias outer 1 6 (type (;0;))) + (export (;1;) "ptr" (type (eq 0))) + (type (;2;) (func (param "a0" s32) (param "a1" s32) (param "a2" s32) (param "a3" s32) (param "a4" s32) (param "a5" s32) (param "a6" s32) (param "a7" s32) (param "result-ptr" 1))) + (export (;0;) "blake3-hash-one-to-one" (func (type 2))) + ) + ) + (import "miden:core-import/stdlib-crypto-hashes@1.0.0" (instance (;4;) (type 7))) + (alias export 1 "felt" (type (;8;))) + (alias export 1 "ptr" (type (;9;))) + (type (;10;) + (instance + (alias outer 1 8 (type (;0;))) + (export (;1;) "felt" (type (eq 0))) + (alias outer 1 9 (type (;2;))) + (export (;3;) "ptr" (type (eq 2))) + (type (;4;) (func (param "asset0" 1) (param "asset1" 1) (param "asset2" 1) (param "asset3" 1) (param "result-ptr" 3))) + (export (;0;) "add-asset" (func (type 4))) + (export (;1;) "remove-asset" (func (type 4))) + ) + ) + (import "miden:core-import/account@1.0.0" (instance (;5;) (type 10))) + (alias export 1 "felt" (type (;11;))) + (type (;12;) + (instance + (alias outer 1 11 (type (;0;))) + (export (;1;) "felt" (type (eq 0))) + (type (;2;) (func (param "asset0" 1) (param "asset1" 1) (param "asset2" 1) (param "asset3" 1) (param "tag" 1) (param "note-type" 1) (param "recipient0" 1) (param "recipient1" 1) (param "recipient2" 1) (param "recipient3" 1) (result 1))) + (export (;0;) "create-note" (func (type 2))) + ) + ) + (import "miden:core-import/tx@1.0.0" (instance (;6;) (type 12))) + (core module (;0;) + (type (;0;) (func (param f32 f32) (result f32))) + (type (;1;) (func (param i32 i32 i32 i32 i32 i32 i32 i32 i32))) + (type (;2;) (func (result i32))) + (type (;3;) (func (param f32 f32 f32 f32 i32))) + (type (;4;) (func (param f32 f32 f32 f32 f32 f32 f32 f32 f32 f32) (result f32))) + (type (;5;) (func)) + (type (;6;) (func (param i32 i32) (result i32))) + (type (;7;) (func (param i32 i32 i32))) + (type (;8;) (func (param i32 i32 i32 i32) (result i32))) + (type (;9;) (func (param f32 f32 f32 f32))) + (type (;10;) (func (param f32 f32 f32 f32 f32 f32 f32 f32 f32 f32))) + (type (;11;) (func (param i32))) + (type (;12;) (func (param i32 i32 i32) (result i32))) + (type (;13;) (func (param i32 i32))) + (type (;14;) (func (param i32 f32 f32 i32) (result f32))) + (type (;15;) (func (param i32 i32 i32 i32))) + (import "miden:core-import/intrinsics-felt@1.0.0" "add" (func $miden_stdlib_sys::intrinsics::felt::extern_add (;0;) (type 0))) + (import "miden:core-import/stdlib-crypto-hashes@1.0.0" "blake3-hash-one-to-one" (func $miden_stdlib_sys::stdlib::crypto::hashes::extern_blake3_hash_1to1 (;1;) (type 1))) + (import "miden:core-import/intrinsics-mem@1.0.0" "heap-base" (func $miden_sdk_alloc::heap_base (;2;) (type 2))) + (import "miden:core-import/account@1.0.0" "add-asset" (func $miden_base_sys::bindings::tx::externs::extern_account_add_asset (;3;) (type 3))) + (import "miden:core-import/account@1.0.0" "remove-asset" (func $miden_base_sys::bindings::tx::externs::extern_account_remove_asset (;4;) (type 3))) + (import "miden:core-import/tx@1.0.0" "create-note" (func $miden_base_sys::bindings::tx::externs::extern_tx_create_note (;5;) (type 4))) + (func $__wasm_call_ctors (;6;) (type 5)) + (func $basic_wallet::bindings::__link_custom_section_describing_imports (;7;) (type 5)) + (func $__rust_alloc (;8;) (type 6) (param i32 i32) (result i32) + i32.const 1048620 + local.get 1 + local.get 0 + call $::alloc + ) + (func $__rust_dealloc (;9;) (type 7) (param i32 i32 i32)) + (func $__rust_realloc (;10;) (type 8) (param i32 i32 i32 i32) (result i32) + block ;; label = @1 + i32.const 1048620 + local.get 2 + local.get 3 + call $::alloc + local.tee 2 + i32.eqz + br_if 0 (;@1;) + local.get 2 + local.get 0 + local.get 1 + local.get 3 + local.get 1 + local.get 3 + i32.lt_u + select + memory.copy + end + local.get 2 + ) + (func $__rust_alloc_zeroed (;11;) (type 6) (param i32 i32) (result i32) + block ;; label = @1 + i32.const 1048620 + local.get 1 + local.get 0 + call $::alloc + local.tee 1 + i32.eqz + br_if 0 (;@1;) + local.get 1 + i32.const 0 + local.get 0 + memory.fill + end + local.get 1 + ) + (func $miden:basic-wallet/basic-wallet@1.0.0#receive-asset (;12;) (type 9) (param f32 f32 f32 f32) + (local i32 i32) + global.get $__stack_pointer + local.tee 4 + i32.const 64 + i32.sub + i32.const -32 + i32.and + local.tee 5 + global.set $__stack_pointer + call $wit_bindgen_rt::run_ctors_once + local.get 5 + local.get 3 + f32.store offset=12 + local.get 5 + local.get 2 + f32.store offset=8 + local.get 5 + local.get 1 + f32.store offset=4 + local.get 5 + local.get 0 + f32.store + local.get 5 + i32.const 32 + i32.add + local.get 5 + call $miden_base_sys::bindings::tx::add_asset + local.get 4 + global.set $__stack_pointer + ) + (func $miden:basic-wallet/basic-wallet@1.0.0#send-asset (;13;) (type 10) (param f32 f32 f32 f32 f32 f32 f32 f32 f32 f32) + (local i32 i32) + global.get $__stack_pointer + local.tee 10 + i32.const 96 + i32.sub + i32.const -32 + i32.and + local.tee 11 + global.set $__stack_pointer + call $wit_bindgen_rt::run_ctors_once + local.get 11 + local.get 3 + f32.store offset=12 + local.get 11 + local.get 2 + f32.store offset=8 + local.get 11 + local.get 1 + f32.store offset=4 + local.get 11 + local.get 0 + f32.store + local.get 11 + local.get 9 + f32.store offset=44 + local.get 11 + local.get 8 + f32.store offset=40 + local.get 11 + local.get 7 + f32.store offset=36 + local.get 11 + local.get 6 + f32.store offset=32 + local.get 11 + i32.const 64 + i32.add + local.get 11 + call $miden_base_sys::bindings::tx::remove_asset + local.get 11 + i32.const 64 + i32.add + local.get 4 + local.get 5 + local.get 11 + i32.const 32 + i32.add + call $miden_base_sys::bindings::tx::create_note + drop + local.get 10 + global.set $__stack_pointer + ) + (func $miden:basic-wallet/basic-wallet@1.0.0#test-felt-intrinsics (;14;) (type 0) (param f32 f32) (result f32) + call $wit_bindgen_rt::run_ctors_once + local.get 0 + local.get 1 + call $miden_stdlib_sys::intrinsics::felt::extern_add + ) + (func $miden:basic-wallet/basic-wallet@1.0.0#test-stdlib (;15;) (type 6) (param i32 i32) (result i32) + (local i32 i32 i32 i32 i32 i32 i32 i32) + global.get $__stack_pointer + local.tee 2 + local.set 3 + local.get 2 + i32.const 96 + i32.sub + i32.const -32 + i32.and + local.tee 2 + global.set $__stack_pointer + call $wit_bindgen_rt::run_ctors_once + local.get 2 + local.get 0 + i32.store offset=24 + local.get 2 + local.get 1 + i32.store offset=20 + block ;; label = @1 + block ;; label = @2 + local.get 1 + i32.const 32 + i32.ne + br_if 0 (;@2;) + local.get 2 + i32.const 0 + i32.store offset=28 + local.get 0 + i32.load align=1 + local.set 1 + local.get 0 + i32.load offset=4 align=1 + local.set 4 + local.get 0 + i32.load offset=8 align=1 + local.set 5 + local.get 0 + i32.load offset=12 align=1 + local.set 6 + local.get 0 + i32.load offset=16 align=1 + local.set 7 + local.get 0 + i32.load offset=20 align=1 + local.set 8 + local.get 0 + i32.load offset=24 align=1 + local.set 9 + local.get 0 + i32.load offset=28 align=1 + local.set 0 + local.get 2 + i32.const 20 + i32.add + call $ as core::ops::drop::Drop>::drop + local.get 2 + i32.const 20 + i32.add + call $ as core::ops::drop::Drop>::drop + local.get 1 + local.get 4 + local.get 5 + local.get 6 + local.get 7 + local.get 8 + local.get 9 + local.get 0 + local.get 2 + i32.const 32 + i32.add + call $miden_stdlib_sys::stdlib::crypto::hashes::extern_blake3_hash_1to1 + local.get 2 + i32.const 84 + i32.add + i32.const 32 + i32.const 0 + call $alloc::raw_vec::RawVec::try_allocate_in + local.get 2 + i32.load offset=88 + local.set 1 + local.get 2 + i32.load offset=84 + i32.const 1 + i32.eq + br_if 1 (;@1;) + local.get 2 + i32.load offset=92 + local.tee 0 + i32.const 24 + i32.add + local.get 2 + i64.load offset=56 + i64.store align=1 + local.get 0 + i32.const 16 + i32.add + local.get 2 + i64.load offset=48 + i64.store align=1 + local.get 0 + i32.const 8 + i32.add + local.get 2 + i64.load offset=40 + i64.store align=1 + local.get 0 + local.get 2 + i64.load offset=32 + i64.store align=1 + local.get 2 + i32.const 32 + i32.store offset=92 + local.get 2 + local.get 0 + i32.store offset=88 + local.get 2 + local.get 1 + i32.store offset=84 + local.get 2 + i32.const 8 + i32.add + local.get 2 + i32.const 84 + i32.add + call $alloc::vec::Vec::into_boxed_slice + i32.const 0 + local.get 2 + i64.load offset=8 + i64.store offset=1048612 align=4 + local.get 3 + global.set $__stack_pointer + i32.const 1048612 + return + end + unreachable + end + local.get 1 + local.get 2 + i32.load offset=92 + call $alloc::raw_vec::handle_error + unreachable + ) + (func $cabi_post_miden:basic-wallet/basic-wallet@1.0.0#test-stdlib (;16;) (type 11) (param i32)) + (func $cabi_realloc_wit_bindgen_0_28_0 (;17;) (type 8) (param i32 i32 i32 i32) (result i32) + local.get 0 + local.get 1 + local.get 2 + local.get 3 + call $wit_bindgen_rt::cabi_realloc + ) + (func $wit_bindgen_rt::cabi_realloc (;18;) (type 8) (param i32 i32 i32 i32) (result i32) + block ;; label = @1 + block ;; label = @2 + block ;; label = @3 + local.get 1 + br_if 0 (;@3;) + local.get 3 + i32.eqz + br_if 2 (;@1;) + i32.const 0 + i32.load8_u offset=1048624 + drop + local.get 3 + local.get 2 + call $__rust_alloc + local.set 2 + br 1 (;@2;) + end + local.get 0 + local.get 1 + local.get 2 + local.get 3 + call $__rust_realloc + local.set 2 + end + local.get 2 + br_if 0 (;@1;) + unreachable + end + local.get 2 + ) + (func $wit_bindgen_rt::run_ctors_once (;19;) (type 5) + block ;; label = @1 + i32.const 0 + i32.load8_u offset=1048625 + br_if 0 (;@1;) + call $__wasm_call_ctors + i32.const 0 + i32.const 1 + i32.store8 offset=1048625 + end + ) + (func $::alloc (;20;) (type 12) (param i32 i32 i32) (result i32) + (local i32 i32) + block ;; label = @1 + local.get 1 + i32.const 32 + local.get 1 + i32.const 32 + i32.gt_u + select + local.tee 1 + i32.popcnt + i32.const 1 + i32.ne + br_if 0 (;@1;) + i32.const -2147483648 + local.get 1 + i32.sub + local.get 2 + i32.lt_u + br_if 0 (;@1;) + i32.const 0 + local.set 3 + local.get 1 + local.get 2 + i32.add + i32.const -1 + i32.add + i32.const 0 + local.get 1 + i32.sub + i32.and + local.set 2 + block ;; label = @2 + local.get 0 + i32.load + br_if 0 (;@2;) + local.get 0 + call $miden_sdk_alloc::heap_base + memory.size + i32.const 16 + i32.shl + i32.add + i32.store + end + block ;; label = @2 + i32.const 268435456 + local.get 0 + i32.load + local.tee 4 + i32.sub + local.get 2 + i32.lt_u + br_if 0 (;@2;) + local.get 0 + local.get 4 + local.get 2 + i32.add + i32.store + local.get 4 + local.get 1 + i32.add + local.set 3 + end + local.get 3 + return + end + unreachable + ) + (func $miden_base_sys::bindings::tx::add_asset (;21;) (type 13) (param i32 i32) + local.get 1 + f32.load + local.get 1 + f32.load offset=4 + local.get 1 + f32.load offset=8 + local.get 1 + f32.load offset=12 + local.get 0 + call $miden_base_sys::bindings::tx::externs::extern_account_add_asset + ) + (func $miden_base_sys::bindings::tx::remove_asset (;22;) (type 13) (param i32 i32) + local.get 1 + f32.load + local.get 1 + f32.load offset=4 + local.get 1 + f32.load offset=8 + local.get 1 + f32.load offset=12 + local.get 0 + call $miden_base_sys::bindings::tx::externs::extern_account_remove_asset + ) + (func $miden_base_sys::bindings::tx::create_note (;23;) (type 14) (param i32 f32 f32 i32) (result f32) + local.get 0 + f32.load + local.get 0 + f32.load offset=4 + local.get 0 + f32.load offset=8 + local.get 0 + f32.load offset=12 + local.get 1 + local.get 2 + local.get 3 + f32.load + local.get 3 + f32.load offset=4 + local.get 3 + f32.load offset=8 + local.get 3 + f32.load offset=12 + call $miden_base_sys::bindings::tx::externs::extern_tx_create_note + ) + (func $alloc::vec::Vec::into_boxed_slice (;24;) (type 13) (param i32 i32) + (local i32 i32) + global.get $__stack_pointer + i32.const 16 + i32.sub + local.tee 2 + global.set $__stack_pointer + block ;; label = @1 + block ;; label = @2 + local.get 1 + i32.load + local.get 1 + i32.load offset=8 + local.tee 3 + i32.le_u + br_if 0 (;@2;) + local.get 2 + i32.const 8 + i32.add + local.get 1 + local.get 3 + call $alloc::raw_vec::RawVec::shrink_unchecked + local.get 2 + i32.load offset=8 + i32.const -2147483647 + i32.ne + br_if 1 (;@1;) + local.get 1 + i32.load offset=8 + local.set 3 + end + local.get 0 + local.get 3 + i32.store offset=4 + local.get 0 + local.get 1 + i32.load offset=4 + i32.store + local.get 2 + i32.const 16 + i32.add + global.set $__stack_pointer + return + end + unreachable + ) + (func $ as core::ops::drop::Drop>::drop (;25;) (type 11) (param i32)) + (func $ as core::ops::drop::Drop>::drop (;26;) (type 11) (param i32) + (local i32) + block ;; label = @1 + local.get 0 + i32.load + local.tee 1 + i32.eqz + br_if 0 (;@1;) + local.get 0 + i32.load offset=4 + i32.const 1 + local.get 1 + call $::deallocate + end + ) + (func $alloc::raw_vec::RawVec::try_allocate_in (;27;) (type 7) (param i32 i32 i32) + (local i32 i32) + global.get $__stack_pointer + i32.const 16 + i32.sub + local.tee 3 + global.set $__stack_pointer + block ;; label = @1 + block ;; label = @2 + local.get 1 + br_if 0 (;@2;) + local.get 0 + i64.const 4294967296 + i64.store offset=4 align=4 + i32.const 0 + local.set 1 + br 1 (;@1;) + end + block ;; label = @2 + block ;; label = @3 + local.get 1 + i32.const -1 + i32.gt_s + local.tee 4 + br_if 0 (;@3;) + local.get 0 + i32.const 0 + i32.store offset=4 + br 1 (;@2;) + end + block ;; label = @3 + block ;; label = @4 + local.get 2 + br_if 0 (;@4;) + local.get 3 + i32.const 8 + i32.add + local.get 4 + local.get 1 + call $::allocate + local.get 3 + i32.load offset=8 + local.set 2 + br 1 (;@3;) + end + local.get 3 + local.get 4 + local.get 1 + i32.const 1 + call $alloc::alloc::Global::alloc_impl + local.get 3 + i32.load + local.set 2 + end + block ;; label = @3 + local.get 2 + i32.eqz + br_if 0 (;@3;) + local.get 0 + local.get 2 + i32.store offset=8 + local.get 0 + local.get 1 + i32.store offset=4 + i32.const 0 + local.set 1 + br 2 (;@1;) + end + local.get 0 + local.get 1 + i32.store offset=8 + local.get 0 + local.get 4 + i32.store offset=4 + end + i32.const 1 + local.set 1 + end + local.get 0 + local.get 1 + i32.store + local.get 3 + i32.const 16 + i32.add + global.set $__stack_pointer + ) + (func $::allocate (;28;) (type 7) (param i32 i32 i32) + (local i32) + global.get $__stack_pointer + i32.const 16 + i32.sub + local.tee 3 + global.set $__stack_pointer + local.get 3 + i32.const 8 + i32.add + local.get 1 + local.get 2 + i32.const 0 + call $alloc::alloc::Global::alloc_impl + local.get 3 + i32.load offset=12 + local.set 2 + local.get 0 + local.get 3 + i32.load offset=8 + i32.store + local.get 0 + local.get 2 + i32.store offset=4 + local.get 3 + i32.const 16 + i32.add + global.set $__stack_pointer + ) + (func $alloc::alloc::Global::alloc_impl (;29;) (type 15) (param i32 i32 i32 i32) + block ;; label = @1 + local.get 2 + i32.eqz + br_if 0 (;@1;) + block ;; label = @2 + local.get 3 + br_if 0 (;@2;) + i32.const 0 + i32.load8_u offset=1048624 + drop + local.get 2 + local.get 1 + call $__rust_alloc + local.set 1 + br 1 (;@1;) + end + local.get 2 + local.get 1 + call $__rust_alloc_zeroed + local.set 1 + end + local.get 0 + local.get 2 + i32.store offset=4 + local.get 0 + local.get 1 + i32.store + ) + (func $alloc::raw_vec::RawVec::shrink_unchecked (;30;) (type 7) (param i32 i32 i32) + (local i32 i32 i32 i32) + i32.const -2147483647 + local.set 3 + block ;; label = @1 + local.get 1 + i32.load + local.tee 4 + i32.eqz + br_if 0 (;@1;) + local.get 1 + i32.load offset=4 + local.set 5 + block ;; label = @2 + block ;; label = @3 + local.get 2 + br_if 0 (;@3;) + i32.const 1 + local.set 6 + local.get 5 + i32.const 1 + local.get 4 + call $::deallocate + br 1 (;@2;) + end + i32.const 1 + local.set 3 + local.get 5 + local.get 4 + i32.const 1 + local.get 2 + call $__rust_realloc + local.tee 6 + i32.eqz + br_if 1 (;@1;) + end + local.get 1 + local.get 2 + i32.store + local.get 1 + local.get 6 + i32.store offset=4 + i32.const -2147483647 + local.set 3 + end + local.get 0 + local.get 2 + i32.store offset=4 + local.get 0 + local.get 3 + i32.store + ) + (func $::deallocate (;31;) (type 7) (param i32 i32 i32) + block ;; label = @1 + local.get 2 + i32.eqz + br_if 0 (;@1;) + local.get 0 + local.get 2 + local.get 1 + call $__rust_dealloc + end + ) + (func $alloc::raw_vec::handle_error (;32;) (type 13) (param i32 i32) + unreachable + ) + (func $cabi_realloc (;33;) (type 8) (param i32 i32 i32 i32) (result i32) + local.get 0 + local.get 1 + local.get 2 + local.get 3 + call $cabi_realloc_wit_bindgen_0_28_0 + ) + (table (;0;) 3 3 funcref) + (memory (;0;) 17) + (global $__stack_pointer (;0;) (mut i32) i32.const 1048576) + (export "memory" (memory 0)) + (export "miden:basic-wallet/basic-wallet@1.0.0#receive-asset" (func $miden:basic-wallet/basic-wallet@1.0.0#receive-asset)) + (export "miden:basic-wallet/basic-wallet@1.0.0#send-asset" (func $miden:basic-wallet/basic-wallet@1.0.0#send-asset)) + (export "miden:basic-wallet/basic-wallet@1.0.0#test-felt-intrinsics" (func $miden:basic-wallet/basic-wallet@1.0.0#test-felt-intrinsics)) + (export "miden:basic-wallet/basic-wallet@1.0.0#test-stdlib" (func $miden:basic-wallet/basic-wallet@1.0.0#test-stdlib)) + (export "cabi_post_miden:basic-wallet/basic-wallet@1.0.0#test-stdlib" (func $cabi_post_miden:basic-wallet/basic-wallet@1.0.0#test-stdlib)) + (export "cabi_realloc_wit_bindgen_0_28_0" (func $cabi_realloc_wit_bindgen_0_28_0)) + (export "cabi_realloc" (func $cabi_realloc)) + (elem (;0;) (i32.const 1) func $basic_wallet::bindings::__link_custom_section_describing_imports $cabi_realloc) + (data $.rodata (;0;) (i32.const 1048576) "\01\00\00\00\01\00\00\00\01\00\00\00\01\00\00\00\01\00\00\00\01\00\00\00\01\00\00\00\01\00\00\00\02\00\00\00") + ) + (alias export 3 "add" (func (;0;))) + (core func (;0;) (canon lower (func 0))) + (core instance (;0;) + (export "add" (func 0)) + ) + (alias export 4 "blake3-hash-one-to-one" (func (;1;))) + (core func (;1;) (canon lower (func 1))) + (core instance (;1;) + (export "blake3-hash-one-to-one" (func 1)) + ) + (alias export 2 "heap-base" (func (;2;))) + (core func (;2;) (canon lower (func 2))) + (core instance (;2;) + (export "heap-base" (func 2)) + ) + (alias export 5 "add-asset" (func (;3;))) + (core func (;3;) (canon lower (func 3))) + (alias export 5 "remove-asset" (func (;4;))) + (core func (;4;) (canon lower (func 4))) + (core instance (;3;) + (export "add-asset" (func 3)) + (export "remove-asset" (func 4)) + ) + (alias export 6 "create-note" (func (;5;))) + (core func (;5;) (canon lower (func 5))) + (core instance (;4;) + (export "create-note" (func 5)) + ) + (core instance (;5;) (instantiate 0 + (with "miden:core-import/intrinsics-felt@1.0.0" (instance 0)) + (with "miden:core-import/stdlib-crypto-hashes@1.0.0" (instance 1)) + (with "miden:core-import/intrinsics-mem@1.0.0" (instance 2)) + (with "miden:core-import/account@1.0.0" (instance 3)) + (with "miden:core-import/tx@1.0.0" (instance 4)) + ) + ) + (alias core export 5 "memory" (core memory (;0;))) + (alias core export 5 "cabi_realloc" (core func (;6;))) + (alias export 0 "core-asset" (type (;13;))) + (type (;14;) (func (param "core-asset" 13))) + (alias core export 5 "miden:basic-wallet/basic-wallet@1.0.0#receive-asset" (core func (;7;))) + (func (;6;) (type 14) (canon lift (core func 7))) + (alias export 0 "tag" (type (;15;))) + (alias export 0 "note-type" (type (;16;))) + (alias export 0 "recipient" (type (;17;))) + (type (;18;) (func (param "core-asset" 13) (param "tag" 15) (param "note-type" 16) (param "recipient" 17))) + (alias core export 5 "miden:basic-wallet/basic-wallet@1.0.0#send-asset" (core func (;8;))) + (func (;7;) (type 18) (canon lift (core func 8))) + (alias export 0 "felt" (type (;19;))) + (type (;20;) (func (param "a" 19) (param "b" 19) (result 19))) + (alias core export 5 "miden:basic-wallet/basic-wallet@1.0.0#test-felt-intrinsics" (core func (;9;))) + (func (;8;) (type 20) (canon lift (core func 9))) + (type (;21;) (list u8)) + (type (;22;) (func (param "input" 21) (result 21))) + (alias core export 5 "miden:basic-wallet/basic-wallet@1.0.0#test-stdlib" (core func (;10;))) + (alias core export 5 "cabi_post_miden:basic-wallet/basic-wallet@1.0.0#test-stdlib" (core func (;11;))) + (func (;9;) (type 22) (canon lift (core func 10) (memory 0) (realloc 6) (post-return 11))) + (alias export 0 "felt" (type (;23;))) + (alias export 0 "word" (type (;24;))) + (alias export 0 "core-asset" (type (;25;))) + (alias export 0 "tag" (type (;26;))) + (alias export 0 "recipient" (type (;27;))) + (alias export 0 "note-type" (type (;28;))) + (component (;0;) + (type (;0;) (record (field "inner" float32))) + (import "import-type-felt" (type (;1;) (eq 0))) + (type (;2;) (tuple 1 1 1 1)) + (type (;3;) (record (field "inner" 2))) + (import "import-type-word" (type (;4;) (eq 3))) + (type (;5;) (record (field "inner" 4))) + (import "import-type-core-asset" (type (;6;) (eq 5))) + (type (;7;) (record (field "inner" 1))) + (import "import-type-tag" (type (;8;) (eq 7))) + (type (;9;) (record (field "inner" 4))) + (import "import-type-recipient" (type (;10;) (eq 9))) + (type (;11;) (record (field "inner" 1))) + (import "import-type-note-type" (type (;12;) (eq 11))) + (import "import-type-core-asset0" (type (;13;) (eq 6))) + (type (;14;) (func (param "core-asset" 13))) + (import "import-func-receive-asset" (func (;0;) (type 14))) + (import "import-type-tag0" (type (;15;) (eq 8))) + (import "import-type-note-type0" (type (;16;) (eq 12))) + (import "import-type-recipient0" (type (;17;) (eq 10))) + (type (;18;) (func (param "core-asset" 13) (param "tag" 15) (param "note-type" 16) (param "recipient" 17))) + (import "import-func-send-asset" (func (;1;) (type 18))) + (import "import-type-felt0" (type (;19;) (eq 1))) + (type (;20;) (func (param "a" 19) (param "b" 19) (result 19))) + (import "import-func-test-felt-intrinsics" (func (;2;) (type 20))) + (type (;21;) (list u8)) + (type (;22;) (func (param "input" 21) (result 21))) + (import "import-func-test-stdlib" (func (;3;) (type 22))) + (export (;23;) "core-asset" (type 6)) + (export (;24;) "tag" (type 8)) + (export (;25;) "recipient" (type 10)) + (export (;26;) "note-type" (type 12)) + (export (;27;) "felt" (type 1)) + (type (;28;) (func (param "core-asset" 23))) + (export (;4;) "receive-asset" (func 0) (func (type 28))) + (type (;29;) (func (param "core-asset" 23) (param "tag" 24) (param "note-type" 26) (param "recipient" 25))) + (export (;5;) "send-asset" (func 1) (func (type 29))) + (type (;30;) (func (param "a" 27) (param "b" 27) (result 27))) + (export (;6;) "test-felt-intrinsics" (func 2) (func (type 30))) + (type (;31;) (list u8)) + (type (;32;) (func (param "input" 31) (result 31))) + (export (;7;) "test-stdlib" (func 3) (func (type 32))) + ) + (instance (;7;) (instantiate 0 + (with "import-func-receive-asset" (func 6)) + (with "import-func-send-asset" (func 7)) + (with "import-func-test-felt-intrinsics" (func 8)) + (with "import-func-test-stdlib" (func 9)) + (with "import-type-felt" (type 23)) + (with "import-type-word" (type 24)) + (with "import-type-core-asset" (type 25)) + (with "import-type-tag" (type 26)) + (with "import-type-recipient" (type 27)) + (with "import-type-note-type" (type 28)) + (with "import-type-core-asset0" (type 13)) + (with "import-type-tag0" (type 15)) + (with "import-type-note-type0" (type 16)) + (with "import-type-recipient0" (type 17)) + (with "import-type-felt0" (type 19)) + ) + ) + (export (;8;) "miden:basic-wallet/basic-wallet@1.0.0" (instance 7)) +) \ No newline at end of file diff --git a/tests/integration/src/compiler_test.rs b/tests/integration/src/compiler_test.rs index 9a4a46182..b8285300d 100644 --- a/tests/integration/src/compiler_test.rs +++ b/tests/integration/src/compiler_test.rs @@ -370,6 +370,15 @@ impl CompilerTestBuilder { // Cargo-based source types share a lot of configuration in common match self.source { + CompilerTestInputType::CargoMiden(ref config) => { + let manifest_path = project_dir.join("Cargo.toml"); + command + .arg("--manifest-path") + .arg(manifest_path) + .arg("--release") + .arg("--target") + .arg(config.target.as_ref()); + } CompilerTestInputType::CargoComponent(_) => { let manifest_path = project_dir.join("Cargo.toml"); command.arg("--manifest-path").arg(manifest_path).arg("--release"); @@ -635,6 +644,23 @@ impl CompilerTestBuilder { builder } + /// Compile the Rust project using cargo-miden + pub fn rust_source_cargo_miden( + cargo_project_folder: impl AsRef, + config: WasmTranslationConfig, + ) -> Self { + let name = cargo_project_folder + .as_ref() + .file_stem() + .map(|name| name.to_string_lossy().into_owned()) + .unwrap_or("".to_string()); + let mut builder = CompilerTestBuilder::new(CompilerTestInputType::CargoMiden( + CargoTest::new(name, cargo_project_folder.as_ref().to_path_buf()), + )); + builder.with_wasm_translation_config(config); + builder + } + /// Set the Rust source code to compile a library Cargo project to Wasm module pub fn rust_source_cargo_lib( cargo_project_folder: impl AsRef, @@ -983,6 +1009,14 @@ impl CompilerTest { CompilerTestBuilder::rust_source_cargo_component(cargo_project_folder, config).build() } + /// Compile the Rust project using cargo-miden + pub fn rust_source_cargo_miden( + cargo_project_folder: impl AsRef, + config: WasmTranslationConfig, + ) -> Self { + CompilerTestBuilder::rust_source_cargo_miden(cargo_project_folder, config).build() + } + /// Set the Rust source code to compile a library Cargo project to Wasm module pub fn rust_source_cargo_lib( cargo_project_folder: impl AsRef, diff --git a/tests/integration/src/rust_masm_tests/rust_sdk.rs b/tests/integration/src/rust_masm_tests/rust_sdk.rs index 2e369a484..c619a5c9c 100644 --- a/tests/integration/src/rust_masm_tests/rust_sdk.rs +++ b/tests/integration/src/rust_masm_tests/rust_sdk.rs @@ -1,6 +1,9 @@ -use std::path::PathBuf; +use std::{collections::BTreeMap, path::PathBuf}; use expect_test::expect_file; +use miden_core::crypto::hash::RpoDigest; +use midenc_frontend_wasm::{ImportMetadata, WasmTranslationConfig}; +use midenc_hir::{InterfaceFunctionIdent, InterfaceIdent, Symbol}; use crate::{cargo_proj::project, compiler_test::sdk_crate_path, CompilerTest}; @@ -26,30 +29,98 @@ fn account() { } #[test] -fn basic_wallet() { +fn rust_sdk_basic_wallet() { + let _ = env_logger::builder().is_test(true).try_init(); let project_name = "rust_sdk_basic_wallet"; - let source = r#" -pub struct Account; + let interface_tx = InterfaceIdent::from_full_ident("miden:core-import/tx@1.0.0".to_string()); + let create_note_ident = InterfaceFunctionIdent { + interface: interface_tx, + function: Symbol::intern("create-note"), + }; + let interface_intrinsics_mem = + InterfaceIdent::from_full_ident("miden:core-import/intrinsics-mem@1.0.0".to_string()); + let heap_base_ident = InterfaceFunctionIdent { + interface: interface_intrinsics_mem, + function: Symbol::intern("heap-base"), + }; + let interface_intrinsics_felt = + InterfaceIdent::from_full_ident("miden:core-import/intrinsics-felt@1.0.0".to_string()); + // TODO: remove this after it's translated in the frontend + let felt_add_ident = InterfaceFunctionIdent { + interface: interface_intrinsics_felt, + function: Symbol::intern("add"), + }; -impl Account { - #[no_mangle] - pub fn receive_asset(asset: CoreAsset) { - add_asset(asset); - } + let interface_stdlib_crypto_hashes = + InterfaceIdent::from_full_ident("miden:core-import/stdlib-crypto-hashes@1.0.0".to_string()); - #[no_mangle] - pub fn send_asset(asset: CoreAsset, tag: Tag, note_type: NoteType, recipient: Recipient) { - let asset = remove_asset(asset); - create_note(asset, tag, note_type, recipient); - } -} -"#; + let blake3_hash_one_to_one_ident = InterfaceFunctionIdent { + interface: interface_stdlib_crypto_hashes, + function: Symbol::intern("blake3-hash-one-to-one"), + }; + + let interface_account = + InterfaceIdent::from_full_ident("miden:core-import/account@1.0.0".to_string()); + let add_asset_ident = InterfaceFunctionIdent { + interface: interface_account, + function: Symbol::intern("add-asset"), + }; + let remove_asset_ident = InterfaceFunctionIdent { + interface: interface_account, + function: Symbol::intern("remove-asset"), + }; + let import_metadata: BTreeMap = [ + ( + create_note_ident, + ImportMetadata { + digest: RpoDigest::default(), + }, + ), + ( + remove_asset_ident, + ImportMetadata { + digest: RpoDigest::default(), + }, + ), + ( + add_asset_ident, + ImportMetadata { + digest: RpoDigest::default(), + }, + ), + ( + heap_base_ident, + ImportMetadata { + digest: RpoDigest::default(), + }, + ), + ( + felt_add_ident, + ImportMetadata { + digest: RpoDigest::default(), + }, + ), + ( + blake3_hash_one_to_one_ident, + ImportMetadata { + digest: RpoDigest::default(), + }, + ), + ] + .into_iter() + .collect(); + let config = WasmTranslationConfig { + import_metadata: import_metadata.clone(), + ..Default::default() + }; - let mut test = CompilerTest::rust_source_with_sdk(project_name, source, true, None, None); - let artifact_name = test.artifact_name(); - test.expect_wasm(expect_file![format!("../../expected/{project_name}/{artifact_name}.wat")]); - test.expect_ir(expect_file![format!("../../expected/{project_name}/{artifact_name}.hir")]); + let mut test = + CompilerTest::rust_source_cargo_miden("../rust-apps-wasm/rust-sdk/basic-wallet", config); + let artifact_name = test.artifact_name().to_string(); + test.expect_wasm(expect_file![format!("../../expected/rust_sdk/{artifact_name}.wat")]); + test.expect_ir(expect_file![format!("../../expected/rust_sdk/{artifact_name}.hir")]); + // test.expect_masm(expect_file![format!("../../expected/rust_sdk/{artifact_name}.masm")]); // TODO: fix flaky test, "exec."_ZN19miden_sdk_tx_kernel9add_asset17h6f4cff304c095ffc" is // changing the suffix on every n-th run test.expect_masm(expect_file![format!("../../ // expected/{project_name}/{artifact_name}.masm" )]); diff --git a/tests/rust-apps-wasm/rust-sdk/basic-wallet/.gitignore b/tests/rust-apps-wasm/rust-sdk/basic-wallet/.gitignore new file mode 100644 index 000000000..c41cc9e35 --- /dev/null +++ b/tests/rust-apps-wasm/rust-sdk/basic-wallet/.gitignore @@ -0,0 +1 @@ +/target \ No newline at end of file diff --git a/tests/rust-apps-wasm/rust-sdk/basic-wallet/Cargo.lock b/tests/rust-apps-wasm/rust-sdk/basic-wallet/Cargo.lock new file mode 100644 index 000000000..12a87cc27 --- /dev/null +++ b/tests/rust-apps-wasm/rust-sdk/basic-wallet/Cargo.lock @@ -0,0 +1,41 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "basic_wallet" +version = "0.1.0" +dependencies = [ + "miden-sdk", + "wit-bindgen-rt", +] + +[[package]] +name = "miden-base-sys" +version = "0.0.7" +dependencies = [ + "miden-stdlib-sys", +] + +[[package]] +name = "miden-sdk" +version = "0.0.7" +dependencies = [ + "miden-base-sys", + "miden-sdk-alloc", + "miden-stdlib-sys", +] + +[[package]] +name = "miden-sdk-alloc" +version = "0.0.7" + +[[package]] +name = "miden-stdlib-sys" +version = "0.0.7" + +[[package]] +name = "wit-bindgen-rt" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a37bd9274cb2d4754b915d624447ec0dce9105d174361841c0826efc79ceb9" diff --git a/tests/rust-apps-wasm/rust-sdk/basic-wallet/Cargo.toml b/tests/rust-apps-wasm/rust-sdk/basic-wallet/Cargo.toml new file mode 100644 index 000000000..d7e94a69b --- /dev/null +++ b/tests/rust-apps-wasm/rust-sdk/basic-wallet/Cargo.toml @@ -0,0 +1,44 @@ +[package] +name = "basic_wallet" +version = "0.1.0" +edition = "2021" + +[lib] +# Build this crate as a self-contained, C-style dynamic library +# This is required to emit the proper Wasm module type +crate-type = ["cdylib"] + +[dependencies] +# Miden SDK consists of a stdlib (intrinsic functions for VM ops, stdlib functions and types) +# and transaction kernel API for the Miden rollup +miden-sdk = { path = "../../../../sdk/sdk" } +wit-bindgen-rt = "0.28" + + +[profile.release] +# optimize the output for size +opt-level = "z" +# Explicitly disable panic infrastructure on Wasm, as +# there is no proper support for them anyway, and it +# ensures that panics do not pull in a bunch of standard +# library code unintentionally +panic = "abort" + +[profile.dev] +# Explicitly disable panic infrastructure on Wasm, as +# there is no proper support for them anyway, and it +# ensures that panics do not pull in a bunch of standard +# library code unintentionally +panic = "abort" +opt-level = 1 +debug-assertions = false +overflow-checks = false +debug = true + +# TODO: switch to miden table +[package.metadata.component] +package = "miden:basic-wallet" + +[package.metadata.component.target.dependencies] +"miden:base" = { path = "wit-sdk/miden.wit" } +"miden:core-import" = { path = "wit-sdk/miden-core-import.wit" } \ No newline at end of file diff --git a/tests/rust-apps-wasm/rust-sdk/basic-wallet/README.md b/tests/rust-apps-wasm/rust-sdk/basic-wallet/README.md new file mode 100644 index 000000000..c4e0f3098 --- /dev/null +++ b/tests/rust-apps-wasm/rust-sdk/basic-wallet/README.md @@ -0,0 +1,19 @@ +# basic_wallet + +## Useful commands + +`basic_wallet` is built using the [Miden compiler](https://github.com/0xPolygonMiden/compiler). + +`cargo miden` is a `cargo` cargo extension. Check out its [documentation](https://github.com/0xPolygonMiden/compiler/tree/main/tools/cargo-miden) +for more details. + + +### Build + +To build this project, run: + +```bash +cargo miden build --release +``` + +The compiled Miden artifact will be located in `target/miden/release`. diff --git a/tests/rust-apps-wasm/rust-sdk/basic-wallet/rust-toolchain.toml b/tests/rust-apps-wasm/rust-sdk/basic-wallet/rust-toolchain.toml new file mode 100644 index 000000000..a4cb17f1f --- /dev/null +++ b/tests/rust-apps-wasm/rust-sdk/basic-wallet/rust-toolchain.toml @@ -0,0 +1,5 @@ +[toolchain] +channel = "nightly-2024-08-06" +components = ["rustfmt", "rust-src"] +targets = ["wasm32-wasi"] +profile = "minimal" diff --git a/tests/rust-apps-wasm/rust-sdk/basic-wallet/src/bindings.rs b/tests/rust-apps-wasm/rust-sdk/basic-wallet/src/bindings.rs new file mode 100644 index 000000000..c599e9377 --- /dev/null +++ b/tests/rust-apps-wasm/rust-sdk/basic-wallet/src/bindings.rs @@ -0,0 +1,664 @@ +#[allow(dead_code)] +pub mod miden { + #[allow(dead_code)] + pub mod base { + #[allow(dead_code, clippy::all)] + pub mod core_types { + #[used] + #[doc(hidden)] + static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports; + /// Unique identifier of an account. + /// + /// Account ID consists of 1 field element (~64 bits). This field element uniquely identifies a + /// single account and also specifies the type of the underlying account. Specifically: + /// - The two most significant bits of the ID specify the type of the account: + /// - 00 - regular account with updatable code. + /// - 01 - regular account with immutable code. + /// - 10 - fungible asset faucet with immutable code. + /// - 11 - non-fungible asset faucet with immutable code. + /// - The third most significant bit of the ID specifies whether the account data is stored on-chain: + /// - 0 - full account data is stored on-chain. + /// - 1 - only the account hash is stored on-chain which serves as a commitment to the account state. + /// As such the three most significant bits fully describes the type of the account. + #[repr(C)] + #[derive(Clone, Copy)] + pub struct AccountId { + pub inner: miden_sdk::Felt, + } + impl ::core::fmt::Debug for AccountId { + fn fmt( + &self, + f: &mut ::core::fmt::Formatter<'_>, + ) -> ::core::fmt::Result { + f.debug_struct("AccountId").field("inner", &self.inner).finish() + } + } + } + } + #[allow(dead_code)] + pub mod core_import { + #[allow(dead_code, clippy::all)] + pub mod types { + #[used] + #[doc(hidden)] + static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports; + /// Represents base field element in the field using Montgomery representation. + /// Internal values represent x * R mod M where R = 2^64 mod M and x in [0, M). + /// The backing type is `f64` but the internal values are always integer in the range [0, M). + /// Field modulus M = 2^64 - 2^32 + 1 + pub type Felt = f32; + pub type Ptr = i32; + } + #[allow(dead_code, clippy::all)] + pub mod intrinsics_mem { + #[used] + #[doc(hidden)] + static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports; + pub type Ptr = super::super::super::miden::core_import::types::Ptr; + #[allow(unused_unsafe, clippy::all)] + pub fn heap_base() -> Ptr { + unsafe { + #[cfg(target_arch = "wasm32")] + #[link( + wasm_import_module = "miden:core-import/intrinsics-mem@1.0.0" + )] + extern "C" { + #[link_name = "heap-base"] + fn wit_import() -> i32; + } + #[cfg(not(target_arch = "wasm32"))] + fn wit_import() -> i32 { + unreachable!() + } + let ret = wit_import(); + ret + } + } + } + #[allow(dead_code, clippy::all)] + pub mod intrinsics_felt { + #[used] + #[doc(hidden)] + static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + pub type Felt = super::super::super::miden::core_import::types::Felt; + #[allow(unused_unsafe, clippy::all)] + pub fn add(a: Felt, b: Felt) -> Felt { + unsafe { + #[cfg(target_arch = "wasm32")] + #[link( + wasm_import_module = "miden:core-import/intrinsics-felt@1.0.0" + )] + extern "C" { + #[link_name = "add"] + fn wit_import(_: f32, _: f32) -> f32; + } + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: f32, _: f32) -> f32 { + unreachable!() + } + let ret = wit_import(_rt::as_f32(a), _rt::as_f32(b)); + ret + } + } + } + #[allow(dead_code, clippy::all)] + pub mod stdlib_crypto_hashes { + #[used] + #[doc(hidden)] + static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + pub type Ptr = super::super::super::miden::core_import::types::Ptr; + #[allow(unused_unsafe, clippy::all)] + pub fn blake3_hash_one_to_one( + a0: i32, + a1: i32, + a2: i32, + a3: i32, + a4: i32, + a5: i32, + a6: i32, + a7: i32, + result_ptr: Ptr, + ) { + unsafe { + #[cfg(target_arch = "wasm32")] + #[link( + wasm_import_module = "miden:core-import/stdlib-crypto-hashes@1.0.0" + )] + extern "C" { + #[link_name = "blake3-hash-one-to-one"] + fn wit_import( + _: i32, + _: i32, + _: i32, + _: i32, + _: i32, + _: i32, + _: i32, + _: i32, + _: i32, + ); + } + #[cfg(not(target_arch = "wasm32"))] + fn wit_import( + _: i32, + _: i32, + _: i32, + _: i32, + _: i32, + _: i32, + _: i32, + _: i32, + _: i32, + ) { + unreachable!() + } + wit_import( + _rt::as_i32(&a0), + _rt::as_i32(&a1), + _rt::as_i32(&a2), + _rt::as_i32(&a3), + _rt::as_i32(&a4), + _rt::as_i32(&a5), + _rt::as_i32(&a6), + _rt::as_i32(&a7), + _rt::as_i32(result_ptr), + ); + } + } + } + #[allow(dead_code, clippy::all)] + pub mod account { + #[used] + #[doc(hidden)] + static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + pub type Felt = super::super::super::miden::core_import::types::Felt; + pub type Ptr = super::super::super::miden::core_import::types::Ptr; + #[allow(unused_unsafe, clippy::all)] + /// Add the specified asset to the vault. Panics under various conditions. + /// Returns the final asset in the account vault defined as follows: If asset is + /// a non-fungible asset, then returns the same as asset. If asset is a + /// fungible asset, then returns the total fungible asset in the account + /// vault after asset was added to it. + pub fn add_asset( + asset0: Felt, + asset1: Felt, + asset2: Felt, + asset3: Felt, + result_ptr: Ptr, + ) { + unsafe { + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:core-import/account@1.0.0")] + extern "C" { + #[link_name = "add-asset"] + fn wit_import(_: f32, _: f32, _: f32, _: f32, _: i32); + } + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: f32, _: f32, _: f32, _: f32, _: i32) { + unreachable!() + } + wit_import( + _rt::as_f32(asset0), + _rt::as_f32(asset1), + _rt::as_f32(asset2), + _rt::as_f32(asset3), + _rt::as_i32(result_ptr), + ); + } + } + #[allow(unused_unsafe, clippy::all)] + /// Remove the specified asset from the vault + pub fn remove_asset( + asset0: Felt, + asset1: Felt, + asset2: Felt, + asset3: Felt, + result_ptr: Ptr, + ) { + unsafe { + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:core-import/account@1.0.0")] + extern "C" { + #[link_name = "remove-asset"] + fn wit_import(_: f32, _: f32, _: f32, _: f32, _: i32); + } + #[cfg(not(target_arch = "wasm32"))] + fn wit_import(_: f32, _: f32, _: f32, _: f32, _: i32) { + unreachable!() + } + wit_import( + _rt::as_f32(asset0), + _rt::as_f32(asset1), + _rt::as_f32(asset2), + _rt::as_f32(asset3), + _rt::as_i32(result_ptr), + ); + } + } + } + #[allow(dead_code, clippy::all)] + pub mod tx { + #[used] + #[doc(hidden)] + static __FORCE_SECTION_REF: fn() = super::super::super::__link_custom_section_describing_imports; + use super::super::super::_rt; + pub type Felt = super::super::super::miden::core_import::types::Felt; + #[allow(unused_unsafe, clippy::all)] + /// Creates a new note. + /// asset is the asset to be included in the note. + /// tag is the tag to be included in the note. + /// recipient is the recipient of the note. + /// Returns the id of the created note. + pub fn create_note( + asset0: Felt, + asset1: Felt, + asset2: Felt, + asset3: Felt, + tag: Felt, + note_type: Felt, + recipient0: Felt, + recipient1: Felt, + recipient2: Felt, + recipient3: Felt, + ) -> Felt { + unsafe { + #[cfg(target_arch = "wasm32")] + #[link(wasm_import_module = "miden:core-import/tx@1.0.0")] + extern "C" { + #[link_name = "create-note"] + fn wit_import( + _: f32, + _: f32, + _: f32, + _: f32, + _: f32, + _: f32, + _: f32, + _: f32, + _: f32, + _: f32, + ) -> f32; + } + #[cfg(not(target_arch = "wasm32"))] + fn wit_import( + _: f32, + _: f32, + _: f32, + _: f32, + _: f32, + _: f32, + _: f32, + _: f32, + _: f32, + _: f32, + ) -> f32 { + unreachable!() + } + let ret = wit_import( + _rt::as_f32(asset0), + _rt::as_f32(asset1), + _rt::as_f32(asset2), + _rt::as_f32(asset3), + _rt::as_f32(tag), + _rt::as_f32(note_type), + _rt::as_f32(recipient0), + _rt::as_f32(recipient1), + _rt::as_f32(recipient2), + _rt::as_f32(recipient3), + ); + ret + } + } + } + } +} +#[allow(dead_code)] +pub mod exports { + #[allow(dead_code)] + pub mod miden { + #[allow(dead_code)] + pub mod basic_wallet { + #[allow(dead_code, clippy::all)] + pub mod basic_wallet { + #[used] + #[doc(hidden)] + static __FORCE_SECTION_REF: fn() = super::super::super::super::__link_custom_section_describing_imports; + use super::super::super::super::_rt; + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_receive_asset_cabi( + arg0: f32, + arg1: f32, + arg2: f32, + arg3: f32, + ) { + #[cfg(target_arch = "wasm32")] _rt::run_ctors_once(); + T::receive_asset(miden_sdk::CoreAsset { + inner: miden_sdk::Word { + inner: ( + miden_sdk::Felt { inner: arg0 }, + miden_sdk::Felt { inner: arg1 }, + miden_sdk::Felt { inner: arg2 }, + miden_sdk::Felt { inner: arg3 }, + ), + }, + }); + } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_send_asset_cabi( + arg0: f32, + arg1: f32, + arg2: f32, + arg3: f32, + arg4: f32, + arg5: f32, + arg6: f32, + arg7: f32, + arg8: f32, + arg9: f32, + ) { + #[cfg(target_arch = "wasm32")] _rt::run_ctors_once(); + T::send_asset( + miden_sdk::CoreAsset { + inner: miden_sdk::Word { + inner: ( + miden_sdk::Felt { inner: arg0 }, + miden_sdk::Felt { inner: arg1 }, + miden_sdk::Felt { inner: arg2 }, + miden_sdk::Felt { inner: arg3 }, + ), + }, + }, + miden_sdk::Tag { + inner: miden_sdk::Felt { inner: arg4 }, + }, + miden_sdk::NoteType { + inner: miden_sdk::Felt { inner: arg5 }, + }, + miden_sdk::Recipient { + inner: miden_sdk::Word { + inner: ( + miden_sdk::Felt { inner: arg6 }, + miden_sdk::Felt { inner: arg7 }, + miden_sdk::Felt { inner: arg8 }, + miden_sdk::Felt { inner: arg9 }, + ), + }, + }, + ); + } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_test_felt_intrinsics_cabi( + arg0: f32, + arg1: f32, + ) -> f32 { + #[cfg(target_arch = "wasm32")] _rt::run_ctors_once(); + let result0 = T::test_felt_intrinsics( + miden_sdk::Felt { inner: arg0 }, + miden_sdk::Felt { inner: arg1 }, + ); + let miden_sdk::Felt { inner: inner1 } = result0; + _rt::as_f32(inner1) + } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn _export_test_stdlib_cabi( + arg0: *mut u8, + arg1: usize, + ) -> *mut u8 { + #[cfg(target_arch = "wasm32")] _rt::run_ctors_once(); + let len0 = arg1; + let result1 = T::test_stdlib( + _rt::Vec::from_raw_parts(arg0.cast(), len0, len0), + ); + let ptr2 = _RET_AREA.0.as_mut_ptr().cast::(); + let vec3 = (result1).into_boxed_slice(); + let ptr3 = vec3.as_ptr().cast::(); + let len3 = vec3.len(); + ::core::mem::forget(vec3); + *ptr2.add(4).cast::() = len3; + *ptr2.add(0).cast::<*mut u8>() = ptr3.cast_mut(); + ptr2 + } + #[doc(hidden)] + #[allow(non_snake_case)] + pub unsafe fn __post_return_test_stdlib(arg0: *mut u8) { + let l0 = *arg0.add(0).cast::<*mut u8>(); + let l1 = *arg0.add(4).cast::(); + let base2 = l0; + let len2 = l1; + _rt::cabi_dealloc(base2, len2 * 1, 1); + } + pub trait Guest { + fn receive_asset(core_asset: miden_sdk::CoreAsset); + fn send_asset( + core_asset: miden_sdk::CoreAsset, + tag: miden_sdk::Tag, + note_type: miden_sdk::NoteType, + recipient: miden_sdk::Recipient, + ); + fn test_felt_intrinsics( + a: miden_sdk::Felt, + b: miden_sdk::Felt, + ) -> miden_sdk::Felt; + fn test_stdlib(input: _rt::Vec) -> _rt::Vec; + } + #[doc(hidden)] + macro_rules! __export_miden_basic_wallet_basic_wallet_1_0_0_cabi { + ($ty:ident with_types_in $($path_to_types:tt)*) => { + const _ : () = { #[export_name = + "miden:basic-wallet/basic-wallet@1.0.0#receive-asset"] unsafe + extern "C" fn export_receive_asset(arg0 : f32, arg1 : f32, arg2 : + f32, arg3 : f32,) { $($path_to_types)*:: + _export_receive_asset_cabi::<$ty > (arg0, arg1, arg2, arg3) } + #[export_name = + "miden:basic-wallet/basic-wallet@1.0.0#send-asset"] unsafe extern + "C" fn export_send_asset(arg0 : f32, arg1 : f32, arg2 : f32, arg3 + : f32, arg4 : f32, arg5 : f32, arg6 : f32, arg7 : f32, arg8 : + f32, arg9 : f32,) { $($path_to_types)*:: + _export_send_asset_cabi::<$ty > (arg0, arg1, arg2, arg3, arg4, + arg5, arg6, arg7, arg8, arg9) } #[export_name = + "miden:basic-wallet/basic-wallet@1.0.0#test-felt-intrinsics"] + unsafe extern "C" fn export_test_felt_intrinsics(arg0 : f32, arg1 + : f32,) -> f32 { $($path_to_types)*:: + _export_test_felt_intrinsics_cabi::<$ty > (arg0, arg1) } + #[export_name = + "miden:basic-wallet/basic-wallet@1.0.0#test-stdlib"] unsafe + extern "C" fn export_test_stdlib(arg0 : * mut u8, arg1 : usize,) + -> * mut u8 { $($path_to_types)*:: _export_test_stdlib_cabi::<$ty + > (arg0, arg1) } #[export_name = + "cabi_post_miden:basic-wallet/basic-wallet@1.0.0#test-stdlib"] + unsafe extern "C" fn _post_return_test_stdlib(arg0 : * mut u8,) { + $($path_to_types)*:: __post_return_test_stdlib::<$ty > (arg0) } + }; + }; + } + #[doc(hidden)] + pub(crate) use __export_miden_basic_wallet_basic_wallet_1_0_0_cabi; + #[repr(align(4))] + struct _RetArea([::core::mem::MaybeUninit; 8]); + static mut _RET_AREA: _RetArea = _RetArea( + [::core::mem::MaybeUninit::uninit(); 8], + ); + } + } + } +} +mod _rt { + pub fn as_f32(t: T) -> f32 { + t.as_f32() + } + pub trait AsF32 { + fn as_f32(self) -> f32; + } + impl<'a, T: Copy + AsF32> AsF32 for &'a T { + fn as_f32(self) -> f32 { + (*self).as_f32() + } + } + impl AsF32 for f32 { + #[inline] + fn as_f32(self) -> f32 { + self as f32 + } + } + pub fn as_i32(t: T) -> i32 { + t.as_i32() + } + pub trait AsI32 { + fn as_i32(self) -> i32; + } + impl<'a, T: Copy + AsI32> AsI32 for &'a T { + fn as_i32(self) -> i32 { + (*self).as_i32() + } + } + impl AsI32 for i32 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + impl AsI32 for u32 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + impl AsI32 for i16 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + impl AsI32 for u16 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + impl AsI32 for i8 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + impl AsI32 for u8 { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + impl AsI32 for char { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + impl AsI32 for usize { + #[inline] + fn as_i32(self) -> i32 { + self as i32 + } + } + #[cfg(target_arch = "wasm32")] + pub fn run_ctors_once() { + wit_bindgen_rt::run_ctors_once(); + } + pub use alloc_crate::vec::Vec; + pub unsafe fn cabi_dealloc(ptr: *mut u8, size: usize, align: usize) { + if size == 0 { + return; + } + let layout = alloc::Layout::from_size_align_unchecked(size, align); + alloc::dealloc(ptr, layout); + } + extern crate alloc as alloc_crate; + pub use alloc_crate::alloc; +} +/// Generates `#[no_mangle]` functions to export the specified type as the +/// root implementation of all generated traits. +/// +/// For more information see the documentation of `wit_bindgen::generate!`. +/// +/// ```rust +/// # macro_rules! export{ ($($t:tt)*) => (); } +/// # trait Guest {} +/// struct MyType; +/// +/// impl Guest for MyType { +/// // ... +/// } +/// +/// export!(MyType); +/// ``` +#[allow(unused_macros)] +#[doc(hidden)] +macro_rules! __export_basic_wallet_world_impl { + ($ty:ident) => { + self::export!($ty with_types_in self); + }; + ($ty:ident with_types_in $($path_to_types_root:tt)*) => { + $($path_to_types_root)*:: + exports::miden::basic_wallet::basic_wallet::__export_miden_basic_wallet_basic_wallet_1_0_0_cabi!($ty + with_types_in $($path_to_types_root)*:: + exports::miden::basic_wallet::basic_wallet); + }; +} +#[doc(inline)] +pub(crate) use __export_basic_wallet_world_impl as export; +#[cfg(target_arch = "wasm32")] +#[link_section = "component-type:wit-bindgen:0.31.0:miden:basic-wallet@1.0.0:basic-wallet-world:encoded world"] +#[doc(hidden)] +pub static __WIT_BINDGEN_COMPONENT_TYPE: [u8; 1707] = *b"\ +\0asm\x0d\0\x01\0\0\x19\x16wit-component-encoding\x04\0\x07\xa2\x0c\x01A\x02\x01\ +A\x17\x01B\x1f\x01r\x01\x05innerv\x04\0\x04felt\x03\0\0\x01o\x04\x01\x01\x01\x01\ +\x01r\x01\x05inner\x02\x04\0\x04word\x03\0\x03\x01r\x01\x05inner\x01\x04\0\x0aac\ +count-id\x03\0\x05\x01r\x01\x05inner\x04\x04\0\x09recipient\x03\0\x07\x01r\x01\x05\ +inner\x01\x04\0\x03tag\x03\0\x09\x01r\x01\x05inner\x04\x04\0\x0acore-asset\x03\0\ +\x0b\x01r\x01\x05inner\x01\x04\0\x05nonce\x03\0\x0d\x01r\x01\x05inner\x04\x04\0\x0c\ +account-hash\x03\0\x0f\x01r\x01\x05inner\x04\x04\0\x0ablock-hash\x03\0\x11\x01r\x01\ +\x05inner\x04\x04\0\x0dstorage-value\x03\0\x13\x01r\x01\x05inner\x04\x04\0\x0cst\ +orage-root\x03\0\x15\x01r\x01\x05inner\x04\x04\0\x11account-code-root\x03\0\x17\x01\ +r\x01\x05inner\x04\x04\0\x10vault-commitment\x03\0\x19\x01r\x01\x05inner\x01\x04\ +\0\x07note-id\x03\0\x1b\x01r\x01\x05inner\x01\x04\0\x09note-type\x03\0\x1d\x03\x01\ +\x1bmiden:base/core-types@1.0.0\x05\0\x01B\x04\x01v\x04\0\x04felt\x03\0\0\x01z\x04\ +\0\x03ptr\x03\0\x02\x03\x01\x1dmiden:core-import/types@1.0.0\x05\x01\x02\x03\0\x01\ +\x04felt\x02\x03\0\x01\x03ptr\x01B\x06\x02\x03\x02\x01\x02\x04\0\x04felt\x03\0\0\ +\x02\x03\x02\x01\x03\x04\0\x03ptr\x03\0\x02\x01@\0\0\x03\x04\0\x09heap-base\x01\x04\ +\x03\x01&miden:core-import/intrinsics-mem@1.0.0\x05\x04\x01B\x06\x02\x03\x02\x01\ +\x02\x04\0\x04felt\x03\0\0\x02\x03\x02\x01\x03\x04\0\x03ptr\x03\0\x02\x01@\x02\x01\ +a\x01\x01b\x01\0\x01\x04\0\x03add\x01\x04\x03\x01'miden:core-import/intrinsics-f\ +elt@1.0.0\x05\x05\x01B\x06\x02\x03\x02\x01\x02\x04\0\x04felt\x03\0\0\x02\x03\x02\ +\x01\x03\x04\0\x03ptr\x03\0\x02\x01@\x09\x02a0z\x02a1z\x02a2z\x02a3z\x02a4z\x02a\ +5z\x02a6z\x02a7z\x0aresult-ptr\x03\x01\0\x04\0\x16blake3-hash-one-to-one\x01\x04\ +\x03\x01,miden:core-import/stdlib-crypto-hashes@1.0.0\x05\x06\x01B\x07\x02\x03\x02\ +\x01\x02\x04\0\x04felt\x03\0\0\x02\x03\x02\x01\x03\x04\0\x03ptr\x03\0\x02\x01@\x05\ +\x06asset0\x01\x06asset1\x01\x06asset2\x01\x06asset3\x01\x0aresult-ptr\x03\x01\0\ +\x04\0\x09add-asset\x01\x04\x04\0\x0cremove-asset\x01\x04\x03\x01\x1fmiden:core-\ +import/account@1.0.0\x05\x07\x01B\x04\x02\x03\x02\x01\x02\x04\0\x04felt\x03\0\0\x01\ +@\x0a\x06asset0\x01\x06asset1\x01\x06asset2\x01\x06asset3\x01\x03tag\x01\x09note\ +-type\x01\x0arecipient0\x01\x0arecipient1\x01\x0arecipient2\x01\x0arecipient3\x01\ +\0\x01\x04\0\x0bcreate-note\x01\x02\x03\x01\x1amiden:core-import/tx@1.0.0\x05\x08\ +\x02\x03\0\0\x0acore-asset\x02\x03\0\0\x03tag\x02\x03\0\0\x09recipient\x02\x03\0\ +\0\x09note-type\x02\x03\0\0\x04felt\x01B\x13\x02\x03\x02\x01\x09\x04\0\x0acore-a\ +sset\x03\0\0\x02\x03\x02\x01\x0a\x04\0\x03tag\x03\0\x02\x02\x03\x02\x01\x0b\x04\0\ +\x09recipient\x03\0\x04\x02\x03\x02\x01\x0c\x04\0\x09note-type\x03\0\x06\x02\x03\ +\x02\x01\x0d\x04\0\x04felt\x03\0\x08\x01@\x01\x0acore-asset\x01\x01\0\x04\0\x0dr\ +eceive-asset\x01\x0a\x01@\x04\x0acore-asset\x01\x03tag\x03\x09note-type\x07\x09r\ +ecipient\x05\x01\0\x04\0\x0asend-asset\x01\x0b\x01@\x02\x01a\x09\x01b\x09\0\x09\x04\ +\0\x14test-felt-intrinsics\x01\x0c\x01p}\x01@\x01\x05input\x0d\0\x0d\x04\0\x0bte\ +st-stdlib\x01\x0e\x04\x01%miden:basic-wallet/basic-wallet@1.0.0\x05\x0e\x04\x01+\ +miden:basic-wallet/basic-wallet-world@1.0.0\x04\0\x0b\x18\x01\0\x12basic-wallet-\ +world\x03\0\0\0G\x09producers\x01\x0cprocessed-by\x02\x0dwit-component\x070.216.\ +0\x10wit-bindgen-rust\x060.31.0"; +#[inline(never)] +#[doc(hidden)] +pub fn __link_custom_section_describing_imports() { + wit_bindgen_rt::maybe_link_cabi_realloc(); +} diff --git a/tests/rust-apps-wasm/rust-sdk/basic-wallet/src/lib.rs b/tests/rust-apps-wasm/rust-sdk/basic-wallet/src/lib.rs new file mode 100644 index 000000000..62a786f41 --- /dev/null +++ b/tests/rust-apps-wasm/rust-sdk/basic-wallet/src/lib.rs @@ -0,0 +1,47 @@ +// Do not link against libstd (i.e. anything defined in `std::`) +#![no_std] + +// However, we could still use some standard library types while +// remaining no-std compatible, if we uncommented the following lines: +// +extern crate alloc; +use alloc::vec::Vec; + +// Global allocator to use heap memory in no-std environment +#[global_allocator] +static ALLOC: BumpAlloc = miden_sdk::BumpAlloc::new(); + +// Required for no-std crates +#[panic_handler] +fn my_panic(_info: &core::panic::PanicInfo) -> ! { + loop {} +} + +use miden_sdk::*; + +bindings::export!(Component with_types_in bindings); + +mod bindings; +use bindings::exports::miden::basic_wallet::basic_wallet::Guest; + +struct Component; + +impl Guest for Component { + fn receive_asset(asset: CoreAsset) { + add_asset(asset); + } + + fn send_asset(asset: CoreAsset, tag: Tag, note_type: NoteType, recipient: Recipient) { + let asset = remove_asset(asset); + create_note(asset, tag, note_type, recipient); + } + + fn test_felt_intrinsics(a: Felt, b: Felt) -> Felt { + a + b + } + + fn test_stdlib(input: Vec) -> Vec { + let input: [u8; 32] = input.try_into().unwrap(); + blake3_hash_1to1(input).to_vec() + } +} diff --git a/tests/rust-apps-wasm/rust-sdk/basic-wallet/wit-sdk/miden-core-import.wit b/tests/rust-apps-wasm/rust-sdk/basic-wallet/wit-sdk/miden-core-import.wit new file mode 100644 index 000000000..98675eeb8 --- /dev/null +++ b/tests/rust-apps-wasm/rust-sdk/basic-wallet/wit-sdk/miden-core-import.wit @@ -0,0 +1,75 @@ +package miden:core-import@1.0.0; + +interface types { + + /// Represents base field element in the field using Montgomery representation. + /// Internal values represent x * R mod M where R = 2^64 mod M and x in [0, M). + /// The backing type is `f64` but the internal values are always integer in the range [0, M). + /// Field modulus M = 2^64 - 2^32 + 1 + type felt = f32; + type ptr = s32; + +} + +interface intrinsics-mem { + use types.{felt, ptr}; + + heap-base: func() -> ptr; +} + +interface intrinsics-felt { + use types.{felt, ptr}; + + add: func(a: felt, b: felt) -> felt; +} + +interface stdlib-crypto-hashes { + use types.{felt, ptr}; + + blake3-hash-one-to-one: func(a0: s32, a1: s32, a2: s32, a3: s32, a4: s32, a5: s32, a6: s32, a7: s32, result-ptr: ptr); +} + +interface account { + use types.{felt, ptr}; + + /// Add the specified asset to the vault. Panics under various conditions. + /// Returns the final asset in the account vault defined as follows: If asset is + /// a non-fungible asset, then returns the same as asset. If asset is a + /// fungible asset, then returns the total fungible asset in the account + /// vault after asset was added to it. + add-asset: func(asset0: felt, asset1: felt, asset2: felt, asset3: felt, result-ptr: ptr); + /// Remove the specified asset from the vault + remove-asset: func(asset0: felt, asset1: felt, asset2: felt, asset3: felt, result-ptr: ptr); +} + +interface tx { + use types.{felt}; + + /// Creates a new note. + /// asset is the asset to be included in the note. + /// tag is the tag to be included in the note. + /// recipient is the recipient of the note. + /// Returns the id of the created note. + create-note: func( + asset0: felt, + asset1: felt, + asset2: felt, + asset3: felt, + tag: felt, + note-type: felt, + recipient0: felt, + recipient1: felt, + recipient2: felt, + recipient3: felt, + ) -> felt; + +} + +world all { + import intrinsics-mem; + import intrinsics-felt; + import stdlib-crypto-hashes; + import account; + import tx; + +} \ No newline at end of file diff --git a/tests/rust-apps-wasm/rust-sdk/basic-wallet/wit-sdk/miden.wit b/tests/rust-apps-wasm/rust-sdk/basic-wallet/wit-sdk/miden.wit new file mode 100644 index 000000000..7347ca0a8 --- /dev/null +++ b/tests/rust-apps-wasm/rust-sdk/basic-wallet/wit-sdk/miden.wit @@ -0,0 +1,324 @@ +package miden:base@1.0.0; + +/// Types to be used in tx-kernel interface +interface core-types { + /// Represents base field element in the field using Montgomery representation. + /// Internal values represent x * R mod M where R = 2^64 mod M and x in [0, M). + /// The backing type is `f64` but the internal values are always integer in the range [0, M). + /// Field modulus M = 2^64 - 2^32 + 1 + record felt { + /// We plan to use f32 as the backing type for the field element. It has the size that we need and + /// we don't plan to support floating point arithmetic in programs for Miden VM. + inner: f32, + } + + + /// A group of four field elements in the Miden base field. + // type word = tuple; + record word { + inner: tuple + } + + /// Unique identifier of an account. + /// + /// Account ID consists of 1 field element (~64 bits). This field element uniquely identifies a + /// single account and also specifies the type of the underlying account. Specifically: + /// - The two most significant bits of the ID specify the type of the account: + /// - 00 - regular account with updatable code. + /// - 01 - regular account with immutable code. + /// - 10 - fungible asset faucet with immutable code. + /// - 11 - non-fungible asset faucet with immutable code. + /// - The third most significant bit of the ID specifies whether the account data is stored on-chain: + /// - 0 - full account data is stored on-chain. + /// - 1 - only the account hash is stored on-chain which serves as a commitment to the account state. + /// As such the three most significant bits fully describes the type of the account. + record account-id { + inner: felt + } + + /// Creates a new account ID from a field element. + //account-id-from-felt: func(felt: felt) -> account-id; + + /// Recipient of the note, i.e., hash(hash(hash(serial_num, [0; 4]), note_script_hash), input_hash) + record recipient { + inner: word + } + + record tag { + inner: felt + } + + /// A fungible or a non-fungible asset. + /// + /// All assets are encoded using a single word (4 elements) such that it is easy to determine the + /// type of an asset both inside and outside Miden VM. Specifically: + /// Element 1 will be: + /// - ZERO for a fungible asset + /// - non-ZERO for a non-fungible asset + /// The most significant bit will be: + /// - ONE for a fungible asset + /// - ZERO for a non-fungible asset + /// + /// The above properties guarantee that there can never be a collision between a fungible and a + /// non-fungible asset. + /// + /// The methodology for constructing fungible and non-fungible assets is described below. + /// + /// # Fungible assets + /// The most significant element of a fungible asset is set to the ID of the faucet which issued + /// the asset. This guarantees the properties described above (the first bit is ONE). + /// + /// The least significant element is set to the amount of the asset. This amount cannot be greater + /// than 2^63 - 1 and thus requires 63-bits to store. + /// + /// Elements 1 and 2 are set to ZERO. + /// + /// It is impossible to find a collision between two fungible assets issued by different faucets as + /// the faucet_id is included in the description of the asset and this is guaranteed to be different + /// for each faucet as per the faucet creation logic. + /// + /// # Non-fungible assets + /// The 4 elements of non-fungible assets are computed as follows: + /// - First the asset data is hashed. This compresses an asset of an arbitrary length to 4 field + /// elements: [d0, d1, d2, d3]. + /// - d1 is then replaced with the faucet_id which issues the asset: [d0, faucet_id, d2, d3]. + /// - Lastly, the most significant bit of d3 is set to ZERO. + /// + /// It is impossible to find a collision between two non-fungible assets issued by different faucets + /// as the faucet_id is included in the description of the non-fungible asset and this is guaranteed + /// to be different as per the faucet creation logic. Collision resistance for non-fungible assets + /// issued by the same faucet is ~2^95. + record core-asset { + inner: word + } + + /// Account nonce + record nonce { + inner: felt + } + + /// Account hash + record account-hash { + inner: word + } + + /// Block hash + record block-hash { + inner: word + } + + /// Storage value + record storage-value { + inner: word + } + + /// Account storage root + record storage-root { + inner: word + } + + /// Account code root + record account-code-root { + inner: word + } + + /// Commitment to the account vault + record vault-commitment { + inner: word + } + + /// An id of the created note + record note-id { + inner: felt + } + + record note-type { + inner: felt + } + +} + + +/// Account-related functions +interface account { + use core-types.{felt,core-asset, tag, recipient, account-id, nonce, account-hash, storage-value, storage-root, account-code-root, vault-commitment}; + + /// Get the id of the currently executing account + get-id: func() -> account-id; + /// Return the account nonce + get-nonce: func() -> nonce; + /// Get the initial hash of the currently executing account + get-initial-hash: func() -> account-hash; + /// Get the current hash of the account data stored in memory + get-current-hash: func() -> account-hash; + /// Increment the account nonce by the specified value. + /// value can be at most 2^32 - 1 otherwise this procedure panics + incr-nonce: func(value: felt); + /// Get the value of the specified key in the account storage + get-item: func(index: felt) -> storage-value; + /// Set the value of the specified key in the account storage + /// Returns the old value of the key and the new storage root + set-item: func(index: felt, value: storage-value) -> tuple; + /// Sets the code of the account the transaction is being executed against. + /// This procedure can only be executed on regular accounts with updatable + /// code. Otherwise, this procedure fails. code is the hash of the code + /// to set. + set-code: func(code-root: account-code-root); + /// Returns the balance of a fungible asset associated with a account_id. + /// Panics if the asset is not a fungible asset. account_id is the faucet id + /// of the fungible asset of interest. balance is the vault balance of the + /// fungible asset. + get-balance: func(account-id: account-id) -> felt; + /// Returns a boolean indicating whether the non-fungible asset is present + /// in the vault. Panics if the asset is a fungible asset. asset is the + /// non-fungible asset of interest. has_asset is a boolean indicating + /// whether the account vault has the asset of interest. + has-non-fungible-asset: func(asset: core-asset) -> bool; + /// Add the specified asset to the vault. Panics under various conditions. + /// Returns the final asset in the account vault defined as follows: If asset is + /// a non-fungible asset, then returns the same as asset. If asset is a + /// fungible asset, then returns the total fungible asset in the account + /// vault after asset was added to it. + add-asset: func(asset0: felt, asset1: felt, asset2: felt, asset3: felt, result-ptr: u32); + /// Remove the specified asset from the vault + remove-asset: func(asset0: felt, asset1: felt, asset2: felt, asset3: felt, result-ptr: u32); + /// Returns the commitment to the account vault. + get-vault-commitment: func() -> vault-commitment; +} + +// Note-related functions +interface note { + use core-types.{felt, core-asset, tag, recipient, account-id, nonce, account-hash, storage-value, storage-root, account-code-root, vault-commitment}; + + /// Get the inputs of the currently executed note + get-inputs: func() -> list; + /// Get the assets of the currently executing note + get-assets: func() -> list; + /// Get the sender of the currently executing note + get-sender: func() -> account-id; + +} + +/// Transaction-related functions +interface tx { + use core-types.{felt, core-asset, tag, recipient, account-id, nonce, account-hash, storage-value, storage-root, account-code-root, vault-commitment, block-hash, word, note-id, note-type}; + + /// Returns the block number of the last known block at the time of transaction execution. + get-block-number: func() -> felt; + /// Returns the block hash of the last known block at the time of transaction execution. + get-block-hash: func() -> block-hash; + /// Returns the input notes hash. This is computed as a sequential hash of + /// (nullifier, script_root) tuples over all input notes. + get-input-notes-hash: func() -> word; + /// Returns the output notes hash. This is computed as a sequential hash of + /// (note_hash, note_metadata) tuples over all output notes. + get-output-notes-hash: func() -> word; + /// Creates a new note. + /// asset is the asset to be included in the note. + /// tag is the tag to be included in the note. + /// recipient is the recipient of the note. + /// Returns the id of the created note. + create-note: func( + asset0: felt, + asset1: felt, + asset2: felt, + asset3: felt, + tag: felt, + note-type: felt, + recipient0: felt, + recipient1: felt, + recipient2: felt, + recipient3: felt, + ) -> felt; + +} + +/// Asset-related functions. These functions can only be called by faucet accounts. +interface asset { + use core-types.{felt, core-asset, tag, recipient, account-id, nonce, account-hash, storage-value, storage-root, account-code-root, vault-commitment, block-hash, word}; + + /// Builds a fungible asset for the specified fungible faucet and amount. + /// faucet_id is the faucet to create the asset for. + /// amount is the amount of the asset to create. + /// Returns the created asset. + build-fungible-asset: func(faucet-id: account-id, amount: felt) -> core-asset; + /// Creates a fungible asset for the faucet the transaction is being + /// executed against. + /// amount is the amount of the asset to create. + /// Returns the created asset. + create-fungible-asset: func(amount: felt) -> core-asset; + /// Builds a non-fungible asset for the specified non-fungible faucet and + /// data-hash. + /// faucet_id is the faucet to create the asset for. + /// data-hash is the data hash of the non-fungible asset to build. + /// Returns the created asset. + build-non-fungible-asset: func(faucet-id: account-id, data-hash: word) -> core-asset; + /// Creates a non-fungible asset for the faucet the transaction is being executed against. + /// data-hash is the data hash of the non-fungible asset to create. + /// Returns the created asset. + create-non-fungible-asset: func(data-hash: word) -> core-asset; +} + + +/// Faucet-related functions. These functions can only be called by faucet accounts. +interface faucet { + use core-types.{felt, core-asset, tag, recipient, account-id, nonce, account-hash, storage-value, storage-root, account-code-root, vault-commitment, block-hash, word}; + + /// Mint an asset from the faucet transaction is being executed against. + /// Returns the minted asset. + mint: func(asset: core-asset) -> core-asset; + /// Burn an asset from the faucet transaction is being executed against. + /// Returns the burned asset. + burn: func(asset: core-asset) -> core-asset; + /// Returns the total issuance of the fungible faucet the transaction is + /// being executed against. Panics if the transaction is not being executed + /// against a fungible faucet. + get-total-issuance: func() -> felt; + +} + + +/// High-level representation of core types +interface types { + use core-types.{felt, account-id, word, core-asset}; + + /// A fungible asset + record fungible-asset { + /// Faucet ID of the faucet which issued the asset as well as the asset amount. + asset: account-id, + /// Asset amount is guaranteed to be 2^63 - 1 or smaller. + amount: u64 + } + + /// A commitment to a non-fungible asset. + /// + /// A non-fungible asset consists of 4 field elements which are computed by hashing asset data + /// (which can be of arbitrary length) to produce: [d0, d1, d2, d3]. We then replace d1 with the + /// faucet_id that issued the asset: [d0, faucet_id, d2, d3]. We then set the most significant bit + /// of the most significant element to ZERO. + record non-fungible-asset { + inner: word, + } + + /// A fungible or a non-fungible asset. + variant asset { + fungible(fungible-asset), + non-fungible(non-fungible-asset), + } + + /// Converts a core asset to a an asset representation. + from-core-asset: func(core-asset: core-asset) -> asset; + /// Converts an asset to a core asset representation. + to-core-asset: func(asset: asset) -> core-asset; +} + + +/// Note script interface that is expected to be implemented by the note script. +interface note-script { + note-script: func(); +} + +world base-world { + export types; + export core-types; +} diff --git a/tests/rust-apps-wasm/rust-sdk/basic-wallet/wit/basic-wallet.wit b/tests/rust-apps-wasm/rust-sdk/basic-wallet/wit/basic-wallet.wit new file mode 100644 index 000000000..21ae5a4c4 --- /dev/null +++ b/tests/rust-apps-wasm/rust-sdk/basic-wallet/wit/basic-wallet.wit @@ -0,0 +1,19 @@ +package miden:basic-wallet@1.0.0; + +use miden:base/core-types@1.0.0; + +interface basic-wallet { + use core-types.{core-asset, tag, recipient, note-type, felt}; + + receive-asset: func(core-asset: core-asset); + send-asset: func(core-asset: core-asset, tag: tag, note-type: note-type, recipient: recipient); + + test-felt-intrinsics: func(a: felt, b: felt) -> felt; + test-stdlib: func(input: list) -> list; +} + +world basic-wallet-world { + include miden:core-import/all@1.0.0; + + export basic-wallet; +} \ No newline at end of file diff --git a/tools/cargo-miden/Cargo.toml b/tools/cargo-miden/Cargo.toml index 5dfdac61d..13b450efe 100644 --- a/tools/cargo-miden/Cargo.toml +++ b/tools/cargo-miden/Cargo.toml @@ -28,12 +28,16 @@ env_logger.workspace = true log.workspace = true clap.workspace = true anyhow.workspace = true -cargo-component = "0.16" -cargo-component-core = "0.16" +cargo-component = { version = "0.17.0-dev", git = "https://github.com/greenhat/cargo-component", branch = "use-as-lib" } +cargo-component-core = { version = "0.17.0-dev", git = "https://github.com/greenhat/cargo-component", branch = "use-as-lib" } +# cargo-component = { version = "0.17.0-dev", path = "../../../cargo-component" } +# cargo-component-core = { version = "0.17.0-dev", path = "../../../cargo-component/crates/core" } cargo_metadata = "0.18" cargo-generate = "0.22" semver = "1.0.20" parse_arg = "0.1.4" path-absolutize = "3.1.1" +tokio.workspace = true +cargo-config2 = "0.1.24" [dev-dependencies] diff --git a/tools/cargo-miden/src/commands/mod.rs b/tools/cargo-miden/src/commands/mod.rs new file mode 100644 index 000000000..4ef48446b --- /dev/null +++ b/tools/cargo-miden/src/commands/mod.rs @@ -0,0 +1,3 @@ +mod new_project; + +pub use new_project::*; diff --git a/tools/cargo-miden/src/new_project.rs b/tools/cargo-miden/src/commands/new_project.rs similarity index 100% rename from tools/cargo-miden/src/new_project.rs rename to tools/cargo-miden/src/commands/new_project.rs diff --git a/tools/cargo-miden/src/build.rs b/tools/cargo-miden/src/compile_masm.rs similarity index 98% rename from tools/cargo-miden/src/build.rs rename to tools/cargo-miden/src/compile_masm.rs index 5b88a071d..d8e25f76d 100644 --- a/tools/cargo-miden/src/build.rs +++ b/tools/cargo-miden/src/compile_masm.rs @@ -9,7 +9,7 @@ use midenc_session::{ InputFile, OutputType, }; -pub fn build_masm( +pub fn wasm_to_masm( wasm_file_path: &Path, output_folder: &Path, is_bin: bool, diff --git a/tools/cargo-miden/src/config.rs b/tools/cargo-miden/src/config.rs deleted file mode 100644 index 593416639..000000000 --- a/tools/cargo-miden/src/config.rs +++ /dev/null @@ -1,789 +0,0 @@ -//! Module for cargo-miden configuration. -//! -//! This implements an argument parser because `clap` is not -//! designed for parsing unknown or unsupported arguments. -//! -//! See https://github.com/clap-rs/clap/issues/1404 for some -//! discussion around this issue. -//! -//! To properly "wrap" `cargo` commands, we need to be able to -//! detect certain arguments, but not error out if the arguments -//! are otherwise unknown as they will be passed to `cargo` directly. -//! -//! This will allow `cargo-miden` to be used as a drop-in -//! replacement for `cargo` without having to be fully aware of -//! the many subcommands and options that `cargo` supports. -//! -//! What is detected here is the minimal subset of the arguments -//! that `cargo` supports which are necessary for `cargo-miden` -//! to function. - -use std::{collections::BTreeMap, fmt, fmt::Display, path::PathBuf, str::FromStr}; - -use anyhow::{anyhow, bail, Context, Result}; -use cargo_component_core::terminal::{Color, Terminal}; -use parse_arg::{iter_short, match_arg}; -use semver::Version; - -/// Represents a cargo package specifier. -/// -/// See `cargo help pkgid` for more information. -#[derive(Debug, Clone, Eq, PartialEq)] -pub struct CargoPackageSpec { - /// The name of the package, e.g. `foo`. - pub name: String, - /// The version of the package, if specified. - pub version: Option, -} - -impl CargoPackageSpec { - /// Creates a new package specifier from a string. - pub fn new(spec: impl Into) -> Result { - let spec = spec.into(); - - // Bail out if the package specifier contains a URL. - if spec.contains("://") { - bail!("URL package specifier `{spec}` is not supported"); - } - - Ok(match spec.split_once('@') { - Some((name, version)) => Self { - name: name.to_string(), - version: Some( - version - .parse() - .with_context(|| format!("invalid package specified `{spec}`"))?, - ), - }, - None => Self { - name: spec, - version: None, - }, - }) - } -} - -impl FromStr for CargoPackageSpec { - type Err = anyhow::Error; - - fn from_str(s: &str) -> Result { - Self::new(s) - } -} - -impl fmt::Display for CargoPackageSpec { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{name}", name = self.name)?; - if let Some(version) = &self.version { - write!(f, "@{version}")?; - } - - Ok(()) - } -} - -#[derive(Debug, Clone)] -enum Arg { - Flag { - name: &'static str, - short: Option, - value: bool, - }, - Single { - name: &'static str, - value_name: &'static str, - short: Option, - value: Option, - }, - Multiple { - name: &'static str, - value_name: &'static str, - short: Option, - values: Vec, - }, - Counting { - name: &'static str, - short: Option, - value: usize, - }, -} - -impl Arg { - fn name(&self) -> &'static str { - match self { - Self::Flag { name, .. } - | Self::Single { name, .. } - | Self::Multiple { name, .. } - | Self::Counting { name, .. } => name, - } - } - - fn short(&self) -> Option { - match self { - Self::Flag { short, .. } - | Self::Single { short, .. } - | Self::Multiple { short, .. } - | Self::Counting { short, .. } => *short, - } - } - - fn expects_value(&self) -> bool { - matches!(self, Self::Single { .. } | Self::Multiple { .. }) - } - - fn set_value(&mut self, v: String) -> Result<()> { - match self { - Self::Single { value, .. } => { - if value.is_some() { - bail!("the argument '{self}' cannot be used multiple times"); - } - - *value = Some(v); - Ok(()) - } - Self::Multiple { values, .. } => { - values.push(v); - Ok(()) - } - _ => unreachable!(), - } - } - - fn set_present(&mut self) -> Result<()> { - match self { - Self::Flag { value, .. } => { - if *value { - bail!("the argument '{self}' cannot be used multiple times"); - } - - *value = true; - Ok(()) - } - Self::Counting { value, .. } => { - *value += 1; - Ok(()) - } - _ => unreachable!(), - } - } - - fn take_single(&mut self) -> Option { - match self { - Self::Single { value, .. } => value.take(), - _ => None, - } - } - - fn take_multiple(&mut self) -> Vec { - match self { - Self::Multiple { values, .. } => std::mem::take(values), - _ => Vec::new(), - } - } - - fn count(&self) -> usize { - match self { - Arg::Flag { value, .. } => *value as usize, - Arg::Single { value, .. } => value.is_some() as usize, - Arg::Multiple { values, .. } => values.len(), - Arg::Counting { value, .. } => *value, - } - } - - #[cfg(test)] - fn reset(&mut self) { - match self { - Arg::Flag { value, .. } => *value = false, - Arg::Single { value, .. } => *value = None, - Arg::Multiple { values, .. } => values.clear(), - Arg::Counting { value, .. } => *value = 0, - } - } -} - -impl Display for Arg { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{name}", name = self.name())?; - match self { - Self::Single { value_name, .. } | Self::Multiple { value_name, .. } => { - write!(f, " <{value_name}>") - } - _ => Ok(()), - } - } -} - -#[derive(Default, Debug, Clone)] -struct Args { - args: Vec, - long: BTreeMap<&'static str, usize>, - short: BTreeMap, -} - -impl Args { - fn flag(self, name: &'static str, short: Option) -> Self { - self.insert(Arg::Flag { - name, - short, - value: false, - }) - } - - fn single(self, name: &'static str, value_name: &'static str, short: Option) -> Self { - self.insert(Arg::Single { - name, - value_name, - short, - value: None, - }) - } - - fn multiple(self, name: &'static str, value_name: &'static str, short: Option) -> Self { - self.insert(Arg::Multiple { - name, - value_name, - short, - values: Vec::new(), - }) - } - - fn counting(self, name: &'static str, short: Option) -> Self { - self.insert(Arg::Counting { - name, - short, - value: 0, - }) - } - - fn get(&mut self, name: &str) -> Option<&Arg> { - self.long.get(name).copied().map(|i| &self.args[i]) - } - - fn get_mut(&mut self, name: &str) -> Option<&mut Arg> { - self.long.get(name).copied().map(|i| &mut self.args[i]) - } - - fn get_short_mut(&mut self, short: char) -> Option<&mut Arg> { - self.short.get(&short).copied().map(|i| &mut self.args[i]) - } - - fn insert(mut self, arg: Arg) -> Self { - let name = arg.name(); - let short = arg.short(); - - let index = self.args.len(); - self.args.push(arg); - - let prev = self.long.insert(name, index); - assert!(prev.is_none(), "duplicate argument `{name}` provided"); - - if let Some(short) = short { - let prev = self.short.insert(short, index); - assert!(prev.is_none(), "duplicate argument `-{short}` provided"); - } - - self - } - - /// Parses an argument as an option. - /// - /// Returns `Ok(true)` if the argument is an option. - /// - /// Returns `Ok(false)` if the argument is not an option. - fn parse(&mut self, arg: &str, iter: &mut impl Iterator) -> Result { - // Handle short options - if let Some(mut short) = iter_short(arg) { - while let Some(c) = short.next() { - if let Some(option) = self.get_short_mut(c) { - if option.expects_value() { - let value: String = short.parse_remaining(iter).map_err(|_| { - anyhow!("a value is required for '{option}' but none was supplied") - })?; - - // Strip a leading `=` out of the value if present - option - .set_value(value.strip_prefix('=').map(Into::into).unwrap_or(value))?; - return Ok(true); - } - - option.set_present()?; - } - } - - // The argument is an option - return Ok(true); - } - - // Handle long options - if arg.starts_with("--") { - if let Some(option) = self.get_mut(arg.split_once('=').map(|(n, _)| n).unwrap_or(arg)) { - if option.expects_value() { - if let Some(v) = match_arg(option.name(), &arg, iter) { - option.set_value(v.map_err(|_| { - anyhow!("a value is required for '{option}' but none was supplied") - })?)?; - } - } else if option.name() == arg { - option.set_present()?; - } - } - - // The argument is an option - return Ok(true); - } - - // Not an option - Ok(false) - } -} - -/// Represents known cargo arguments. -/// -/// This is a subset of the arguments that cargo supports that -/// are necessary for cargo-miden to function. -#[derive(Default, Debug, Clone, Eq, PartialEq)] -pub struct CargoArguments { - /// The --color argument. - pub color: Option, - /// The (count of) --verbose argument. - pub verbose: usize, - /// The --quiet argument. - pub quiet: bool, - /// The --target argument. - pub targets: Vec, - /// The --manifest-path argument. - pub manifest_path: Option, - /// The --frozen argument. - pub frozen: bool, - /// The --locked argument. - pub locked: bool, - /// The --release argument. - pub release: bool, - /// The --offline argument. - pub offline: bool, - /// The --workspace argument. - pub workspace: bool, - /// The --package argument. - pub packages: Vec, -} - -impl CargoArguments { - /// Determines if network access is allowed based on the configuration. - pub fn network_allowed(&self) -> bool { - !self.frozen && !self.offline - } - - /// Determines if an update to the lock file is allowed based on the configuration. - pub fn lock_update_allowed(&self) -> bool { - !self.frozen && !self.locked - } - - /// Parses the arguments from the environment. - pub fn parse() -> Result { - Self::parse_from(std::env::args().skip(1)) - } - - /// Parses the arguments from an iterator. - pub fn parse_from(iter: impl Iterator) -> Result - where - T: Into, - { - let mut args = Args::default() - .single("--color", "WHEN", Some('c')) - .single("--manifest-path", "PATH", None) - .multiple("--package", "SPEC", Some('p')) - .multiple("--target", "TRIPLE", None) - .flag("--release", Some('r')) - .flag("--frozen", None) - .flag("--locked", None) - .flag("--offline", None) - .flag("--all", None) - .flag("--workspace", None) - .counting("--verbose", Some('v')) - .flag("--quiet", Some('q')); - - let mut iter = iter.map(Into::into).peekable(); - - // Skip the first argument if it is `miden` - if let Some(arg) = iter.peek() { - if arg == "miden" { - iter.next().unwrap(); - } - } - - while let Some(arg) = iter.next() { - // Break out of processing at the first `--` - if arg == "--" { - break; - } - - // Parse options - if args.parse(&arg, &mut iter)? { - continue; - } - } - - Ok(Self { - color: args.get_mut("--color").unwrap().take_single().map(|v| v.parse()).transpose()?, - verbose: args.get("--verbose").unwrap().count(), - quiet: args.get("--quiet").unwrap().count() > 0, - manifest_path: args - .get_mut("--manifest-path") - .unwrap() - .take_single() - .map(PathBuf::from), - targets: args.get_mut("--target").unwrap().take_multiple(), - frozen: args.get("--frozen").unwrap().count() > 0, - locked: args.get("--locked").unwrap().count() > 0, - offline: args.get("--offline").unwrap().count() > 0, - release: args.get("--release").unwrap().count() > 0, - workspace: args.get("--workspace").unwrap().count() > 0 - || args.get("--all").unwrap().count() > 0, - packages: args - .get_mut("--package") - .unwrap() - .take_multiple() - .into_iter() - .map(CargoPackageSpec::new) - .collect::>()?, - }) - } -} - -/// Configuration information for cargo-miden. -/// -/// This is used to configure the behavior of cargo-miden. -#[derive(Debug)] -pub struct Config { - /// The terminal to use. - terminal: Terminal, -} - -impl Config { - /// Create a new `Config` with the given terminal. - pub fn new(terminal: Terminal) -> Result { - Ok(Self { terminal }) - } - - /// Gets a reference to the terminal for writing messages. - pub fn terminal(&self) -> &Terminal { - &self.terminal - } -} - -#[cfg(test)] -mod test { - use std::iter::empty; - - use super::*; - - #[test] - fn it_parses_flags() { - let mut args = Args::default().flag("--flag", Some('f')); - - // Test not the flag - args.parse("--not-flag", &mut empty::()).unwrap(); - let arg = args.get("--flag").unwrap(); - assert_eq!(arg.count(), 0); - - // Test the flag - args.parse("--flag", &mut empty::()).unwrap(); - assert_eq!( - args.parse("--flag", &mut empty::()).unwrap_err().to_string(), - "the argument '--flag' cannot be used multiple times" - ); - let arg = args.get_mut("--flag").unwrap(); - assert_eq!(arg.count(), 1); - arg.reset(); - - // Test not the short flag - args.parse("-rxd", &mut empty::()).unwrap(); - let arg = args.get("--flag").unwrap(); - assert_eq!(arg.count(), 0); - - // Test the short flag - args.parse("-rfx", &mut empty::()).unwrap(); - assert_eq!( - args.parse("-fxz", &mut empty::()).unwrap_err().to_string(), - "the argument '--flag' cannot be used multiple times" - ); - let arg = args.get("--flag").unwrap(); - assert_eq!(arg.count(), 1); - - // Test it prints correctly - assert_eq!(arg.to_string(), "--flag") - } - - #[test] - fn it_parses_single_values() { - let mut args = Args::default().single("--option", "VALUE", Some('o')); - - // Test not the option - args.parse("--not-option", &mut empty::()).unwrap(); - let arg = args.get_mut("--option").unwrap(); - assert_eq!(arg.take_single(), None); - - // Test missing value - assert_eq!( - args.parse("--option", &mut empty::()).unwrap_err().to_string(), - "a value is required for '--option ' but none was supplied" - ); - - // Test the option with equals - args.parse("--option=value", &mut empty::()).unwrap(); - assert_eq!( - args.parse("--option=value", &mut empty::()).unwrap_err().to_string(), - "the argument '--option ' cannot be used multiple times" - ); - let arg = args.get_mut("--option").unwrap(); - assert_eq!(arg.take_single(), Some("value".to_string())); - arg.reset(); - - // Test the option with space - let mut iter = ["value".to_string()].into_iter(); - args.parse("--option", &mut iter).unwrap(); - assert!(iter.next().is_none()); - let mut iter = ["value".to_string()].into_iter(); - assert_eq!( - args.parse("--option", &mut iter).unwrap_err().to_string(), - "the argument '--option ' cannot be used multiple times" - ); - let arg = args.get_mut("--option").unwrap(); - assert_eq!(arg.take_single(), Some("value".to_string())); - arg.reset(); - - // Test not the short option - args.parse("-xyz", &mut empty::()).unwrap(); - let arg = args.get_mut("--option").unwrap(); - assert_eq!(arg.take_single(), None); - - assert_eq!( - args.parse("-fo", &mut empty::()).unwrap_err().to_string(), - "a value is required for '--option ' but none was supplied" - ); - - // Test the short option without equals - args.parse("-xofoo", &mut empty::()).unwrap(); - assert_eq!( - args.parse("-zyobar", &mut iter).unwrap_err().to_string(), - "the argument '--option ' cannot be used multiple times" - ); - let arg = args.get_mut("--option").unwrap(); - assert_eq!(arg.take_single(), Some(String::from("foo"))); - - // Test the short option with equals - args.parse("-xo=foo", &mut empty::()).unwrap(); - assert_eq!( - args.parse("-zyo=bar", &mut iter).unwrap_err().to_string(), - "the argument '--option ' cannot be used multiple times" - ); - let arg = args.get_mut("--option").unwrap(); - assert_eq!(arg.take_single(), Some(String::from("foo"))); - - // Test the short option with space - let mut iter = ["value".to_string()].into_iter(); - args.parse("-xo", &mut iter).unwrap(); - let mut iter = ["value".to_string()].into_iter(); - assert_eq!( - args.parse("-zyo", &mut iter).unwrap_err().to_string(), - "the argument '--option ' cannot be used multiple times" - ); - let arg = args.get_mut("--option").unwrap(); - assert_eq!(arg.take_single(), Some(String::from("value"))); - - // Test it prints correctly - assert_eq!(arg.to_string(), "--option ") - } - - #[test] - fn it_parses_multiple_values() { - let mut args = Args::default().multiple("--option", "VALUE", Some('o')); - - // Test not the option - args.parse("--not-option", &mut empty::()).unwrap(); - let arg = args.get_mut("--option").unwrap(); - assert_eq!(arg.take_multiple(), Vec::::new()); - - // Test missing value - assert_eq!( - args.parse("--option", &mut empty::()).unwrap_err().to_string(), - "a value is required for '--option ' but none was supplied" - ); - - // Test the option with equals - args.parse("--option=foo", &mut empty::()).unwrap(); - args.parse("--option=bar", &mut empty::()).unwrap(); - args.parse("--option=baz", &mut empty::()).unwrap(); - let arg = args.get_mut("--option").unwrap(); - assert_eq!( - arg.take_multiple(), - vec!["foo".to_string(), "bar".to_string(), "baz".to_string(),] - ); - arg.reset(); - - // Test the option with space - let mut iter = ["foo".to_string()].into_iter(); - args.parse("--option", &mut iter).unwrap(); - assert!(iter.next().is_none()); - let mut iter = ["bar".to_string()].into_iter(); - args.parse("--option", &mut iter).unwrap(); - assert!(iter.next().is_none()); - let mut iter = ["baz".to_string()].into_iter(); - args.parse("--option", &mut iter).unwrap(); - assert!(iter.next().is_none()); - let arg = args.get_mut("--option").unwrap(); - assert_eq!( - arg.take_multiple(), - vec!["foo".to_string(), "bar".to_string(), "baz".to_string(),] - ); - arg.reset(); - - // Test not the short option - args.parse("-xyz", &mut empty::()).unwrap(); - let arg = args.get_mut("--option").unwrap(); - assert_eq!(arg.take_single(), None); - - // Test missing shot option value - assert_eq!( - args.parse("-fo", &mut empty::()).unwrap_err().to_string(), - "a value is required for '--option ' but none was supplied" - ); - - // Test the short option without equals - args.parse("-xofoo", &mut empty::()).unwrap(); - args.parse("-yobar", &mut empty::()).unwrap(); - args.parse("-zobaz", &mut empty::()).unwrap(); - let arg = args.get_mut("--option").unwrap(); - assert_eq!( - arg.take_multiple(), - vec!["foo".to_string(), "bar".to_string(), "baz".to_string(),] - ); - - // Test the short option with equals - args.parse("-xo=foo", &mut empty::()).unwrap(); - args.parse("-yo=bar", &mut empty::()).unwrap(); - args.parse("-zo=baz", &mut empty::()).unwrap(); - let arg = args.get_mut("--option").unwrap(); - assert_eq!( - arg.take_multiple(), - vec!["foo".to_string(), "bar".to_string(), "baz".to_string(),] - ); - - // Test the short option with space - let mut iter = ["foo".to_string()].into_iter(); - args.parse("-xo", &mut iter).unwrap(); - let mut iter = ["bar".to_string()].into_iter(); - args.parse("-yo", &mut iter).unwrap(); - let mut iter = ["baz".to_string()].into_iter(); - args.parse("-zo", &mut iter).unwrap(); - let arg = args.get_mut("--option").unwrap(); - assert_eq!( - arg.take_multiple(), - vec!["foo".to_string(), "bar".to_string(), "baz".to_string(),] - ); - - // Test it prints correctly - assert_eq!(arg.to_string(), "--option ") - } - - #[test] - fn it_parses_counting_flag() { - let mut args = Args::default().counting("--flag", Some('f')); - - // Test not the flag - args.parse("--not-flag", &mut empty::()).unwrap(); - let arg = args.get("--flag").unwrap(); - assert_eq!(arg.count(), 0); - - // Test the flag - args.parse("--flag", &mut empty::()).unwrap(); - args.parse("--flag", &mut empty::()).unwrap(); - args.parse("--flag", &mut empty::()).unwrap(); - let arg = args.get_mut("--flag").unwrap(); - assert_eq!(arg.count(), 3); - arg.reset(); - - // Test the short flag - args.parse("-xfzf", &mut empty::()).unwrap(); - args.parse("-pfft", &mut empty::()).unwrap(); - args.parse("-abcd", &mut empty::()).unwrap(); - let arg = args.get_mut("--flag").unwrap(); - assert_eq!(arg.count(), 4); - - // Test it prints correctly - assert_eq!(arg.to_string(), "--flag") - } - - #[test] - fn it_parses_cargo_arguments() { - let args: CargoArguments = - CargoArguments::parse_from(["miden", "build", "--workspace"].into_iter()).unwrap(); - assert_eq!( - args, - CargoArguments { - color: None, - verbose: 0, - quiet: false, - targets: Vec::new(), - manifest_path: None, - release: false, - frozen: false, - locked: false, - offline: false, - workspace: true, - packages: Vec::new(), - } - ); - - let args = CargoArguments::parse_from( - [ - "miden", - "publish", - "-vvv", - "--color=auto", - "--manifest-path", - "Cargo.toml", - "--release", - "--package", - "package1", - "-p=package2@1.1.1", - "--target=foo", - "--target", - "bar", - "--quiet", - "--frozen", - "--locked", - "--offline", - "--all", - "--not-an-option", - ] - .into_iter(), - ) - .unwrap(); - assert_eq!( - args, - CargoArguments { - color: Some(Color::Auto), - verbose: 3, - quiet: true, - targets: vec!["foo".to_string(), "bar".to_string()], - manifest_path: Some("Cargo.toml".into()), - release: true, - frozen: true, - locked: true, - offline: true, - workspace: true, - packages: vec![ - CargoPackageSpec { - name: "package1".to_string(), - version: None - }, - CargoPackageSpec { - name: "package2".to_string(), - version: Some(Version::parse("1.1.1").unwrap()) - } - ], - } - ); - } -} diff --git a/tools/cargo-miden/src/lib.rs b/tools/cargo-miden/src/lib.rs index d413e8d5f..33edff4bd 100644 --- a/tools/cargo-miden/src/lib.rs +++ b/tools/cargo-miden/src/lib.rs @@ -1,17 +1,22 @@ use std::path::PathBuf; -use cargo_component::load_metadata; +use anyhow::bail; +use cargo_component::{ + config::{CargoArguments, Config}, + load_component_metadata, load_metadata, run_cargo_command, +}; +use cargo_component_core::{ + command::{CACHE_DIR_ENV_VAR, CONFIG_FILE_ENV_VAR}, + terminal::{Color, Terminal, Verbosity}, +}; use clap::{CommandFactory, Parser}; -use config::CargoArguments; -use midenc_session::diagnostics::Report; -use new_project::NewCommand; +use commands::NewCommand; +use compile_masm::wasm_to_masm; +use non_component::run_cargo_command_for_non_component; -use crate::run_cargo_command::run_cargo_command; - -mod build; -pub mod config; -mod new_project; -mod run_cargo_command; +mod commands; +mod compile_masm; +mod non_component; mod target; fn version() -> &'static str { @@ -24,6 +29,13 @@ const BUILTIN_COMMANDS: &[&str] = &[ "new", ]; +/// The list of commands that are explicitly unsupported by `cargo-miden`. +/// +/// These commands are intended to integrate with `crates.io` and have no +/// analog in `cargo-miden` currently. +const UNSUPPORTED_COMMANDS: &[&str] = + &["install", "login", "logout", "owner", "package", "search", "uninstall"]; + const AFTER_HELP: &str = "Unrecognized subcommands will be passed to cargo verbatim and the artifacts will be processed afterwards (e.g. `build` command compiles MASM). \nSee `cargo help` for more information on available cargo commands."; @@ -56,7 +68,7 @@ where I: IntoIterator, T: Into + Clone, { - let mut iter = args.into_iter().map(Into::into).skip(1).peekable(); + let mut iter = args.into_iter().map(Into::into).peekable(); // Skip the first argument if it is `miden` (i.e. `cargo miden`) if let Some(arg) = iter.peek() { @@ -79,11 +91,14 @@ where None } -pub fn run(args: T) -> Result, Report> +/// Runs the cargo-miden command +/// The arguments are expected to start with `["cargo", "miden", ...]` followed by a subcommand with options +// TODO: Use Report instead of anyhow? +pub fn run(args: T) -> anyhow::Result> where T: Iterator, { - let args = args.collect::>(); + let args = args.skip_while(|arg| arg == "cargo").collect::>(); let subcommand = detect_subcommand(args.clone()); let outputs = match subcommand.as_deref() { @@ -91,11 +106,19 @@ where Some(cmd) if BUILTIN_COMMANDS.contains(&cmd) => { match CargoMiden::parse_from(args.clone()) { CargoMiden::Miden(cmd) | CargoMiden::Command(cmd) => match cmd { - Command::New(cmd) => vec![cmd.exec().map_err(Report::msg)?], + Command::New(cmd) => vec![cmd.exec()?], }, } } - + // Check for explicitly unsupported commands (e.g. those that deal with crates.io) + Some(cmd) if UNSUPPORTED_COMMANDS.contains(&cmd) => { + let terminal = Terminal::new(Verbosity::Normal, Color::Auto); + terminal.error(format!( + "command `{cmd}` is not supported by `cargo component`\n\nuse `cargo {cmd}` \ + instead" + ))?; + std::process::exit(1); + } // If no subcommand was detected, None => { // Attempt to parse the supported CLI (expected to fail) @@ -103,25 +126,130 @@ where // If somehow the CLI parsed correctly despite no subcommand, // print the help instead - CargoMiden::command().print_long_help().map_err(Report::msg)?; + CargoMiden::command().print_long_help()?; Vec::new() } _ => { // Not a built-in command, run the cargo command - let cargo_args = - CargoArguments::parse_from(args.clone().into_iter()).map_err(Report::msg)?; - let metadata = - load_metadata(cargo_args.manifest_path.as_deref()).map_err(Report::msg)?; - if metadata.packages.is_empty() { - return Err(Report::msg(format!( + let args = args.into_iter().skip_while(|arg| arg == "miden").collect::>(); + let cargo_args = CargoArguments::parse_from(args.clone().into_iter())?; + dbg!(&cargo_args); + let cache_dir = std::env::var(CACHE_DIR_ENV_VAR).map(PathBuf::from).ok(); + let config_file = std::env::var(CONFIG_FILE_ENV_VAR).map(PathBuf::from).ok(); + let config = Config::new( + Terminal::new( + if cargo_args.quiet { + Verbosity::Quiet + } else { + match cargo_args.verbose { + 0 => Verbosity::Normal, + _ => Verbosity::Verbose, + } + }, + cargo_args.color.unwrap_or_default(), + ), + config_file, + )?; + let metadata = load_metadata(cargo_args.manifest_path.as_deref())?; + let mut packages = load_component_metadata( + &metadata, + cargo_args.packages.iter(), + cargo_args.workspace, + )?; + + if packages.is_empty() { + bail!( "manifest `{path}` contains no package or the workspace has no members", path = metadata.workspace_root.join("Cargo.toml") - ))); + ); + } + + for package in packages.iter_mut() { + // TODO: do we want/need to explicitly specify the package version? + package.metadata.section.bindings.with = [ + ("miden:base/core-types@1.0.0/felt", "miden_sdk::Felt"), + ("miden:base/core-types@1.0.0/word", "miden_sdk::Word"), + ("miden:base/core-types@1.0.0/core-asset", "miden_sdk::CoreAsset"), + ("miden:base/core-types@1.0.0/tag", "miden_sdk::Tag"), + ("miden:base/core-types@1.0.0/note-type", "miden_sdk::NoteType"), + ("miden:base/core-types@1.0.0/recipient", "miden_sdk::Recipient"), + ] + .into_iter() + .map(|(k, v)| (k.to_string(), v.to_string())) + .collect(); + } + + let mut spawn_args: Vec<_> = args.into_iter().collect(); + spawn_args.extend_from_slice( + &[ + "-Z", + // compile std as part of crate graph compilation + // https://doc.rust-lang.org/cargo/reference/unstable.html#build-std + // to abort on panic below + "build-std=std,core,alloc,panic_abort", + "-Z", + // abort on panic without message formatting (core::fmt uses call_indirect) + "build-std-features=panic_immediate_abort", + ] + .map(|s| s.to_string()), + ); + + let env_vars = + vec![("RUSTFLAGS".to_string(), "-C target-feature=+bulk-memory".to_string())] + .into_iter() + .collect(); + + let mut builder = tokio::runtime::Builder::new_current_thread(); + let rt = builder.enable_all().build()?; + dbg!(&packages); + let mut wasm_outputs = rt.block_on(async { + let client = config.client(cache_dir, cargo_args.offline).await?; + run_cargo_command( + client, + &config, + &metadata, + &packages, + subcommand.as_deref(), + &cargo_args, + &spawn_args, + &env_vars, + ) + .await + })?; + // TODO: analyze `packages` and find the ones that don't have a WIT component and get Wasm binary (core module) for them with our own version of run_cargo_command + if wasm_outputs.is_empty() { + // crates that don't have a WIT component are ignored by the `cargo-component` run_cargo_command + // build them with our own version of run_cargo_command + wasm_outputs = run_cargo_command_for_non_component( + &config, + subcommand.as_deref(), + &cargo_args, + &spawn_args, + &env_vars, + )?; } + dbg!(&wasm_outputs); + return Ok(wasm_outputs); + + // let miden_out_dir = + // metadata.target_directory.join("miden").join(if cargo_args.release { + // "release" + // } else { + // "debug" + // }); + // if !miden_out_dir.exists() { + // std::fs::create_dir_all(&miden_out_dir)?; + // } - let spawn_args: Vec<_> = args.into_iter().skip(1).collect(); - run_cargo_command(&metadata, subcommand.as_deref(), &cargo_args, &spawn_args)? + // let mut outputs = Vec::new(); + // for wasm in wasm_outputs { + // let is_bin = false; + // let output = wasm_to_masm(&wasm, miden_out_dir.as_std_path(), is_bin) + // .map_err(|e| anyhow::anyhow!("{e}"))?; + // outputs.push(output); + // } + // outputs } }; Ok(outputs) diff --git a/tools/cargo-miden/src/main.rs b/tools/cargo-miden/src/main.rs index 6129d0672..770dcde7b 100644 --- a/tools/cargo-miden/src/main.rs +++ b/tools/cargo-miden/src/main.rs @@ -1,5 +1,6 @@ -use cargo_component_core::terminal::{Terminal, Verbosity}; -use cargo_miden::{config::CargoArguments, run}; +use anyhow::Ok; +use cargo_component_core::terminal::{Color, Terminal, Verbosity}; +use cargo_miden::run; fn main() -> anyhow::Result<()> { // Initialize logger @@ -8,23 +9,10 @@ fn main() -> anyhow::Result<()> { builder.format_timestamp(None); builder.init(); - let cargo_args = CargoArguments::parse_from(std::env::args())?; - let terminal = Terminal::new( - if cargo_args.quiet { - Verbosity::Quiet - } else { - match cargo_args.verbose { - 0 => Verbosity::Normal, - _ => Verbosity::Verbose, - } - }, - cargo_args.color.unwrap_or_default(), - ); - if let Err(e) = run(std::env::args()) { - terminal.error(format!("{e:?}"))?; + let terminal = Terminal::new(Verbosity::Normal, Color::Auto); + terminal.error(format!("{e}"))?; std::process::exit(1); } - Ok(()) } diff --git a/tools/cargo-miden/src/non_component.rs b/tools/cargo-miden/src/non_component.rs new file mode 100644 index 000000000..757da2c92 --- /dev/null +++ b/tools/cargo-miden/src/non_component.rs @@ -0,0 +1,151 @@ +use std::{ + collections::HashMap, + io::{BufRead, BufReader}, + path::{Path, PathBuf}, + process::{Command, Stdio}, +}; + +use anyhow::{bail, Context, Result}; +use cargo_component::config::{CargoArguments, Config}; +use cargo_metadata::{Artifact, Message}; + +use crate::target::install_wasm32_wasip1; + +fn is_wasm_target(target: &str) -> bool { + target == "wasm32-wasi" || target == "wasm32-wasip1" || target == "wasm32-unknown-unknown" +} + +pub fn run_cargo_command_for_non_component( + config: &Config, + subcommand: Option<&str>, + cargo_args: &CargoArguments, + spawn_args: &[String], + env_vars: &HashMap, +) -> anyhow::Result> { + let cargo_path = std::env::var("CARGO") + .map(PathBuf::from) + .ok() + .unwrap_or_else(|| PathBuf::from("cargo")); + + let is_build = matches!(subcommand, Some("b") | Some("build")); + + let (build_args, _output_args) = match spawn_args.iter().position(|a| a == "--") { + Some(position) => spawn_args.split_at(position), + None => (spawn_args, &[] as _), + }; + + let mut args = build_args.iter().peekable(); + if let Some(arg) = args.peek() { + if *arg == "miden" { + args.next().unwrap(); + } + } + + // Spawn the actual cargo command + log::debug!( + "spawning cargo `{path}` with arguments `{args:?}`", + path = cargo_path.display(), + args = args.clone().collect::>(), + ); + + let mut cargo = Command::new(&cargo_path); + cargo.envs(env_vars); + cargo.args(args); + + let cargo_config = cargo_config2::Config::load()?; + + // Handle the target for build command + if is_build { + install_wasm32_wasip1(config)?; + + // Add an implicit wasm32-wasip1 target if there isn't a wasm target present + if !cargo_args.targets.iter().any(|t| is_wasm_target(t)) + && !cargo_config + .build + .target + .as_ref() + .is_some_and(|v| v.iter().any(|t| is_wasm_target(t.triple()))) + { + cargo.arg("--target").arg("wasm32-wasip1"); + } + + if let Some(format) = &cargo_args.message_format { + if format != "json-render-diagnostics" { + bail!("unsupported cargo message format `{format}`"); + } + } + + // It will output the message as json so we can extract the wasm files + // that will be componentized + cargo.arg("--message-format").arg("json-render-diagnostics"); + cargo.stdout(Stdio::piped()); + } else { + cargo.stdout(Stdio::inherit()); + } + + let artifacts = spawn_cargo(cargo, &cargo_path, cargo_args, is_build)?; + Ok(artifacts + .into_iter() + .flat_map(|a| { + a.filenames.into_iter().filter(|p| p.extension() == Some("wasm") && p.exists()) + }) + .map(|p| p.as_std_path().to_path_buf()) + .collect()) +} + +fn spawn_cargo( + mut cmd: Command, + cargo: &Path, + cargo_args: &CargoArguments, + process_messages: bool, +) -> Result> { + log::debug!("spawning command {:?}", cmd); + + let mut child = cmd + .spawn() + .context(format!("failed to spawn `{cargo}`", cargo = cargo.display()))?; + + let mut artifacts = Vec::new(); + if process_messages { + let stdout = child.stdout.take().expect("no stdout"); + let reader = BufReader::new(stdout); + for line in reader.lines() { + let line = line.context("failed to read output from `cargo`")?; + + // If the command line arguments also had `--message-format`, echo the line + if cargo_args.message_format.is_some() { + println!("{line}"); + } + + if line.is_empty() { + continue; + } + + for message in Message::parse_stream(line.as_bytes()) { + if let Message::CompilerArtifact(artifact) = + message.context("unexpected JSON message from cargo")? + { + for path in &artifact.filenames { + match path.extension() { + Some("wasm") => { + artifacts.push(artifact); + break; + } + _ => continue, + } + } + } + } + } + } + + let status = child + .wait() + .context(format!("failed to wait for `{cargo}` to finish", cargo = cargo.display()))?; + + if !status.success() { + std::process::exit(status.code().unwrap_or(1)); + } + + Ok(artifacts) +} diff --git a/tools/cargo-miden/src/run_cargo_command.rs b/tools/cargo-miden/src/run_cargo_command.rs deleted file mode 100644 index c35d4c9fc..000000000 --- a/tools/cargo-miden/src/run_cargo_command.rs +++ /dev/null @@ -1,136 +0,0 @@ -use std::{path::PathBuf, process::Command}; - -use cargo_metadata::Metadata; -use midenc_session::diagnostics::{IntoDiagnostic, Report}; - -use crate::{ - build::build_masm, - config::CargoArguments, - target::{install_wasm32_wasi, WASM32_WASI_TARGET}, -}; - -fn is_wasm_target(target: &str) -> bool { - target == WASM32_WASI_TARGET -} - -/// Runs the cargo command as specified in the configuration. -/// -/// Returns any relevant output artifacts. -pub fn run_cargo_command( - metadata: &Metadata, - subcommand: Option<&str>, - cargo_args: &CargoArguments, - spawn_args: &[String], -) -> Result, Report> { - let cargo = std::env::var("CARGO") - .map(PathBuf::from) - .ok() - .unwrap_or_else(|| PathBuf::from("cargo")); - - let mut args = spawn_args.iter().peekable(); - if let Some(arg) = args.peek() { - if *arg == "miden" { - args.next().unwrap(); - } - } - - // Spawn the actual cargo command - log::debug!( - "spawning cargo `{cargo}` with arguments `{args:?}`", - cargo = cargo.display(), - args = args.clone().collect::>(), - ); - - let mut cmd = Command::new(&cargo); - cmd.args(args); - - let is_build = matches!(subcommand, Some("b") | Some("build")); - - // Handle the target for build commands - if is_build { - install_wasm32_wasi().map_err(Report::msg)?; - - // Add an implicit wasm32-wasi target if there isn't a wasm target present - if !cargo_args.targets.iter().any(|t| is_wasm_target(t)) { - cmd.arg("--target").arg(WASM32_WASI_TARGET); - } - } - - cmd.arg("-Z") - // compile std as part of crate graph compilation - // https://doc.rust-lang.org/cargo/reference/unstable.html#build-std - // to abort on panic below - .arg("build-std=std,core,alloc,panic_abort") - .arg("-Z") - // abort on panic without message formatting (core::fmt uses call_indirect) - .arg("build-std-features=panic_immediate_abort"); - - match cmd.status() { - Ok(status) => { - if !status.success() { - return Err(Report::msg(format!( - "cargo failed with exit code {}", - status.code().unwrap_or(1) - ))); - } - } - Err(e) => { - return Err(Report::msg(format!( - "failed to spawn `{cargo}`: {e}", - cargo = cargo.display() - ))); - } - } - let mut outputs = Vec::new(); - if is_build { - log::debug!("searching for WebAssembly modules to compile to MASM"); - let targets = cargo_args - .targets - .iter() - .map(String::as_str) - .filter(|t| is_wasm_target(t)) - .chain(cargo_args.targets.is_empty().then_some(WASM32_WASI_TARGET)); - - for target in targets { - let out_dir = metadata.target_directory.join(target).join(if cargo_args.release { - "release" - } else { - "debug" - }); - - let miden_out_dir = - metadata.target_directory.join("miden").join(if cargo_args.release { - "release" - } else { - "debug" - }); - if !miden_out_dir.exists() { - std::fs::create_dir_all(&miden_out_dir).into_diagnostic()?; - } - - for package in &metadata.packages { - let is_bin = package.targets.iter().any(|t| t.is_bin()); - - // First try for .wasm - let path = out_dir.join(&package.name).with_extension("wasm"); - if path.exists() { - let output = - build_masm(path.as_std_path(), miden_out_dir.as_std_path(), is_bin)?; - outputs.push(output); - } else { - let path = out_dir.join(package.name.replace('-', "_")).with_extension("wasm"); - if path.exists() { - let output = - build_masm(path.as_std_path(), miden_out_dir.as_std_path(), is_bin)?; - outputs.push(output); - } else { - log::debug!("no output found for package `{name}`", name = package.name); - return Err(Report::msg("Cargo build failed, no Wasm artifact found")); - } - } - } - } - } - - Ok(outputs) -} diff --git a/tools/cargo-miden/src/target.rs b/tools/cargo-miden/src/target.rs index 51d257d1f..8b0fa16f7 100644 --- a/tools/cargo-miden/src/target.rs +++ b/tools/cargo-miden/src/target.rs @@ -5,34 +5,34 @@ use std::{ }; use anyhow::{bail, Result}; +use cargo_component::config::Config; -pub const WASM32_WASI_TARGET: &str = "wasm32-wasip1"; - -pub fn install_wasm32_wasi() -> Result<()> { - log::info!("Installing {WASM32_WASI_TARGET} target"); +pub fn install_wasm32_wasip1(config: &Config) -> Result<()> { let sysroot = get_sysroot()?; - if sysroot.join(format!("lib/rustlib/{}", WASM32_WASI_TARGET)).exists() { + if sysroot.join("lib/rustlib/wasm32-wasip1").exists() { return Ok(()); } if env::var_os("RUSTUP_TOOLCHAIN").is_none() { bail!( - "failed to find the `{WASM32_WASI_TARGET}` target and `rustup` is not available. If \ - you're using rustup make sure that it's correctly installed; if not, make sure to \ - install the `{WASM32_WASI_TARGET}` target before using this command", + "failed to find the `wasm32-wasip1` target and `rustup` is not available. If you're \ + using rustup make sure that it's correctly installed; if not, make sure to install \ + the `wasm32-wasip1` target before using this command" ); } + config.terminal().status("Installing", "wasm32-wasip1 target")?; + let output = Command::new("rustup") .arg("target") .arg("add") - .arg(WASM32_WASI_TARGET) + .arg("wasm32-wasip1") .stderr(Stdio::inherit()) .stdout(Stdio::inherit()) .output()?; if !output.status.success() { - bail!("failed to install the `{WASM32_WASI_TARGET}` target"); + bail!("failed to install the `wasm32-wasip1` target"); } Ok(()) diff --git a/tools/cargo-miden/tests/build.rs b/tools/cargo-miden/tests/build.rs index 12e155e80..558586055 100644 --- a/tools/cargo-miden/tests/build.rs +++ b/tools/cargo-miden/tests/build.rs @@ -15,6 +15,7 @@ fn new_project_args(project_name: &str, template_path: Option<&str>) -> Vec