diff --git a/docs/Cargo.lock b/docs/Cargo.lock index 83b87d8e..e5f29d65 100644 --- a/docs/Cargo.lock +++ b/docs/Cargo.lock @@ -422,6 +422,45 @@ dependencies = [ "zeroize", ] +[[package]] +name = "clap" +version = "4.5.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876" +dependencies = [ + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + [[package]] name = "colorchoice" version = "1.0.4" @@ -1221,7 +1260,7 @@ dependencies = [ "hyper", "libc", "pin-project-lite", - "socket2", + "socket2 0.6.1", "tokio", "tower-service", "tracing", @@ -1556,7 +1595,7 @@ dependencies = [ "miden-utils-sync", "primitive-types", "regex", - "thiserror", + "thiserror 2.0.17", "walkdir", ] @@ -1569,7 +1608,7 @@ dependencies = [ "miden-core", "miden-crypto", "miden-utils-indexing", - "thiserror", + "thiserror 2.0.17", "tracing", ] @@ -1587,7 +1626,7 @@ dependencies = [ "miden-package-registry", "miden-project", "smallvec", - "thiserror", + "thiserror 2.0.17", ] [[package]] @@ -1612,7 +1651,7 @@ dependencies = [ "semver 1.0.27", "serde", "smallvec", - "thiserror", + "thiserror 2.0.17", ] [[package]] @@ -1622,14 +1661,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cde56bcea3cebe307786a856e204d84e7987c318e5a2909bcbb655d16286ce31" dependencies = [ "miden-protocol", - "thiserror", + "thiserror 2.0.17", ] [[package]] name = "miden-client" -version = "0.14.0" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49957f76717961769c911237113bb9c1841c3b13970c15ca09a0ae639c33fc45" +checksum = "15007f2cf4e80316a8141665b43f454e77ce0dfd2ac0307ce6cdf7a5d552d58b" dependencies = [ "anyhow", "async-trait", @@ -1638,6 +1677,7 @@ dependencies = [ "getrandom 0.3.4", "gloo-timers", "hex", + "miden-debug", "miden-node-proto-build", "miden-note-transport-proto-build", "miden-protocol", @@ -1651,7 +1691,8 @@ dependencies = [ "rand 0.9.2", "serde", "serde_json", - "thiserror", + "tempfile", + "thiserror 2.0.17", "tokio", "tonic", "tonic-health", @@ -1665,9 +1706,9 @@ dependencies = [ [[package]] name = "miden-client-sqlite-store" -version = "0.14.0" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ab146099a4bf8319f5cac47e110eca7d3e3caa9d2fc354693458f905f4750a7" +checksum = "53a6d9c9bf443b9df440c010eeab6916ab6bc529faed5eb19f84ab7bc21aad59" dependencies = [ "anyhow", "async-trait", @@ -1678,7 +1719,7 @@ dependencies = [ "miden-protocol", "rusqlite", "rusqlite_migration", - "thiserror", + "thiserror 2.0.17", "tokio", ] @@ -1701,7 +1742,7 @@ dependencies = [ "proptest", "proptest-derive", "serde", - "thiserror", + "thiserror 2.0.17", ] [[package]] @@ -1718,7 +1759,7 @@ dependencies = [ "miden-package-registry", "miden-processor", "miden-utils-sync", - "thiserror", + "thiserror 2.0.17", ] [[package]] @@ -1760,7 +1801,7 @@ dependencies = [ "sha2", "sha3", "subtle", - "thiserror", + "thiserror 2.0.17", "x25519-dalek", ] @@ -1774,6 +1815,77 @@ dependencies = [ "syn 2.0.115", ] +[[package]] +name = "miden-debug" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df04a684eeb96efabc63e2800a01945f7f6e19ffd00d3b49064e85f7e1fac444" +dependencies = [ + "clap", + "futures", + "glob", + "log", + "miden-assembly", + "miden-assembly-syntax", + "miden-core", + "miden-crypto", + "miden-debug-dap", + "miden-debug-engine", + "miden-debug-types", + "miden-mast-package", + "miden-processor", + "miden-protocol", + "miden-thiserror", + "miden-tx", + "num-traits", + "rustc-demangle", + "serde", + "serde_json", + "smallvec", + "socket2 0.5.10", + "tokio", + "tokio-util", + "toml 0.8.23", +] + +[[package]] +name = "miden-debug-dap" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38cd41176322df12836bb4deecd4b619f7cf8239ed7b2c4ac1da7b2830e5199c" +dependencies = [ + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "miden-debug-engine" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e03dd00bd4dab99dbfdec9fd07009811a7e3b3a988e74a28c6ccb735ac34e138" +dependencies = [ + "clap", + "glob", + "log", + "miden-assembly", + "miden-assembly-syntax", + "miden-core", + "miden-debug-dap", + "miden-debug-types", + "miden-mast-package", + "miden-processor", + "miden-thiserror", + "miden-tx", + "num-traits", + "rustc-demangle", + "serde", + "serde_json", + "smallvec", + "socket2 0.5.10", + "toml 0.8.23", +] + [[package]] name = "miden-debug-types" version = "0.22.1" @@ -1788,8 +1900,8 @@ dependencies = [ "miden-utils-sync", "paste", "serde", - "serde_spanned", - "thiserror", + "serde_spanned 1.1.1", + "thiserror 2.0.17", ] [[package]] @@ -1807,7 +1919,7 @@ dependencies = [ "rand 0.10.0", "serde", "subtle", - "thiserror", + "thiserror 2.0.17", ] [[package]] @@ -1830,7 +1942,7 @@ dependencies = [ "miden-core", "miden-debug-types", "serde", - "thiserror", + "thiserror 2.0.17", ] [[package]] @@ -1853,7 +1965,7 @@ dependencies = [ "strip-ansi-escapes", "syn 2.0.115", "textwrap", - "thiserror", + "thiserror 2.0.17", "trybuild", "unicode-width 0.1.14", ] @@ -1871,9 +1983,9 @@ dependencies = [ [[package]] name = "miden-node-proto-build" -version = "0.14.4" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9beefe1d90ebeb044b15a8c764eb7031d892f9ae357ac9c8847c1cab3b07045a" +checksum = "6e457758c9a6aa5f70f687f1081833f102572ee1d02baf549625868917495815" dependencies = [ "build-rs", "fs-err", @@ -1906,7 +2018,7 @@ dependencies = [ "pubgrub", "serde", "smallvec", - "thiserror", + "thiserror 2.0.17", ] [[package]] @@ -1923,7 +2035,7 @@ dependencies = [ "miden-utils-indexing", "paste", "rayon", - "thiserror", + "thiserror 2.0.17", "tokio", "tracing", ] @@ -1940,15 +2052,15 @@ dependencies = [ "miden-package-registry", "serde", "serde-untagged", - "thiserror", + "thiserror 2.0.17", "toml 1.1.2+spec-1.1.0", ] [[package]] name = "miden-protocol" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e860cc978d3467297de076e9bd22f0573b82ef73a3d223d6bb957731a45b8164" +checksum = "140b1b3d6b2a3a2bfaeca8b0d2ca15a8ee6a7e0abebbc4f1a2a3a1f1b7f7f58d" dependencies = [ "bech32", "fs-err", @@ -1969,7 +2081,7 @@ dependencies = [ "regex", "semver 1.0.27", "serde", - "thiserror", + "thiserror 2.0.17", "toml 1.1.2+spec-1.1.0", "walkdir", ] @@ -1998,16 +2110,16 @@ dependencies = [ "miden-debug-types", "miden-processor", "serde", - "thiserror", + "thiserror 2.0.17", "tokio", "tracing", ] [[package]] name = "miden-remote-prover-client" -version = "0.14.4" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf7590551de605a7dc6217d81e76c8f00196dbaeb905cef4239c7bc7725fbeb6" +checksum = "5a388883f27bff95127c962669eb5d294d27379ac357d6dac5c77faa81b30def" dependencies = [ "build-rs", "fs-err", @@ -2017,7 +2129,7 @@ dependencies = [ "miden-tx", "miette", "prost", - "thiserror", + "thiserror 2.0.17", "tokio", "tonic", "tonic-prost", @@ -2037,9 +2149,9 @@ dependencies = [ [[package]] name = "miden-standards" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f455a087f41c30636b45ead961d1e66114d2d20661887b307cede05307eeb942" +checksum = "a08e4e4edb289460b1b676a9cdb1727131c2749218dd85a333571d09e1cfa621" dependencies = [ "fs-err", "miden-assembly", @@ -2049,7 +2161,7 @@ dependencies = [ "miden-protocol", "rand 0.9.2", "regex", - "thiserror", + "thiserror 2.0.17", "walkdir", ] @@ -2073,7 +2185,27 @@ dependencies = [ "miden-tx-batch-prover", "rand 0.9.2", "rand_chacha", - "thiserror", + "thiserror 2.0.17", +] + +[[package]] +name = "miden-thiserror" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183ff8de338956ecfde3a38573241eb7a6f3d44d73866c210e5629c07fa00253" +dependencies = [ + "miden-thiserror-impl", +] + +[[package]] +name = "miden-thiserror-impl" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee4176a0f2e7d29d2a8ee7e60b6deb14ce67a20e94c3e2c7275cdb8804e1862" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", ] [[package]] @@ -2084,9 +2216,6 @@ dependencies = [ "miden-client-sqlite-store", "miden-protocol", "rand 0.9.2", - "rand_chacha", - "serde", - "serde_json", "tokio", ] @@ -2101,7 +2230,7 @@ dependencies = [ "miden-prover", "miden-standards", "miden-verifier", - "thiserror", + "thiserror 2.0.17", ] [[package]] @@ -2146,7 +2275,7 @@ checksum = "c8834e76299686bcce3de1685158aa4cff49b7fa5e0e00a6cc811e8f2cf5775f" dependencies = [ "miden-crypto", "serde", - "thiserror", + "thiserror 2.0.17", ] [[package]] @@ -2172,7 +2301,7 @@ dependencies = [ "miden-core", "miden-crypto", "serde", - "thiserror", + "thiserror 2.0.17", "tracing", ] @@ -2187,7 +2316,7 @@ dependencies = [ "serde", "serde_repr", "smallvec", - "thiserror", + "thiserror 2.0.17", ] [[package]] @@ -2562,7 +2691,7 @@ dependencies = [ "p3-field", "p3-matrix", "p3-util", - "thiserror", + "thiserror 2.0.17", ] [[package]] @@ -2581,7 +2710,7 @@ dependencies = [ "p3-miden-transcript", "p3-util", "rand 0.10.0", - "thiserror", + "thiserror 2.0.17", "tracing", ] @@ -2602,7 +2731,7 @@ dependencies = [ "p3-miden-stateful-hasher", "p3-miden-transcript", "p3-util", - "thiserror", + "thiserror 2.0.17", "tracing", ] @@ -2622,7 +2751,7 @@ dependencies = [ "p3-util", "rand 0.10.0", "serde", - "thiserror", + "thiserror 2.0.17", "tracing", ] @@ -2645,7 +2774,7 @@ dependencies = [ "p3-challenger", "p3-field", "serde", - "thiserror", + "thiserror 2.0.17", ] [[package]] @@ -3028,7 +3157,7 @@ dependencies = [ "prost-reflect", "prost-types", "protox-parse", - "thiserror", + "thiserror 2.0.17", ] [[package]] @@ -3040,7 +3169,7 @@ dependencies = [ "logos", "miette", "prost-types", - "thiserror", + "thiserror 2.0.17", ] [[package]] @@ -3053,7 +3182,7 @@ dependencies = [ "log", "priority-queue", "rustc-hash", - "thiserror", + "thiserror 2.0.17", "version-ranges", ] @@ -3574,6 +3703,15 @@ dependencies = [ "syn 2.0.115", ] +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + [[package]] name = "serde_spanned" version = "1.1.1" @@ -3656,6 +3794,16 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "socket2" version = "0.6.1" @@ -3727,6 +3875,12 @@ dependencies = [ "vte", ] +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "subtle" version = "2.6.1" @@ -3852,13 +4006,33 @@ dependencies = [ "unicode-width 0.2.2", ] +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + [[package]] name = "thiserror" version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.17", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", ] [[package]] @@ -3900,7 +4074,7 @@ dependencies = [ "libc", "mio", "pin-project-lite", - "socket2", + "socket2 0.6.1", "tokio-macros", "windows-sys 0.61.2", ] @@ -3951,6 +4125,19 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "indexmap", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_edit", +] + [[package]] name = "toml" version = "0.9.8" @@ -3959,7 +4146,7 @@ checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" dependencies = [ "indexmap", "serde_core", - "serde_spanned", + "serde_spanned 1.1.1", "toml_datetime 0.7.3", "toml_parser", "toml_writer", @@ -3974,13 +4161,22 @@ checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ "indexmap", "serde_core", - "serde_spanned", + "serde_spanned 1.1.1", "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", "toml_writer", "winnow 1.0.1", ] +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + [[package]] name = "toml_datetime" version = "0.7.3" @@ -3999,6 +4195,20 @@ dependencies = [ "serde_core", ] +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_write", + "winnow 0.7.13", +] + [[package]] name = "toml_parser" version = "1.1.2+spec-1.1.0" @@ -4008,6 +4218,12 @@ dependencies = [ "winnow 1.0.1", ] +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + [[package]] name = "toml_writer" version = "1.1.1+spec-1.1.0" @@ -4033,7 +4249,7 @@ dependencies = [ "percent-encoding", "pin-project", "rustls-native-certs", - "socket2", + "socket2 0.6.1", "sync_wrapper", "tokio", "tokio-rustls", @@ -4112,7 +4328,7 @@ dependencies = [ "httparse", "js-sys", "pin-project", - "thiserror", + "thiserror 2.0.17", "tonic", "tower-service", "wasm-bindgen", @@ -4854,6 +5070,9 @@ name = "winnow" version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +dependencies = [ + "memchr", +] [[package]] name = "winnow" diff --git a/docs/Cargo.toml b/docs/Cargo.toml index eeb43898..24b18f66 100644 --- a/docs/Cargo.toml +++ b/docs/Cargo.toml @@ -8,7 +8,4 @@ miden-client = { version = "0.14", features = ["testing", "tonic"] } miden-client-sqlite-store = { version = "0.14", package = "miden-client-sqlite-store" } miden-protocol = { version = "0.14" } rand = { version = "0.9" } -serde = { version = "1", features = ["derive"] } -serde_json = { version = "1.0", features = ["raw_value"] } tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } -rand_chacha = "0.9.0" diff --git a/docs/src/lib.rs b/docs/src/lib.rs index 2cf4c50a..b70e3a76 100644 --- a/docs/src/lib.rs +++ b/docs/src/lib.rs @@ -9,3 +9,4 @@ #![doc = include_str!("rust-client/creating_notes_in_masm_tutorial.md")] #![doc = include_str!("rust-client/delegated_proving_tutorial.md")] #![doc = include_str!("rust-client/network_transactions_tutorial.md")] +#![doc = include_str!("rust-client/oracle_tutorial.md")] diff --git a/docs/src/rust-client/counter_contract_tutorial.md b/docs/src/rust-client/counter_contract_tutorial.md index 866deb2b..d09a4c95 100644 --- a/docs/src/rust-client/counter_contract_tutorial.md +++ b/docs/src/rust-client/counter_contract_tutorial.md @@ -41,10 +41,7 @@ miden-client = { version = "0.14", features = ["testing", "tonic"] } miden-client-sqlite-store = { version = "0.14", package = "miden-client-sqlite-store" } miden-protocol = { version = "0.14" } rand = { version = "0.9" } -serde = { version = "1", features = ["derive"] } -serde_json = { version = "1.0", features = ["raw_value"] } tokio = { version = "1.46", features = ["rt-multi-thread", "net", "macros", "fs"] } -rand_chacha = "0.9.0" ``` ### Set up your `src/main.rs` file @@ -54,50 +51,23 @@ In the previous section, we explained how to instantiate the Miden client. We ca Copy and paste the following code into your `src/main.rs` file: ```rust no_run -use miden_client::auth::NoAuth; -use miden_client::transaction::TransactionKernel; use rand::RngCore; -use std::{fs, path::Path, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; use miden_client::{ - address::NetworkId, - assembly::{ - Assembler, - CodeBuilder, - DefaultSourceManager, - Module, - ModuleKind, - Path as AssemblyPath, + account::{ + component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountStorageMode, + AccountType, StorageSlot, StorageSlotName, }, + address::NetworkId, + auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, rpc::{Endpoint, GrpcClient}, transaction::TransactionRequestBuilder, - ClientError, + ClientError, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -use miden_client::{ - account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountStorageMode, - AccountType, StorageSlot, StorageSlotName, - }, - Word, -}; - -fn create_library( - library_path: &str, - source_code: &str, -) -> Result, Box> { - let source_manager = Arc::new(DefaultSourceManager::default()); - let assembler = TransactionKernel::assembler_with_source_manager(source_manager.clone()); - let module = Module::parser(ModuleKind::Library).parse_str( - AssemblyPath::new(library_path), - source_code, - source_manager, - )?; - let library = assembler.assemble_library([module])?; - Ok(library) -} #[tokio::main] async fn main() -> Result<(), ClientError> { @@ -107,10 +77,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -256,15 +226,17 @@ To build the counter contract copy and paste the following code at the end of yo // ------------------------------------------------------------------------- println!("\n[STEP 1] Creating counter contract."); -// Load the MASM file for the counter contract -let counter_path = Path::new("../masm/accounts/counter.masm"); -let counter_code = fs::read_to_string(counter_path).unwrap(); +// Load the MASM file for the counter contract. `include_str!` resolves at +// compile time relative to this source file, so the binary is independent of +// the working directory it is run from. +let counter_code = include_str!("../masm/accounts/counter.masm"); -// Compile the account code into `AccountComponent` with one storage slot +// Compile the account code into `AccountComponent` with one storage slot. let counter_slot_name = StorageSlotName::new("miden::tutorials::counter").expect("valid slot name"); -let component_code = CodeBuilder::new() - .compile_component_code("external_contract::counter_contract", &counter_code) +let component_code = client + .code_builder() + .compile_component_code("external_contract::counter_contract", counter_code) .unwrap(); let counter_component = AccountComponent::new( component_code, @@ -324,21 +296,15 @@ Paste the following code at the end of your `src/main.rs` file: println!("\n[STEP 2] Call Counter Contract With Script"); // Load the MASM script referencing the increment procedure -let script_path = Path::new("../masm/scripts/counter_script.masm"); -let script_code = fs::read_to_string(script_path).unwrap(); - -// Create a library from the counter contract code -let account_component_lib = create_library( - "external_contract::counter_contract", - &counter_code, -) -.unwrap(); +let script_code = include_str!("../masm/scripts/counter_script.masm"); +// Compile the script with the counter contract code linked as a module +// on the same `CodeBuilder` chain. let tx_script = client .code_builder() - .with_dynamically_linked_library(&account_component_lib) + .with_linked_module("external_contract::counter_contract", counter_code) .unwrap() - .compile_tx_script(&script_code) + .compile_tx_script(script_code) .unwrap(); // Build a transaction request with the custom script @@ -384,50 +350,23 @@ println!( The final `src/main.rs` file should look like this: ```rust no_run -use miden_client::auth::NoAuth; -use miden_client::transaction::TransactionKernel; use rand::RngCore; -use std::{fs, path::Path, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; use miden_client::{ - address::NetworkId, - assembly::{ - Assembler, - CodeBuilder, - DefaultSourceManager, - Module, - ModuleKind, - Path as AssemblyPath, + account::{ + component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountStorageMode, + AccountType, StorageSlot, StorageSlotName, }, + address::NetworkId, + auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, rpc::{Endpoint, GrpcClient}, transaction::TransactionRequestBuilder, - ClientError, + ClientError, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -use miden_client::{ - account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountStorageMode, - AccountType, StorageSlot, StorageSlotName, - }, - Word, -}; - -fn create_library( - library_path: &str, - source_code: &str, -) -> Result, Box> { - let source_manager = Arc::new(DefaultSourceManager::default()); - let assembler = TransactionKernel::assembler_with_source_manager(source_manager.clone()); - let module = Module::parser(ModuleKind::Library).parse_str( - AssemblyPath::new(library_path), - source_code, - source_manager, - )?; - let library = assembler.assemble_library([module])?; - Ok(library) -} #[tokio::main] async fn main() -> Result<(), ClientError> { @@ -437,10 +376,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -458,15 +397,17 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 1] Creating counter contract."); - // Load the MASM file for the counter contract - let counter_path = Path::new("../masm/accounts/counter.masm"); - let counter_code = fs::read_to_string(counter_path).unwrap(); + // Load the MASM file for the counter contract. `include_str!` resolves at + // compile time relative to this source file, so the binary is independent + // of the working directory it is run from. + let counter_code = include_str!("../masm/accounts/counter.masm"); - // Compile the account code into `AccountComponent` with one storage slot + // Compile the account code into `AccountComponent` with one storage slot. let counter_slot_name = StorageSlotName::new("miden::tutorials::counter").expect("valid slot name"); - let component_code = CodeBuilder::new() - .compile_component_code("external_contract::counter_contract", &counter_code) + let component_code = client + .code_builder() + .compile_component_code("external_contract::counter_contract", counter_code) .unwrap(); let counter_component = AccountComponent::new( component_code, @@ -503,21 +444,15 @@ async fn main() -> Result<(), ClientError> { println!("\n[STEP 2] Call Counter Contract With Script"); // Load the MASM script referencing the increment procedure - let script_path = Path::new("../masm/scripts/counter_script.masm"); - let script_code = fs::read_to_string(script_path).unwrap(); - - // Create a library from the counter contract code - let account_component_lib = create_library( - "external_contract::counter_contract", - &counter_code, - ) - .unwrap(); + let script_code = include_str!("../masm/scripts/counter_script.masm"); + // Compile the script with the counter contract code linked as a module + // on the same `CodeBuilder` chain. let tx_script = client .code_builder() - .with_dynamically_linked_library(&account_component_lib) + .with_linked_module("external_contract::counter_contract", counter_code) .unwrap() - .compile_tx_script(&script_code) + .compile_tx_script(script_code) .unwrap(); // Build a transaction request with the custom script diff --git a/docs/src/rust-client/create_deploy_tutorial.md b/docs/src/rust-client/create_deploy_tutorial.md index f355e862..517a4f3b 100644 --- a/docs/src/rust-client/create_deploy_tutorial.md +++ b/docs/src/rust-client/create_deploy_tutorial.md @@ -52,10 +52,7 @@ miden-client = { version = "0.14", features = ["testing", "tonic"] } miden-client-sqlite-store = { version = "0.14", package = "miden-client-sqlite-store" } miden-protocol = { version = "0.14" } rand = { version = "0.9" } -serde = { version = "1", features = ["derive"] } -serde_json = { version = "1.0", features = ["raw_value"] } tokio = { version = "1.46", features = ["rt-multi-thread", "net", "macros", "fs"] } -rand_chacha = "0.9.0" ``` ## Step 2: Initialize the client @@ -72,7 +69,7 @@ Copy and paste the following code into your `src/main.rs` file. ```rust no_run use miden_client::auth::{AuthSchemeId, AuthSingleSig}; use rand::RngCore; -use std::sync::Arc; +use std::{path::PathBuf, sync::Arc}; use tokio::time::Duration; use miden_client::{ @@ -105,10 +102,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -242,7 +239,7 @@ Your updated `main()` function in `src/main.rs` should look like this: ```rust no_run use miden_client::auth::{AuthSchemeId, AuthSingleSig}; use rand::RngCore; -use std::sync::Arc; +use std::{path::PathBuf, sync::Arc}; use tokio::time::Duration; use miden_client::{ @@ -275,10 +272,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) diff --git a/docs/src/rust-client/creating_notes_in_masm_tutorial.md b/docs/src/rust-client/creating_notes_in_masm_tutorial.md index 4f831b41..fd4fd845 100644 --- a/docs/src/rust-client/creating_notes_in_masm_tutorial.md +++ b/docs/src/rust-client/creating_notes_in_masm_tutorial.md @@ -55,10 +55,7 @@ miden-client = { version = "0.14", features = ["testing", "tonic"] } miden-client-sqlite-store = { version = "0.14", package = "miden-client-sqlite-store" } miden-protocol = { version = "0.14" } rand = { version = "0.9" } -serde = { version = "1", features = ["derive"] } -serde_json = { version = "1.0", features = ["raw_value"] } tokio = { version = "1.46", features = ["rt-multi-thread", "net", "macros", "fs"] } -rand_chacha = "0.9.0" ``` ## Step 2: Write the Note Script @@ -80,7 +77,7 @@ masm/ └── notes/ ``` -Inside the `masm/notes/` directory, create the file `iterative_output_note.masm`: +Inside the `masm/notes/` directory, create the file `iterative_output_note.masm`. Note scripts in v0.14.5+ are compiled as libraries; the `@note_script` attribute marks the entrypoint procedure. ```masm use miden::protocol::active_note @@ -97,8 +94,10 @@ const ASSET_HALF_VALUE_PTR=8 # half-amount ASSET_VALUE stored here const ACCOUNT_ID_PREFIX=12 # storage: [prefix, suffix, tag, 0] const TAG=14 # = ACCOUNT_ID_PREFIX + 2 -# => [] -begin +#! Inputs: [] +#! Outputs: [] +@note_script +pub proc main # Drop word if user accidentally pushes note_args dropw # => [] @@ -204,7 +203,7 @@ Copy and paste the following code into your `src/main.rs` file. ```rust no_run use miden_client::auth::{AuthSchemeId, AuthSingleSig}; use rand::RngCore; -use std::{fs, path::Path, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; use tokio::time::{sleep, Duration}; use miden_client::{ @@ -312,10 +311,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -395,13 +394,15 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 3] Create iterative output note"); - let code = fs::read_to_string(Path::new("../masm/notes/iterative_output_note.masm")).unwrap(); + // `include_str!` resolves at compile time relative to this source file, + // so the binary is independent of the working directory it is run from. + let code = include_str!("../masm/notes/iterative_output_note.masm"); let serial_num = client.rng().draw_word(); // Create note metadata and tag let tag = NoteTag::new(0); let metadata = NoteMetadata::new(alice_account.id(), NoteType::Public).with_tag(tag); - let note_script = client.code_builder().compile_note_script(&code).unwrap(); + let note_script = client.code_builder().compile_note_script(code).unwrap(); let note_storage = NoteStorage::new(vec![ alice_account.id().prefix().as_felt(), alice_account.id().suffix(), diff --git a/docs/src/rust-client/custom_note_how_to.md b/docs/src/rust-client/custom_note_how_to.md index 7fc58599..7459c7b8 100644 --- a/docs/src/rust-client/custom_note_how_to.md +++ b/docs/src/rust-client/custom_note_how_to.md @@ -49,7 +49,7 @@ Now, combine the minted asset and the secret hash to build the custom note. The 2. **Miden Assembly Code:** - The Miden assembly note script ensures that the note can only be consumed if the provided secret, when hashed, matches the hash stored in the note input. -Below is the Miden Assembly code for the note: +Below is the Miden Assembly code for the note. Note scripts in v0.14.5+ are compiled as libraries; the `@note_script` attribute marks the entrypoint procedure. ```masm use miden::protocol::active_note @@ -70,7 +70,8 @@ const ERROR_DIGEST_MISMATCH="Expected digest does not match computed digest" #! #! Note storage is assumed to be as follows: #! => EXPECTED_DIGEST -begin +@note_script +pub proc main # => HASH_PREIMAGE_SECRET # Hashing the secret number hash @@ -124,7 +125,7 @@ The following Rust code demonstrates how to implement the steps outlined above u ```rust no_run use miden_client::auth::{AuthSchemeId, AuthSingleSig}; use rand::RngCore; -use std::{fs, path::Path, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; use tokio::time::{sleep, Duration}; use miden_client::{ @@ -243,10 +244,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -334,7 +335,9 @@ async fn main() -> Result<(), ClientError> { let digest = Hasher::hash_elements(&secret_vals); println!("digest: {:?}", digest); - let code = fs::read_to_string(Path::new("../masm/notes/hash_preimage_note.masm")).unwrap(); + // `include_str!` resolves at compile time relative to this source file, + // so the binary is independent of the working directory it is run from. + let code = include_str!("../masm/notes/hash_preimage_note.masm"); let serial_num = client.rng().draw_word(); let note_script = client.code_builder().compile_note_script(code).unwrap(); diff --git a/docs/src/rust-client/delegated_proving_tutorial.md b/docs/src/rust-client/delegated_proving_tutorial.md index e3413ce8..7d443822 100644 --- a/docs/src/rust-client/delegated_proving_tutorial.md +++ b/docs/src/rust-client/delegated_proving_tutorial.md @@ -52,10 +52,7 @@ miden-client = { version = "0.14", features = ["testing", "tonic"] } miden-client-sqlite-store = { version = "0.14", package = "miden-client-sqlite-store" } miden-protocol = { version = "0.14" } rand = { version = "0.9" } -serde = { version = "1", features = ["derive"] } -serde_json = { version = "1.0", features = ["raw_value"] } tokio = { version = "1.46", features = ["rt-multi-thread", "net", "macros", "fs"] } -rand_chacha = "0.9.0" ``` ## Step 2: Initialize the client and prover and construct transactions @@ -67,7 +64,7 @@ We construct a `LocalTransactionProver` for this walkthrough. use miden_client::auth::AuthSecretKey; use miden_client::auth::{AuthSchemeId, AuthSingleSig}; use rand::RngCore; -use std::sync::Arc; +use std::{path::PathBuf, sync::Arc}; use miden_client::{ account::component::BasicWallet, @@ -93,10 +90,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) diff --git a/docs/src/rust-client/foreign_procedure_invocation_tutorial.md b/docs/src/rust-client/foreign_procedure_invocation_tutorial.md index f7df1084..e10cf495 100644 --- a/docs/src/rust-client/foreign_procedure_invocation_tutorial.md +++ b/docs/src/rust-client/foreign_procedure_invocation_tutorial.md @@ -125,47 +125,23 @@ end ```rust no_run use rand::RngCore; -use std::{fs, path::Path, sync::Arc, time::Duration}; +use std::{path::PathBuf, sync::Arc, time::Duration}; use tokio::time::sleep; use miden_client::{ account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, + component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountId, AccountStorageMode, AccountType, StorageSlot, StorageSlotName, }, - account::AccountId, - assembly::{ - CodeBuilder, - DefaultSourceManager, - Library, - Module, - ModuleKind, - Path as AssemblyPath, - }, auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, rpc::{domain::account::AccountStorageRequirements, Endpoint, GrpcClient}, - transaction::{ForeignAccount, TransactionKernel, TransactionRequestBuilder}, + transaction::{ForeignAccount, TransactionRequestBuilder}, ClientError, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -fn create_library( - library_path: &str, - source_code: &str, -) -> Result, Box> { - let source_manager = Arc::new(DefaultSourceManager::default()); - let assembler = TransactionKernel::assembler_with_source_manager(source_manager.clone()); - let module = Module::parser(ModuleKind::Library).parse_str( - AssemblyPath::new(library_path), - source_code, - source_manager, - )?; - let library = assembler.assemble_library([module])?; - Ok(library) -} - #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client @@ -173,10 +149,10 @@ async fn main() -> Result<(), ClientError> { let timeout_ms = 10_000; let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -194,13 +170,15 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 1] Creating count reader contract."); - let count_reader_path = Path::new("../masm/accounts/count_reader.masm"); - let count_reader_code = fs::read_to_string(count_reader_path).unwrap(); + // `include_str!` resolves at compile time relative to this source file, + // so the binary is independent of the working directory it is run from. + let count_reader_code = include_str!("../masm/accounts/count_reader.masm"); let count_reader_slot_name = StorageSlotName::new("miden::tutorials::count_reader").expect("valid slot name"); - let count_reader_component_code = CodeBuilder::new() - .compile_component_code("external_contract::count_reader_contract", &count_reader_code) + let count_reader_component_code = client + .code_builder() + .compile_component_code("external_contract::count_reader_contract", count_reader_code) .unwrap(); let count_reader_component = AccountComponent::new( count_reader_component_code, @@ -297,13 +275,13 @@ Add this snippet to the end of your file in the `main()` function: println!("\n[STEP 3] Call counter contract with FPI from count reader contract"); // Derive the get_count procedure hash from the locally compiled counter library. -let counter_contract_path = Path::new("../masm/accounts/counter.masm"); -let counter_contract_code = fs::read_to_string(counter_contract_path).unwrap(); +let counter_contract_code = include_str!("../masm/accounts/counter.masm"); // Compile the counter as a component (same path as the deploy binary) to get // the correct procedure root that matches the on-chain MAST. -let counter_component_code = CodeBuilder::new() - .compile_component_code("external_contract::counter_contract", &counter_contract_code) +let counter_component_code = client + .code_builder() + .compile_component_code("external_contract::counter_contract", counter_contract_code) .unwrap(); let counter_component = AccountComponent::new( counter_component_code, @@ -323,9 +301,7 @@ println!("get_count hash: {:?}", get_count_hash); println!("counter id prefix: {:?}", counter_contract_id.prefix()); println!("counter id suffix: {:?}", counter_contract_id.suffix()); -let script_path = Path::new("../masm/scripts/reader_script.masm"); -let script_code_original = fs::read_to_string(script_path).unwrap(); -let script_code = script_code_original +let script_code = include_str!("../masm/scripts/reader_script.masm") .replace("{get_count_proc_hash}", &get_count_hash) .replace( "{account_id_suffix}", @@ -336,17 +312,13 @@ let script_code = script_code_original &u64::from(counter_contract_id.prefix()).to_string(), ); -let account_component_lib = create_library( - "external_contract::count_reader_contract", - &count_reader_code, -) -.unwrap(); - +// Link the count reader contract code into the same `CodeBuilder` chain +// that compiles the script. let tx_script = client .code_builder() - .with_dynamically_linked_library(&account_component_lib) + .with_linked_module("external_contract::count_reader_contract", count_reader_code) .unwrap() - .compile_tx_script(&script_code) + .compile_tx_script(script_code.as_str()) .unwrap(); let foreign_account = @@ -406,7 +378,7 @@ The final `src/main.rs` file should look like this: ```rust no_run use rand::RngCore; -use std::{fs, path::Path, sync::Arc, time::Duration}; +use std::{path::PathBuf, sync::Arc, time::Duration}; use tokio::time::sleep; use miden_client::{ @@ -414,34 +386,15 @@ use miden_client::{ component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountId, AccountStorageMode, AccountType, StorageSlot, StorageSlotName, }, - assembly::{ - CodeBuilder, DefaultSourceManager, Library, Module, ModuleKind, - Path as AssemblyPath, - }, auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, rpc::{domain::account::AccountStorageRequirements, Endpoint, GrpcClient}, - transaction::{ForeignAccount, TransactionKernel, TransactionRequestBuilder}, + transaction::{ForeignAccount, TransactionRequestBuilder}, ClientError, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -fn create_library( - library_path: &str, - source_code: &str, -) -> Result, Box> { - let source_manager = Arc::new(DefaultSourceManager::default()); - let assembler = TransactionKernel::assembler_with_source_manager(source_manager.clone()); - let module = Module::parser(ModuleKind::Library).parse_str( - AssemblyPath::new(library_path), - source_code, - source_manager, - )?; - let library = assembler.assemble_library([module])?; - Ok(library) -} - #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client @@ -449,10 +402,10 @@ async fn main() -> Result<(), ClientError> { let timeout_ms = 10_000; let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -470,15 +423,17 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 1] Creating count reader contract."); - let count_reader_path = Path::new("../masm/accounts/count_reader.masm"); - let count_reader_code = fs::read_to_string(count_reader_path).unwrap(); + // `include_str!` resolves at compile time relative to this source file, + // so the binary is independent of the working directory it is run from. + let count_reader_code = include_str!("../masm/accounts/count_reader.masm"); let count_reader_slot_name = StorageSlotName::new("miden::tutorials::count_reader").expect("valid slot name"); - let count_reader_component_code = CodeBuilder::new() + let count_reader_component_code = client + .code_builder() .compile_component_code( "external_contract::count_reader_contract", - &count_reader_code, + count_reader_code, ) .unwrap(); let count_reader_component = AccountComponent::new( @@ -547,13 +502,13 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 3] Call counter contract with FPI from count reader contract"); - let counter_contract_path = Path::new("../masm/accounts/counter.masm"); - let counter_contract_code = fs::read_to_string(counter_contract_path).unwrap(); + let counter_contract_code = include_str!("../masm/accounts/counter.masm"); // Compile the counter as a component (same path as the deploy binary) to get // the correct procedure root that matches the on-chain MAST. - let counter_component_code = CodeBuilder::new() - .compile_component_code("external_contract::counter_contract", &counter_contract_code) + let counter_component_code = client + .code_builder() + .compile_component_code("external_contract::counter_contract", counter_contract_code) .unwrap(); let counter_component = AccountComponent::new( counter_component_code, @@ -573,9 +528,7 @@ async fn main() -> Result<(), ClientError> { println!("counter id prefix: {:?}", counter_contract_id.prefix()); println!("counter id suffix: {:?}", counter_contract_id.suffix()); - let script_path = Path::new("../masm/scripts/reader_script.masm"); - let script_code_original = fs::read_to_string(script_path).unwrap(); - let script_code = script_code_original + let script_code = include_str!("../masm/scripts/reader_script.masm") .replace("{get_count_proc_hash}", &get_count_hash) .replace( "{account_id_suffix}", @@ -586,17 +539,13 @@ async fn main() -> Result<(), ClientError> { &u64::from(counter_contract_id.prefix()).to_string(), ); - let account_component_lib = create_library( - "external_contract::count_reader_contract", - &count_reader_code, - ) - .unwrap(); - + // Link the count reader contract code into the same `CodeBuilder` chain + // that compiles the script. let tx_script = client .code_builder() - .with_dynamically_linked_library(&account_component_lib) + .with_linked_module("external_contract::count_reader_contract", count_reader_code) .unwrap() - .compile_tx_script(&script_code) + .compile_tx_script(script_code.as_str()) .unwrap(); let foreign_account = diff --git a/docs/src/rust-client/mappings_in_masm_how_to.md b/docs/src/rust-client/mappings_in_masm_how_to.md index 46ab6e87..5c2b9621 100644 --- a/docs/src/rust-client/mappings_in_masm_how_to.md +++ b/docs/src/rust-client/mappings_in_masm_how_to.md @@ -145,49 +145,22 @@ The script calls the `write_to_map` procedure in the account which writes the ke Below is the Rust code that deploys the smart contract, creates the transaction script, and submits a transaction to update the mapping in the account: ```rust no_run -use miden_client::auth::NoAuth; -use miden_client::transaction::TransactionKernel; use rand::RngCore; -use std::{fs, path::Path, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; use miden_client::{ - assembly::{ - Assembler, - CodeBuilder, - DefaultSourceManager, - Module, - ModuleKind, - Path as AssemblyPath, + account::{ + component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountStorageMode, + AccountType, StorageMap, StorageSlot, StorageSlotName, }, + auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, rpc::{Endpoint, GrpcClient}, transaction::TransactionRequestBuilder, - ClientError, + ClientError, Felt, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -use miden_client::{ - account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountStorageMode, - AccountType, StorageMap, StorageSlot, StorageSlotName, - }, - Felt, Word, -}; - -fn create_library( - assembler: Assembler, - library_path: &str, - source_code: &str, -) -> Result, Box> { - let source_manager = Arc::new(DefaultSourceManager::default()); - let module = Module::parser(ModuleKind::Library).parse_str( - AssemblyPath::new(library_path), - source_code, - source_manager.clone(), - )?; - let library = assembler.clone().assemble_library([module])?; - Ok(library) -} #[tokio::main] async fn main() -> Result<(), ClientError> { @@ -197,10 +170,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -218,12 +191,9 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 1] Deploy a smart contract with a mapping"); - // Load the MASM file for the counter contract - let file_path = Path::new("../masm/accounts/mapping_example_contract.masm"); - let account_code = fs::read_to_string(file_path).unwrap(); - - // Prepare assembler (debug mode = true) - let assembler: Assembler = TransactionKernel::assembler(); + // Load the MASM file for the counter contract. `include_str!` resolves at + // compile time relative to this source file. + let account_code = include_str!("../masm/accounts/mapping_example_contract.masm"); // Using an empty storage value in slot 0 since this is usually reserved // for the account pub_key and metadata @@ -238,8 +208,9 @@ async fn main() -> Result<(), ClientError> { let storage_slot_map = StorageSlot::with_map(map_slot_name.clone(), storage_map.clone()); // Compile the account code into `AccountComponent` with one storage slot - let component_code = CodeBuilder::new() - .compile_component_code("miden_by_example::mapping_example_contract", &account_code) + let component_code = client + .code_builder() + .compile_component_code("miden_by_example::mapping_example_contract", account_code) .unwrap(); let mapping_contract_component = AccountComponent::new( component_code, @@ -271,23 +242,15 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 2] Call Mapping Contract With Script"); - let script_code = - fs::read_to_string(Path::new("../masm/scripts/mapping_example_script.masm")).unwrap(); - - // Create the library from the account source code using the helper function. - let account_component_lib = create_library( - assembler.clone(), - "miden_by_example::mapping_example_contract", - &account_code, - ) - .unwrap(); + let script_code = include_str!("../masm/scripts/mapping_example_script.masm"); - // Compile the transaction script with the library. + // Compile the transaction script with the account code linked as a + // module on the same `CodeBuilder` chain. let tx_script = client .code_builder() - .with_dynamically_linked_library(&account_component_lib) + .with_linked_module("miden_by_example::mapping_example_contract", account_code) .unwrap() - .compile_tx_script(&script_code) + .compile_tx_script(script_code) .unwrap(); // Build a transaction request with the custom script diff --git a/docs/src/rust-client/mint_consume_create_tutorial.md b/docs/src/rust-client/mint_consume_create_tutorial.md index 302aca40..6d050f44 100644 --- a/docs/src/rust-client/mint_consume_create_tutorial.md +++ b/docs/src/rust-client/mint_consume_create_tutorial.md @@ -251,7 +251,7 @@ Your `src/main.rs` function should now look like this: ```rust no_run use miden_client::auth::{AuthSchemeId, AuthSingleSig}; use rand::RngCore; -use std::sync::Arc; +use std::{path::PathBuf, sync::Arc}; use tokio::time::Duration; use miden_client::{ @@ -284,10 +284,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) diff --git a/docs/src/rust-client/network_transactions_tutorial.md b/docs/src/rust-client/network_transactions_tutorial.md index af58f456..ec59e540 100644 --- a/docs/src/rust-client/network_transactions_tutorial.md +++ b/docs/src/rust-client/network_transactions_tutorial.md @@ -53,10 +53,7 @@ miden-client = { version = "0.14", features = ["testing", "tonic"] } miden-client-sqlite-store = { version = "0.14", package = "miden-client-sqlite-store" } miden-protocol = { version = "0.14" } rand = { version = "0.9" } -serde = { version = "1", features = ["derive"] } -serde_json = { version = "1.0", features = ["raw_value"] } tokio = { version = "1.46", features = ["rt-multi-thread", "net", "macros", "fs"] } -rand_chacha = "0.9.0" ``` ## Step 2: Set up MASM files @@ -124,12 +121,15 @@ This script executes a function call (increment) that creates a necessary state ### Network Note for User Interaction -Create `masm/notes/network_increment_note.masm`: +Create `masm/notes/network_increment_note.masm`. Note scripts in v0.14.5+ are compiled as libraries; the `@note_script` attribute marks the entrypoint procedure. ```masm use external_contract::counter_contract -begin +#! Inputs: [] +#! Outputs: [] +@note_script +pub proc main call.counter_contract::increment_count end ``` @@ -143,14 +143,17 @@ Before deploying the network account and creating network notes, we need to set Copy and paste the following code into your `src/main.rs` file: ```rust no_run -use std::{fs, path::Path, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; -use miden_client::account::component::BasicWallet; use miden_client::{ + account::{ + component::{AccountComponentMetadata, BasicWallet}, AccountBuilder, AccountComponent, + AccountStorageMode, AccountType, StorageSlot, StorageSlotName, + }, address::NetworkId, - auth::AuthSecretKey, - crypto::FeltRng, + auth::{self, AuthSchemeId, AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, + crypto::FeltRng, keystore::{FilesystemKeyStore, Keystore}, note::{ NetworkAccountTarget, Note, NoteAssets, NoteError, NoteExecutionHint, NoteMetadata, @@ -162,23 +165,6 @@ use miden_client::{ Client, ClientError, Felt, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -use miden_client::auth::{self, AuthSchemeId, AuthSingleSig}; -use miden_client::transaction::TransactionKernel; -use miden_client::{ - account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountStorageMode, - AccountType, StorageSlot, StorageSlotName, - }, - assembly::{ - Assembler, - CodeBuilder, - DefaultSourceManager, - Library, - Module, - ModuleKind, - Path as AssemblyPath, - }, -}; use rand::RngCore; use tokio::time::{sleep, Duration}; @@ -214,22 +200,6 @@ async fn wait_for_tx( Ok(()) } -/// Creates a Miden library from the provided account code and library path. -fn create_library( - account_code: String, - library_path: &str, -) -> Result, Box> { - let assembler: Assembler = TransactionKernel::assembler(); - let source_manager = Arc::new(DefaultSourceManager::default()); - let module = Module::parser(ModuleKind::Library).parse_str( - AssemblyPath::new(library_path), - account_code, - source_manager.clone(), - )?; - let library = assembler.clone().assemble_library([module])?; - Ok(library) -} - #[tokio::main] async fn main() -> Result<(), Box> { // Initialize client @@ -238,10 +208,10 @@ async fn main() -> Result<(), Box> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -303,14 +273,17 @@ Add this code to your `main()` function: // ------------------------------------------------------------------------- println!("\n[STEP 2] Creating a network counter smart contract"); -let counter_code = fs::read_to_string(Path::new("../masm/accounts/counter.masm")).unwrap(); +// `include_str!` resolves at compile time relative to this source file, +// so the binary is independent of the working directory it is run from. +let counter_code = include_str!("../masm/accounts/counter.masm"); // Create the network counter smart contract account // First, compile the MASM code into an account component let counter_slot_name = StorageSlotName::new("miden::tutorials::counter").expect("valid slot name"); -let component_code = CodeBuilder::new() - .compile_component_code("external_contract::counter_contract", &counter_code) +let component_code = client + .code_builder() + .compile_component_code("external_contract::counter_contract", counter_code) .unwrap(); let counter_component = AccountComponent::new( component_code, @@ -354,17 +327,14 @@ Add this code to your `main()` function: // ------------------------------------------------------------------------- println!("\n[STEP 3] Deploy network counter smart contract"); -let script_code = fs::read_to_string(Path::new("../masm/scripts/counter_script.masm")).unwrap(); - -let account_code = fs::read_to_string(Path::new("../masm/accounts/counter.masm")).unwrap(); -let library_path = "external_contract::counter_contract"; - -let library = create_library(account_code, library_path).unwrap(); +let script_code = include_str!("../masm/scripts/counter_script.masm"); +// Link the counter contract code into the same `CodeBuilder` chain that +// compiles the script. let tx_script = client .code_builder() - .with_dynamically_linked_library(&library)? - .compile_tx_script(&script_code)?; + .with_linked_module("external_contract::counter_contract", counter_code)? + .compile_tx_script(script_code)?; let tx_increment_request = TransactionRequestBuilder::new() .custom_script(tx_script) @@ -399,22 +369,18 @@ Add this code to your `main()` function: // ------------------------------------------------------------------------- println!("\n[STEP 4] Creating a network note for network counter contract"); -let network_note_code = - fs::read_to_string(Path::new("../masm/notes/network_increment_note.masm")).unwrap(); -let account_code = fs::read_to_string(Path::new("../masm/accounts/counter.masm")).unwrap(); - -let library_path = "external_contract::counter_contract"; -let library = create_library(account_code, library_path).unwrap(); +let network_note_code = include_str!("../masm/notes/network_increment_note.masm"); // Create and submit the network note that will increment the counter // Generate a random serial number for the note let serial_num = client.rng().draw_word(); -// Compile the note script with the counter contract library +// Compile the note script with the counter contract code linked as a +// module on the same `CodeBuilder` chain. let note_script = client .code_builder() - .with_dynamically_linked_library(&library)? - .compile_note_script(&network_note_code)?; + .with_linked_module("external_contract::counter_contract", counter_code)? + .compile_note_script(network_note_code)?; // Create note recipient with empty storage let note_storage = NoteStorage::new([].to_vec())?; @@ -496,14 +462,17 @@ This step creates a public note that the network operator can consume to execute Your complete `main()` function should look like this: ```rust no_run -use std::{fs, path::Path, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; -use miden_client::account::component::BasicWallet; use miden_client::{ + account::{ + component::{AccountComponentMetadata, BasicWallet}, AccountBuilder, AccountComponent, + AccountStorageMode, AccountType, StorageSlot, StorageSlotName, + }, address::NetworkId, - auth::AuthSecretKey, - crypto::FeltRng, + auth::{self, AuthSchemeId, AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, + crypto::FeltRng, keystore::{FilesystemKeyStore, Keystore}, note::{ NetworkAccountTarget, Note, NoteAssets, NoteError, NoteExecutionHint, NoteMetadata, @@ -515,23 +484,6 @@ use miden_client::{ Client, ClientError, Felt, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -use miden_client::auth::{self, AuthSchemeId, AuthSingleSig}; -use miden_client::transaction::TransactionKernel; -use miden_client::{ - account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountStorageMode, - AccountType, StorageSlot, StorageSlotName, - }, - assembly::{ - Assembler, - CodeBuilder, - DefaultSourceManager, - Library, - Module, - ModuleKind, - Path as AssemblyPath, - }, -}; use rand::RngCore; use tokio::time::{sleep, Duration}; @@ -567,22 +519,6 @@ async fn wait_for_tx( Ok(()) } -/// Creates a Miden library from the provided account code and library path. -fn create_library( - account_code: String, - library_path: &str, -) -> Result, Box> { - let assembler: Assembler = TransactionKernel::assembler(); - let source_manager = Arc::new(DefaultSourceManager::default()); - let module = Module::parser(ModuleKind::Library).parse_str( - AssemblyPath::new(library_path), - account_code, - source_manager.clone(), - )?; - let library = assembler.clone().assemble_library([module])?; - Ok(library) -} - #[tokio::main] async fn main() -> Result<(), Box> { // Initialize client @@ -591,10 +527,10 @@ async fn main() -> Result<(), Box> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -643,14 +579,17 @@ async fn main() -> Result<(), Box> { // ------------------------------------------------------------------------- println!("\n[STEP 2] Creating a network counter smart contract"); - let counter_code = fs::read_to_string(Path::new("../masm/accounts/counter.masm")).unwrap(); + // `include_str!` resolves at compile time relative to this source file, + // so the binary is independent of the working directory it is run from. + let counter_code = include_str!("../masm/accounts/counter.masm"); // Create the network counter smart contract account // First, compile the MASM code into an account component let counter_slot_name = StorageSlotName::new("miden::tutorials::counter").expect("valid slot name"); - let component_code = CodeBuilder::new() - .compile_component_code("external_contract::counter_contract", &counter_code) + let component_code = client + .code_builder() + .compile_component_code("external_contract::counter_contract", counter_code) .unwrap(); let counter_component = AccountComponent::new( component_code, @@ -684,17 +623,14 @@ async fn main() -> Result<(), Box> { // ------------------------------------------------------------------------- println!("\n[STEP 3] Deploy network counter smart contract"); - let script_code = fs::read_to_string(Path::new("../masm/scripts/counter_script.masm")).unwrap(); - - let account_code = fs::read_to_string(Path::new("../masm/accounts/counter.masm")).unwrap(); - let library_path = "external_contract::counter_contract"; - - let library = create_library(account_code, library_path).unwrap(); + let script_code = include_str!("../masm/scripts/counter_script.masm"); + // Link the counter contract code into the same `CodeBuilder` chain that + // compiles the script. let tx_script = client .code_builder() - .with_dynamically_linked_library(&library)? - .compile_tx_script(&script_code)?; + .with_linked_module("external_contract::counter_contract", counter_code)? + .compile_tx_script(script_code)?; let tx_increment_request = TransactionRequestBuilder::new() .custom_script(tx_script) @@ -719,22 +655,18 @@ async fn main() -> Result<(), Box> { // ------------------------------------------------------------------------- println!("\n[STEP 4] Creating a network note for network counter contract"); - let network_note_code = - fs::read_to_string(Path::new("../masm/notes/network_increment_note.masm")).unwrap(); - let account_code = fs::read_to_string(Path::new("../masm/accounts/counter.masm")).unwrap(); - - let library_path = "external_contract::counter_contract"; - let library = create_library(account_code, library_path).unwrap(); + let network_note_code = include_str!("../masm/notes/network_increment_note.masm"); // Create and submit the network note that will increment the counter // Generate a random serial number for the note let serial_num = client.rng().draw_word(); - // Compile the note script with the counter contract library + // Compile the note script with the counter contract code linked as a + // module on the same `CodeBuilder` chain. let note_script = client .code_builder() - .with_dynamically_linked_library(&library)? - .compile_note_script(&network_note_code)?; + .with_linked_module("external_contract::counter_contract", counter_code)? + .compile_note_script(network_note_code)?; // Create note recipient with empty inputs let note_storage = NoteStorage::new([].to_vec())?; diff --git a/docs/src/rust-client/oracle_tutorial.md b/docs/src/rust-client/oracle_tutorial.md index 92f9825e..9b1bb251 100644 --- a/docs/src/rust-client/oracle_tutorial.md +++ b/docs/src/rust-client/oracle_tutorial.md @@ -308,7 +308,7 @@ mkdir -p masm/accounts masm/scripts This will create: -``` +```text masm/ ├── accounts/ └── scripts/ @@ -387,13 +387,13 @@ end Run the following command to execute src/main.rs: -``` +```bash cargo run --release ``` The output of our program will look something like this: -``` +```text Latest block: 806773 Oracle accountId prefix: V0(AccountIdPrefixV0 { prefix: 17041133956008732928 }) suffix: 1562038061251555584 Stack state before step 11449: diff --git a/docs/src/rust-client/public_account_interaction_tutorial.md b/docs/src/rust-client/public_account_interaction_tutorial.md index 1bdc4b1d..4f375fe9 100644 --- a/docs/src/rust-client/public_account_interaction_tutorial.md +++ b/docs/src/rust-client/public_account_interaction_tutorial.md @@ -41,10 +41,7 @@ miden-client = { version = "0.14", features = ["testing", "tonic"] } miden-client-sqlite-store = { version = "0.14", package = "miden-client-sqlite-store" } miden-protocol = { version = "0.14" } rand = { version = "0.9" } -serde = { version = "1", features = ["derive"] } -serde_json = { version = "1.0", features = ["raw_value"] } tokio = { version = "1.46", features = ["rt-multi-thread", "net", "macros", "fs"] } -rand_chacha = "0.9.0" ``` ## Step 2: Build the counter contract @@ -121,18 +118,10 @@ end Copy and paste the following code into your `src/main.rs` file: ```rust no_run -use miden_client::transaction::TransactionKernel; -use std::{fs, path::Path, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; use miden_client::{ - account::AccountId, - assembly::{ - Assembler, - DefaultSourceManager, - Module, - ModuleKind, - Path as AssemblyPath, - }, + account::{AccountId, StorageSlotName}, builder::ClientBuilder, keystore::FilesystemKeyStore, rpc::{Endpoint, GrpcClient}, @@ -141,21 +130,6 @@ use miden_client::{ }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -fn create_library( - assembler: Assembler, - library_path: &str, - source_code: &str, -) -> Result, Box> { - let source_manager = Arc::new(DefaultSourceManager::default()); - let module = Module::parser(ModuleKind::Library).parse_str( - AssemblyPath::new(library_path), - source_code, - source_manager.clone(), - )?; - let library = assembler.clone().assemble_library([module])?; - Ok(library) -} - #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client @@ -164,10 +138,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -241,26 +215,18 @@ Add the following code snippet to the end of your `src/main.rs` function: // ------------------------------------------------------------------------- println!("\n[STEP 2] Call the increment_count procedure in the counter contract"); -// Load the MASM script referencing the increment procedure -let script_path = Path::new("../masm/scripts/counter_script.masm"); -let script_code = fs::read_to_string(script_path).unwrap(); - -let counter_path = Path::new("../masm/accounts/counter.masm"); -let counter_code = fs::read_to_string(counter_path).unwrap(); - -let assembler = TransactionKernel::assembler(); -let account_component_lib = create_library( - assembler.clone(), - "external_contract::counter_contract", - &counter_code, -) -.unwrap(); +// Load the MASM sources at compile time so the binary is independent of +// the working directory it is run from. +let script_code = include_str!("../masm/scripts/counter_script.masm"); +let counter_code = include_str!("../masm/accounts/counter.masm"); +// Compile the script with the counter contract code linked as a module +// on the same `CodeBuilder` chain. let tx_script = client .code_builder() - .with_dynamically_linked_library(&account_component_lib) + .with_linked_module("external_contract::counter_contract", counter_code) .unwrap() - .compile_tx_script(&script_code) + .compile_tx_script(script_code) .unwrap(); // Build a transaction request with the custom script @@ -302,18 +268,10 @@ println!( The final `src/main.rs` file should look like this: ```rust no_run -use miden_client::transaction::TransactionKernel; -use std::{fs, path::Path, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; use miden_client::{ - account::AccountId, - assembly::{ - Assembler, - DefaultSourceManager, - Module, - ModuleKind, - Path as AssemblyPath, - }, + account::{AccountId, StorageSlotName}, builder::ClientBuilder, keystore::FilesystemKeyStore, rpc::{Endpoint, GrpcClient}, @@ -322,21 +280,6 @@ use miden_client::{ }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -fn create_library( - assembler: Assembler, - library_path: &str, - source_code: &str, -) -> Result, Box> { - let source_manager = Arc::new(DefaultSourceManager::default()); - let module = Module::parser(ModuleKind::Library).parse_str( - AssemblyPath::new(library_path), - source_code, - source_manager.clone(), - )?; - let library = assembler.clone().assemble_library([module])?; - Ok(library) -} - #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client @@ -345,10 +288,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -390,26 +333,18 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 2] Call the increment_count procedure in the counter contract"); - // Load the MASM script referencing the increment procedure - let script_path = Path::new("../masm/scripts/counter_script.masm"); - let script_code = fs::read_to_string(script_path).unwrap(); - - let counter_path = Path::new("../masm/accounts/counter.masm"); - let counter_code = fs::read_to_string(counter_path).unwrap(); - - let assembler = TransactionKernel::assembler(); - let account_component_lib = create_library( - assembler.clone(), - "external_contract::counter_contract", - &counter_code, - ) - .unwrap(); + // Load the MASM sources at compile time so the binary is independent of + // the working directory it is run from. + let script_code = include_str!("../masm/scripts/counter_script.masm"); + let counter_code = include_str!("../masm/accounts/counter.masm"); + // Compile the script with the counter contract code linked as a module + // on the same `CodeBuilder` chain. let tx_script = client .code_builder() - .with_dynamically_linked_library(&account_component_lib) + .with_linked_module("external_contract::counter_contract", counter_code) .unwrap() - .compile_tx_script(&script_code) + .compile_tx_script(script_code) .unwrap(); // Build a transaction request with the custom script diff --git a/docs/src/rust-client/unauthenticated_note_how_to.md b/docs/src/rust-client/unauthenticated_note_how_to.md index d9e3560c..436917c2 100644 --- a/docs/src/rust-client/unauthenticated_note_how_to.md +++ b/docs/src/rust-client/unauthenticated_note_how_to.md @@ -55,7 +55,7 @@ Alice ➡ Bob ➡ Charlie ➡ Dave ➡ Eve ➡ Frank ➡ ... ```rust no_run use miden_client::auth::{AuthSchemeId, AuthSingleSig}; use rand::RngCore; -use std::sync::Arc; +use std::{path::PathBuf, sync::Arc}; use tokio::time::{sleep, Duration, Instant}; use miden_client::{ @@ -115,10 +115,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) diff --git a/masm/notes/hash_preimage_note.masm b/masm/notes/hash_preimage_note.masm index 4c54840a..fc18ed48 100644 --- a/masm/notes/hash_preimage_note.masm +++ b/masm/notes/hash_preimage_note.masm @@ -16,7 +16,8 @@ const ERROR_DIGEST_MISMATCH="Expected digest does not match computed digest" #! #! Note storage is assumed to be as follows: #! => EXPECTED_DIGEST -begin +@note_script +pub proc main # => HASH_PREIMAGE_SECRET # Hashing the secret number hash diff --git a/masm/notes/iterative_output_note.masm b/masm/notes/iterative_output_note.masm index dd193014..6a812497 100644 --- a/masm/notes/iterative_output_note.masm +++ b/masm/notes/iterative_output_note.masm @@ -12,8 +12,10 @@ const ASSET_HALF_VALUE_PTR=8 # half-amount ASSET_VALUE stored here const ACCOUNT_ID_PREFIX=12 # storage: [prefix, suffix, tag, 0] const TAG=14 # = ACCOUNT_ID_PREFIX + 2 -# => [] -begin +#! Inputs: [] +#! Outputs: [] +@note_script +pub proc main # Drop word if user accidentally pushes note_args dropw # => [] diff --git a/masm/notes/network_increment_note.masm b/masm/notes/network_increment_note.masm index a0e1a0c7..3b26cecd 100644 --- a/masm/notes/network_increment_note.masm +++ b/masm/notes/network_increment_note.masm @@ -1,5 +1,8 @@ use external_contract::counter_contract -begin +#! Inputs: [] +#! Outputs: [] +@note_script +pub proc main call.counter_contract::increment_count end diff --git a/rust-client/Cargo.lock b/rust-client/Cargo.lock index ce9c7be4..b2afebbe 100644 --- a/rust-client/Cargo.lock +++ b/rust-client/Cargo.lock @@ -420,6 +420,45 @@ dependencies = [ "zeroize", ] +[[package]] +name = "clap" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ddb117e43bbf7dacf0a4190fef4d345b9bad68dfc649cb349e7d17d28428e51" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" +dependencies = [ + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ce8604710f6733aa641a2b3731eaa1e8b3d9973d5e3565da11800813f997a9" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "clap_lex" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" + [[package]] name = "colorchoice" version = "1.0.5" @@ -1236,7 +1275,7 @@ dependencies = [ "hyper", "libc", "pin-project-lite", - "socket2", + "socket2 0.5.10", "tokio", "tower-service", "tracing", @@ -1571,7 +1610,7 @@ dependencies = [ "miden-utils-sync", "primitive-types", "regex", - "thiserror", + "thiserror 2.0.18", "walkdir", ] @@ -1584,7 +1623,7 @@ dependencies = [ "miden-core", "miden-crypto", "miden-utils-indexing", - "thiserror", + "thiserror 2.0.18", "tracing", ] @@ -1602,7 +1641,7 @@ dependencies = [ "miden-package-registry", "miden-project", "smallvec", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -1627,7 +1666,7 @@ dependencies = [ "semver 1.0.28", "serde", "smallvec", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -1637,14 +1676,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cde56bcea3cebe307786a856e204d84e7987c318e5a2909bcbb655d16286ce31" dependencies = [ "miden-protocol", - "thiserror", + "thiserror 2.0.18", ] [[package]] name = "miden-client" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cf411027beb1db257a403f3a53f5e6ea6cb8998ec8dcafaa4995cee51ab7c68" +checksum = "15007f2cf4e80316a8141665b43f454e77ce0dfd2ac0307ce6cdf7a5d552d58b" dependencies = [ "anyhow", "async-trait", @@ -1653,6 +1692,7 @@ dependencies = [ "getrandom 0.3.4", "gloo-timers", "hex", + "miden-debug", "miden-node-proto-build", "miden-note-transport-proto-build", "miden-protocol", @@ -1667,7 +1707,7 @@ dependencies = [ "serde", "serde_json", "tempfile", - "thiserror", + "thiserror 2.0.18", "tokio", "tonic", "tonic-health", @@ -1681,9 +1721,9 @@ dependencies = [ [[package]] name = "miden-client-sqlite-store" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a16f63ecd582f0371218c88a188d7b73ba3d92fb39d9452b4fd31a44dbaec0d2" +checksum = "53a6d9c9bf443b9df440c010eeab6916ab6bc529faed5eb19f84ab7bc21aad59" dependencies = [ "anyhow", "async-trait", @@ -1694,7 +1734,7 @@ dependencies = [ "miden-protocol", "rusqlite", "rusqlite_migration", - "thiserror", + "thiserror 2.0.18", "tokio", ] @@ -1717,7 +1757,7 @@ dependencies = [ "proptest", "proptest-derive", "serde", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -1734,7 +1774,7 @@ dependencies = [ "miden-package-registry", "miden-processor", "miden-utils-sync", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -1776,7 +1816,7 @@ dependencies = [ "sha2", "sha3", "subtle", - "thiserror", + "thiserror 2.0.18", "x25519-dalek", ] @@ -1790,6 +1830,77 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "miden-debug" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df04a684eeb96efabc63e2800a01945f7f6e19ffd00d3b49064e85f7e1fac444" +dependencies = [ + "clap", + "futures", + "glob", + "log", + "miden-assembly", + "miden-assembly-syntax", + "miden-core", + "miden-crypto", + "miden-debug-dap", + "miden-debug-engine", + "miden-debug-types", + "miden-mast-package", + "miden-processor", + "miden-protocol", + "miden-thiserror", + "miden-tx", + "num-traits", + "rustc-demangle", + "serde", + "serde_json", + "smallvec", + "socket2 0.5.10", + "tokio", + "tokio-util", + "toml 0.8.23", +] + +[[package]] +name = "miden-debug-dap" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38cd41176322df12836bb4deecd4b619f7cf8239ed7b2c4ac1da7b2830e5199c" +dependencies = [ + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "miden-debug-engine" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e03dd00bd4dab99dbfdec9fd07009811a7e3b3a988e74a28c6ccb735ac34e138" +dependencies = [ + "clap", + "glob", + "log", + "miden-assembly", + "miden-assembly-syntax", + "miden-core", + "miden-debug-dap", + "miden-debug-types", + "miden-mast-package", + "miden-processor", + "miden-thiserror", + "miden-tx", + "num-traits", + "rustc-demangle", + "serde", + "serde_json", + "smallvec", + "socket2 0.5.10", + "toml 0.8.23", +] + [[package]] name = "miden-debug-types" version = "0.22.1" @@ -1804,8 +1915,8 @@ dependencies = [ "miden-utils-sync", "paste", "serde", - "serde_spanned", - "thiserror", + "serde_spanned 1.1.1", + "thiserror 2.0.18", ] [[package]] @@ -1823,7 +1934,7 @@ dependencies = [ "rand 0.10.1", "serde", "subtle", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -1846,7 +1957,7 @@ dependencies = [ "miden-core", "miden-debug-types", "serde", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -1869,7 +1980,7 @@ dependencies = [ "strip-ansi-escapes", "syn 2.0.117", "textwrap", - "thiserror", + "thiserror 2.0.18", "trybuild", "unicode-width 0.1.14", ] @@ -1887,9 +1998,9 @@ dependencies = [ [[package]] name = "miden-node-proto-build" -version = "0.14.8" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccc6d12ffab3127e7d75dada761fbd78ef9f9cdb107e33110a4c86e014781e02" +checksum = "6e457758c9a6aa5f70f687f1081833f102572ee1d02baf549625868917495815" dependencies = [ "build-rs", "fs-err", @@ -1922,7 +2033,7 @@ dependencies = [ "pubgrub", "serde", "smallvec", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -1939,7 +2050,7 @@ dependencies = [ "miden-utils-indexing", "paste", "rayon", - "thiserror", + "thiserror 2.0.18", "tokio", "tracing", ] @@ -1956,15 +2067,15 @@ dependencies = [ "miden-package-registry", "serde", "serde-untagged", - "thiserror", - "toml", + "thiserror 2.0.18", + "toml 1.1.2+spec-1.1.0", ] [[package]] name = "miden-protocol" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e860cc978d3467297de076e9bd22f0573b82ef73a3d223d6bb957731a45b8164" +checksum = "140b1b3d6b2a3a2bfaeca8b0d2ca15a8ee6a7e0abebbc4f1a2a3a1f1b7f7f58d" dependencies = [ "bech32", "fs-err", @@ -1985,8 +2096,8 @@ dependencies = [ "regex", "semver 1.0.28", "serde", - "thiserror", - "toml", + "thiserror 2.0.18", + "toml 1.1.2+spec-1.1.0", "walkdir", ] @@ -2014,16 +2125,16 @@ dependencies = [ "miden-debug-types", "miden-processor", "serde", - "thiserror", + "thiserror 2.0.18", "tokio", "tracing", ] [[package]] name = "miden-remote-prover-client" -version = "0.14.8" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba0f6545b6b7fdfdd7d57da4b2cbe546bdfc5e177f14c3086e2761ad65afae7d" +checksum = "5a388883f27bff95127c962669eb5d294d27379ac357d6dac5c77faa81b30def" dependencies = [ "build-rs", "fs-err", @@ -2033,7 +2144,7 @@ dependencies = [ "miden-tx", "miette", "prost", - "thiserror", + "thiserror 2.0.18", "tokio", "tonic", "tonic-prost", @@ -2053,9 +2164,9 @@ dependencies = [ [[package]] name = "miden-standards" -version = "0.14.4" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f455a087f41c30636b45ead961d1e66114d2d20661887b307cede05307eeb942" +checksum = "a08e4e4edb289460b1b676a9cdb1727131c2749218dd85a333571d09e1cfa621" dependencies = [ "fs-err", "miden-assembly", @@ -2065,7 +2176,7 @@ dependencies = [ "miden-protocol", "rand 0.9.4", "regex", - "thiserror", + "thiserror 2.0.18", "walkdir", ] @@ -2089,7 +2200,27 @@ dependencies = [ "miden-tx-batch-prover", "rand 0.9.4", "rand_chacha", - "thiserror", + "thiserror 2.0.18", +] + +[[package]] +name = "miden-thiserror" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "183ff8de338956ecfde3a38573241eb7a6f3d44d73866c210e5629c07fa00253" +dependencies = [ + "miden-thiserror-impl", +] + +[[package]] +name = "miden-thiserror-impl" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ee4176a0f2e7d29d2a8ee7e60b6deb14ce67a20e94c3e2c7275cdb8804e1862" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] @@ -2103,7 +2234,7 @@ dependencies = [ "miden-prover", "miden-standards", "miden-verifier", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -2148,7 +2279,7 @@ checksum = "c8834e76299686bcce3de1685158aa4cff49b7fa5e0e00a6cc811e8f2cf5775f" dependencies = [ "miden-crypto", "serde", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -2174,7 +2305,7 @@ dependencies = [ "miden-core", "miden-crypto", "serde", - "thiserror", + "thiserror 2.0.18", "tracing", ] @@ -2189,7 +2320,7 @@ dependencies = [ "serde", "serde_repr", "smallvec", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -2564,7 +2695,7 @@ dependencies = [ "p3-field", "p3-matrix", "p3-util", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -2583,7 +2714,7 @@ dependencies = [ "p3-miden-transcript", "p3-util", "rand 0.10.1", - "thiserror", + "thiserror 2.0.18", "tracing", ] @@ -2604,7 +2735,7 @@ dependencies = [ "p3-miden-stateful-hasher", "p3-miden-transcript", "p3-util", - "thiserror", + "thiserror 2.0.18", "tracing", ] @@ -2624,7 +2755,7 @@ dependencies = [ "p3-util", "rand 0.10.1", "serde", - "thiserror", + "thiserror 2.0.18", "tracing", ] @@ -2647,7 +2778,7 @@ dependencies = [ "p3-challenger", "p3-field", "serde", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -3034,7 +3165,7 @@ dependencies = [ "prost-reflect", "prost-types", "protox-parse", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -3046,7 +3177,7 @@ dependencies = [ "logos", "miette", "prost-types", - "thiserror", + "thiserror 2.0.18", ] [[package]] @@ -3059,7 +3190,7 @@ dependencies = [ "log", "priority-queue", "rustc-hash", - "thiserror", + "thiserror 2.0.18", "version-ranges", ] @@ -3328,9 +3459,6 @@ dependencies = [ "miden-client-sqlite-store", "miden-protocol", "rand 0.9.4", - "rand_chacha", - "serde", - "serde_json", "tokio", ] @@ -3588,6 +3716,15 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + [[package]] name = "serde_spanned" version = "1.1.1" @@ -3670,6 +3807,16 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "socket2" version = "0.6.3" @@ -3741,6 +3888,12 @@ dependencies = [ "vte", ] +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "subtle" version = "2.6.1" @@ -3866,13 +4019,33 @@ dependencies = [ "unicode-width 0.2.2", ] +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + [[package]] name = "thiserror" version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl", + "thiserror-impl 2.0.18", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", ] [[package]] @@ -3914,7 +4087,7 @@ dependencies = [ "libc", "mio", "pin-project-lite", - "socket2", + "socket2 0.6.3", "tokio-macros", "windows-sys 0.61.2", ] @@ -3965,6 +4138,19 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "indexmap", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_edit", +] + [[package]] name = "toml" version = "1.1.2+spec-1.1.0" @@ -3973,11 +4159,20 @@ checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ "indexmap", "serde_core", - "serde_spanned", - "toml_datetime", + "serde_spanned 1.1.1", + "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", "toml_writer", - "winnow", + "winnow 1.0.1", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", ] [[package]] @@ -3989,15 +4184,35 @@ dependencies = [ "serde_core", ] +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.11", + "toml_write", + "winnow 0.7.15", +] + [[package]] name = "toml_parser" version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow", + "winnow 1.0.1", ] +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + [[package]] name = "toml_writer" version = "1.1.1+spec-1.1.0" @@ -4023,7 +4238,7 @@ dependencies = [ "percent-encoding", "pin-project", "rustls-native-certs", - "socket2", + "socket2 0.6.3", "sync_wrapper", "tokio", "tokio-rustls", @@ -4102,7 +4317,7 @@ dependencies = [ "httparse", "js-sys", "pin-project", - "thiserror", + "thiserror 2.0.18", "tonic", "tower-service", "wasm-bindgen", @@ -4232,7 +4447,7 @@ dependencies = [ "serde_json", "target-triple", "termcolor", - "toml", + "toml 1.1.2+spec-1.1.0", ] [[package]] @@ -4682,6 +4897,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + [[package]] name = "winnow" version = "1.0.1" diff --git a/rust-client/Cargo.toml b/rust-client/Cargo.toml index 25a57283..39339e55 100644 --- a/rust-client/Cargo.toml +++ b/rust-client/Cargo.toml @@ -8,7 +8,4 @@ miden-client = { version = "0.14", features = ["testing", "tonic"] } miden-client-sqlite-store = { version = "0.14", package = "miden-client-sqlite-store" } miden-protocol = { version = "0.14" } rand = { version = "0.9" } -serde = { version = "1", features = ["derive"] } -serde_json = { version = "1.0", features = ["raw_value"] } tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } -rand_chacha = "0.9.0" diff --git a/rust-client/src/bin/counter_contract_deploy.rs b/rust-client/src/bin/counter_contract_deploy.rs index 0638e47b..b8cab7c5 100644 --- a/rust-client/src/bin/counter_contract_deploy.rs +++ b/rust-client/src/bin/counter_contract_deploy.rs @@ -1,5 +1,5 @@ use rand::RngCore; -use std::{fs, path::Path, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; use miden_client::{ account::{ @@ -7,34 +7,15 @@ use miden_client::{ AccountStorageMode, AccountType, StorageSlot, StorageSlotName, }, address::NetworkId, - assembly::{ - CodeBuilder, DefaultSourceManager, Library, Module, ModuleKind, - Path as AssemblyPath, - }, auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, rpc::{Endpoint, GrpcClient}, - transaction::{TransactionKernel, TransactionRequestBuilder}, + transaction::TransactionRequestBuilder, ClientError, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -fn create_library( - library_path: &str, - source_code: &str, -) -> Result, Box> { - let source_manager = Arc::new(DefaultSourceManager::default()); - let assembler = TransactionKernel::assembler_with_source_manager(source_manager.clone()); - let module = Module::parser(ModuleKind::Library).parse_str( - AssemblyPath::new(library_path), - source_code, - source_manager, - )?; - let library = assembler.assemble_library([module])?; - Ok(library) -} - #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client @@ -43,10 +24,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -64,15 +45,17 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 1] Creating counter contract."); - // Load the MASM file for the counter contract - let counter_path = Path::new("../masm/accounts/counter.masm"); - let counter_code = fs::read_to_string(counter_path).unwrap(); + // Load the MASM file for the counter contract. `include_str!` resolves at + // compile time relative to this source file, so the binary is independent + // of the working directory it is run from. + let counter_code = include_str!("../../../masm/accounts/counter.masm"); - // Compile the account code into `AccountComponent` with one storage slot + // Compile the account code into `AccountComponent` with one storage slot. let counter_slot_name = StorageSlotName::new("miden::tutorials::counter").expect("valid slot name"); - let component_code = CodeBuilder::new() - .compile_component_code("external_contract::counter_contract", &counter_code) + let component_code = client + .code_builder() + .compile_component_code("external_contract::counter_contract", counter_code) .unwrap(); let counter_component = AccountComponent::new( component_code, @@ -112,21 +95,15 @@ async fn main() -> Result<(), ClientError> { println!("\n[STEP 2] Call Counter Contract With Script"); // Load the MASM script referencing the increment procedure - let script_path = Path::new("../masm/scripts/counter_script.masm"); - let script_code = fs::read_to_string(script_path).unwrap(); - - // Create a library from the counter contract code - let account_component_lib = create_library( - "external_contract::counter_contract", - &counter_code, - ) - .unwrap(); + let script_code = include_str!("../../../masm/scripts/counter_script.masm"); + // Compile the script with the counter contract code linked as a module + // on the same `CodeBuilder` chain. let tx_script = client .code_builder() - .with_dynamically_linked_library(&account_component_lib) + .with_linked_module("external_contract::counter_contract", counter_code) .unwrap() - .compile_tx_script(&script_code) + .compile_tx_script(script_code) .unwrap(); // Build a transaction request with the custom script diff --git a/rust-client/src/bin/counter_contract_fpi.rs b/rust-client/src/bin/counter_contract_fpi.rs index 0bcb9c1e..6a2e044b 100644 --- a/rust-client/src/bin/counter_contract_fpi.rs +++ b/rust-client/src/bin/counter_contract_fpi.rs @@ -1,5 +1,5 @@ use rand::RngCore; -use std::{fs, path::Path, sync::Arc, time::Duration}; +use std::{path::PathBuf, sync::Arc, time::Duration}; use tokio::time::sleep; use miden_client::{ @@ -7,34 +7,15 @@ use miden_client::{ component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountId, AccountStorageMode, AccountType, StorageSlot, StorageSlotName, }, - assembly::{ - CodeBuilder, DefaultSourceManager, Library, Module, ModuleKind, - Path as AssemblyPath, - }, auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, rpc::{domain::account::AccountStorageRequirements, Endpoint, GrpcClient}, - transaction::{ForeignAccount, TransactionKernel, TransactionRequestBuilder}, + transaction::{ForeignAccount, TransactionRequestBuilder}, ClientError, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -fn create_library( - library_path: &str, - source_code: &str, -) -> Result, Box> { - let source_manager = Arc::new(DefaultSourceManager::default()); - let assembler = TransactionKernel::assembler_with_source_manager(source_manager.clone()); - let module = Module::parser(ModuleKind::Library).parse_str( - AssemblyPath::new(library_path), - source_code, - source_manager, - )?; - let library = assembler.assemble_library([module])?; - Ok(library) -} - #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client @@ -43,10 +24,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -64,15 +45,17 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 1] Creating count reader contract."); - let count_reader_path = Path::new("../masm/accounts/count_reader.masm"); - let count_reader_code = fs::read_to_string(count_reader_path).unwrap(); + // `include_str!` resolves at compile time relative to this source file, + // so the binary is independent of the working directory it is run from. + let count_reader_code = include_str!("../../../masm/accounts/count_reader.masm"); let count_reader_slot_name = StorageSlotName::new("miden::tutorials::count_reader").expect("valid slot name"); - let count_reader_component_code = CodeBuilder::new() + let count_reader_component_code = client + .code_builder() .compile_component_code( "external_contract::count_reader_contract", - &count_reader_code, + count_reader_code, ) .unwrap(); let count_reader_component = AccountComponent::new( @@ -141,13 +124,13 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 3] Call counter contract with FPI from count reader contract"); - let counter_contract_path = Path::new("../masm/accounts/counter.masm"); - let counter_contract_code = fs::read_to_string(counter_contract_path).unwrap(); + let counter_contract_code = include_str!("../../../masm/accounts/counter.masm"); // Compile the counter as a component (same path as the deploy binary) to get // the correct procedure root that matches the on-chain MAST. - let counter_component_code = CodeBuilder::new() - .compile_component_code("external_contract::counter_contract", &counter_contract_code) + let counter_component_code = client + .code_builder() + .compile_component_code("external_contract::counter_contract", counter_contract_code) .unwrap(); let counter_component = AccountComponent::new( counter_component_code, @@ -167,9 +150,7 @@ async fn main() -> Result<(), ClientError> { println!("counter id prefix: {:?}", counter_contract_id.prefix()); println!("counter id suffix: {:?}", counter_contract_id.suffix()); - let script_path = Path::new("../masm/scripts/reader_script.masm"); - let script_code_original = fs::read_to_string(script_path).unwrap(); - let script_code = script_code_original + let script_code = include_str!("../../../masm/scripts/reader_script.masm") .replace("{get_count_proc_hash}", &get_count_hash) .replace( "{account_id_suffix}", @@ -180,17 +161,13 @@ async fn main() -> Result<(), ClientError> { &u64::from(counter_contract_id.prefix()).to_string(), ); - let account_component_lib = create_library( - "external_contract::count_reader_contract", - &count_reader_code, - ) - .unwrap(); - + // Link the count reader contract code into the same `CodeBuilder` chain + // that compiles the script. let tx_script = client .code_builder() - .with_dynamically_linked_library(&account_component_lib) + .with_linked_module("external_contract::count_reader_contract", count_reader_code) .unwrap() - .compile_tx_script(&script_code) + .compile_tx_script(script_code.as_str()) .unwrap(); let foreign_account = diff --git a/rust-client/src/bin/counter_contract_increment.rs b/rust-client/src/bin/counter_contract_increment.rs index cad179b8..4d065b29 100644 --- a/rust-client/src/bin/counter_contract_increment.rs +++ b/rust-client/src/bin/counter_contract_increment.rs @@ -1,33 +1,15 @@ -use std::{fs, path::Path, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; use miden_client::{ account::{AccountId, StorageSlotName}, - assembly::{ - DefaultSourceManager, Library, Module, ModuleKind, Path as AssemblyPath, - }, builder::ClientBuilder, keystore::FilesystemKeyStore, rpc::{Endpoint, GrpcClient}, - transaction::{TransactionKernel, TransactionRequestBuilder}, + transaction::TransactionRequestBuilder, ClientError, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -fn create_library( - library_path: &str, - source_code: &str, -) -> Result, Box> { - let source_manager = Arc::new(DefaultSourceManager::default()); - let assembler = TransactionKernel::assembler_with_source_manager(source_manager.clone()); - let module = Module::parser(ModuleKind::Library).parse_str( - AssemblyPath::new(library_path), - source_code, - source_manager, - )?; - let library = assembler.assemble_library([module])?; - Ok(library) -} - #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client @@ -36,10 +18,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -81,24 +63,18 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 2] Call the increment_count procedure in the counter contract"); - // Load the MASM script referencing the increment procedure - let script_path = Path::new("../masm/scripts/counter_script.masm"); - let script_code = fs::read_to_string(script_path).unwrap(); - - let counter_path = Path::new("../masm/accounts/counter.masm"); - let counter_code = fs::read_to_string(counter_path).unwrap(); - - let account_component_lib = create_library( - "external_contract::counter_contract", - &counter_code, - ) - .unwrap(); + // Load the MASM sources at compile time so the binary is independent of + // the working directory it is run from. + let script_code = include_str!("../../../masm/scripts/counter_script.masm"); + let counter_code = include_str!("../../../masm/accounts/counter.masm"); + // Compile the script with the counter contract code linked as a module + // on the same `CodeBuilder` chain. let tx_script = client .code_builder() - .with_dynamically_linked_library(&account_component_lib) + .with_linked_module("external_contract::counter_contract", counter_code) .unwrap() - .compile_tx_script(&script_code) + .compile_tx_script(script_code) .unwrap(); // Build a transaction request with the custom script diff --git a/rust-client/src/bin/create_mint_consume_send.rs b/rust-client/src/bin/create_mint_consume_send.rs index 4bb7ed5d..25f7f3d1 100644 --- a/rust-client/src/bin/create_mint_consume_send.rs +++ b/rust-client/src/bin/create_mint_consume_send.rs @@ -1,5 +1,5 @@ use rand::RngCore; -use std::sync::Arc; +use std::{path::PathBuf, sync::Arc}; use tokio::time::Duration; use miden_client::{ @@ -28,10 +28,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) diff --git a/rust-client/src/bin/delegated_prover.rs b/rust-client/src/bin/delegated_prover.rs index 96d8b758..535565b3 100644 --- a/rust-client/src/bin/delegated_prover.rs +++ b/rust-client/src/bin/delegated_prover.rs @@ -1,5 +1,5 @@ use rand::RngCore; -use std::sync::Arc; +use std::{path::PathBuf, sync::Arc}; use miden_client::{ account::{component::BasicWallet, AccountBuilder, AccountStorageMode, AccountType}, @@ -22,10 +22,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) diff --git a/rust-client/src/bin/hash_preimage_note.rs b/rust-client/src/bin/hash_preimage_note.rs index 5a970ba5..726d7534 100644 --- a/rust-client/src/bin/hash_preimage_note.rs +++ b/rust-client/src/bin/hash_preimage_note.rs @@ -1,5 +1,5 @@ use rand::RngCore; -use std::{fs, path::Path, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; use tokio::time::{sleep, Duration}; use miden_client::{ @@ -113,10 +113,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -202,7 +202,9 @@ async fn main() -> Result<(), ClientError> { let digest = Hasher::hash_elements(&secret_vals); println!("digest: {:?}", digest); - let code = fs::read_to_string(Path::new("../masm/notes/hash_preimage_note.masm")).unwrap(); + // `include_str!` resolves at compile time relative to this source file, + // so the binary is independent of the working directory it is run from. + let code = include_str!("../../../masm/notes/hash_preimage_note.masm"); let serial_num = client.rng().draw_word(); let note_script = client.code_builder().compile_note_script(code).unwrap(); diff --git a/rust-client/src/bin/mapping_example.rs b/rust-client/src/bin/mapping_example.rs index bf703450..43ea8a9b 100644 --- a/rust-client/src/bin/mapping_example.rs +++ b/rust-client/src/bin/mapping_example.rs @@ -1,39 +1,20 @@ use rand::RngCore; -use std::{fs, path::Path, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; use miden_client::{ account::{ component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountStorageMode, AccountType, StorageMap, StorageSlot, StorageSlotName, }, - assembly::{ - CodeBuilder, DefaultSourceManager, Library, Module, ModuleKind, - Path as AssemblyPath, - }, auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, rpc::{Endpoint, GrpcClient}, - transaction::{TransactionKernel, TransactionRequestBuilder}, + transaction::TransactionRequestBuilder, ClientError, Felt, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -fn create_library( - library_path: &str, - source_code: &str, -) -> Result, Box> { - let source_manager = Arc::new(DefaultSourceManager::default()); - let assembler = TransactionKernel::assembler_with_source_manager(source_manager.clone()); - let module = Module::parser(ModuleKind::Library).parse_str( - AssemblyPath::new(library_path), - source_code, - source_manager, - )?; - let library = assembler.assemble_library([module])?; - Ok(library) -} - #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client @@ -42,10 +23,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -63,9 +44,9 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 1] Deploy a smart contract with a mapping"); - // Load the MASM file for the counter contract - let file_path = Path::new("../masm/accounts/mapping_example_contract.masm"); - let account_code = fs::read_to_string(file_path).unwrap(); + // Load the MASM file for the counter contract. `include_str!` resolves at + // compile time relative to this source file. + let account_code = include_str!("../../../masm/accounts/mapping_example_contract.masm"); // Using an empty storage value in slot 0 since this is usually reserved // for the account pub_key and metadata @@ -80,8 +61,9 @@ async fn main() -> Result<(), ClientError> { let storage_slot_map = StorageSlot::with_map(map_slot_name.clone(), storage_map.clone()); // Compile the account code into `AccountComponent` with one storage slot - let component_code = CodeBuilder::new() - .compile_component_code("miden_by_example::mapping_example_contract", &account_code) + let component_code = client + .code_builder() + .compile_component_code("miden_by_example::mapping_example_contract", account_code) .unwrap(); let mapping_contract_component = AccountComponent::new( component_code, @@ -113,22 +95,15 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 2] Call Mapping Contract With Script"); - let script_code = - fs::read_to_string(Path::new("../masm/scripts/mapping_example_script.masm")).unwrap(); - - // Create the library from the account source code using the helper function. - let account_component_lib = create_library( - "miden_by_example::mapping_example_contract", - &account_code, - ) - .unwrap(); + let script_code = include_str!("../../../masm/scripts/mapping_example_script.masm"); - // Compile the transaction script with the library. + // Compile the transaction script with the account code linked as a + // module on the same `CodeBuilder` chain. let tx_script = client .code_builder() - .with_dynamically_linked_library(&account_component_lib) + .with_linked_module("miden_by_example::mapping_example_contract", account_code) .unwrap() - .compile_tx_script(&script_code) + .compile_tx_script(script_code) .unwrap(); // Build a transaction request with the custom script diff --git a/rust-client/src/bin/network_notes_counter_contract.rs b/rust-client/src/bin/network_notes_counter_contract.rs index ba61159a..3330d333 100644 --- a/rust-client/src/bin/network_notes_counter_contract.rs +++ b/rust-client/src/bin/network_notes_counter_contract.rs @@ -1,4 +1,4 @@ -use std::{fs, path::Path, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; use miden_client::{ account::{ @@ -6,10 +6,6 @@ use miden_client::{ AccountStorageMode, AccountType, StorageSlot, StorageSlotName, }, address::NetworkId, - assembly::{ - CodeBuilder, DefaultSourceManager, Library, Module, ModuleKind, - Path as AssemblyPath, - }, auth::{self, AuthSchemeId, AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, crypto::FeltRng, @@ -21,7 +17,7 @@ use miden_client::{ rpc::{Endpoint, GrpcClient}, store::TransactionFilter, transaction::{ - TransactionId, TransactionKernel, TransactionRequestBuilder, TransactionStatus, + TransactionId, TransactionRequestBuilder, TransactionStatus, }, Client, ClientError, Felt, Word, }; @@ -61,22 +57,6 @@ async fn wait_for_tx( Ok(()) } -/// Creates a Miden library from the provided account code and library path. -fn create_library( - account_code: String, - library_path: &str, -) -> Result, Box> { - let source_manager = Arc::new(DefaultSourceManager::default()); - let assembler = TransactionKernel::assembler_with_source_manager(source_manager.clone()); - let module = Module::parser(ModuleKind::Library).parse_str( - AssemblyPath::new(library_path), - account_code, - source_manager, - )?; - let library = assembler.assemble_library([module])?; - Ok(library) -} - #[tokio::main] async fn main() -> Result<(), Box> { // Initialize client @@ -85,10 +65,10 @@ async fn main() -> Result<(), Box> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -137,14 +117,17 @@ async fn main() -> Result<(), Box> { // ------------------------------------------------------------------------- println!("\n[STEP 2] Creating a network counter smart contract"); - let counter_code = fs::read_to_string(Path::new("../masm/accounts/counter.masm")).unwrap(); + // `include_str!` resolves at compile time relative to this source file, + // so the binary is independent of the working directory it is run from. + let counter_code = include_str!("../../../masm/accounts/counter.masm"); // Create the network counter smart contract account // First, compile the MASM code into an account component let counter_slot_name = StorageSlotName::new("miden::tutorials::counter").expect("valid slot name"); - let component_code = CodeBuilder::new() - .compile_component_code("external_contract::counter_contract", &counter_code)?; + let component_code = client + .code_builder() + .compile_component_code("external_contract::counter_contract", counter_code)?; let counter_component = AccountComponent::new( component_code, vec![StorageSlot::with_value( @@ -179,17 +162,14 @@ async fn main() -> Result<(), Box> { // ------------------------------------------------------------------------- println!("\n[STEP 3] Deploy network counter smart contract"); - let script_code = fs::read_to_string(Path::new("../masm/scripts/counter_script.masm")).unwrap(); - - let account_code = fs::read_to_string(Path::new("../masm/accounts/counter.masm")).unwrap(); - let library_path = "external_contract::counter_contract"; - - let library = create_library(account_code, library_path).unwrap(); + let script_code = include_str!("../../../masm/scripts/counter_script.masm"); + // Link the counter contract code into the same `CodeBuilder` chain that + // compiles the script. let tx_script = client .code_builder() - .with_dynamically_linked_library(&library)? - .compile_tx_script(&script_code)?; + .with_linked_module("external_contract::counter_contract", counter_code)? + .compile_tx_script(script_code)?; let tx_increment_request = TransactionRequestBuilder::new() .custom_script(tx_script) @@ -214,22 +194,18 @@ async fn main() -> Result<(), Box> { // ------------------------------------------------------------------------- println!("\n[STEP 4] Creating a network note for network counter contract"); - let network_note_code = - fs::read_to_string(Path::new("../masm/notes/network_increment_note.masm")).unwrap(); - let account_code = fs::read_to_string(Path::new("../masm/accounts/counter.masm")).unwrap(); - - let library_path = "external_contract::counter_contract"; - let library = create_library(account_code, library_path).unwrap(); + let network_note_code = include_str!("../../../masm/notes/network_increment_note.masm"); // Create and submit the network note that will increment the counter // Generate a random serial number for the note let serial_num = client.rng().draw_word(); - // Compile the note script with the counter contract library + // Compile the note script with the counter contract code linked as a + // module on the same `CodeBuilder` chain. let note_script = client .code_builder() - .with_dynamically_linked_library(&library)? - .compile_note_script(&network_note_code)?; + .with_linked_module("external_contract::counter_contract", counter_code)? + .compile_note_script(network_note_code)?; // Create note recipient with empty inputs let note_storage = NoteStorage::new([].to_vec())?; diff --git a/rust-client/src/bin/note_creation_in_masm.rs b/rust-client/src/bin/note_creation_in_masm.rs index 5dc30263..aec47edd 100644 --- a/rust-client/src/bin/note_creation_in_masm.rs +++ b/rust-client/src/bin/note_creation_in_masm.rs @@ -1,5 +1,5 @@ use rand::RngCore; -use std::{fs, path::Path, sync::Arc}; +use std::{path::PathBuf, sync::Arc}; use tokio::time::{sleep, Duration}; use miden_client::{ @@ -103,10 +103,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client) @@ -186,13 +186,15 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 3] Create iterative output note"); - let code = fs::read_to_string(Path::new("../masm/notes/iterative_output_note.masm")).unwrap(); + // `include_str!` resolves at compile time relative to this source file, + // so the binary is independent of the working directory it is run from. + let code = include_str!("../../../masm/notes/iterative_output_note.masm"); let serial_num = client.rng().draw_word(); // Create note metadata and tag let tag = NoteTag::new(0); let metadata = NoteMetadata::new(alice_account.id(), NoteType::Public).with_tag(tag); - let note_script = client.code_builder().compile_note_script(&code).unwrap(); + let note_script = client.code_builder().compile_note_script(code).unwrap(); let note_storage = NoteStorage::new(vec![ alice_account.id().prefix().as_felt(), alice_account.id().suffix(), diff --git a/rust-client/src/bin/unauthenticated_note_transfer.rs b/rust-client/src/bin/unauthenticated_note_transfer.rs index fcaacbbd..9494f563 100644 --- a/rust-client/src/bin/unauthenticated_note_transfer.rs +++ b/rust-client/src/bin/unauthenticated_note_transfer.rs @@ -1,5 +1,5 @@ use rand::RngCore; -use std::sync::Arc; +use std::{path::PathBuf, sync::Arc}; use tokio::time::{sleep, Duration, Instant}; use miden_client::{ @@ -61,10 +61,10 @@ async fn main() -> Result<(), ClientError> { let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); // Initialize keystore - let keystore_path = std::path::PathBuf::from("./keystore"); + let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); - let store_path = std::path::PathBuf::from("./store.sqlite3"); + let store_path = PathBuf::from("./store.sqlite3"); let mut client = ClientBuilder::new() .rpc(rpc_client)