From acebbe05d4fc9b7c831779425bfc7cfb8ea977ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Vigara=20Fern=C3=A1ndez?= <312482795+0xrouss-miden@users.noreply.github.com> Date: Wed, 9 Sep 2026 02:02:33 +0200 Subject: [PATCH 1/3] chore: migrate tutorials to Miden SDK v0.16 --- README.md | 2 +- docs/Cargo.lock | 2450 ++++++++++--- docs/Cargo.toml | 9 +- docs/src/miden_node_setup.md | 24 +- .../rust-client/counter_contract_tutorial.md | 309 +- .../src/rust-client/create_deploy_tutorial.md | 253 +- .../creating_notes_in_masm_tutorial.md | 418 ++- docs/src/rust-client/custom_note_how_to.md | 284 +- .../rust-client/delegated_proving_tutorial.md | 97 +- .../foreign_procedure_invocation_tutorial.md | 306 +- docs/src/rust-client/index.md | 34 + .../rust-client/mappings_in_masm_how_to.md | 211 +- .../mint_consume_create_tutorial.md | 356 +- .../network_transactions_tutorial.md | 557 ++- docs/src/rust-client/oracle_tutorial.md | 345 +- .../public_account_interaction_tutorial.md | 315 +- .../unauthenticated_note_how_to.md | 330 +- .../bridging_with_epoch_tutorial.md | 119 +- .../web-client/counter_contract_tutorial.md | 218 +- docs/src/web-client/create_deploy_tutorial.md | 187 +- .../creating_multiple_notes_tutorial.md | 234 +- .../foreign_procedure_invocation_tutorial.md | 282 +- .../mint_consume_create_tutorial.md | 186 +- docs/src/web-client/react_wallet_tutorial.md | 108 +- docs/src/web-client/setup_guide.md | 38 +- .../web-client/unauthenticated_note_how_to.md | 192 +- examples/bridging-app/.env.example | 12 +- examples/bridging-app/README.md | 24 +- examples/bridging-app/package.json | 14 +- .../components/__tests__/IntentForm.test.tsx | 8 +- .../__tests__/WithdrawConsume.test.tsx | 2 +- .../src/components/crosschain/IntentForm.tsx | 63 +- .../components/crosschain/WithdrawConsume.tsx | 16 +- .../components/crosschain/WithdrawForm.tsx | 3 +- .../src/components/layout/Header.tsx | 4 +- examples/bridging-app/src/config.ts | 12 +- .../bridging-app/src/hooks/useEpochIntent.ts | 10 +- .../src/lib/__tests__/network.test.ts | 35 + examples/bridging-app/src/lib/explorers.ts | 6 +- examples/bridging-app/src/providers.tsx | 5 +- .../__tests__/epoch-collateral.test.ts | 47 + .../bridging-app/src/services/epoch-bridge.ts | 36 +- .../src/services/epoch-collateral.ts | 34 + examples/bridging-app/yarn.lock | 262 +- masm/accounts/auth/no_auth.masm | 33 +- masm/accounts/count_reader.masm | 47 +- masm/accounts/counter.masm | 44 +- masm/accounts/mapping_example_contract.masm | 63 +- masm/accounts/oracle_reader.masm | 52 +- masm/notes/hash_preimage_note.masm | 52 +- masm/notes/iterative_output_note.masm | 144 +- masm/notes/network_increment_note.masm | 17 +- masm/scripts/counter_script.masm | 16 +- masm/scripts/mapping_example_script.masm | 29 +- masm/scripts/oracle_reader_script.masm | 18 +- masm/scripts/reader_script.masm | 18 +- rust-client/Cargo.lock | 3157 ++++++++++++----- rust-client/Cargo.toml | 16 +- .../src/bin/counter_contract_deploy.rs | 36 +- rust-client/src/bin/counter_contract_fpi.rs | 61 +- .../src/bin/counter_contract_increment.rs | 46 +- .../src/bin/create_mint_consume_send.rs | 184 +- rust-client/src/bin/delegated_prover.rs | 45 +- rust-client/src/bin/hash_preimage_note.rs | 143 +- rust-client/src/bin/mapping_example.rs | 60 +- .../src/bin/network_notes_counter_contract.rs | 166 +- rust-client/src/bin/note_creation_in_masm.rs | 162 +- rust-client/src/bin/oracle_data_query.rs | 132 +- .../src/bin/unauthenticated_note_transfer.rs | 178 +- rust-client/src/lib.rs | 547 +++ rust-client/tests/masm_compilation.rs | 36 + rust-toolchain.toml | 4 + scripts/run_tutorials.sh | 46 +- web-client/README.md | 3 + web-client/app/react-tutorials/page.tsx | 44 + web-client/lib/createMintConsume.ts | 46 +- web-client/lib/feeSupport.ts | 288 ++ web-client/lib/foreignProcedureInvocation.ts | 122 +- web-client/lib/incrementCounterContract.ts | 67 +- web-client/lib/masm/count_reader.masm | 47 +- web-client/lib/masm/counter_contract.masm | 44 +- web-client/lib/mintTestnetToAddress.ts | 30 +- .../lib/multiSendWithDelegatedProver.ts | 59 +- web-client/lib/react/createMintConsume.tsx | 106 +- .../react/multiSendWithDelegatedProver.tsx | 106 +- web-client/lib/react/tutorialSupport.tsx | 175 + .../lib/react/unauthenticatedNoteTransfer.tsx | 118 +- web-client/lib/unauthenticatedNoteTransfer.ts | 48 +- web-client/package.json | 4 +- web-client/playwright.config.ts | 7 +- web-client/tests/react-tutorials.spec.ts | 47 + web-client/tests/tutorials.spec.ts | 3 +- web-client/yarn.lock | 54 +- 93 files changed, 10623 insertions(+), 4804 deletions(-) create mode 100644 examples/bridging-app/src/lib/__tests__/network.test.ts create mode 100644 examples/bridging-app/src/services/__tests__/epoch-collateral.test.ts create mode 100644 examples/bridging-app/src/services/epoch-collateral.ts create mode 100644 rust-client/src/lib.rs create mode 100644 rust-client/tests/masm_compilation.rs create mode 100644 rust-toolchain.toml create mode 100644 web-client/app/react-tutorials/page.tsx create mode 100644 web-client/lib/feeSupport.ts create mode 100644 web-client/lib/react/tutorialSupport.tsx create mode 100644 web-client/tests/react-tutorials.spec.ts diff --git a/README.md b/README.md index 8e020e6c..c5a02cbf 100644 --- a/README.md +++ b/README.md @@ -14,4 +14,4 @@ This repository is organized into several parts: The documentation (tutorials) in the `docs` folder is built using Docusaurus and is automatically absorbed into the main [miden-docs](https://github.com/0xMiden/miden-docs) repository for the main documentation website. Changes to the `next` branch trigger an automated deployment workflow. The docs folder requires npm packages to be installed before building. -The documentation folder is also a standalone Rust repository. The purpose of this is to be able to run `cargo doc test`, to test the Rust code inside of the tutorial markdowns. +The documentation folder is also a Rust crate. Run `cargo test --doc` inside `docs/` to check the Rust examples in the tutorial markdowns. diff --git a/docs/Cargo.lock b/docs/Cargo.lock index 1477cc89..defd92ef 100644 --- a/docs/Cargo.lock +++ b/docs/Cargo.lock @@ -19,12 +19,12 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aead" -version = "0.5.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +checksum = "1973cfbc1a2daf9cf550e74e1f088c28e7f7d8c1e1418fb6c9dc5184b7e84c99" dependencies = [ - "crypto-common", - "generic-array", + "crypto-common 0.2.2", + "inout", ] [[package]] @@ -50,7 +50,17 @@ dependencies = [ "paste", "ruint", "rustc-hash", - "sha3", + "sha3 0.10.8", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24671b1f62edcf0f9b62994c7bf72cd621a04a4b99f5020ece1a647b40e2f103" +dependencies = [ + "arrayvec", + "bytes", ] [[package]] @@ -76,11 +86,11 @@ dependencies = [ "alloy-sol-macro-input", "const-hex", "heck", - "indexmap", + "indexmap 2.14.0", "proc-macro-error2", "proc-macro2", "quote", - "sha3", + "sha3 0.10.8", "syn 2.0.115", "syn-solidity", ] @@ -179,6 +189,269 @@ dependencies = [ "backtrace", ] +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint 0.4.6", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint 0.4.6", + "num-traits", + "paste", + "rustc_version 0.4.1", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" +dependencies = [ + "ark-ff-asm 0.5.0", + "ark-ff-macros 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "educe", + "itertools 0.13.0", + "num-bigint 0.4.6", + "num-traits", + "paste", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7a806ac6c8307b929df4645776290a50ee2aac754ad09d8bdf73391309e43af" +dependencies = [ + "ark-ff-asm 0.6.0", + "ark-ff-macros 0.6.0", + "ark-serialize 0.6.0", + "ark-std 0.6.0", + "digest 0.10.7", + "educe", + "num-bigint 0.4.6", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" +dependencies = [ + "quote", + "syn 2.0.115", +] + +[[package]] +name = "ark-ff-asm" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1479009684adc073dff49a1025d3a7065b317a9ead25aaaca38cdc70058ba8a2" +dependencies = [ + "quote", + "syn 2.0.115", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "ark-ff-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0691ed21ef00ef89c1e9bda832eba493dda3ec2f8d892fb25b705f73f06bb8" +dependencies = [ + "num-bigint 0.4.6", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint 0.4.6", +] + +[[package]] +name = "ark-serialize" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" +dependencies = [ + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "num-bigint 0.4.6", +] + +[[package]] +name = "ark-serialize" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a74dd304fd536fb95d0a328e72be759209cc496a9da094c5bc56e5fea4f9e86b" +dependencies = [ + "ark-serialize-derive", + "ark-std 0.6.0", + "digest 0.10.7", + "num-bigint 0.4.6", + "serde_with", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f153690697a2b91e5e1251ff98411ee5371500a111a0fd317a70e588eb300f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "367c9c827ed431bff6868b7aa926e05b16eb46603cc8b6e768e4a5553fa1d155" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + [[package]] name = "arrayref" version = "0.3.9" @@ -191,15 +464,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" -[[package]] -name = "ascii-canvas" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" -dependencies = [ - "term", -] - [[package]] name = "async-trait" version = "0.1.89" @@ -217,6 +481,17 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "auto_impl" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -249,9 +524,9 @@ dependencies = [ [[package]] name = "base16ct" -version = "0.2.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" [[package]] name = "base64" @@ -278,35 +553,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" [[package]] -name = "bincode" -version = "1.3.3" +name = "bitflags" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] -name = "bit-set" -version = "0.8.0" +name = "bitvec" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" dependencies = [ - "bit-vec", + "funty", + "radium", + "tap", + "wyz", ] -[[package]] -name = "bit-vec" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" - -[[package]] -name = "bitflags" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" - [[package]] name = "blake3" version = "1.8.2" @@ -329,6 +592,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + [[package]] name = "bon" version = "3.9.3" @@ -354,6 +626,15 @@ dependencies = [ "syn 2.0.115", ] +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + [[package]] name = "build-rs" version = "0.3.3" @@ -369,6 +650,12 @@ version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +[[package]] +name = "byte-slice-cast" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" + [[package]] name = "byteorder" version = "1.5.0" @@ -399,28 +686,34 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "cfg_aliases" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" + [[package]] name = "chacha20" -version = "0.9.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" dependencies = [ "cfg-if", "cipher", - "cpufeatures", + "cpufeatures 0.3.0", + "rand_core 0.10.0", ] [[package]] name = "chacha20poly1305" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +checksum = "9b89e1c441e926b9c82a8d023f6e1b7ae0adcfaa7d621814e4d60789bac751cb" dependencies = [ "aead", "chacha20", "cipher", "poly1305", - "zeroize", ] [[package]] @@ -432,28 +725,35 @@ dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", "windows-link 0.2.1", ] [[package]] name = "cipher" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ - "crypto-common", + "block-buffer 0.12.1", + "crypto-common 0.2.2", "inout", - "zeroize", ] +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "codegen" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "573800db6c3319bc125ddbf9b9cb001ad1602957f53642ba8d09ff3ddd4da7f1" dependencies = [ - "indexmap", + "indexmap 2.14.0", ] [[package]] @@ -469,16 +769,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "531185e432bb31db1ecda541e9e7ab21468d4d844ad7505e0546a49b4945d49b" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "proptest", "serde_core", ] [[package]] name = "const-oid" -version = "0.9.6" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + +[[package]] +name = "const_format" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" +dependencies = [ + "const_format_proc_macros", + "konst", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] [[package]] name = "constant_time_eq" @@ -502,6 +823,12 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cpubits" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -511,6 +838,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "critical-section" version = "1.2.0" @@ -550,12 +886,15 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" -version = "0.5.5" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +checksum = "1a52aa3fcda4e6302a9f48734f234d35d4721b96f8fe07d073f07ce9df4f0271" dependencies = [ - "generic-array", - "rand_core 0.6.4", + "cpubits", + "ctutils", + "hybrid-array", + "num-traits", + "rand_core 0.10.0", "subtle", "zeroize", ] @@ -567,20 +906,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core 0.6.4", "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", + "rand_core 0.10.0", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", + "subtle", +] + [[package]] name = "curve25519-dalek" -version = "4.1.3" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "b5eed333089e2e1c1ac8c6c0398e5e2497b4c9926ca6d0365ed1e099afa5bc23" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.3.0", "curve25519-dalek-derive", - "digest", + "digest 0.11.3", "fiat-crypto", "rustc_version 0.4.1", "subtle", @@ -664,14 +1022,34 @@ dependencies = [ [[package]] name = "der" -version = "0.7.10" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "a69dedd701da44b0536442edf09c81a64b0ab97a7a4a5e3d1971f00027cbc63d" dependencies = [ "const-oid", "zeroize", ] +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_more" version = "2.0.1" @@ -694,15 +1072,45 @@ dependencies = [ ] [[package]] -name = "digest" -version = "0.10.7" +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "crypto-common 0.1.6", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", + "const-oid", + "crypto-common 0.2.2", + "ctutils", +] + +[[package]] +name = "displaydoc" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", - "subtle", + "proc-macro2", + "quote", + "syn 3.0.3", ] [[package]] @@ -717,25 +1125,32 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + [[package]] name = "ecdsa" -version = "0.16.9" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +checksum = "c0681a4fc24c767085329728d8dfba959af91228aa4610cca4f8ce317ba46ae0" dependencies = [ "der", - "digest", + "digest 0.11.3", "elliptic-curve", "rfc6979", "signature", "spki", + "zeroize", ] [[package]] name = "ed25519" -version = "2.2.3" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +checksum = "29fcf32e6c73d1079f83ab4d782de2d81620346a5f38c6237a86a22f8368980a" dependencies = [ "pkcs8", "signature", @@ -743,18 +1158,31 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +checksum = "6ebaa1a2bf1290ab3bfe5a7b771d050ebffab2711c19a81691c683a5144a25de" dependencies = [ "curve25519-dalek", "ed25519", "serde", - "sha2", + "sha2 0.11.0", + "signature", "subtle", "zeroize", ] +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.115", +] + [[package]] name = "either" version = "1.15.0" @@ -763,31 +1191,43 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elliptic-curve" -version = "0.13.8" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "9d65aa39b3a5c1c9c1b745c9a019234bb7a21b77abcb4f4d266d706e2d577d65" dependencies = [ "base16ct", "crypto-bigint", - "digest", + "crypto-common 0.2.2", + "digest 0.11.3", "ff", - "generic-array", "group", "hkdf", + "hybrid-array", "pkcs8", - "rand_core 0.6.4", + "rand_core 0.10.0", "sec1", "subtle", "zeroize", ] [[package]] -name = "ena" -version = "0.14.3" +name = "enum-ordinalize" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d248bdd43ce613d87415282f69b9bb99d947d290b10962dd6c56233312c2ad5" +checksum = "89dd01549b09589510cf0647475075d12071456586d70f5c75c98ae2a5537677" dependencies = [ - "log", + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65863d15a4ce2888bd2f0f543cc963d3879c3a022c8ee43f6141d479a3ac815" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", ] [[package]] @@ -858,21 +1298,43 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "fastrlp" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce8dba4714ef14b8274c371879b175aa55b16b30f269663f19d576f380018dc4" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + [[package]] name = "ff" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +checksum = "a1f686ab92a9fb0eaf188f6c6c87b89490baa6fdb0db4544ba4dc47f7942489f" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.10.0", "subtle", ] [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" [[package]] name = "find-msvc-tools" @@ -886,6 +1348,9 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", "static_assertions", ] @@ -897,13 +1362,10 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flume" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" dependencies = [ - "futures-core", - "futures-sink", - "nanorand", "spin 0.9.8", ] @@ -919,6 +1381,21 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + [[package]] name = "fs-err" version = "3.2.2" @@ -928,6 +1405,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "futures" version = "0.3.31" @@ -1039,7 +1522,6 @@ checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", - "zeroize", ] [[package]] @@ -1079,6 +1561,7 @@ dependencies = [ "js-sys", "libc", "r-efi 6.0.0", + "rand_core 0.10.0", "wasip2", "wasip3", "wasm-bindgen", @@ -1110,12 +1593,12 @@ dependencies = [ [[package]] name = "group" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core 0.10.0", "subtle", ] @@ -1131,20 +1614,26 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap", + "indexmap 2.14.0", "slab", "tokio", "tokio-util", "tracing", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "foldhash", + "foldhash 0.1.5", ] [[package]] @@ -1152,6 +1641,9 @@ name = "hashbrown" version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +dependencies = [ + "foldhash 0.2.0", +] [[package]] name = "hashlink" @@ -1182,20 +1674,20 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hkdf" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" dependencies = [ "hmac", ] [[package]] name = "hmac" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "digest", + "digest 0.11.3", ] [[package]] @@ -1244,6 +1736,17 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hybrid-array" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" +dependencies = [ + "subtle", + "typenum", + "zeroize", +] + [[package]] name = "hyper" version = "1.7.0" @@ -1267,6 +1770,22 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + [[package]] name = "hyper-timeout" version = "0.5.2" @@ -1286,6 +1805,7 @@ version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ + "base64", "bytes", "futures-channel", "futures-core", @@ -1293,7 +1813,9 @@ dependencies = [ "http", "http-body", "hyper", + "ipnet", "libc", + "percent-encoding", "pin-project-lite", "socket2", "tokio", @@ -1325,6 +1847,89 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" + +[[package]] +name = "icu_properties" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" + +[[package]] +name = "icu_provider" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + [[package]] name = "id-arena" version = "2.3.0" @@ -1337,12 +1942,64 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", +] + [[package]] name = "indenter" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + [[package]] name = "indexmap" version = "2.14.0" @@ -1357,13 +2014,19 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" dependencies = [ - "generic-array", + "hybrid-array", ] +[[package]] +name = "ipnet" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a756c3fac73139e83f14c2d742155dd2b78d3ee56597b419a0579b7bdd6dd78" + [[package]] name = "is_ci" version = "1.2.0" @@ -1376,6 +2039,24 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.14.0" @@ -1385,6 +2066,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.15" @@ -1398,10 +2088,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" dependencies = [ "jiff-static", + "jiff-tzdb-platform", "log", "portable-atomic", "portable-atomic-util", "serde", + "windows-sys 0.52.0", ] [[package]] @@ -1415,6 +2107,21 @@ dependencies = [ "syn 2.0.115", ] +[[package]] +name = "jiff-tzdb" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + [[package]] name = "jobserver" version = "0.1.34" @@ -1439,16 +2146,16 @@ dependencies = [ [[package]] name = "k256" -version = "0.13.4" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +checksum = "93f50113171a713f4a4231ef82eb26703607139b35dcb56241f0ceab2ae1f7d8" dependencies = [ - "cfg-if", + "cpubits", "ecdsa", "elliptic-curve", - "once_cell", - "sha2", - "signature", + "primeorder", + "sha2 0.11.0", + "wnaf", ] [[package]] @@ -1457,39 +2164,34 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] -name = "lalrpop" -version = "0.22.2" +name = "keccak" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" +checksum = "ffd9697dc4a9a62e2da93389f34400b77a28f0287711263cabb203b3ccb9c0e4" dependencies = [ - "ascii-canvas", - "bit-set", - "ena", - "itertools", - "lalrpop-util", - "petgraph", - "regex", - "regex-syntax", - "sha3", - "string_cache", - "term", - "unicode-xid", - "walkdir", + "cfg-if", + "cpufeatures 0.3.0", ] [[package]] -name = "lalrpop-util" -version = "0.22.2" +name = "konst" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" +checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" dependencies = [ - "rustversion", + "konst_macro_rules", ] +[[package]] +name = "konst_macro_rules" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" + [[package]] name = "lazy_static" version = "1.5.0" @@ -1531,6 +2233,12 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +[[package]] +name = "litemap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" + [[package]] name = "lock_api" version = "0.4.14" @@ -1593,6 +2301,12 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "macro-string" version = "0.1.4" @@ -1621,10 +2335,11 @@ checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "miden-ace-codegen" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd45076fe4fef71f0f8b30aa0f018eb39c3086eeb5f3cafc0e12d60cd28339e" +checksum = "1219d5caa6fcb00a96e1ec0ffc66bc03d86fc3e6367d5d8021e7ed420973d64e" dependencies = [ + "miden-constraint-compiler", "miden-core", "miden-crypto", "thiserror", @@ -1632,37 +2347,38 @@ dependencies = [ [[package]] name = "miden-agglayer" -version = "0.15.3" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ead17cc16651de0fea5fc3ea67109ad449c7bb274ca8ff91c5b25e2be4a0c9f8" +checksum = "3664d9d786b69d3ddef13eda4a2d8eb1138ad381ddb740367167fe721dd9cb76" dependencies = [ "alloy-sol-types", "fs-err", "miden-assembly", "miden-core", + "miden-core-lib", "miden-crypto", + "miden-mast-package", + "miden-package-registry", "miden-protocol", + "miden-protocol-build-utils", "miden-standards", "miden-utils-sync", - "primitive-types", - "regex", "serde", "serde_json", "thiserror", - "walkdir", ] [[package]] name = "miden-air" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f1a80330b3e3d3f98e08817dc6a5e3d90d11ab5e88aa9c0dad5d3b4202598b" +checksum = "20a825f5e8b687969ad32107a669b9ae254ba780c18f2e43869407aa010bc5e8" dependencies = [ "miden-ace-codegen", "miden-core", "miden-crypto", - "miden-lifted-stark", "miden-utils-indexing", + "p3-field", "proptest", "thiserror", "tracing", @@ -1670,9 +2386,9 @@ dependencies = [ [[package]] name = "miden-assembly" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8582d184360be35eb2111a99245f556f43e1066ed09192fbcd0f218c466862a5" +checksum = "3f1487a11b83df90e74469fdf61ee0b27831562972c3a4689e0c9bb7b0158ba5" dependencies = [ "env_logger", "log", @@ -1688,15 +2404,13 @@ dependencies = [ [[package]] name = "miden-assembly-syntax" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffa307bc2cbd1f0cb74ed58981823f400a433900fb8f963762331fbb8389d5dc" +checksum = "e77f0289745bb1887147ee67acfb47e14443579b7c7d0655660599f62545bc34" dependencies = [ - "aho-corasick", "env_logger", - "lalrpop", - "lalrpop-util", "log", + "miden-assembly-syntax-cst", "miden-core", "miden-debug-types", "miden-utils-diagnostics", @@ -1711,11 +2425,23 @@ dependencies = [ "thiserror", ] +[[package]] +name = "miden-assembly-syntax-cst" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f41c6c73726eb40149ca2d174c5dd5ac9fcbcd738d851bc4c7ddb7b7f6d4561" +dependencies = [ + "miden-debug-types", + "miden-rowan", + "miden-utils-diagnostics", + "thiserror", +] + [[package]] name = "miden-block-prover" -version = "0.15.3" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "292ded918a0ddd056dc34db471f0bef6ac7991467d513ba505a4fcc0b1ecfac4" +checksum = "286198b93e8ada957dc89fa920fdd442066c02bb0f28efbe0172fce03119545f" dependencies = [ "miden-protocol", "thiserror", @@ -1723,9 +2449,9 @@ dependencies = [ [[package]] name = "miden-client" -version = "0.15.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eb783623b8f55d013833c4eef35190f44da3629d0d13a13693285004f8d3fe2" +checksum = "c9862fde2ef60a6a1f1066834c9920f50973a2012465c451ec64381fea4654fc" dependencies = [ "anyhow", "async-trait", @@ -1735,18 +2461,19 @@ dependencies = [ "gloo-timers", "hex", "miden-agglayer", + "miden-assembly-syntax", "miden-node-proto-build", "miden-note-transport-proto-build", + "miden-processor", "miden-protocol", - "miden-remote-prover-client", "miden-standards", "miden-testing", "miden-tx", - "miden-tx-batch-prover", + "miden-tx-batch", "miette", "prost", "prost-types", - "rand 0.9.2", + "rand 0.10.2", "serde", "serde_json", "tempfile", @@ -1763,9 +2490,9 @@ dependencies = [ [[package]] name = "miden-client-sqlite-store" -version = "0.15.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb7f78f6ce83e114c49c601aa563df2863ebebea471023d70c3577177356b39" +checksum = "b1bdb490a10753418209cf9efcb8d923b3b0a39105b9cba987e9674dd1528b66" dependencies = [ "anyhow", "async-trait", @@ -1778,13 +2505,24 @@ dependencies = [ "rusqlite_migration", "thiserror", "tokio", + "tracing", +] + +[[package]] +name = "miden-constraint-compiler" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec5809dc0c9bc973f90cdb76116bfc3f5463d1e1ef9ce73a671141ba9f6d89a" +dependencies = [ + "miden-core", + "miden-crypto", ] [[package]] name = "miden-core" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80657c32850817f5f67dcf114866495a4b055531778b7c26d0602646ce777eb8" +checksum = "e8727b184f044ca41e61c9c2c345336d0e570f29c041bb49575520aade3c8f2d" dependencies = [ "derive_more", "log", @@ -1794,36 +2532,47 @@ dependencies = [ "miden-utils-core-derive", "miden-utils-indexing", "miden-utils-sync", - "num-derive", - "num-traits", "proptest", - "proptest-derive", "serde", "thiserror", ] [[package]] name = "miden-core-lib" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16410655f32f98537afc9ddf57b71cb6d1ca9d980da5f4eea164cafcaf891b2e" +checksum = "e48b2c62c2c0144717e4219cb42aaf427d58ccd730a18ba97f2e37387a3c3193" dependencies = [ "env_logger", "fs-err", "miden-assembly", + "miden-assembly-syntax", "miden-core", + "miden-core-lib-codegen", "miden-crypto", + "miden-mast-package", "miden-package-registry", + "miden-precompiles", "miden-processor", "miden-utils-sync", "thiserror", ] +[[package]] +name = "miden-core-lib-codegen" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0a0787b5fd63be0e6f5ee96bc531c075e96c0a787b3608fbaf60db0d82c47ed" +dependencies = [ + "miden-core", + "miden-precompiles", +] + [[package]] name = "miden-crypto" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35198bebd353cddc25ad4aafb5f4ef9e71b283d71c787b8938c575c16974135d" +checksum = "8202e1536816c254332798e27f5d46f4940766e01322826553b77489b78ce44d" dependencies = [ "blake3", "cc", @@ -1850,14 +2599,12 @@ dependencies = [ "p3-maybe-rayon", "p3-symmetric", "p3-util", - "rand 0.9.2", - "rand_chacha", - "rand_core 0.9.3", - "rand_hc", + "rand 0.10.2", + "rand_chacha 0.10.0", "rayon", "serde", - "sha2", - "sha3", + "sha2 0.11.0", + "sha3 0.12.0", "subtle", "thiserror", "x25519-dalek", @@ -1865,9 +2612,9 @@ dependencies = [ [[package]] name = "miden-crypto-derive" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9068c6554db0e051f62913575de9949841a46b96ae92d4b7d28e1fed5d8f052b" +checksum = "dcdc897827882684b76ac4b45cae93885cc252ee69c578e6b8ce0e3954043674" dependencies = [ "quote", "syn 2.0.115", @@ -1875,9 +2622,9 @@ dependencies = [ [[package]] name = "miden-debug-types" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956708ccb2f643db398b4b3d4f8d0baf199b1bfb5e34c8be1cd1bc811c005e8e" +checksum = "da1533b6a269126a48dbcb14ce22c3e31be0d0284b516b84f0954261c79f1756" dependencies = [ "memchr", "miden-crypto", @@ -1890,22 +2637,23 @@ dependencies = [ "serde", "serde_spanned", "thiserror", + "zerocopy", ] [[package]] name = "miden-field" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379a39db52cd932a95d4017a18b712ee53ed0f86cfedf8c63ed72d687a18a191" +checksum = "8d9c9b62982fcb18fa1b6c3bcaefc7956da30859d5e881a7f88f77dcf972db99" dependencies = [ "miden-serde-utils", - "num-bigint", + "num-bigint 0.5.1", "p3-challenger", "p3-field", "p3-goldilocks", "p3-util", "paste", - "rand 0.10.0", + "rand 0.10.2", "serde", "subtle", "thiserror", @@ -1922,11 +2670,12 @@ dependencies = [ [[package]] name = "miden-lifted-air" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789e0e469d1731012d8a018057317f31580611535c20d2a47c022213228cb733" +checksum = "8314dec43170ef8549a7a00ae6dd016975d772c9bdf03c06fb8a69d39fed300f" dependencies = [ "p3-air", + "p3-challenger", "p3-field", "p3-matrix", "p3-util", @@ -1935,9 +2684,9 @@ dependencies = [ [[package]] name = "miden-lifted-stark" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f62cca91182917b22a47e150028b7c785df620a15b2974a39c64e2b1b7a889d3" +checksum = "48166c2c8ee308ecbaea6ec8db07981973ff42f99bb39c09b914c30510942a9b" dependencies = [ "miden-lifted-air", "miden-stark-transcript", @@ -1950,7 +2699,7 @@ dependencies = [ "p3-maybe-rayon", "p3-symmetric", "p3-util", - "rand 0.10.0", + "rand 0.10.2", "serde", "thiserror", "tracing", @@ -1958,15 +2707,20 @@ dependencies = [ [[package]] name = "miden-mast-package" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f37c21836b40785ce297d363c57740d4e33edcc411f84185a524eddadd5f53c7" +checksum = "3e99190edc3ae5a8be14aa77aa38df7a06d28455f8e9c02f4486a653f92e21cc" dependencies = [ + "hashbrown 0.17.0", + "log", "miden-assembly-syntax", "miden-core", "miden-debug-types", + "miden-utils-indexing", + "rustc-hash", "serde", "thiserror", + "zerocopy", ] [[package]] @@ -2007,9 +2761,9 @@ dependencies = [ [[package]] name = "miden-node-proto-build" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef3b301741cedd6d0b532583690bc21dbf856d4e14218c591f3924bc905c660a" +checksum = "724a79e7663157e73de1fc19fcd6e30c7cee4e4c4189d44477922a3969797acb" dependencies = [ "build-rs", "codegen", @@ -2021,9 +2775,9 @@ dependencies = [ [[package]] name = "miden-note-transport-proto-build" -version = "0.4.1" +version = "0.5.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7399c2999453c781601f16d82f328ecc695f9375e2415a05147449990f32f71f" +checksum = "5a9d736051a42941788c6534caf8cf779b388c0ae72c9d5f0d729d2a9872d833" dependencies = [ "fs-err", "miette", @@ -2033,9 +2787,9 @@ dependencies = [ [[package]] name = "miden-package-registry" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ece6064beb0582d1c64ba30d0c548c4b7a45f87abae6d69e22fd49c8b343258" +checksum = "5a4b2c12e20f45e74c24ef88819c1ba36724519ce3b76d367a72e1d958df62b8" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -2047,16 +2801,51 @@ dependencies = [ "thiserror", ] +[[package]] +name = "miden-precompiles" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "823d3e418adcbe5a8cea6843f2a167f6f5b521ab827075261974b807ef979ccf" +dependencies = [ + "miden-core", + "miden-crypto", +] + +[[package]] +name = "miden-precompiles-prover" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "467e9fb8d805d8c4621af093a31f0a2465eefd68d63208b49f5663eaf030f89f" +dependencies = [ + "miden-ace-codegen", + "miden-air", + "miden-core", + "miden-crypto", + "miden-lifted-air", + "miden-lifted-stark", + "miden-precompiles", + "miden-serde-utils", + "ruint", + "serde", + "serde-wincode", + "thiserror", + "tracing", + "wincode", +] + [[package]] name = "miden-processor" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea972ca9e45dbf26aa396367e8508db0f7292adea6f6ddf8d39d0e334285fe2b" +checksum = "1a350061ef4f412639475c5bd8d68ae665ce9fd34ffc768c6082acd3972f791c" dependencies = [ - "itertools", + "hashbrown 0.17.0", + "itertools 0.15.0", "miden-air", "miden-core", "miden-debug-types", + "miden-mast-package", + "miden-precompiles", "miden-utils-diagnostics", "miden-utils-indexing", "paste", @@ -2067,9 +2856,9 @@ dependencies = [ [[package]] name = "miden-project" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5320e7e5b562359bd6161ac752dfe43dd4f69bb06e87f94a21a27bb656e5a20d" +checksum = "dbfb83107a2016867e3650e0b34bb8bc356ab2a039dce1992b808bab73da7385" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -2084,13 +2873,13 @@ dependencies = [ [[package]] name = "miden-protocol" -version = "0.15.3" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66340243e37da5936cb278a8dd11037813f1dc6731c2fc866703b76ed465ebc3" +checksum = "46b3c270a0fabe3618006176f1b9600e9b5b59a53a8e26ce6afcf65f1b02cb16" dependencies = [ "bech32", "fs-err", - "getrandom 0.3.4", + "getrandom 0.4.2", "miden-assembly", "miden-assembly-syntax", "miden-core", @@ -2098,89 +2887,96 @@ dependencies = [ "miden-crypto", "miden-crypto-derive", "miden-mast-package", + "miden-package-registry", "miden-processor", + "miden-protocol-build-utils", "miden-utils-sync", "miden-verifier", - "rand 0.9.2", - "rand_chacha", + "rand 0.10.2", + "rand_chacha 0.10.0", "rand_xoshiro", "regex", "semver 1.0.27", "serde", "thiserror", "toml 1.1.2+spec-1.1.0", +] + +[[package]] +name = "miden-protocol-build-utils" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb3076db13d4b6d12bf01d96ffc3fea400f415fce26467d81081400dcdc59c9" +dependencies = [ + "fs-err", + "miden-assembly", + "miden-core", + "miden-mast-package", + "miden-package-registry", + "miden-project", + "regex", "walkdir", ] [[package]] name = "miden-prover" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a91bcc00840b01126cd54e3b68ce3235def2ed48803f2eeb36a035d6951fbc1" +checksum = "65268275b38d5add4cb2542b2e2f2047047a96d6f7bac3b43678e78e36d51794" dependencies = [ - "bincode", "miden-air", "miden-core", "miden-crypto", + "miden-precompiles-prover", "miden-processor", "serde", + "serde-wincode", "tracing", ] [[package]] -name = "miden-remote-prover-client" -version = "0.15.0" +name = "miden-rowan" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2acdb9494689feeec0f60e3b61901b5eb2362b49b993b4cbc3eb75ad83514dd" +checksum = "c13695bf99aabaa21d6572b807c66bb26251aa3d9b75e828b3c99b97a3b1ce7e" dependencies = [ - "build-rs", - "fs-err", - "getrandom 0.4.2", - "miden-node-proto-build", - "miden-protocol", - "miden-tx", - "miette", - "prost", - "thiserror", - "tokio", - "tonic", - "tonic-prost", - "tonic-prost-build", - "tonic-web-wasm-client", + "hashbrown 0.17.0", + "rustc-hash", ] [[package]] name = "miden-serde-utils" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78cd1d4fcad937312e544f7d53423485e453598aa4fb989d2b6374027a8c136" +checksum = "e1f37aa58c6ec69c19ed0edbdba0322c2112356fbbc131a42b5994462a2b794d" dependencies = [ "p3-field", "p3-goldilocks", + "wincode", ] [[package]] name = "miden-standards" -version = "0.15.3" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c7146b028e637f4079b5bdefeefc54d7d6e47a805451fa0a18859d19efa2ff" +checksum = "6be6c71d2114157431f3d5860450b189e902a1fdf3351c8a7d91be8906fd35ce" dependencies = [ "bon", - "fs-err", "miden-assembly", "miden-core-lib", + "miden-package-registry", "miden-protocol", - "rand 0.9.2", - "regex", + "miden-protocol-build-utils", + "primitive-types 0.14.0", + "rand 0.10.2", "thiserror", - "walkdir", ] [[package]] name = "miden-stark-transcript" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05901db2e30d3954243960fe21cea7fbec39f97c27774b56fd5031c28c4881ba" +checksum = "5b3238f74844f9826a9ee41d39b1d726426fd298a5aba16c34346471d7d184db" dependencies = [ "p3-challenger", "p3-field", @@ -2190,9 +2986,9 @@ dependencies = [ [[package]] name = "miden-stateful-hasher" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faeb47a90c55c5d45051d23cf691588804dd531995b4582c79108b64e445a905" +checksum = "88a5545db3e83e041e365c7bb1ba5b8c5953b45a7ad32d698d3b4c30e45727a8" dependencies = [ "p3-field", "p3-symmetric", @@ -2200,12 +2996,12 @@ dependencies = [ [[package]] name = "miden-testing" -version = "0.15.3" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4096fc44a4c88f37405be284e25efdce194d6051e9472ae136ab9249659433c" +checksum = "dba121f560380c4cf70ba422098feedc512d897f41130163255a7dfd94c9aab3" dependencies = [ "anyhow", - "itertools", + "itertools 0.15.0", "miden-block-prover", "miden-core-lib", "miden-crypto", @@ -2213,9 +3009,9 @@ dependencies = [ "miden-protocol", "miden-standards", "miden-tx", - "miden-tx-batch-prover", - "rand 0.9.2", - "rand_chacha", + "miden-tx-batch", + "rand 0.10.2", + "rand_chacha 0.10.0", "thiserror", ] @@ -2226,39 +3022,44 @@ dependencies = [ "miden-client", "miden-client-sqlite-store", "miden-protocol", - "rand 0.9.2", + "rand 0.10.2", + "rust-client", "tokio", ] [[package]] name = "miden-tx" -version = "0.15.3" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94092b45bc0abc656af25473c9807d1e6cee8e682c58d3b1186f0bd0fb6471fb" +checksum = "9dcc3e4708af1d15dc13baec1162fd9c1b9663fd4eeac1c2d2f79ef4202d018c" dependencies = [ + "bon", + "miden-agglayer", "miden-processor", "miden-protocol", "miden-prover", "miden-standards", - "miden-verifier", "thiserror", ] [[package]] -name = "miden-tx-batch-prover" -version = "0.15.3" +name = "miden-tx-batch" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60add2b40559352661bc86970541f88ffcf98c528f301295f9dc3bf15481b46" +checksum = "5db9201b5b56c96dbed1cd5540e7344530a83348fe82e31cabce2b0d963c1dbe" dependencies = [ + "miden-processor", "miden-protocol", - "miden-tx", + "miden-prover", + "miden-verifier", + "thiserror", ] [[package]] name = "miden-utils-core-derive" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0b1ee4662beb049a824e11bb21f95a79746c52874967983c9999f1b19a2f471" +checksum = "d0e529fda0dc73e1fdb56d0c29ca92780a4f3d766cf5bf2bc688b95b0f8a8623" dependencies = [ "proc-macro2", "quote", @@ -2267,11 +3068,10 @@ dependencies = [ [[package]] name = "miden-utils-diagnostics" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fdc1cd4eda372e1c4b99b9c3677e9b1f87a4d2e362a9f4b8f904273d395efc9" +checksum = "197029df3c899525204f4a1f7e5b6e82c69427489b36032ae56fbcf53f9d6b2f" dependencies = [ - "miden-crypto", "miden-debug-types", "miden-miette", "tracing", @@ -2279,11 +3079,11 @@ dependencies = [ [[package]] name = "miden-utils-indexing" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31444125649f4dad9cde647f614309b6be4f918fed276ada4eb99c01e8b9ca7" +checksum = "5b87e9b3f949c27e56dc390d9c9e679f2886e6ea6adfbc7158de7f377c1b6940" dependencies = [ - "miden-crypto", + "miden-serde-utils", "proptest", "serde", "thiserror", @@ -2291,9 +3091,9 @@ dependencies = [ [[package]] name = "miden-utils-sync" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "807c8ae625b7652ae7246b225c907c05da72927c31a0fd71c835c4f80931e92e" +checksum = "e9e911afc22a03dcf439a0d1d20a67631169a6757100230b257c57e546dd5c3a" dependencies = [ "lock_api", "loom", @@ -2303,24 +3103,26 @@ dependencies = [ [[package]] name = "miden-verifier" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec5556dac919a1c13edeb2bd7181fc6a4c2ce52764a3e518bcdcd9ed48e5b38e" +checksum = "6aaf6b63aa6300832a302207f3e93932faae299679e75a0c993de6b1c02f5cde" dependencies = [ - "bincode", "miden-air", "miden-core", "miden-crypto", + "miden-precompiles", + "miden-precompiles-prover", + "miden-serde-utils", "serde", + "serde-wincode", "thiserror", - "tracing", ] [[package]] name = "midenc-hir-type" -version = "0.6.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff0511aa2201f7098995e38a3c97a319d379c3b2d26fb83677b21b71f61a7b4" +checksum = "f72909a4bae8dca4bbd34c28dcbcdff595afc47e48c312a683108f7452bd270b" dependencies = [ "miden-formatting", "miden-serde-utils", @@ -2386,21 +3188,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom 0.2.16", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -2416,7 +3203,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "num-bigint", + "num-bigint 0.4.6", "num-complex", "num-integer", "num-iter", @@ -2434,6 +3221,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-bigint" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e7820bc0a80a0238e650327316f929ba18d5be054b647490a3a6a339f3e7c0" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-complex" version = "0.4.6" @@ -2444,15 +3241,10 @@ dependencies = [ ] [[package]] -name = "num-derive" -version = "0.4.2" +name = "num-conv" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.115", -] +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-integer" @@ -2480,7 +3272,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "num-bigint", + "num-bigint 0.4.6", "num-integer", "num-traits", ] @@ -2530,12 +3322,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "openssl-probe" version = "0.1.6" @@ -2550,9 +3336,9 @@ checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" [[package]] name = "p3-air" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f2ec9cbfc642fc5173817287c3f8b789d07743b5f7e812d058b7a03e344f9ab" +checksum = "ddb1be05c0d6f691afe0c9f468018a9a37cfa904dee78a8081ec96eb3cdd88e8" dependencies = [ "p3-field", "p3-matrix", @@ -2561,9 +3347,9 @@ dependencies = [ [[package]] name = "p3-blake3" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b667f43b19499dd939c9e2553aa95688936a88360d50117dae3c8848d07dbc70" +checksum = "6f202f5fbcceb6f56f783d98efb5de27e5a171470e3364de97b0923b39c87ab5" dependencies = [ "blake3", "p3-symmetric", @@ -2572,9 +3358,9 @@ dependencies = [ [[package]] name = "p3-challenger" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0b490c745a7d2adeeafff06411814c8078c432740162332b3cd71be0158a76" +checksum = "84d5d5e1ecf2c80b09b48ce870e8abd08b643454101c5dc9d0fd71bfbd78224d" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -2586,42 +3372,42 @@ dependencies = [ [[package]] name = "p3-dft" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55301e91544440254977108b85c32c09d7ea05f2f0dd61092a2825339906a4a7" +checksum = "4321a952da2721ecd85ca593ea189798dfb4e439a2cc1378ce1442091880f173" dependencies = [ - "itertools", + "itertools 0.15.0", "p3-field", "p3-matrix", "p3-maybe-rayon", "p3-util", - "spin 0.10.0", + "spin 0.12.3", "tracing", ] [[package]] name = "p3-field" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85affca7fc983889f260655c4cf74163eebb94605f702e4b6809ead707cba54f" +checksum = "53db75d38e04fc255826f388eca9d05976733dc9754aa3db411bc9ea1a37c1a0" dependencies = [ - "itertools", - "num-bigint", + "itertools 0.15.0", + "num-bigint 0.5.1", "p3-maybe-rayon", "p3-util", "paste", - "rand 0.10.0", + "rand 0.10.2", "serde", "tracing", ] [[package]] name = "p3-goldilocks" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ca1081f5c47b940f2d75a11c04f62ea1cc58a5d480dd465fef3861c045c63cd" +checksum = "d03b3f31080df31be723b876709246f8f1e532e1c5b82efb5281d705c8304c63" dependencies = [ - "num-bigint", + "num-bigint 0.5.1", "p3-challenger", "p3-dft", "p3-field", @@ -2631,15 +3417,16 @@ dependencies = [ "p3-symmetric", "p3-util", "paste", - "rand 0.10.0", + "rand 0.10.2", "serde", + "spin 0.12.3", ] [[package]] name = "p3-keccak" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcf27615ece1995e4fcf4c69740f1cf515d1481367a20b4b3ce7f4f1b8d70f7" +checksum = "ae50c8c37eb847c660298fb275e53c025c49b2623a8cfabf67f5322258b2b4db" dependencies = [ "p3-symmetric", "p3-util", @@ -2648,49 +3435,49 @@ dependencies = [ [[package]] name = "p3-matrix" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53428126b009071563d1d07305a9de8be0d21de00b57d2475289ee32ffca6577" +checksum = "473eb920c446a6f4536e0d3528fbdca2a23c0e24e1d0d7767452e6d385dd335c" dependencies = [ - "itertools", + "itertools 0.15.0", "p3-field", "p3-maybe-rayon", "p3-util", - "rand 0.10.0", + "rand 0.10.2", "serde", "tracing", ] [[package]] name = "p3-maybe-rayon" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "082bf467011c06c768c579ec6eb9accb5e1e62108891634cc770396e917f978a" +checksum = "e6fddfd435f96394769414cf5590b77058aa506659bf20d6592e9d1989e04440" dependencies = [ "rayon", ] [[package]] name = "p3-mds" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35209e6214102ea6ec6b8cb1b9c15a9b8e597a39f9173597c957f123bced81b3" +checksum = "551ba0ab2cccd89f85a99450224898aff224e323bbf61f777ba6344f0896ef10" dependencies = [ "p3-dft", "p3-field", "p3-symmetric", "p3-util", - "rand 0.10.0", + "rand 0.10.2", ] [[package]] name = "p3-monty-31" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffa8c99ec50c035020bbf5457c6a729ba6a975719c1a8dd3f16421081e4f650c" +checksum = "871f635f7340cd0868b17e43e0c98fefdafdaed90469d0725caf6d8372a2a47c" dependencies = [ - "itertools", - "num-bigint", + "itertools 0.15.0", + "num-bigint 0.5.1", "p3-dft", "p3-field", "p3-matrix", @@ -2701,43 +3488,44 @@ dependencies = [ "p3-symmetric", "p3-util", "paste", - "rand 0.10.0", + "rand 0.10.2", "serde", - "spin 0.10.0", + "spin 0.12.3", "tracing", ] [[package]] name = "p3-poseidon1" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a018b618e3fa0aec8be933b1d8e404edd23f46991f6bf3f5c2f3f95e9413fe9" +checksum = "8d0d304e9a1f29c0d66534aa84e69528e2118351fdce08dcf5898af4e0fecc32" dependencies = [ "p3-field", + "p3-mds", "p3-symmetric", - "rand 0.10.0", + "rand 0.10.2", ] [[package]] name = "p3-poseidon2" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256a668a9ba916f8767552f13d0ba50d18968bc74a623bfdafa41e2970c944d0" +checksum = "43eb8a73a26d14becaed1c67c3e8a047e4311d7909b402383c82ca9643ba17c6" dependencies = [ "p3-field", "p3-mds", "p3-symmetric", "p3-util", - "rand 0.10.0", + "rand 0.10.2", ] [[package]] name = "p3-symmetric" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c60a71a1507c13611b0f2b0b6e83669fd5b76f8e3115bcbced5ccfdf3ca7807" +checksum = "2015ea80cad969b6aabf27a04884286fe1354393b166d968ee0d80a95126b2a4" dependencies = [ - "itertools", + "itertools 0.15.0", "p3-field", "p3-util", "serde", @@ -2745,13 +3533,40 @@ dependencies = [ [[package]] name = "p3-util" -version = "0.5.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8b766b9e9254bf3fa98d76e42cf8a5b30628c182dfd5272d270076ee12f0fc0" +checksum = "6c5466fc40e6df89d3b291a2eff16b33e68e8571207790370137ec18090aadab" dependencies = [ "rayon", "serde", - "transpose", +] + +[[package]] +name = "parity-scale-codec" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "const_format", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "rustversion", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.115", ] [[package]] @@ -2783,6 +3598,12 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pastey" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" + [[package]] name = "percent-encoding" version = "2.3.2" @@ -2790,22 +3611,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] -name = "petgraph" -version = "0.7.1" +name = "pest" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +checksum = "5a07a60cc7a4d00c91f95c685609d1d2f79050e6804b70ebedd7650f0b839bcf" dependencies = [ - "fixedbitset", - "indexmap", + "memchr", + "ucd-trie", ] [[package]] -name = "phf_shared" -version = "0.11.3" +name = "petgraph" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" dependencies = [ - "siphasher", + "fixedbitset", + "indexmap 2.14.0", ] [[package]] @@ -2842,9 +3664,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkcs8" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ "der", "spki", @@ -2858,12 +3680,11 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "poly1305" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +checksum = "6e2d0073b297041425c7c3df6eb4792d598a15323fe63346852b092eca02904c" dependencies = [ - "cpufeatures", - "opaque-debug", + "cpufeatures 0.3.0", "universal-hash", ] @@ -2883,28 +3704,74 @@ dependencies = [ ] [[package]] -name = "ppv-lite86" -version = "0.2.21" +name = "potential_utf" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.115", +] + +[[package]] +name = "primefield" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c555a6e4eb7d4e158fcb028c835c3b8642206ddc279b5c6b202ef9a8bdb592f4" +dependencies = [ + "crypto-bigint", + "crypto-common 0.2.2", + "ff", + "rand_core 0.10.0", + "subtle", + "zeroize", +] + +[[package]] +name = "primeorder" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +checksum = "5c9f42978c78a00e3d68f69fc03e57a234debae69da4020a4fb588fcdcd07b06" dependencies = [ - "zerocopy", + "elliptic-curve", + "primefield", + "serdect", + "wnaf", ] [[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - -[[package]] -name = "prettyplease" -version = "0.2.37" +name = "primitive-types" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" dependencies = [ - "proc-macro2", - "syn 2.0.115", + "fixed-hash", + "impl-codec", + "uint 0.9.5", ] [[package]] @@ -2914,7 +3781,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "721a1da530b5a2633218dc9f75713394c983c352be88d2d7c9ee85e2c4c21794" dependencies = [ "fixed-hash", - "uint", + "uint 0.10.0", ] [[package]] @@ -2924,10 +3791,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" dependencies = [ "equivalent", - "indexmap", + "indexmap 2.14.0", "serde", ] +[[package]] +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro-error-attr2" version = "2.0.0" @@ -2952,9 +3828,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -2968,7 +3844,7 @@ dependencies = [ "bitflags", "num-traits", "rand 0.9.2", - "rand_chacha", + "rand_chacha 0.9.0", "rand_xorshift", "regex-syntax", "unarray", @@ -3002,7 +3878,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac6c3320f9abac597dcbc668774ef006702672474aad53c6d596b62e487b40b1" dependencies = [ "heck", - "itertools", + "itertools 0.14.0", "log", "multimap", "once_cell", @@ -3024,7 +3900,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" dependencies = [ "anyhow", - "itertools", + "itertools 0.14.0", "proc-macro2", "quote", "syn 2.0.115", @@ -3084,7 +3960,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f5df7e552bc7edd075f5783a87fbfc21d6a546e32c16985679c488c18192d83" dependencies = [ - "indexmap", + "indexmap 2.14.0", "log", "priority-queue", "rustc-hash", @@ -3112,11 +3988,67 @@ dependencies = [ "pulldown-cmark", ] +[[package]] +name = "quinn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04759210543be93709136e28212294a659ef5001836ff4eab4d663e4529bba83" +dependencies = [ + "bytes", + "getrandom 0.4.2", + "lru-slab", + "rand 0.10.2", + "rand_pcg", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.61.2", +] + [[package]] name = "quote" -version = "1.0.41" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -3133,12 +4065,20 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand" version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ + "libc", + "rand_chacha 0.3.1", "rand_core 0.6.4", ] @@ -3148,19 +4088,31 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "rand_chacha", + "rand_chacha 0.9.0", "rand_core 0.9.3", ] [[package]] name = "rand" -version = "0.10.0" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc266eb313df6c5c09c1c7b1fbe2510961e5bcd3add930c1e31f7ed9da0feff8" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ + "chacha20", + "getrandom 0.4.2", "rand_core 0.10.0", ] +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + [[package]] name = "rand_chacha" version = "0.9.0" @@ -3171,6 +4123,16 @@ dependencies = [ "rand_core 0.9.3", ] +[[package]] +name = "rand_chacha" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e6af7f3e25ded52c41df4e0b1af2d047e45896c2f3281792ed68a1c243daedb" +dependencies = [ + "ppv-lite86", + "rand_core 0.10.0", +] + [[package]] name = "rand_core" version = "0.6.4" @@ -3196,12 +4158,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c8d0fd677905edcbeedbf2edb6494d676f0e98d54d5cf9bda0b061cb8fb8aba" [[package]] -name = "rand_hc" -version = "0.3.2" +name = "rand_pcg" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b363d4f6370f88d62bf586c80405657bde0f0e1b8945d47d2ad59b906cb4f54" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.10.0", ] [[package]] @@ -3215,18 +4177,18 @@ dependencies = [ [[package]] name = "rand_xoshiro" -version = "0.7.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" +checksum = "662effc7698e08ea324d3acccf8d9d7f7bf79b9785e270a174ea36e56900c91d" dependencies = [ - "rand_core 0.9.3", + "rand_core 0.10.0", ] [[package]] name = "rayon" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" +checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" dependencies = [ "either", "rayon-core", @@ -3251,6 +4213,26 @@ dependencies = [ "bitflags", ] +[[package]] +name = "ref-cast" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + [[package]] name = "regex" version = "1.12.2" @@ -3280,14 +4262,52 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64", + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + [[package]] name = "rfc6979" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +checksum = "b4a459cddafb3fe76b31fd8f1108007566c40301feb64dc7b54656eb7388172b" dependencies = [ + "crypto-bigint", "hmac", - "subtle", ] [[package]] @@ -3304,15 +4324,39 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + [[package]] name = "ruint" -version = "1.17.2" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c141e807189ad38a07276942c6623032d3753c8859c146104ac2e4d68865945a" +checksum = "f5e99bff0393163bb25029a6af25d3d8d202ba5b5438a74d1bd8789f5c822970" dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "ark-ff 0.5.0", + "ark-ff 0.6.0", + "bytes", + "fastrlp 0.3.1", + "fastrlp 0.4.0", + "num-bigint 0.4.6", + "num-integer", + "num-traits", + "parity-scale-codec", + "primitive-types 0.12.2", "proptest", "rand 0.8.5", "rand 0.9.2", + "rlp", "ruint-macro", "serde_core", "valuable", @@ -3349,6 +4393,21 @@ dependencies = [ "rusqlite", ] +[[package]] +name = "rust-client" +version = "0.1.0" +dependencies = [ + "hex", + "miden-client", + "miden-client-sqlite-store", + "miden-protocol", + "rand 0.10.2", + "reqwest", + "serde", + "sha2 0.10.9", + "tokio", +] + [[package]] name = "rustc-demangle" version = "0.1.26" @@ -3361,6 +4420,12 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + [[package]] name = "rustc_version" version = "0.2.3" @@ -3370,6 +4435,15 @@ dependencies = [ "semver 0.9.0", ] +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + [[package]] name = "rustc_version" version = "0.4.1" @@ -3425,6 +4499,7 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" dependencies = [ + "web-time", "zeroize", ] @@ -3469,6 +4544,30 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -3483,14 +4582,14 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sec1" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" dependencies = [ "base16ct", + "ctutils", "der", - "generic-array", - "pkcs8", + "hybrid-array", "subtle", "zeroize", ] @@ -3524,7 +4623,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser", + "semver-parser 0.7.0", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser 0.10.3", ] [[package]] @@ -3543,6 +4651,15 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "semver-parser" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" +dependencies = [ + "pest", +] + [[package]] name = "serde" version = "1.0.228" @@ -3565,6 +4682,17 @@ dependencies = [ "typeid", ] +[[package]] +name = "serde-wincode" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa9d3a86c66cf10ce79df36f555a5a4c8d72a82515d9ea8ca420e02c925c30f" +dependencies = [ + "serde", + "thiserror", + "wincode", +] + [[package]] name = "serde_core" version = "1.0.228" @@ -3618,25 +4746,89 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee78f1fbe43ac4a0e47aadb3dbd357b69eb0d3793e948624cd03dd2750ab1c0a" +dependencies = [ + "base64", + "bs58", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.14.0", + "jiff", + "schemars 0.9.0", + "schemars 1.2.2", + "serde_core", + "serde_json", + "time", +] + +[[package]] +name = "serdect" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66cf8fedced2fcf12406bcb34223dffb92eaf34908ede12fed414c82b7f00b3e" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "sha2" version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "digest 0.10.7", + "keccak 0.1.5", ] [[package]] name = "sha3" -version = "0.10.8" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +checksum = "bc9bad02c26382724b2d2692c6f179285e4b54eeecd7968f52a50059c3c11759" dependencies = [ - "digest", - "keccak", + "digest 0.11.3", + "keccak 0.2.1", + "sponge-cursor", ] [[package]] @@ -3656,20 +4848,14 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signature" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" dependencies = [ - "digest", - "rand_core 0.6.4", + "digest 0.11.3", + "rand_core 0.10.0", ] -[[package]] -name = "siphasher" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" - [[package]] name = "slab" version = "0.4.11" @@ -3712,46 +4898,40 @@ dependencies = [ [[package]] name = "spin" -version = "0.10.0" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +checksum = "0134f9043ed38b087ac4f7d4af44c79e2c9e5094421fe3164f435ce585953b10" dependencies = [ "lock_api", ] [[package]] name = "spki" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" dependencies = [ "base64ct", "der", ] [[package]] -name = "static_assertions" -version = "1.1.0" +name = "sponge-cursor" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "3a0219bd7d979d58245a4f41f695e1ac9f8befdffadd7f61f1bae9e39abc6620" [[package]] -name = "strength_reduce" -version = "0.2.4" +name = "stable_deref_trait" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] -name = "string_cache" -version = "0.8.9" +name = "static_assertions" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" -dependencies = [ - "new_debug_unreachable", - "parking_lot", - "phf_shared", - "precomputed-hash", -] +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "strip-ansi-escapes" @@ -3817,6 +4997,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn-solidity" version = "1.5.7" @@ -3834,6 +5025,26 @@ name = "sync_wrapper" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-triple" @@ -3854,15 +5065,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "term" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2111ef44dae28680ae9752bb89409e7310ca33a8c621ebe7b106cf5c928b3ac0" -dependencies = [ - "windows-sys 0.61.2", -] - [[package]] name = "termcolor" version = "1.4.1" @@ -3895,22 +5097,22 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.17" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.17" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 2.0.115", + "syn 3.0.3", ] [[package]] @@ -3922,6 +5124,36 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "time-macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -3931,6 +5163,31 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinystr" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" version = "1.48.0" @@ -3998,7 +5255,7 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" dependencies = [ - "indexmap", + "indexmap 2.14.0", "serde_core", "serde_spanned", "toml_datetime 0.7.3", @@ -4013,7 +5270,7 @@ version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" dependencies = [ - "indexmap", + "indexmap 2.14.0", "serde_core", "serde_spanned", "toml_datetime 1.1.1+spec-1.1.0", @@ -4040,6 +5297,18 @@ dependencies = [ "serde_core", ] +[[package]] +name = "toml_edit" +version = "0.25.13+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b" +dependencies = [ + "indexmap 2.14.0", + "toml_datetime 1.1.1+spec-1.1.0", + "toml_parser", + "winnow 1.0.1", +] + [[package]] name = "toml_parser" version = "1.1.2+spec-1.1.0" @@ -4170,7 +5439,7 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "indexmap", + "indexmap 2.14.0", "pin-project-lite", "slab", "sync_wrapper", @@ -4181,6 +5450,24 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "url", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -4254,16 +5541,6 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "transpose" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" -dependencies = [ - "num-integer", - "strength_reduce", -] - [[package]] name = "try-lock" version = "0.2.5" @@ -4294,9 +5571,27 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "uint" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] [[package]] name = "uint" @@ -4354,12 +5649,12 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" dependencies = [ - "crypto-common", - "subtle", + "crypto-common 0.2.2", + "ctutils", ] [[package]] @@ -4368,6 +5663,24 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -4537,7 +5850,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" dependencies = [ "anyhow", - "indexmap", + "indexmap 2.14.0", "wasm-encoder", "wasmparser", ] @@ -4563,7 +5876,7 @@ checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ "bitflags", "hashbrown 0.15.5", - "indexmap", + "indexmap 2.14.0", "semver 1.0.27", ] @@ -4577,6 +5890,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi-util" version = "0.1.11" @@ -4586,6 +5918,18 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "wincode" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfc6339f1ba427bf7ad7c42403b28e524832ba2ddb5eef1bb2cc3b85db6b7b75" +dependencies = [ + "pastey", + "proc-macro2", + "quote", + "thiserror", +] + [[package]] name = "windows" version = "0.61.3" @@ -4901,6 +6245,9 @@ name = "winnow" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" +dependencies = [ + "memchr", +] [[package]] name = "wit-bindgen" @@ -4936,7 +6283,7 @@ checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", "heck", - "indexmap", + "indexmap 2.14.0", "prettyplease", "syn 2.0.115", "wasm-metadata", @@ -4967,7 +6314,7 @@ checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", "bitflags", - "indexmap", + "indexmap 2.14.0", "log", "serde", "serde_derive", @@ -4986,7 +6333,7 @@ checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" dependencies = [ "anyhow", "id-arena", - "indexmap", + "indexmap 2.14.0", "log", "semver 1.0.27", "serde", @@ -4996,14 +6343,63 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "wnaf" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab12e7090f27e2ffd9322651492942d50c2926094af30601e1964337db39daf1" +dependencies = [ + "ff", + "group", + "hybrid-array", +] + +[[package]] +name = "writeable" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "x25519-dalek" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +checksum = "e7e8131a03190127fb2263afc72b322ecadae46b6ff8c6f399ff5d02f5559af6" dependencies = [ "curve25519-dalek", - "rand_core 0.6.4", + "rand_core 0.10.0", +] + +[[package]] +name = "yoke" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", + "synstructure", ] [[package]] @@ -5026,8 +6422,76 @@ dependencies = [ "syn 2.0.115", ] +[[package]] +name = "zerofrom" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", + "synstructure", +] + [[package]] name = "zeroize" version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.115", +] + +[[package]] +name = "zerotrie" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] diff --git a/docs/Cargo.toml b/docs/Cargo.toml index d95f3098..0dab8cf9 100644 --- a/docs/Cargo.toml +++ b/docs/Cargo.toml @@ -4,8 +4,9 @@ version = "0.1.0" edition = "2021" [dependencies] -miden-client = { version = "0.15", features = ["testing", "tonic"] } -miden-client-sqlite-store = { version = "0.15", package = "miden-client-sqlite-store" } -miden-protocol = { version = "0.15" } -rand = { version = "0.9" } +miden-client = { version = "=0.16.0", features = ["testing", "tonic"] } +miden-client-sqlite-store = { version = "=0.16.0", package = "miden-client-sqlite-store" } +miden-protocol = { version = "=0.16.0" } +rust-client = { path = "../rust-client" } +rand = { version = "0.10" } tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } diff --git a/docs/src/miden_node_setup.md b/docs/src/miden_node_setup.md index 281c4fd7..65bc8c89 100644 --- a/docs/src/miden_node_setup.md +++ b/docs/src/miden_node_setup.md @@ -5,17 +5,27 @@ sidebar_position: 2 # Miden Node Setup Tutorial -To run the Miden tutorial examples, you connect to a Miden node. By default, **every tutorial in this book targets the public Miden testnet** — no local setup is required. If you would rather run against your own node, you can start a local network instead. +The v0.16 client tutorials connect to public Miden testnet by default, so no local +node is required. You can also configure them to use your own network. -## Connecting to the Miden testnet +## Connecting to the public networks -The tutorials use the public testnet by default. Its RPC endpoint is: +The testnet RPC endpoint is: + +```text +https://rpc.testnet.miden.io +``` + +Use `Endpoint::testnet()` in Rust or `MidenClient.createTestnet()` in the web SDK. +The tutorial runner selects testnet by default: ```bash -https://rpc.testnet.miden.io:443 +yarn tutorials ``` -This is the endpoint the examples pass to the client (`Endpoint::testnet()` in the Rust client), so they work out of the box with no additional setup. +Testnet transactions pay fees in the native asset. The examples fund new accounts +from the public faucet before their first transaction. Use fresh local stores and +reassemble MASM sources when migrating from an earlier release. ## Running a local network @@ -25,4 +35,6 @@ Running against a local network is optional and only needed for a fully self-hos Network transactions additionally require the **network transaction builder** (`miden-ntx-builder`), the component that executes network notes on an account's behalf. The local-network setup linked above provisions it; a node without the builder will commit network notes but never execute them. -Once your local network is running, point the tutorials at its RPC endpoint instead of `Endpoint::testnet()`. +To use a local network, update the client's RPC endpoint and its address, native +asset, and faucet configuration to match that deployment. The runner's +`TUTORIAL_NETWORK` option accepts only `testnet` and `devnet`, not a local RPC URL. diff --git a/docs/src/rust-client/counter_contract_tutorial.md b/docs/src/rust-client/counter_contract_tutorial.md index d5052bf6..788f6669 100644 --- a/docs/src/rust-client/counter_contract_tutorial.md +++ b/docs/src/rust-client/counter_contract_tutorial.md @@ -7,9 +7,11 @@ sidebar_position: 4 _Using the Miden client in Rust to deploy and interact with a custom smart contract on Miden_ +For toolchain requirements and shared fee helpers, see the [Rust client setup](./index.md#running-the-v016-examples). + ## Overview -In this tutorial, we will build a simple counter smart contract that maintains a count, deploy it to the Miden testnet, and interact with it by incrementing the count. You can also deploy the counter contract on a locally running Miden node, similar to previous tutorials. +In this tutorial, we will build a simple counter smart contract that maintains a count, deploy it to Miden testnet, and interact with it by incrementing the count. Using a script, we will invoke the increment function within the counter contract to update the count. This tutorial provides a foundational understanding of developing and deploying custom smart contracts on Miden. @@ -18,7 +20,7 @@ Using a script, we will invoke the increment function within the counter contrac - Deploying a custom smart contract on Miden - Getting up to speed with the basics of Miden assembly - Calling procedures in an account -- Pure vs state changing procedures +- Read-only vs state-changing procedures ## Prerequisites @@ -26,55 +28,66 @@ This tutorial assumes you have a basic understanding of Miden assembly. To quick ## Step 1: Initialize your repository -Create a new Rust repository for your Miden project and navigate to it with the following command: +From the parent directory of your `tutorials` clone, create a sibling Cargo project: ```bash cargo new miden-counter-contract cd miden-counter-contract +rustup override set 1.98.1 +cp ../tutorials/rust-client/Cargo.lock Cargo.lock ``` Add the following dependencies to your `Cargo.toml` file: ```toml [dependencies] -miden-client = { version = "0.15", features = ["testing", "tonic"] } -miden-client-sqlite-store = { version = "0.15", package = "miden-client-sqlite-store" } -miden-protocol = { version = "0.15" } -rand = { version = "0.9" } -tokio = { version = "1.46", features = ["rt-multi-thread", "net", "macros", "fs"] } +# Clone tutorials next to this Cargo project (see Rust client setup). +rust-client = { path = "../tutorials/rust-client" } +miden-client = { version = "=0.16.0", features = ["testing", "tonic"] } +miden-client-sqlite-store = { version = "=0.16.0", package = "miden-client-sqlite-store" } +miden-protocol = { version = "=0.16.0" } +rand = { version = "0.10" } +tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } + +[profile.dev] +opt-level = 2 ``` ### Set up your `src/main.rs` file -In the previous section, we explained how to instantiate the Miden client. We can reuse the same `initialize_client` function for our counter contract. +In the previous section, we explained how to instantiate the Miden client. We reuse that client setup and the shared fee helpers for our counter contract. Copy and paste the following code into your `src/main.rs` file: ```rust no_run -use rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; use miden_client::{ + ClientError, Word, account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, - AccountType, StorageSlot, StorageSlotName, + AccountBuilder, AccountComponent, AccountType, StorageSlot, StorageSlotName, + component::{AccountComponentMetadata, BasicWallet}, }, - address::NetworkId, auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, - rpc::{Endpoint, GrpcClient}, + rpc::{GrpcClient, VerifyingRpcClient}, transaction::TransactionRequestBuilder, - ClientError, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::{FeeConfig, TutorialNetwork, fund_account_for_fees}; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -86,12 +99,12 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; Ok(()) } @@ -103,35 +116,20 @@ _When running the code above, there will be some unused imports, however, we wil ## Step 2: Build the counter contract -For better code organization, we will separate the Miden assembly code from our Rust code. - -Create a directory named `masm` at the **root** of your `miden-counter-contract` directory. This will contain our contract and script masm code. - -Initialize the `masm` directory: - -```bash -mkdir -p masm/accounts masm/scripts -``` - -This will create: - -```text -masm/ -├── accounts/ -└── scripts/ -``` +The account and transaction-script sources are already in the repository. We examine them below before compiling them from Rust. ### Custom Miden smart contract -Below is our counter contract. It has a two exported procedures: `get_count` and `increment_count`. +Below is our counter contract. It has two exported procedures: `get_count` and `increment_count`. At the beginning of the MASM file, we define our imports. In this case, we import -`miden::protocol::active_account`, `miden::protocol::native_account`, `miden::core::word`, and +`miden::protocol::active_account`, `miden::protocol::native_account`, and `miden::core::sys`. The `miden::protocol::active_account` and `miden::protocol::native_account` modules contain -procedures for reading and writing contract state. We use `miden::core::word` to convert the slot -name into a slot ID for the account storage APIs. +procedures for reading and writing contract state. The compile-time expression +`word("miden::tutorials::counter")` derives the named storage slot's ID; `[0..2]` +selects the two elements used by the account storage APIs. The import `miden::core::sys` contains a useful procedure for truncating the operand stack at the end of a procedure. @@ -152,51 +150,68 @@ end of a procedure. 4. Adds `1` to the count value returned from `active_account::get_item`. 5. Pushes the slot ID prefix and suffix again so we can write the updated count. 6. Calls `native_account::set_item` which saves the incremented count to storage. -7. Calls `sys::truncate_stack` to clean up the stack. +7. Drops the old storage word returned by `set_item`, then calls `sys::truncate_stack` to clean up the stack. -Inside of the `masm/accounts/` directory, create the `counter.masm` file: +The counter is defined in `masm/accounts/counter.masm`: ```masm use miden::protocol::active_account use miden::protocol::native_account -use miden::core::word use miden::core::sys +# CONSTANTS +# ================================================================================================= + const COUNTER_SLOT = word("miden::tutorials::counter") -#! Inputs: [] -#! Outputs: [count] -pub proc get_count +# PUBLIC INTERFACE +# ================================================================================================= + +#! Returns the current count. +#! +#! Inputs: [pad(16)] +#! Outputs: [count, pad(15)] +#! +#! Invocation: call +@account_procedure +pub proc get_count() -> felt push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] exec.sys::truncate_stack - # => [count] + # => [count, pad(15)] end -#! Inputs: [] -#! Outputs: [] -pub proc increment_count +#! Increments the current count by one. +#! +#! Inputs: [pad(16)] +#! Outputs: [pad(16)] +#! +#! Invocation: call +@account_procedure +pub proc increment_count() push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] add.1 - # => [count+1] + # => [[count + 1, 0, 0, 0], pad(16)] push.COUNTER_SLOT[0..2] exec.native_account::set_item - # => [] + # => [OLD_VALUE, pad(16)] + + dropw + # => [pad(16)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end - ``` **Note**: _It's a good habit to add comments below each line of MASM code with the expected stack state. This improves readability and helps with debugging._ ### Authentication Component -**Important**: Starting with Miden Client 0.10.0, all accounts must have an authentication component. For smart contracts that don't require authentication (like our counter contract), we use a `NoAuth` component. +Accounts require an authentication component. This public counter deliberately uses `NoAuth`, which pays transaction fees from the account's native-asset balance and updates its nonce without verifying a signature. This `NoAuth` component allows any user to interact with the smart contract without requiring signature verification. @@ -204,21 +219,35 @@ This `NoAuth` component allows any user to interact with the smart contract with This is a Miden assembly script that will call the `increment_count` procedure during the transaction. -The string `{increment_count}` will be replaced with the hash of the `increment_count` procedure in our rust program. +The Rust code links the counter module as `external_contract::counter_contract`, so the script can call `counter_contract::increment_count` by name. -Inside of the `masm/scripts/` directory, create the `counter_script.masm` file: +The transaction script is defined in `masm/scripts/counter_script.masm`: ```masm use external_contract::counter_contract -begin +#! Increments the counter. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) + dropw + # => [pad(16)] + call.counter_contract::increment_count + # => [pad(16)] end ``` ## Step 3: Build the counter smart contract -To build the counter contract copy and paste the following code at the end of your `src/main.rs` file: +To build the counter contract, insert the following code inside `main`, immediately before its final `Ok(())`: ```rust ignore // ------------------------------------------------------------------------- @@ -226,21 +255,22 @@ 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. `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"); +// Read the MASM source from the tutorials repository. +let counter_code = std::fs::read_to_string("../tutorials/masm/accounts/counter.masm").unwrap(); // 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 = client .code_builder() - .compile_component_code("external_contract::counter_contract", counter_code) + .compile_component_code("external_contract::counter_contract", &counter_code) .unwrap(); let counter_component = AccountComponent::new( component_code, - vec![StorageSlot::with_value(counter_slot_name.clone(), Word::default())], + vec![StorageSlot::with_value( + counter_slot_name.clone(), + Word::default(), + )], AccountComponentMetadata::new("external_contract::counter_contract"), ) .unwrap(); @@ -253,7 +283,8 @@ client.rng().fill_bytes(&mut seed); let counter_contract = AccountBuilder::new(seed) .account_type(AccountType::Public) .with_component(counter_component.clone()) - .with_auth_component(NoAuth) + .with_component(BasicWallet) + .with_component(NoAuth) .build() .unwrap(); @@ -265,28 +296,31 @@ println!("counter_contract id: {:?}", counter_contract.id()); println!("counter_contract storage: {:?}", counter_contract.storage()); client.add_account(&counter_contract, false).await.unwrap(); +fund_account_for_fees(&mut client, counter_contract.id(), &fee_config).await?; ``` Run the following command to execute `src/main.rs`: ```bash -cargo run --release +TUTORIAL_NETWORK=testnet cargo run --release ``` -After the program executes, you should see the counter contract hash and contract id printed to the terminal, for example: +After the program executes, it prints the initial account commitment, ID, and storage. Abridged output looks like this; generated values vary: ```text [STEP 1] Creating counter contract. -counter_contract commitment: RpoDigest([3700134472268167470, 14878091556015233722, 3335592073702485043, 16978997897830363420]) -counter_contract id: "" -counter_contract storage: AccountStorage { slots: [Value([0, 0, 0, 0]), Value([0, 0, 0, 0])] } +counter_contract commitment: Word([...]) +counter_contract id: V1(AccountIdV1 { suffix: ..., prefix: ... }) +counter_contract storage: AccountStorage { slots: [StorageSlot { ... content: Value(Word([0, 0, 0, 0])) }] } ``` +The funding helper then consumes a native-asset note and waits for confirmation. That first transaction publishes the account without incrementing its counter. + ## Step 4: Incrementing the count -Now that we built the counter contract, lets create a transaction request to increment the count: +Now that we have built and funded the counter contract, let's create a transaction request to increment the count: -Paste the following code at the end of your `src/main.rs` file: +Insert the following code after the previous step, still inside `main` and before `Ok(())`: ```rust ignore // ------------------------------------------------------------------------- @@ -295,15 +329,16 @@ 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_code = include_str!("../masm/scripts/counter_script.masm"); +let script_code = + std::fs::read_to_string("../tutorials/masm/scripts/counter_script.masm").unwrap(); // Compile the script with the counter contract code linked as a module // on the same `CodeBuilder` chain. let tx_script = client .code_builder() - .with_linked_module("external_contract::counter_contract", counter_code) + .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 @@ -314,18 +349,19 @@ let tx_increment_request = TransactionRequestBuilder::new() // Execute and submit the transaction let tx_id = client - .submit_new_transaction(counter_contract.id(), tx_increment_request) + .submit_tutorial_transaction(counter_contract.id(), tx_increment_request) .await .unwrap(); println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); println!( "Counter contract id: {:?}", - counter_contract.id().to_bech32(NetworkId::Testnet) + counter_contract.id().to_bech32(network.network_id()) ); client.sync_state().await.unwrap(); @@ -340,39 +376,48 @@ println!( "counter contract storage: {:?}", account.storage().get_item(&counter_slot_name) ); +assert_eq!( + account.storage().get_item(&counter_slot_name).unwrap()[0].as_canonical_u64(), + 1, + "the deployed counter must increment from zero to one", +); ``` -**Note**: _Once our counter contract is deployed, other users can increment the count of the smart contract simply by knowing the account id of the contract and the procedure hash of the `increment_count` procedure._ +Because this counter uses `NoAuth`, another client can import its public state and execute the same increment script. Public visibility alone does not grant that permission; the account's authentication component does. ## Summary The final `src/main.rs` file should look like this: ```rust no_run -use rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; use miden_client::{ + ClientError, Word, account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, - AccountType, StorageSlot, StorageSlotName, + AccountBuilder, AccountComponent, AccountType, StorageSlot, StorageSlotName, + component::{AccountComponentMetadata, BasicWallet}, }, - address::NetworkId, auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, - rpc::{Endpoint, GrpcClient}, + rpc::{GrpcClient, VerifyingRpcClient}, transaction::TransactionRequestBuilder, - ClientError, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::{FeeConfig, TutorialNetwork, fund_account_for_fees}; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -384,33 +429,34 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; // ------------------------------------------------------------------------- // STEP 1: Create a basic counter contract // ------------------------------------------------------------------------- println!("\n[STEP 1] Creating counter contract."); - // 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"); + // Read the MASM source from the tutorials repository. + let counter_code = std::fs::read_to_string("../tutorials/masm/accounts/counter.masm").unwrap(); // 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 = client .code_builder() - .compile_component_code("external_contract::counter_contract", counter_code) + .compile_component_code("external_contract::counter_contract", &counter_code) .unwrap(); let counter_component = AccountComponent::new( component_code, - vec![StorageSlot::with_value(counter_slot_name.clone(), Word::default())], + vec![StorageSlot::with_value( + counter_slot_name.clone(), + Word::default(), + )], AccountComponentMetadata::new("external_contract::counter_contract"), ) .unwrap(); @@ -423,7 +469,8 @@ async fn main() -> Result<(), ClientError> { let counter_contract = AccountBuilder::new(seed) .account_type(AccountType::Public) .with_component(counter_component.clone()) - .with_auth_component(NoAuth) + .with_component(BasicWallet) + .with_component(NoAuth) .build() .unwrap(); @@ -435,6 +482,7 @@ async fn main() -> Result<(), ClientError> { println!("counter_contract storage: {:?}", counter_contract.storage()); client.add_account(&counter_contract, false).await.unwrap(); + fund_account_for_fees(&mut client, counter_contract.id(), &fee_config).await?; // ------------------------------------------------------------------------- // STEP 2: Call the Counter Contract with a script @@ -442,15 +490,16 @@ async fn main() -> Result<(), ClientError> { println!("\n[STEP 2] Call Counter Contract With Script"); // Load the MASM script referencing the increment procedure - let script_code = include_str!("../masm/scripts/counter_script.masm"); + let script_code = + std::fs::read_to_string("../tutorials/masm/scripts/counter_script.masm").unwrap(); // Compile the script with the counter contract code linked as a module // on the same `CodeBuilder` chain. let tx_script = client .code_builder() - .with_linked_module("external_contract::counter_contract", counter_code) + .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 @@ -461,18 +510,19 @@ async fn main() -> Result<(), ClientError> { // Execute and submit the transaction let tx_id = client - .submit_new_transaction(counter_contract.id(), tx_increment_request) + .submit_tutorial_transaction(counter_contract.id(), tx_increment_request) .await .unwrap(); println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); println!( "Counter contract id: {:?}", - counter_contract.id().to_bech32(NetworkId::Testnet) + counter_contract.id().to_bech32(network.network_id()) ); client.sync_state().await.unwrap(); @@ -487,62 +537,41 @@ async fn main() -> Result<(), ClientError> { "counter contract storage: {:?}", account.storage().get_item(&counter_slot_name) ); + assert_eq!( + account.storage().get_item(&counter_slot_name).unwrap()[0].as_canonical_u64(), + 1, + "the deployed counter must increment from zero to one", + ); Ok(()) } ``` -The output of our program will look something like this: +Successful output includes the following lines (abridged; generated values vary): ```text -Latest block: 374255 +Latest block: [STEP 1] Creating counter contract. -one or more warnings were emitted -counter_contract commitment: Word([3964727668949550262, 4265714847747507878, 5784293172192015964, 16803438753763367241]) -counter_contract id: "" -counter_contract storage: AccountStorage { slots: [Value(Word([0, 0, 0, 0]))] } +counter_contract commitment: Word([...]) +counter_contract id: V1(AccountIdV1 { suffix: ..., prefix: ... }) +counter_contract storage: AccountStorage { slots: [StorageSlot { ... content: Value(Word([0, 0, 0, 0])) }] } [STEP 2] Call Counter Contract With Script -Stack state before step 2610: -├── 0: 1 -├── 1: 0 -├── 2: 0 -├── 3: 0 -├── 4: 0 -├── 5: 0 -├── 6: 0 -├── 7: 0 -├── 8: 0 -├── 9: 0 -├── 10: 0 -├── 11: 0 -├── 12: 0 -├── 13: 0 -├── 14: 0 -├── 15: 0 -├── 16: 0 -├── 17: 0 -├── 18: 0 -└── 19: 0 - -└── (0 more items) - -View transaction on MidenScan: https://testnet.midenscan.com/tx/0x9767940bbed7bd3a74c24dc43f1ea8fe90a876dc7925621c217f648c63c4ab7a -counter contract storage: Ok(Word([0, 0, 0, 1])) +View transaction on MidenScan: https://testnet.midenscan.com/tx/ +Counter contract id: "" +counter contract storage: Ok(Word([1, 0, 0, 0])) ``` -The line in the output `Stack state before step 2505` ouputs the stack state when we call "debug.stack" in the `counter.masm` file. - -To increment the count of the counter contract all you need is to know the account id of the counter and the procedure hash of the `increment_count` procedure. To increment the count without deploying the counter each time, you can modify the program above to hardcode the account id of the counter and the procedure hash of the `increment_count` prodedure in the masm script. +To increment the contract again without redeploying it, pass the printed testnet account ID to the [public-account interaction tutorial](./public_account_interaction_tutorial.md). Keeping the ID as an input avoids hard-coding an address that becomes invalid after a testnet reset. ### Running the example -To run the full example, navigate to the `rust-client` directory in the [miden-tutorials](https://github.com/0xMiden/miden-tutorials/) repository and run this command: +To run the checked-in example, return to the root of the [tutorials repository](https://github.com/0xMiden/tutorials/) and run: ```bash cd rust-client -cargo run --release --bin counter_contract_deploy +TUTORIAL_NETWORK=testnet cargo run --release --bin counter_contract_deploy ``` ### Continue learning diff --git a/docs/src/rust-client/create_deploy_tutorial.md b/docs/src/rust-client/create_deploy_tutorial.md index 2876f6a0..c5397462 100644 --- a/docs/src/rust-client/create_deploy_tutorial.md +++ b/docs/src/rust-client/create_deploy_tutorial.md @@ -7,6 +7,8 @@ sidebar_position: 2 _Using the Miden client in Rust to create accounts and deploy faucets_ +For toolchain requirements and shared fee helpers, see the [Rust client setup](./index.md#running-the-v016-examples). + ## Overview In this tutorial, we will create a Miden account for _Alice_ and deploy a fungible faucet. In the next section, we will mint tokens from the faucet to fund her account and transfer tokens from Alice's account to other Miden accounts. @@ -20,39 +22,46 @@ In this tutorial, we will create a Miden account for _Alice_ and deploy a fungib ## Prerequisites -Before you begin, ensure that a Miden node is running locally in a separate terminal window. To get the Miden node running locally, you can follow the instructions on the [Miden Node Setup](../miden_node_setup.md) page. +The commands in this guide select the public testnet explicitly. If you change the endpoint to a local node, start that node first by following [Miden Node Setup](../miden_node_setup.md). ## Public vs. private accounts & notes Before diving into coding, let's clarify the concepts of public and private accounts & notes on Miden: - Public accounts: The account's data and code are stored on-chain and are openly visible, including its assets. -- Private accounts: The account's state and logic are off-chain, only known to its owner. +- Private accounts: Only a commitment to the account state is stored on-chain. The owner keeps the full state locally and may share it with others. - Public notes: The note's state is visible to anyone - perfect for scenarios where transparency is desired. - Private notes: The note's state is stored off-chain, you will need to share the note data with the relevant parties (via email or Telegram) for them to be able to consume the note. Note: _The term "account" can be used interchangeably with the term "smart contract" since account abstraction on Miden is handled natively._ -_It is useful to think of notes on Miden as "cryptographic cashier's checks" that allow users to send tokens. If the note is private, the note transfer is only known to the sender and receiver._ +_It is useful to think of notes on Miden as "cryptographic cashier's checks" that allow users to send tokens. Private note details must be shared with the recipient; the chain still records the note commitment and its eventual nullifier._ ## Step 1: Initialize your repository -Create a new Rust repository for your Miden project and navigate to it with the following command: +Start in the directory containing your `tutorials` clone and create a sibling Cargo project. The dependency path below assumes the clone is named `tutorials`. ```bash cargo new miden-rust-client cd miden-rust-client +rustup override set 1.98.1 +cp ../tutorials/rust-client/Cargo.lock Cargo.lock ``` -Add the following dependencies to your `Cargo.toml` file: +Keep the generated `[package]` section in `Cargo.toml`, replace its empty `[dependencies]` section with the following, and add the development profile: ```toml [dependencies] -miden-client = { version = "0.15", features = ["testing", "tonic"] } -miden-client-sqlite-store = { version = "0.15", package = "miden-client-sqlite-store" } -miden-protocol = { version = "0.15" } -rand = { version = "0.9" } -tokio = { version = "1.46", features = ["rt-multi-thread", "net", "macros", "fs"] } +# Clone tutorials next to this Cargo project (see Rust client setup). +rust-client = { path = "../tutorials/rust-client" } +miden-client = { version = "=0.16.0", features = ["testing", "tonic"] } +miden-client-sqlite-store = { version = "=0.16.0", package = "miden-client-sqlite-store" } +miden-protocol = { version = "=0.16.0" } +rand = { version = "0.10" } +tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } + +[profile.dev] +opt-level = 2 ``` ## Step 2: Initialize the client @@ -67,41 +76,41 @@ Before interacting with the Miden network, we must instantiate the client. In th 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 rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; use tokio::time::Duration; use miden_client::{ + ClientError, account::{ + AccountBuilder, AccountId, AccountType, component::{ - BasicWallet, BurnPolicyConfig, FungibleFaucet, MintPolicyConfig, PolicyRegistration, - TokenName, TokenPolicyManager, + create_singlesig_user_fungible_faucet, BasicWallet, BurnPolicy, FungibleFaucet, + MintPolicy, TokenName, TokenPolicyManager, }, - AccountId, }, - address::NetworkId, - auth::AuthSecretKey, + asset::{AssetAmount, AssetCallbackFlag, AssetId, FungibleAsset, TokenSymbol}, + auth::{AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, - keystore::FilesystemKeyStore, - note::{NoteAttachments, NoteType, P2idNote}, - rpc::{Endpoint, GrpcClient}, - transaction::TransactionRequestBuilder, - ClientError, + keystore::{FilesystemKeyStore, Keystore}, + note::{Note, NoteType, P2idNote}, + rpc::{GrpcClient, VerifyingRpcClient}, + transaction::{PaymentNoteDescription, TransactionRequestBuilder}, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; use miden_protocol::account::AccountIdVersion; -use miden_client::{ - account::{AccountBuilder, AccountType}, - asset::{AssetAmount, FungibleAsset, TokenSymbol}, -}; +use rust_client::{FeeConfig, TutorialNetwork, fund_account_for_fees}; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -113,12 +122,12 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; Ok(()) } @@ -131,24 +140,24 @@ _When running the code above, there will be some unused imports, however, we wil Run the following command to execute `src/main.rs`: ```bash -cargo run --release +TUTORIAL_NETWORK=testnet cargo run --release ``` After the program executes, you should see the latest block number printed to the terminal, for example: ```text -Latest block number: 3855 +Latest block: ``` ## Step 3: Creating a wallet Now that we've initialized the client, we can create a wallet for Alice. -To create a wallet for Alice using the Miden client, we specify whether the account is public or private via `AccountType` (in v0.15 the account type is simply `AccountType::Public` or `AccountType::Private`). A wallet on Miden is simply an account with standardized code. +To create a wallet for Alice using the Miden client, we select `AccountType::Public` or `AccountType::Private`. A wallet on Miden is simply an account with standardized code. In the example below we create a public account for Alice. -Add this snippet to the end of your file in the `main()` function: +Insert this snippet inside `main()`, immediately before its final `Ok(())`: ```rust ignore //------------------------------------------------------------ @@ -165,7 +174,7 @@ let key_pair = AuthSecretKey::new_falcon512_poseidon2_with_rng(client.rng()); // Build the account let alice_account = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet) .build() .unwrap(); @@ -174,20 +183,24 @@ let alice_account = AccountBuilder::new(init_seed) client.add_account(&alice_account, false).await?; // Add the key pair to the keystore -use miden_client::keystore::Keystore; -keystore.add_key(&key_pair, alice_account.id()).await.unwrap(); +keystore + .add_key(&key_pair, alice_account.id()) + .await + .unwrap(); -let alice_account_id_bech32 = alice_account.id().to_bech32(NetworkId::Testnet); +let alice_account_id_bech32 = alice_account.id().to_bech32(network.network_id()); println!("Alice's account ID: {:?}", alice_account_id_bech32); + +fund_account_for_fees(&mut client, alice_account.id(), &fee_config).await?; ``` ## Step 4: Deploying a fungible faucet -To provide Alice with testnet assets, we must first deploy a faucet. A faucet account on Miden mints fungible tokens. +To provide Alice with the tutorial's `MID` asset, we first deploy a faucet. This is separate from the public testnet faucet that supplies the native asset used to pay transaction fees. A faucet account on Miden mints its own fungible token. -We'll create a public faucet with a token symbol, decimals, and a max supply. We will use this faucet to mint tokens to Alice's account in the next section. +We'll create a public faucet with a token symbol, decimals, and a max supply. Amounts in these examples are raw units: with eight decimals, `100` units means `0.000001 MID`. The faucet's maximum supply is `1_000_000` raw units. We will use it to mint tokens to Alice's account in the next section. -Add this snippet to the end of your file in the `main()` function: +Insert this snippet inside `main()`, immediately before its final `Ok(())`: ```rust ignore //------------------------------------------------------------ @@ -208,46 +221,51 @@ let max_supply = AssetAmount::new(1_000_000).unwrap(); let key_pair = AuthSecretKey::new_falcon512_poseidon2_with_rng(client.rng()); // Build the faucet account. -// In v0.15 the faucet is a `FungibleFaucet` component plus a `TokenPolicyManager` +// The faucet is a `FungibleFaucet` component plus a `TokenPolicyManager` // that registers an "allow all" mint (and burn) policy; minting is rejected // unless an active mint policy is present. -let faucet_account = AccountBuilder::new(init_seed) - .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) - .with_component( - FungibleFaucet::builder() - .name(TokenName::new("MID").unwrap()) - .symbol(symbol) - .decimals(decimals) - .max_supply(max_supply) - .build() - .unwrap(), - ) - .with_components( - TokenPolicyManager::new() - .with_mint_policy(MintPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap() - .with_burn_policy(BurnPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap(), - ) +let faucet = FungibleFaucet::builder() + .name(TokenName::new("MID").unwrap()) + .symbol(symbol) + .decimals(decimals) + .max_supply(max_supply) .build() .unwrap(); +let policies = TokenPolicyManager::builder() + .active_mint_policy(MintPolicy::allow_all()) + .active_burn_policy(BurnPolicy::allow_all()) + .build(); +// The SDK factory includes BasicWallet so the faucet can receive the native fee asset. +let faucet_account = create_singlesig_user_fungible_faucet( + init_seed, + faucet, + AuthSingleSig::from_public_key(key_pair.public_key()), + policies, + AccountType::Public, +) +.unwrap(); // Add the faucet to the client client.add_account(&faucet_account, false).await?; // Add the key pair to the keystore -use miden_client::keystore::Keystore; -keystore.add_key(&key_pair, faucet_account.id()).await.unwrap(); +keystore + .add_key(&key_pair, faucet_account.id()) + .await + .unwrap(); -let faucet_account_id_bech32 = faucet_account.id().to_bech32(NetworkId::Testnet); +let faucet_account_id_bech32 = faucet_account.id().to_bech32(network.network_id()); println!("Faucet account ID: {:?}", faucet_account_id_bech32); +fund_account_for_fees(&mut client, faucet_account.id(), &fee_config).await?; + // Resync to show newly deployed faucet client.sync_state().await?; tokio::time::sleep(Duration::from_secs(2)).await; ``` +`client.add_account` registers each new account locally. `fund_account_for_fees` then consumes a native-asset funding note; this first confirmed transaction deploys the account and gives it a fee balance. + _When tokens are minted from this faucet, each token batch is represented as a "note" (UTXO). You can think of a Miden Note as a cryptographic cashier's check that has certain spend conditions attached to it._ ## Summary @@ -255,41 +273,41 @@ _When tokens are minted from this faucet, each token batch is represented as a " 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 rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; use tokio::time::Duration; use miden_client::{ + ClientError, account::{ + AccountBuilder, AccountId, AccountType, component::{ - BasicWallet, BurnPolicyConfig, FungibleFaucet, MintPolicyConfig, PolicyRegistration, - TokenName, TokenPolicyManager, + create_singlesig_user_fungible_faucet, BasicWallet, BurnPolicy, FungibleFaucet, + MintPolicy, TokenName, TokenPolicyManager, }, - AccountId, }, - address::NetworkId, - auth::AuthSecretKey, + asset::{AssetAmount, AssetCallbackFlag, AssetId, FungibleAsset, TokenSymbol}, + auth::{AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, keystore::{FilesystemKeyStore, Keystore}, - note::{NoteAttachments, NoteType, P2idNote}, - rpc::{Endpoint, GrpcClient}, - transaction::TransactionRequestBuilder, - ClientError, + note::{Note, NoteType, P2idNote}, + rpc::{GrpcClient, VerifyingRpcClient}, + transaction::{PaymentNoteDescription, TransactionRequestBuilder}, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; use miden_protocol::account::AccountIdVersion; -use miden_client::{ - account::{AccountBuilder, AccountType}, - asset::{AssetAmount, FungibleAsset, TokenSymbol}, -}; +use rust_client::{FeeConfig, TutorialNetwork, fund_account_for_fees}; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -301,12 +319,12 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; //------------------------------------------------------------ // STEP 1: Create a basic wallet for Alice @@ -322,7 +340,7 @@ async fn main() -> Result<(), ClientError> { // Build the account let alice_account = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet) .build() .unwrap(); @@ -331,11 +349,16 @@ async fn main() -> Result<(), ClientError> { client.add_account(&alice_account, false).await?; // Add the key pair to the keystore - keystore.add_key(&key_pair, alice_account.id()).await.unwrap(); + keystore + .add_key(&key_pair, alice_account.id()) + .await + .unwrap(); - let alice_account_id_bech32 = alice_account.id().to_bech32(NetworkId::Testnet); + let alice_account_id_bech32 = alice_account.id().to_bech32(network.network_id()); println!("Alice's account ID: {:?}", alice_account_id_bech32); + fund_account_for_fees(&mut client, alice_account.id(), &fee_config).await?; + //------------------------------------------------------------ // STEP 2: Deploy a fungible faucet //------------------------------------------------------------ @@ -354,40 +377,44 @@ async fn main() -> Result<(), ClientError> { let key_pair = AuthSecretKey::new_falcon512_poseidon2_with_rng(client.rng()); // Build the faucet account. - // In v0.15 the faucet is a `FungibleFaucet` component plus a `TokenPolicyManager` + // The faucet is a `FungibleFaucet` component plus a `TokenPolicyManager` // that registers an "allow all" mint (and burn) policy; minting is rejected // unless an active mint policy is present. - let faucet_account = AccountBuilder::new(init_seed) - .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) - .with_component( - FungibleFaucet::builder() - .name(TokenName::new("MID").unwrap()) - .symbol(symbol) - .decimals(decimals) - .max_supply(max_supply) - .build() - .unwrap(), - ) - .with_components( - TokenPolicyManager::new() - .with_mint_policy(MintPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap() - .with_burn_policy(BurnPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap(), - ) + let faucet = FungibleFaucet::builder() + .name(TokenName::new("MID").unwrap()) + .symbol(symbol) + .decimals(decimals) + .max_supply(max_supply) .build() .unwrap(); + let policies = TokenPolicyManager::builder() + .active_mint_policy(MintPolicy::allow_all()) + .active_burn_policy(BurnPolicy::allow_all()) + .build(); + // The SDK factory includes BasicWallet so the faucet can receive the native fee asset. + let faucet_account = create_singlesig_user_fungible_faucet( + init_seed, + faucet, + AuthSingleSig::from_public_key(key_pair.public_key()), + policies, + AccountType::Public, + ) + .unwrap(); // Add the faucet to the client client.add_account(&faucet_account, false).await?; // Add the key pair to the keystore - keystore.add_key(&key_pair, faucet_account.id()).await.unwrap(); + keystore + .add_key(&key_pair, faucet_account.id()) + .await + .unwrap(); - let faucet_account_id_bech32 = faucet_account.id().to_bech32(NetworkId::Testnet); + let faucet_account_id_bech32 = faucet_account.id().to_bech32(network.network_id()); println!("Faucet account ID: {:?}", faucet_account_id_bech32); + fund_account_for_fees(&mut client, faucet_account.id(), &fee_config).await?; + // Resync to show newly deployed faucet client.sync_state().await?; tokio::time::sleep(Duration::from_secs(2)).await; @@ -399,19 +426,19 @@ async fn main() -> Result<(), ClientError> { Let's run the `src/main.rs` program again: ```bash -cargo run --release +TUTORIAL_NETWORK=testnet cargo run --release ``` -The output will look like this: +The following is an abbreviated output; account IDs and block numbers vary, and the funding helper also prints transaction confirmations: ```text -Latest block: 17771 +Latest block: [STEP 1] Creating a new account for Alice -Alice's account ID: "0x3cb3e596d14ad410000017901eaa7b" +Alice's account ID: "" [STEP 2] Deploying a new fungible faucet. -Faucet account ID: "0x6ad1894ac233e4200000088311bb6b" +Faucet account ID: "" ``` In this section we explained how to instantiate the Miden client, create a wallet account, and deploy a faucet. @@ -420,11 +447,11 @@ In the next section we will cover how to mint tokens from the faucet, consume no ### Running the example -To run a full working example navigate to the `rust-client` directory in the [miden-tutorials](https://github.com/0xMiden/miden-tutorials/) repository and run this command: +From the root of your `tutorials` clone, run the checked-in example: ```bash cd rust-client -cargo run --release --bin create_mint_consume_send +TUTORIAL_NETWORK=testnet cargo run --release --bin create_mint_consume_send ``` ### Continue learning 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 a168a079..29fad3b7 100644 --- a/docs/src/rust-client/creating_notes_in_masm_tutorial.md +++ b/docs/src/rust-client/creating_notes_in_masm_tutorial.md @@ -7,13 +7,15 @@ sidebar_position: 11 _Creating notes inside the MidenVM using Miden assembly_ +For toolchain requirements and shared fee helpers, see the [Rust client setup](./index.md#running-the-v016-examples). + ## Overview In this tutorial, we will create a custom note that generates a copy of itself when it is consumed by an account. The purpose of this tutorial is to demonstrate how to create notes inside the MidenVM using Miden assembly (MASM). By the end of this tutorial, you will understand how to write MASM code that creates notes. ## What We'll Cover -- Computing the note inputs commitment in MASM +- Computing the note storage commitment and recipient in MASM - Creating notes in MASM ## Prerequisites @@ -26,7 +28,7 @@ Being able to create a note in MASM enables you to build various types of applic Here are some tangible examples of when creating a note in MASM is useful in a DeFi context: -- Creating snapshots of an account's state at a specific point in time (not possible in an EVM context) +- Creating notes that record selected values from an account's state - Representing partially fillable buy/sell orders as notes (SWAPP) - Handling withdrawals from a smart contract @@ -36,166 +38,184 @@ Here are some tangible examples of when creating a note in MASM is useful in a D In the diagram above, note A is consumed by an account, and during the transaction, note A' is created. -In this tutorial, we will create a note that contains an asset. When consumed, it outputs a copy of itself and allows the consuming account to take half of the asset. Although this type of note would not be used in a real-world context, it demonstrates several key concepts for writing MASM code that can create notes. +In this tutorial, Alice creates a note containing 100 raw units of a fungible asset. Bob consumes it, keeps 50 units, and creates a successor note with the other 50, the same script and storage, and an incremented serial number. The script does not restrict consumption to a particular account. + +This example requires exactly one fungible asset with a positive even amount and performs one split, from 100 to 50. MASM `div` is field division, so this script does not implement rounding for odd integer amounts and should not be used as an arbitrary repeated-halving contract. ## Step 1: Initialize Your Repository -Create a new Rust repository for your Miden project and navigate to it with the following command: +Start in the directory containing your `tutorials` clone and create a sibling Cargo project. The dependency path below assumes the clone is named `tutorials`. ```bash cargo new miden-project cd miden-project +rustup override set 1.98.1 +cp ../tutorials/rust-client/Cargo.lock Cargo.lock ``` -Add the following dependencies to your `Cargo.toml` file: +Keep the generated `[package]` section in `Cargo.toml`, replace its empty `[dependencies]` section with the following, and add the development profile: ```toml [dependencies] -miden-client = { version = "0.15", features = ["testing", "tonic"] } -miden-client-sqlite-store = { version = "0.15", package = "miden-client-sqlite-store" } -miden-protocol = { version = "0.15" } -rand = { version = "0.9" } -tokio = { version = "1.46", features = ["rt-multi-thread", "net", "macros", "fs"] } +# Clone tutorials next to this Cargo project (see Rust client setup). +rust-client = { path = "../tutorials/rust-client" } +miden-client = { version = "=0.16.0", features = ["testing", "tonic"] } +miden-client-sqlite-store = { version = "=0.16.0", package = "miden-client-sqlite-store" } +miden-protocol = { version = "=0.16.0" } +rand = { version = "0.10" } +tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } + +[profile.dev] +opt-level = 2 ``` ## Step 2: Write the Note Script -For better code organization, we will separate the Miden assembly code from our Rust code. - -Create a directory named `masm` at the **root** of your `miden-project` directory. This directory will contain our contract and MASM script code. - -Initialize the `masm` directory: - -```bash -mkdir masm/notes -``` - -This will create: - -```text -masm/ -└── notes/ -``` - -Inside the `masm/notes/` directory, create the file `iterative_output_note.masm`. Note scripts are compiled as libraries; the `@note_script` attribute marks the entrypoint procedure. +The note script is in `masm/notes/iterative_output_note.masm`. Note scripts are compiled as libraries; the `@note_script` attribute marks the entrypoint procedure. ```masm use miden::protocol::active_note use miden::protocol::note -use miden::protocol::output_note use miden::core::sys -use miden::standards::wallets::basic->wallet - -# Memory Addresses -# get_assets writes: ASSET_KEY at ASSET_KEY_PTR, ASSET_VALUE at ASSET_KEY_PTR+4 (ASSET_SIZE=8) -const ASSET_KEY_PTR=0 -const ASSET_VALUE_PTR=4 -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 - -#! Inputs: [] -#! Outputs: [] +use miden::standards::wallets::basic as wallet +use miden::standards::note::note_creator + +# CONSTANTS +# ================================================================================================= + +# get_initial_assets writes the eight-felt asset as ASSET_ID followed by ASSET_VALUE +const ASSET_ID_PTR = 0 +const ASSET_VALUE_PTR = 4 +const ASSET_HALF_VALUE_PTR = 8 +const ACCOUNT_ID_PREFIX = 12 # storage: [prefix, suffix, tag, 0] +const TAG = 14 # ACCOUNT_ID_PREFIX + 2 + +# PUBLIC INTERFACE +# ================================================================================================= + +#! Receives this note's assets and creates a successor with half its fungible amount. +#! +#! This example expects exactly one fungible asset with a positive, even amount. Field division +#! by two is not integer rounding, so an odd amount does not produce a valid half-amount transfer. +#! Any account exposing the wallet and note-creator procedures may consume the note; the account +#! ID in storage is copied into the successor's storage and does not restrict consumption. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused note arguments. +#! - note storage contains a copied account ID and the successor's note tag. +#! +#! Panics if: +#! - the account cannot receive the note's assets or move the computed half amount to the successor. +#! +#! Invocation: dyncall @note_script -pub proc main - # Drop word if user accidentally pushes note_args +pub proc main(args: word) + # discard the unused note arguments dropw - # => [] + # => [pad(16)] - # Get asset contained in note into memory (ASSET_KEY at 0, ASSET_VALUE at 4) - # get_assets leaves [num_assets] on the stack in v0.15; drop it. - push.ASSET_KEY_PTR exec.active_note::get_assets drop - # => [] + # get asset contained in note into memory (ASSET_ID at 0, ASSET_VALUE at 4) + # get_initial_assets leaves [num_assets] on the stack; drop it. + push.ASSET_ID_PTR exec.active_note::get_initial_assets drop + # => [pad(16)] - # Load ASSET_VALUE and compute half amount + # load ASSET_VALUE and compute half amount padw push.ASSET_VALUE_PTR mem_loadw_le - # => [av0, av1, av2, av3] (av0 = amount for fungible asset, av1/av2/av3 = 0) + # => [[amount, 0, 0, 0], pad(16)] - # Halve the amount (av0 is the amount for fungible assets) + # halve the even fungible amount push.2 div - # => [av0/2, av1, av2, av3] + # => [[amount / 2, 0, 0, 0], pad(16)] - # Store as ASSET_HALF_VALUE + # store as ASSET_HALF_VALUE mem_storew_le.ASSET_HALF_VALUE_PTR dropw - # => [] + # => [pad(16)] - # Receive all assets from note into the account wallet - exec.wallet::add_assets_to_account - # => [] + # receive all assets from note into the account wallet + exec.wallet::move_note_assets_to_account + # => [pad(16)] - # Push script hash + # push script hash exec.active_note::get_script_root - # => [SCRIPT_HASH] + # => [SCRIPT_ROOT, pad(16)] - # Get the current note serial number + # get the current note serial number exec.active_note::get_serial_number - # => [SERIAL_NUM, SCRIPT_HASH] + # => [SERIAL_NUM, SCRIPT_ROOT, pad(16)] - # Increment the last element of the serial number by 1 + # increment the last element of the serial number by 1 # (serial_num[3] is at depth 3; matches Rust: serial_num[3] + 1) swap.3 push.1 add swap.3 - # => [SERIAL_NUM+1, SCRIPT_HASH] + # => [NEXT_SERIAL_NUM, SCRIPT_ROOT, pad(16)] - # Load note storage into memory for recipient construction. - # get_storage consumes dest_ptr and leaves only [num_storage_items], - # so re-push the storage_ptr for the recipient call rather than swapping. + # load note storage into memory for recipient construction push.ACCOUNT_ID_PREFIX exec.active_note::get_storage - # => [num_storage_items, SERIAL_NUM+1, SCRIPT_HASH] + # => [num_storage_items, NEXT_SERIAL_NUM, SCRIPT_ROOT, pad(16)] push.ACCOUNT_ID_PREFIX - # => [storage_ptr, num_storage_items, SERIAL_NUM+1, SCRIPT_HASH] + # => [storage_ptr, num_storage_items, NEXT_SERIAL_NUM, SCRIPT_ROOT, pad(16)] - # v0.15 renamed note::build_recipient -> note::compute_and_store_recipient - # (arg shape [storage_ptr, num_storage_items, SERIAL_NUM, SCRIPT_ROOT]). + # argument shape: [storage_ptr, num_storage_items, SERIAL_NUM, SCRIPT_ROOT]. exec.note::compute_and_store_recipient - # => [RECIPIENT] + # => [RECIPIENT, pad(16)] - # Push note type to stack (public note = 1) + # push note type to stack (public note = 1) push.1 - # => [note_type, RECIPIENT] + # => [note_type, RECIPIENT, pad(16)] - # Load tag from memory + # load tag from memory mem_load.TAG - # => [tag, note_type, RECIPIENT] + # => [tag, note_type, RECIPIENT, pad(16)] - exec.output_note::create - # => [note_idx] + # note creation from a note script must call the account's note-creator procedure. + # pad the stack for the account procedure call convention. + push.0 movdn.6 push.0 movdn.6 padw padw swapdw + # => [tag, note_type, RECIPIENT, pad(26)] - # Build [ASSET_KEY, ASSET_HALF_VALUE, note_idx] for move_asset_to_note - # Inputs: [ASSET_KEY, ASSET_VALUE, note_idx, pad(7)] + call.note_creator::create_note + # => [note_idx, pad(31)] - # Push ASSET_HALF_VALUE (note_idx moves to depth 4) + movdn.15 dropw dropw dropw drop drop drop + # => [note_idx, pad(16)] + + # build [ASSET_ID, ASSET_HALF_VALUE, note_idx] for move_asset_to_note + # inputs: [ASSET_ID, ASSET_VALUE, note_idx, pad(7)] + + # push ASSET_HALF_VALUE (note_idx moves to depth 4) padw push.ASSET_HALF_VALUE_PTR mem_loadw_le - # => [ASSET_HALF_VALUE, note_idx] + # => [ASSET_HALF_VALUE, note_idx, pad(16)] - # Push ASSET_KEY (ASSET_HALF_VALUE moves to depth 4, note_idx to depth 8) - padw push.ASSET_KEY_PTR mem_loadw_le - # => [ASSET_KEY, ASSET_HALF_VALUE, note_idx] + # push ASSET_ID (ASSET_HALF_VALUE moves to depth 4, note_idx to depth 8) + padw push.ASSET_ID_PTR mem_loadw_le + # => [ASSET_ID, ASSET_HALF_VALUE, note_idx, pad(16)] call.wallet::move_asset_to_note - # => [pad(16)] + # => [pad(25)] dropw dropw dropw dropw - # => [] + # => [pad(16)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end ``` ### How the Assembly Code Works: 1. **Retrieving the asset:** - The note calls `active_note::get_assets` to write the asset into memory, with `ASSET_KEY` at address 0 and `ASSET_VALUE` at address 4. It halves the amount in `ASSET_VALUE` and stores it at `ASSET_HALF_VALUE_PTR`. Finally, it calls `wallet::add_assets_to_account` to receive all note assets into the consuming account. + The note calls `active_note::get_initial_assets` to copy the initial asset into memory, with `ASSET_ID` at address 0 and `ASSET_VALUE` at address 4. It halves the amount in `ASSET_VALUE` and stores it at `ASSET_HALF_VALUE_PTR`. Finally, it calls `wallet::move_note_assets_to_account`, which explicitly removes the assets from the note and receives them into the consuming account. 2. **Getting the script hash and serial number:** The note script calls `active_note::get_script_root` to fetch the script hash and `active_note::get_serial_number` to fetch the current serial number, then increments element 3 (the last element) by 1 to avoid duplicate recipients. 3. **Building the `RECIPIENT`:** The script loads the note storage into memory with `active_note::get_storage`, then calls `note::compute_and_store_recipient`. This computes the storage commitment and stores the preimage in the advice map, which is required for public notes. 4. **Creating the note:** - To create the note, the script pushes the note type and tag onto the stack, then calls the `output_note::create` procedure, which returns the note index. + To create the note from a note script, the script pads the stack for the account-call ABI and calls the account's exported `note_creator::create_note` procedure, which enters the account context and returns the note index. The consuming account must expose `NoteCreator`; `BasicWallet` includes it. 5. **Moving assets to the note:** - After the note is created, the script loads `ASSET_KEY` and `ASSET_HALF_VALUE` from memory onto the stack and calls `wallet::move_asset_to_note` with the note index. + After the note is created, the script loads `ASSET_ID` and `ASSET_HALF_VALUE` from memory onto the stack and calls `wallet::move_asset_to_note` with the note index. 6. **Stack cleanup:** Finally, the script cleans up the stack by calling `sys::truncate_stack`. @@ -206,21 +226,23 @@ With the Miden assembly note script written, we can move on to writing the Rust Copy and paste the following code into your `src/main.rs` file. ```rust no_run -use rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; -use tokio::time::{sleep, Duration}; +use tokio::time::{Duration, sleep}; use miden_client::{ + Client, ClientError, Felt, account::{ + Account, AccountBuilder, AccountType, component::{ - BasicWallet, BurnPolicyConfig, FungibleFaucet, MintPolicyConfig, PolicyRegistration, - TokenName, TokenPolicyManager, + create_singlesig_user_fungible_faucet, BasicWallet, BurnPolicy, FungibleFaucet, + MintPolicy, TokenName, TokenPolicyManager, }, - Account, AccountBuilder, AccountType, }, address::NetworkId, - asset::{AssetAmount, FungibleAsset, TokenSymbol}, - auth::{AuthSchemeId, AuthSecretKey, AuthSingleSig}, + asset::{AssetAmount, AssetId, FungibleAsset, TokenSymbol}, + auth::{AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, crypto::FeltRng, keystore::{FilesystemKeyStore, Keystore}, @@ -228,12 +250,11 @@ use miden_client::{ Note, NoteAssets, NoteDetails, NoteRecipient, NoteStorage, NoteTag, NoteType, PartialNoteMetadata, }, - rpc::{Endpoint, GrpcClient}, - store::TransactionFilter, - transaction::{TransactionId, TransactionRequestBuilder, TransactionStatus}, - Client, ClientError, Felt, + rpc::{GrpcClient, VerifyingRpcClient}, + transaction::{TransactionId, TransactionRequestBuilder}, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::{FeeConfig, TutorialNetwork, fund_account_for_fees}; // Helper to create a basic account async fn create_basic_account( @@ -247,7 +268,7 @@ async fn create_basic_account( let account = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet) .build() .unwrap(); @@ -270,27 +291,25 @@ async fn create_basic_faucet( let decimals = 8; let max_supply = AssetAmount::new(1_000_000).unwrap(); - let account = AccountBuilder::new(init_seed) - .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) - .with_component( - FungibleFaucet::builder() - .name(TokenName::new("MID").unwrap()) - .symbol(symbol) - .decimals(decimals) - .max_supply(max_supply) - .build() - .unwrap(), - ) - .with_components( - TokenPolicyManager::new() - .with_mint_policy(MintPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap() - .with_burn_policy(BurnPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap(), - ) + let faucet = FungibleFaucet::builder() + .name(TokenName::new("MID").unwrap()) + .symbol(symbol) + .decimals(decimals) + .max_supply(max_supply) .build() .unwrap(); + let policies = TokenPolicyManager::builder() + .active_mint_policy(MintPolicy::allow_all()) + .active_burn_policy(BurnPolicy::allow_all()) + .build(); + let account = create_singlesig_user_fungible_faucet( + init_seed, + faucet, + AuthSingleSig::from_public_key(key_pair.public_key()), + policies, + AccountType::Public, + ) + .unwrap(); client.add_account(&account, false).await?; keystore.add_key(&key_pair, account.id()).await.unwrap(); @@ -303,21 +322,29 @@ async fn wait_for_notes( client: &mut Client, account_id: &Account, expected: usize, + network_id: NetworkId, ) -> Result<(), ClientError> { - loop { + for _ in 0..24 { client.sync_state().await?; - let notes = client.get_consumable_notes(Some(account_id.id())).await?; + let notes = client + .get_consumable_tutorial_notes(Some(account_id.id())) + .await?; if notes.len() >= expected { - break; + return Ok(()); } println!( "{} consumable notes found for account {}. Waiting...", notes.len(), - account_id.id().to_bech32(NetworkId::Testnet) + account_id.id().to_bech32(network_id.clone()) ); sleep(Duration::from_secs(3)).await; } - Ok(()) + Err(ClientError::Observer(Box::new(std::io::Error::other( + format!( + "timed out waiting for {expected} tutorial notes for {}", + account_id.id() + ), + )))) } /// Waits for a specific transaction to be committed. @@ -325,39 +352,18 @@ async fn wait_for_tx( client: &mut Client, tx_id: TransactionId, ) -> Result<(), ClientError> { - loop { - client.sync_state().await?; - - // Check transaction status - let txs = client - .get_transactions(TransactionFilter::Ids(vec![tx_id])) - .await?; - let tx_committed = if !txs.is_empty() { - matches!(txs[0].status, TransactionStatus::Committed { .. }) - } else { - false - }; - - if tx_committed { - println!("✅ transaction {} committed", tx_id.to_hex()); - break; - } - - println!( - "Transaction {} not yet committed. Waiting...", - tx_id.to_hex() - ); - sleep(Duration::from_secs(2)).await; - } - Ok(()) + rust_client::wait_for_transaction(client, tx_id).await } #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -369,12 +375,12 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; // ------------------------------------------------------------------------- // STEP 1: Create accounts and deploy faucet @@ -383,20 +389,23 @@ async fn main() -> Result<(), ClientError> { let alice_account = create_basic_account(&mut client, &keystore).await?; println!( "Alice's account ID: {:?}", - alice_account.id().to_bech32(NetworkId::Testnet) + alice_account.id().to_bech32(network.network_id()) ); let bob_account = create_basic_account(&mut client, &keystore).await?; println!( "Bob's account ID: {:?}", - bob_account.id().to_bech32(NetworkId::Testnet) + bob_account.id().to_bech32(network.network_id()) ); println!("\nDeploying a new fungible faucet."); let faucet = create_basic_faucet(&mut client, &keystore).await?; println!( "Faucet account ID: {:?}", - faucet.id().to_bech32(NetworkId::Testnet) + faucet.id().to_bech32(network.network_id()) ); + for account_id in [alice_account.id(), bob_account.id(), faucet.id()] { + fund_account_for_fees(&mut client, account_id, &fee_config).await?; + } client.sync_state().await?; // ------------------------------------------------------------------------- @@ -416,14 +425,16 @@ async fn main() -> Result<(), ClientError> { ) .unwrap(); - let tx_id = client.submit_new_transaction(faucet.id(), tx_req).await?; + let tx_id = client + .submit_tutorial_transaction(faucet.id(), tx_req) + .await?; println!("Minted tokens. TX: {:?}", tx_id); - wait_for_notes(&mut client, &alice_account, 1).await?; + wait_for_notes(&mut client, &alice_account, 1, network.network_id()).await?; // Consume the minted note let consumable_notes = client - .get_consumable_notes(Some(alice_account.id())) + .get_consumable_tutorial_notes(Some(alice_account.id())) .await?; if let Some((note_record, _)) = consumable_notes.first() { @@ -431,7 +442,7 @@ async fn main() -> Result<(), ClientError> { let consume_req = TransactionRequestBuilder::new().build_consume_notes(vec![note])?; let tx_id = client - .submit_new_transaction(alice_account.id(), consume_req) + .submit_tutorial_transaction(alice_account.id(), consume_req) .await?; println!("Consumed minted note. TX: {:?}", tx_id); } @@ -443,15 +454,15 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 3] Create iterative output note"); - // `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"); + // Read the MASM source from the tutorials repository. + let code = + std::fs::read_to_string("../tutorials/masm/notes/iterative_output_note.masm").unwrap(); let serial_num = client.rng().draw_word(); // Create note metadata and tag let tag = NoteTag::new(0); let metadata = PartialNoteMetadata::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(), @@ -470,10 +481,11 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let tx_id = client - .submit_new_transaction(alice_account.id(), note_req) + .submit_tutorial_transaction(alice_account.id(), note_req) .await?; println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); @@ -505,25 +517,53 @@ async fn main() -> Result<(), ClientError> { let consume_custom_req = TransactionRequestBuilder::new() .input_notes([(custom_note, None)]) - .expected_future_notes(vec![( - NoteDetails::from(output_note.clone()), - output_note.metadata().tag(), - ) - .clone()]) + .expected_future_notes(vec![ + ( + NoteDetails::from(output_note.clone()), + output_note.metadata().tag(), + ) + .clone(), + ]) .expected_output_recipients(vec![output_note.recipient().clone()]) .build() .unwrap(); let tx_id = client - .submit_new_transaction(bob_account.id(), consume_custom_req) + .submit_tutorial_transaction(bob_account.id(), consume_custom_req) .await?; println!( - "Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "Consumed Note Tx on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); wait_for_tx(&mut client, tx_id).await?; + // The SDK verifies expected recipients; also check the actual successor's assets and metadata. + let successor = client + .get_output_note(output_note.id()) + .await? + .expect("the transaction must create the expected successor note"); + assert!(successor.is_committed(), "the successor must be committed"); + assert_eq!(successor.assets(), output_note.assets()); + assert_eq!(successor.metadata(), output_note.metadata()); + println!( + "Successor note committed with 50 tokens: {}", + successor.id() + ); + + let bob = client + .get_account(bob_account.id()) + .await? + .expect("Bob's account must exist after consuming the note"); + let balance = bob.vault().get_balance(AssetId::new_fungible(faucet_id))?; + assert_eq!( + balance.as_u64(), + 50, + "Bob must retain the other half of the note's tokens", + ); + println!("Bob's retained token balance: {balance}"); + Ok(()) } ``` @@ -531,44 +571,44 @@ async fn main() -> Result<(), ClientError> { Run the following command to execute `src/main.rs`: ```bash -cargo run --release +TUTORIAL_NETWORK=testnet cargo run --release ``` -The output will look something like this: +The following is an abbreviated output; IDs vary, and funding and repeated confirmation messages are omitted: ```text -Latest block: 488715 +Latest block: [STEP 1] Creating new accounts -Alice's account ID: "mtst1azvwquwfvh0jyytq0dk9xya9tvhvu935" -Bob's account ID: "mtst1ap9hwvau7sy9tvtka6smn0ev7cxtgt03" +Alice's account ID: "" +Bob's account ID: "" Deploying a new fungible faucet. -Faucet account ID: "mtst1apj3jthkj4mweyf7qt254h5m5gdemp9u" +Faucet account ID: "" [STEP 2] Mint tokens with P2ID -Minted tokens. TX: 0xf3c8f183aeefb086ca4a63f2a6f34535ea4217849e8e870033f892503302fb7d -0 consumable notes found for account mtst1azvwquwfvh0jyytq0dk9xya9tvhvu935. Waiting... -Consumed minted note. TX: 0x2d31ce827549d8bf35d1c3613610f8388d6c2369dbd1aa34f4f3406f86fdff55 +Minted tokens. TX: +Consumed minted note. TX: [STEP 3] Create iterative output note -View transaction on MidenScan: https://testnet.midenscan.com/tx/0xadabf7a920ee27bf1fabd3b02e8e6f3d80f84ece31a23d73f27b0b56bbc2fdc3 +View transaction on MidenScan: https://testnet.midenscan.com/tx/ [STEP 4] Bob consumes the note and creates a copy -Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/0xa003d298db5e7de263a8b98930b6e75336c3cca7cd4a090c707edb6a7f061ad5 -Transaction 0xa003d298db5e7de263a8b98930b6e75336c3cca7cd4a090c707edb6a7f061ad5 not yet committed. Waiting... -✅ transaction 0xa003d298db5e7de263a8b98930b6e75336c3cca7cd4a090c707edb6a7f061ad5 committed +Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/ +Transaction committed: +Successor note committed with 50 tokens: +Bob's retained token balance: 50 ``` --- ### Running the example -To run the full example, navigate to the `rust-client` directory in the [miden-tutorials](https://github.com/0xMiden/miden-tutorials/) repository and run this command: +From the root of your `tutorials` clone, run the checked-in example: ```bash cd rust-client -cargo run --release --bin note_creation_in_masm +TUTORIAL_NETWORK=testnet cargo run --release --bin note_creation_in_masm ``` ### Continue learning diff --git a/docs/src/rust-client/custom_note_how_to.md b/docs/src/rust-client/custom_note_how_to.md index e3c28b2e..78f19c9d 100644 --- a/docs/src/rust-client/custom_note_how_to.md +++ b/docs/src/rust-client/custom_note_how_to.md @@ -7,6 +7,8 @@ sidebar_position: 7 _Creating notes with custom logic_ +For toolchain requirements and shared fee helpers, see the [Rust client setup](./index.md#running-the-v016-examples). + ## Overview In this guide, we will create a custom note on Miden that can only be consumed by someone who knows the preimage of the hash stored in the note. This approach securely embeds assets into the note and restricts spending to those who possess the correct secret number. @@ -14,9 +16,9 @@ In this guide, we will create a custom note on Miden that can only be consumed b By following the steps below and using the Miden Assembly code and Rust example, you will learn how to: - Create a note with custom logic. -- Leverage Miden’s privacy features to keep certain transaction details private. +- Store the hash publicly while providing its preimage only to the transaction that consumes the note. -Unlike Ethereum, where all pending transactions are publicly visible in the mempool, Miden enables you to partially or completely hide transaction details. +This example uses public accounts and a public note. Its script checks knowledge of the secret, rather than a particular account ID, so any account with the secret and the required wallet procedure can consume it. ## What we'll cover @@ -37,67 +39,77 @@ First, we create two basic accounts for the two users: The security of the custom note hinges on a secret number. Here, we will: - Choose a secret number (for example, an array of four integers). -- For simplicity, we're only hashing 4 elements. Therefore, we prepend an empty word—consisting of 4 zero integers—as a placeholder. This is required by the RPO hashing algorithm to ensure the input has the correct structure and length for proper processing. -- Compute the hash of the secret. The resulting hash will serve as the note’s input, meaning that the note can only be consumed if the secret number’s hash preimage is provided during consumption. +- Hash the four field elements directly with `miden_protocol::Hasher::hash_elements`, which uses Poseidon2 in v0.16. The MASM `hash` instruction computes the matching digest; do not prepend an extra zero word to the Rust input. +- Compute the hash of the secret. The resulting hash will be stored in the note’s storage, meaning that the note can only be consumed if the secret number’s hash preimage is provided during consumption. ### 3. Creating the custom note Now, combine the minted asset and the secret hash to build the custom note. The note is created using the following key steps: -1. **Note Inputs:** - - The note is set up with the asset and the hash of the secret number as its input. +1. **Assets and storage:** + - The note carries 100 raw units of the tutorial asset and stores the secret's digest in `NoteStorage`. The secret itself is supplied later as the consuming transaction's note arguments. 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. + - 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 storage. Below is the Miden Assembly code for the note. Note scripts are compiled as libraries; the `@note_script` attribute marks the entrypoint procedure. ```masm use miden::protocol::active_note -use miden::standards::wallets::basic->wallet +use miden::standards::wallets::basic as wallet # CONSTANTS # ================================================================================================= -const EXPECTED_DIGEST_PTR=0 +const EXPECTED_DIGEST_PTR = 0 # ERRORS # ================================================================================================= -const ERROR_DIGEST_MISMATCH="Expected digest does not match computed digest" +const ERROR_DIGEST_MISMATCH = "Expected digest does not match computed digest" + +# PUBLIC INTERFACE +# ================================================================================================= -#! Inputs (arguments): [HASH_PREIMAGE_SECRET] -#! Outputs: [] +#! Consumes the note's assets when the secret hashes to its stored digest. +#! +#! Inputs: [HASH_PREIMAGE_SECRET, pad(12)] +#! Outputs: [pad(16)] #! -#! Note storage is assumed to be as follows: -#! => EXPECTED_DIGEST +#! Where: +#! - HASH_PREIMAGE_SECRET is the four-felt secret supplied as note arguments. +#! +#! Panics if: +#! - the supplied secret does not match the digest stored in the note. +#! +#! Invocation: dyncall @note_script -pub proc main - # => HASH_PREIMAGE_SECRET - # Hashing the secret number +pub proc main(hash_preimage_secret: word) + # => [HASH_PREIMAGE_SECRET, pad(12)] + # hashing the secret number hash - # => [DIGEST] + # => [DIGEST, pad(12)] - # Writing the note storage to memory. + # writing the note storage to memory. # get_storage leaves only [num_storage_items], so drop a single element # here, not two, to keep the computed DIGEST intact. push.EXPECTED_DIGEST_PTR exec.active_note::get_storage drop - # Pad stack and load expected digest from memory (LE: mem[addr] ends up on top) + # pad stack and load expected digest from memory (LE: mem[addr] ends up on top) padw push.EXPECTED_DIGEST_PTR mem_loadw_le - # => [EXPECTED_DIGEST, DIGEST] + # => [EXPECTED_DIGEST, DIGEST, pad(12)] - # Assert that the note input matches the digest - # Will fail if the two hashes do not match + # assert that the note input matches the digest + # will fail if the two hashes do not match assert_eqw.err=ERROR_DIGEST_MISMATCH - # => [] + # => [pad(16)] # --------------------------------------------------------------------------------------------- - # If the check is successful, we allow for the asset to be consumed + # if the check is successful, we allow for the asset to be consumed # --------------------------------------------------------------------------------------------- - # Add all assets from the note to the account - exec.wallet::add_assets_to_account - # => [] + # add all assets from the note to the account + exec.wallet::move_note_assets_to_account + # => [pad(16)] end ``` @@ -112,45 +124,73 @@ end 4. **Digest Comparison:** The assembly code loads the expected digest from note storage into memory, then reads it back with `mem_loadw_le` (which places `mem[addr]` on top, matching the hash output order) and compares with the computed hash. If they don't match, the transaction fails with a clear error message. 5. **Asset Transfer:** - If the hash matches, `wallet::add_assets_to_account` transfers all note assets into the consuming account's vault. + If the hash matches, `wallet::move_note_assets_to_account` explicitly removes all assets from the note and transfers them into the consuming account's vault. -### 5. Consuming the note +### 4. Consuming the note With the note created, Bob can now consume it—but only if he provides the correct secret. When Bob initiates the transaction to consume the note, he must supply the same secret number used when Alice created the note. The custom note’s logic will hash the secret and compare it with its stored hash. If they match, Bob’s wallet receives the asset. --- +## Set up the Rust project + +Start in the directory containing your `tutorials` clone and create a sibling Cargo project: + +```bash +cargo new miden-custom-note +cd miden-custom-note +rustup override set 1.98.1 +cp ../tutorials/rust-client/Cargo.lock Cargo.lock +``` + +Keep the generated `[package]` section in `Cargo.toml`, replace its empty `[dependencies]` section with the following, and add the development profile. The path assumes the repository clone is named `tutorials`. + +```toml +[dependencies] +# Clone tutorials next to this Cargo project (see Rust client setup). +rust-client = { path = "../tutorials/rust-client" } +miden-client = { version = "=0.16.0", features = ["testing", "tonic"] } +miden-client-sqlite-store = { version = "=0.16.0", package = "miden-client-sqlite-store" } +miden-protocol = { version = "=0.16.0" } +rand = { version = "0.10" } +tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } + +[profile.dev] +opt-level = 2 +``` + +Copy the complete Rust example below into `src/main.rs`. Run it from this new project's directory with `TUTORIAL_NETWORK=testnet cargo run --release`. The client creates `store.sqlite3` and `keystore/` here; keep both out of version control. + ## Full Rust code example The following Rust code demonstrates how to implement the steps outlined above using the Miden client library: ```rust no_run -use rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; -use tokio::time::{sleep, Duration}; use miden_client::{ + Client, ClientError, Felt, account::{ + Account, AccountBuilder, AccountType, component::{ - BasicWallet, BurnPolicyConfig, FungibleFaucet, MintPolicyConfig, PolicyRegistration, - TokenName, TokenPolicyManager, + create_singlesig_user_fungible_faucet, BasicWallet, BurnPolicy, FungibleFaucet, + MintPolicy, TokenName, TokenPolicyManager, }, - Account, AccountBuilder, AccountType, }, - address::NetworkId, - asset::{AssetAmount, FungibleAsset, TokenSymbol}, - auth::{AuthSchemeId, AuthSecretKey, AuthSingleSig}, + asset::{AssetAmount, AssetId, FungibleAsset, TokenSymbol}, + auth::{AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, crypto::FeltRng, keystore::{FilesystemKeyStore, Keystore}, note::{Note, NoteAssets, NoteRecipient, NoteStorage, NoteTag, NoteType, PartialNoteMetadata}, - rpc::{Endpoint, GrpcClient}, - store::TransactionFilter, - transaction::{TransactionId, TransactionRequestBuilder, TransactionStatus}, - Client, ClientError, Felt, + rpc::{GrpcClient, VerifyingRpcClient}, + transaction::{TransactionId, TransactionRequestBuilder}, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; use miden_protocol::Hasher; +use rust_client::{FeeConfig, TutorialNetwork, fund_account_for_fees}; // Helper to create a basic account async fn create_basic_account( @@ -164,7 +204,7 @@ async fn create_basic_account( let account = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet) .build() .unwrap(); @@ -187,27 +227,25 @@ async fn create_basic_faucet( let decimals = 8; let max_supply = AssetAmount::new(1_000_000).unwrap(); - let account = AccountBuilder::new(init_seed) - .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) - .with_component( - FungibleFaucet::builder() - .name(TokenName::new("MID").unwrap()) - .symbol(symbol) - .decimals(decimals) - .max_supply(max_supply) - .build() - .unwrap(), - ) - .with_components( - TokenPolicyManager::new() - .with_mint_policy(MintPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap() - .with_burn_policy(BurnPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap(), - ) + let faucet = FungibleFaucet::builder() + .name(TokenName::new("MID").unwrap()) + .symbol(symbol) + .decimals(decimals) + .max_supply(max_supply) .build() .unwrap(); + let policies = TokenPolicyManager::builder() + .active_mint_policy(MintPolicy::allow_all()) + .active_burn_policy(BurnPolicy::allow_all()) + .build(); + let account = create_singlesig_user_fungible_faucet( + init_seed, + faucet, + AuthSingleSig::from_public_key(key_pair.public_key()), + policies, + AccountType::Public, + ) + .unwrap(); client.add_account(&account, false).await?; keystore.add_key(&key_pair, account.id()).await.unwrap(); @@ -220,39 +258,18 @@ async fn wait_for_tx( client: &mut Client, tx_id: TransactionId, ) -> Result<(), ClientError> { - loop { - client.sync_state().await?; - - // Check transaction status - let txs = client - .get_transactions(TransactionFilter::Ids(vec![tx_id])) - .await?; - let tx_committed = if !txs.is_empty() { - matches!(txs[0].status, TransactionStatus::Committed { .. }) - } else { - false - }; - - if tx_committed { - println!("✅ transaction {} committed", tx_id.to_hex()); - break; - } - - println!( - "Transaction {} not yet committed. Waiting...", - tx_id.to_hex() - ); - sleep(Duration::from_secs(2)).await; - } - Ok(()) + rust_client::wait_for_transaction(client, tx_id).await } #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -264,12 +281,12 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; // ------------------------------------------------------------------------- // STEP 1: Create accounts and deploy faucet @@ -278,20 +295,23 @@ async fn main() -> Result<(), ClientError> { let alice_account = create_basic_account(&mut client, &keystore).await?; println!( "Alice's account ID: {:?}", - alice_account.id().to_bech32(NetworkId::Testnet) + alice_account.id().to_bech32(network.network_id()) ); let bob_account = create_basic_account(&mut client, &keystore).await?; println!( "Bob's account ID: {:?}", - bob_account.id().to_bech32(NetworkId::Testnet) + bob_account.id().to_bech32(network.network_id()) ); println!("\nDeploying a new fungible faucet."); let faucet = create_basic_faucet(&mut client, &keystore).await?; println!( "Faucet account ID: {:?}", - faucet.id().to_bech32(NetworkId::Testnet) + faucet.id().to_bech32(network.network_id()) ); + for account_id in [alice_account.id(), bob_account.id(), faucet.id()] { + fund_account_for_fees(&mut client, account_id, &fee_config).await?; + } client.sync_state().await?; // ------------------------------------------------------------------------- @@ -311,7 +331,7 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let tx_id = client - .submit_new_transaction(faucet.id(), tx_request) + .submit_tutorial_transaction(faucet.id(), tx_request) .await?; println!("Minted tokens. TX: {:?}", tx_id); @@ -321,17 +341,15 @@ async fn main() -> Result<(), ClientError> { // Consume the minted note let consumable_notes = client - .get_consumable_notes(Some(alice_account.id())) + .get_consumable_tutorial_notes(Some(alice_account.id())) .await?; if let Some((note_record, _)) = consumable_notes.first() { let note: Note = note_record.clone().try_into()?; - let consume_request = TransactionRequestBuilder::new() - .build_consume_notes(vec![note]) - .unwrap(); + let consume_request = TransactionRequestBuilder::new().build_consume_notes(vec![note])?; let tx_id = client - .submit_new_transaction(alice_account.id(), consume_request) + .submit_tutorial_transaction(alice_account.id(), consume_request) .await?; println!("Consumed minted note. TX: {:?}", tx_id); } @@ -342,16 +360,20 @@ async fn main() -> Result<(), ClientError> { // STEP 3: Create custom note // ------------------------------------------------------------------------- println!("\n[STEP 3] Create custom note"); - let secret_vals = vec![Felt::new_unchecked(1), Felt::new_unchecked(2), Felt::new_unchecked(3), Felt::new_unchecked(4)]; + let secret_vals = vec![ + Felt::new_unchecked(1), + Felt::new_unchecked(2), + Felt::new_unchecked(3), + Felt::new_unchecked(4), + ]; let digest = Hasher::hash_elements(&secret_vals); println!("digest: {:?}", digest); - // `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"); + // Read the MASM source from the tutorials repository. + let code = std::fs::read_to_string("../tutorials/masm/notes/hash_preimage_note.masm").unwrap(); let serial_num = client.rng().draw_word(); - 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(digest.to_vec()).unwrap(); let recipient = NoteRecipient::new(serial_num, note_script, note_storage); let tag = NoteTag::new(0); @@ -366,10 +388,11 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let tx_id = client - .submit_new_transaction(alice_account.id(), note_request) + .submit_tutorial_transaction(alice_account.id(), note_request) .await?; println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); @@ -380,30 +403,48 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 4] Bob consumes the Custom Note with Correct Secret"); - let secret = [Felt::new_unchecked(1), Felt::new_unchecked(2), Felt::new_unchecked(3), Felt::new_unchecked(4)]; + let secret = [ + Felt::new_unchecked(1), + Felt::new_unchecked(2), + Felt::new_unchecked(3), + Felt::new_unchecked(4), + ]; let consume_custom_request = TransactionRequestBuilder::new() .input_notes([(custom_note, Some(secret.into()))]) .build() .unwrap(); let tx_id = client - .submit_new_transaction(bob_account.id(), consume_custom_request) + .submit_tutorial_transaction(bob_account.id(), consume_custom_request) .await?; println!( - "Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/{:?} \n", + "Consumed Note Tx on MidenScan: {}/tx/{:?} \n", + network.explorer_url(), tx_id ); wait_for_tx(&mut client, tx_id).await?; + let bob = client + .get_account(bob_account.id()) + .await? + .expect("Bob's account must exist after consuming the note"); + let balance = bob.vault().get_balance(AssetId::new_fungible(faucet_id))?; + assert_eq!( + balance.as_u64(), + amount, + "Bob must receive all assets from the hash-preimage note", + ); + println!("Bob's custom-note token balance: {balance}"); + Ok(()) } ``` -The output of our program will look something like this: +The following is an abbreviated output; IDs vary, and funding and repeated confirmation messages are omitted: ```text -Latest block: 488704 +Latest block: [STEP 1] Creating new accounts Alice's account ID: "" @@ -413,21 +454,20 @@ Deploying a new fungible faucet. Faucet account ID: "" [STEP 2] Mint tokens with P2ID -Minted tokens. TX: 0x970265408eb22068b22ec677f6ad09a2524913ab11b3dbf010e4cae73587e2e3 -Transaction 0x970265408eb22068b22ec677f6ad09a2524913ab11b3dbf010e4cae73587e2e3 not yet committed. Waiting... -✅ transaction 0x970265408eb22068b22ec677f6ad09a2524913ab11b3dbf010e4cae73587e2e3 committed -Consumed minted note. TX: 0x47850a0c44d9e147b8866285c24ba05a0d4bed0a99c1f25a13f32e57feecfe1b +Minted tokens. TX: +Transaction committed: +Consumed minted note. TX: [STEP 3] Create custom note digest: Word([14206540680072267069, 9571949196318390099, 5950603493574130513, 3457190364553631046]) note hash: "0xf48f362f1817bbc5575e0bb8b77c496dd67e4b85d8ff45d21dff5743de2b174d" -View transaction on MidenScan: https://testnet.midenscan.com/tx/0x9911ef1b9d2b066e017de187b7c1f8d95012748366358474b11adc91e49971b5 +View transaction on MidenScan: https://testnet.midenscan.com/tx/ [STEP 4] Bob consumes the Custom Note with Correct Secret -Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/0x2a7a192b692984ae649dd1a13d15e4b79178e9e554615ffec7426e25e75193fa +Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/ -Transaction 0x2a7a192b692984ae649dd1a13d15e4b79178e9e554615ffec7426e25e75193fa not yet committed. Waiting... -✅ transaction 0x2a7a192b692984ae649dd1a13d15e4b79178e9e554615ffec7426e25e75193fa committed +Transaction committed: +Bob's custom-note token balance: 100 ``` ## Conclusion @@ -439,15 +479,15 @@ You have now seen how to create a custom note on Miden that requires a secret pr 3. Building a note with custom logic in Miden Assembly 4. Consuming the note by providing the correct secret -By leveraging Miden’s privacy features, you can create customized logic for secure asset transfers that depend on keeping parts of the transaction private. +The fixed secret `[1, 2, 3, 4]` is for demonstration. A real secret must be unpredictable and shared only with the intended consumer. Anyone who learns it can satisfy this note's spending condition. ### Running the example -To run the custom note example, navigate to the `rust-client` directory in the [miden-tutorials](https://github.com/0xMiden/miden-tutorials/) repository and run this command: +From the root of your `tutorials` clone, run the checked-in example: ```bash cd rust-client -cargo run --release --bin hash_preimage_note +TUTORIAL_NETWORK=testnet cargo run --release --bin hash_preimage_note ``` ### Continue learning diff --git a/docs/src/rust-client/delegated_proving_tutorial.md b/docs/src/rust-client/delegated_proving_tutorial.md index 58d070ae..f7d8c62e 100644 --- a/docs/src/rust-client/delegated_proving_tutorial.md +++ b/docs/src/rust-client/delegated_proving_tutorial.md @@ -7,9 +7,11 @@ sidebar_position: 12 _Using delegated proving to minimize transaction proving times on computationally constrained devices_ +For toolchain requirements and shared fee helpers, see the [Rust client setup](./index.md#running-the-v016-examples). + ## Overview -In this tutorial we will cover how to use delegated proving with the Miden Rust client to minimize the time it takes to generate a valid transaction proof. In the code below, we will create an account, mint tokens from a faucet, then send the tokens to another account using delegated proving. +In this tutorial we will cover how to use delegated proving with the Miden Rust client to minimize the time it takes to generate a valid transaction proof. We create and fund an account, execute a minimal transaction locally, prove it with the network's remote prover, and verify that its confirmed nonce increases by one. Even this minimal transaction pays a verification fee on testnet. ## Prerequisites @@ -26,9 +28,9 @@ Before diving into our code example, let's clarify what "delegated proving" mean Delegated proving is the process of outsourcing the ZK proof generation of your transaction to a third party. For certain computationally constrained devices such as mobile phones and web browser environments, generating ZK proofs might take too long to ensure an acceptable user experience. Devices that do not have the computational resources to generate Miden proofs in under 1-2 seconds can use delegated proving to provide a more responsive user experience. -_How does it work?_ When a user choses to use delegated proving, they send off their locally executed transaction to a dedicated server. This dedicated server generates the ZK proof for the executed transaction and sends the proof back to the user. Proving a transaction with delegated proving is trustless, meaning if the delegated prover is malicious, they could not compromise the security of the account that is submitting a transaction to be processed by the delegated prover. +_How does it work?_ When a user chooses to use delegated proving, they send off their locally executed transaction to a dedicated server. This dedicated server generates the ZK proof for the executed transaction and sends the proof back to the user. The transaction proof is verified under the same rules as a locally generated proof: the delegated prover cannot make an invalid state transition valid. This protects transaction integrity, but does not keep the witness private from the prover. -The only downside of using delegated proving is that it reduces the privacy of the account that uses delegated proving, because the delegated prover would have knowledge of the inputs to the transaction that is being proven. For example, it would not be advisable to use delegated proving in the case of our "How to Create a Custom Note" tutorial, since the note we create requires knowledge of a hash preimage to redeem the assets in the note. Using delegated proving would reveal the hash preimage to the server running the delegated proving service. +Delegated proving reveals the transaction witness to the prover and depends on that service being available. The witness can include private account state and note arguments. For example, it would not be advisable to use delegated proving in the case of our "How to Create a Custom Note" tutorial, since the note we create requires knowledge of a hash preimage to redeem the assets in the note. Using delegated proving would reveal the hash preimage to the server running the delegated proving service. Anyone can run their own delegated prover server. If you are building a product on Miden, it may make sense to run your own delegated prover server for your users. To run your own delegated proving server, follow the instructions here: https://crates.io/crates/miden-remote-prover. @@ -38,52 +40,61 @@ prover instead, point `RemoteTransactionProver` at its URL. ## Step 1: Initialize your repository -Create a new Rust repository for your Miden project and navigate to it with the following command: +Start in the directory containing your `tutorials` clone and create a sibling Cargo project. The dependency path below assumes the clone is named `tutorials`. ```bash cargo new miden-delegated-proving-app cd miden-delegated-proving-app +rustup override set 1.98.1 +cp ../tutorials/rust-client/Cargo.lock Cargo.lock ``` -Add the following dependencies to your `Cargo.toml` file: +Keep the generated `[package]` section in `Cargo.toml`, replace its empty `[dependencies]` section with the following, and add the development profile: ```toml [dependencies] -miden-client = { version = "0.15", features = ["testing", "tonic"] } -miden-client-sqlite-store = { version = "0.15", package = "miden-client-sqlite-store" } -miden-protocol = { version = "0.15" } -rand = { version = "0.9" } -tokio = { version = "1.46", features = ["rt-multi-thread", "net", "macros", "fs"] } +# Clone tutorials next to this Cargo project (see Rust client setup). +rust-client = { path = "../tutorials/rust-client" } +miden-client = { version = "=0.16.0", features = ["testing", "tonic"] } +miden-client-sqlite-store = { version = "=0.16.0", package = "miden-client-sqlite-store" } +miden-protocol = { version = "=0.16.0" } +rand = { version = "0.10" } +tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } + +[profile.dev] +opt-level = 2 ``` ## Step 2: Initialize the client and prover and construct transactions Similarly to previous tutorials, we must instantiate the client. -We construct a `RemoteTransactionProver` pointed at the public Miden testnet delegated prover for this walkthrough. +We construct a `RemoteTransactionProver` pointed at the public Miden testnet delegated prover for this walkthrough. Copy this complete example into `src/main.rs`. The client creates `store.sqlite3` and `keystore/` in the project directory; keep both out of version control. ```rust no_run -use miden_client::auth::AuthSecretKey; -use miden_client::auth::{AuthSchemeId, AuthSingleSig}; -use rand::RngCore; +use rand::Rng; use std::{path::PathBuf, sync::Arc}; use miden_client::{ - account::component::BasicWallet, + ClientError, RemoteTransactionProver, + account::{AccountBuilder, AccountType, component::BasicWallet}, + auth::{AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, keystore::{FilesystemKeyStore, Keystore}, - rpc::{Endpoint, GrpcClient}, + rpc::{GrpcClient, VerifyingRpcClient}, transaction::{TransactionProver, TransactionRequestBuilder}, - ClientError, RemoteTransactionProver, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -use miden_client::account::{AccountBuilder, AccountType}; +use rust_client::{FeeConfig, TutorialNetwork, fund_account_for_fees}; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -95,12 +106,12 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; // Create Alice's account let mut init_seed = [0_u8; 32]; @@ -110,29 +121,37 @@ async fn main() -> Result<(), ClientError> { let alice_account = AccountBuilder::new(init_seed) .account_type(AccountType::Private) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet) .build() .unwrap(); client.add_account(&alice_account, false).await?; - keystore.add_key(&key_pair, alice_account.id()).await.unwrap(); + keystore + .add_key(&key_pair, alice_account.id()) + .await + .unwrap(); + fund_account_for_fees(&mut client, alice_account.id(), &fee_config).await?; // ------------------------------------------------------------------------- // Set up the delegated (remote) tx prover // ------------------------------------------------------------------------- // Delegated proving outsources ZK proof generation to a remote service. This is - // the public Miden testnet prover; run your own + // the public prover for the selected network; run your own // (https://crates.io/crates/miden-remote-prover) and swap the URL to use it. - // The constant `miden_client::grpc_support::TESTNET_PROVER_ENDPOINT` holds this - // same URL. - let remote_tx_prover = RemoteTransactionProver::new("https://tx-prover.testnet.miden.io"); + // The upstream constant keeps this URL synchronized with the selected network. + let remote_tx_prover = RemoteTransactionProver::new(network.remote_prover_url()); let tx_prover: Arc = Arc::new(remote_tx_prover); // We use a dummy transaction request to showcase delegated proving. - // The only effect of this tx should be increasing Alice's nonce. - println!("Alice nonce initial: {:?}", alice_account.nonce()); - let script_code = "begin push.1 drop end"; + // In addition to paying the network fee, this transaction increments Alice's nonce. + let initial_nonce = client + .get_account(alice_account.id()) + .await? + .expect("Alice exists") + .nonce(); + println!("Alice nonce initial: {:?}", initial_nonce); + let script_code = "@transaction_script pub proc main push.1 drop end"; let tx_script = client .code_builder() .compile_tx_script(script_code) @@ -145,6 +164,7 @@ async fn main() -> Result<(), ClientError> { // Step 1: Execute the transaction locally println!("Executing transaction..."); + client.sync_state().await?; let tx_result = client .execute_transaction(alice_account.id(), transaction_request) .await?; @@ -163,6 +183,7 @@ async fn main() -> Result<(), ClientError> { client .apply_transaction(&tx_result, submission_height) .await?; + rust_client::wait_for_transaction(&mut client, tx_result.id()).await?; println!("Transaction submitted successfully using the delegated prover!"); @@ -175,6 +196,7 @@ async fn main() -> Result<(), ClientError> { .expect("alice account not found"); println!("Alice nonce has increased: {:?}", account.nonce()); + assert_eq!(account.nonce(), initial_nonce + miden_client::Felt::ONE); Ok(()) } @@ -183,28 +205,29 @@ async fn main() -> Result<(), ClientError> { Now let's run the `src/main.rs` program: ```bash -cargo run --release +TUTORIAL_NETWORK=testnet cargo run --release ``` -The output will look like this: +The following is an abbreviated output. The funding transaction has already increased Alice's nonce from 0 to 1; the delegated transaction then increases it to 2: ```text -Latest block: 488706 -Alice nonce initial: 0 +Latest block: +Alice nonce initial: 1 Executing transaction... Proving transaction with the delegated prover... Submitting proven transaction... +Transaction committed: Transaction submitted successfully using the delegated prover! -Alice nonce has increased: 1 +Alice nonce has increased: 2 ``` ### Running the example -To run a full working example navigate to the `rust-client` directory in the [miden-tutorials](https://github.com/0xMiden/miden-tutorials/) repository and run this command: +From the root of your `tutorials` clone, run the checked-in example: ```bash cd rust-client -cargo run --release --bin delegated_prover +TUTORIAL_NETWORK=testnet cargo run --release --bin delegated_prover ``` ### Continue learning diff --git a/docs/src/rust-client/foreign_procedure_invocation_tutorial.md b/docs/src/rust-client/foreign_procedure_invocation_tutorial.md index eb178162..b18bb126 100644 --- a/docs/src/rust-client/foreign_procedure_invocation_tutorial.md +++ b/docs/src/rust-client/foreign_procedure_invocation_tutorial.md @@ -7,6 +7,8 @@ sidebar_position: 7 _Using foreign procedure invocation to craft read-only cross-contract calls in the Miden VM_ +For toolchain requirements and shared fee helpers, see the [Rust client setup](./index.md#running-the-v016-examples). + ## Overview In previous tutorials we deployed a public counter contract and incremented the count from a different client instance. @@ -32,43 +34,91 @@ The diagram above depicts the "count copy" smart contract using foreign procedur ## Prerequisites -This tutorial assumes you have a basic understanding of Miden assembly and completed the previous tutorial on deploying the counter contract. We will be working within the same `miden-counter-contract` repository that we created in the [Interacting with Public Smart Contracts](./public_account_interaction_tutorial.md) tutorial. +This tutorial assumes you have a basic understanding of Miden assembly and a counter deployed using the [counter contract tutorial](./counter_contract_tutorial.md). Keep its printed `mtst1...` account ID. The reader runs in a separate Cargo project and reads that counter's public state. ## Step 1: Set up your repository -We will be using the same repository used in the "Interacting with Public Smart Contracts" tutorial. To set up your repository for this tutorial, first follow up until step two [here](./public_account_interaction_tutorial.md). +From the parent directory of your `tutorials` clone, create a sibling Cargo project: + +```bash +cargo new miden-fpi +cd miden-fpi +rustup override set 1.98.1 +cp ../tutorials/rust-client/Cargo.lock Cargo.lock +``` + +Add these dependencies and the development profile to your `Cargo.toml`: + +```toml +[dependencies] +rust-client = { path = "../tutorials/rust-client" } +miden-client = { version = "=0.16.0", features = ["testing", "tonic"] } +miden-client-sqlite-store = { version = "=0.16.0", package = "miden-client-sqlite-store" } +miden-protocol = { version = "=0.16.0" } +rand = { version = "0.10" } +tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } + +[profile.dev] +opt-level = 2 +``` ## Step 2: Set up the "count reader" contract -Inside of the `masm/accounts/` directory, create the `count_reader.masm` file. This is the smart contract that will read the "count" value from the counter contract. +The reader contract in `masm/accounts/count_reader.masm` reads the counter’s value through FPI. `masm/accounts/count_reader.masm`: ```masm -use miden::protocol::active_account use miden::protocol::native_account use miden::protocol::tx -use miden::core::word use miden::core::sys +use {AccountId, AccountProcedureRoot} from miden::protocol::types + +# CONSTANTS +# ================================================================================================= const COUNT_READER_SLOT = word("miden::tutorials::count_reader") -# => [account_id_suffix, account_id_prefix, PROC_HASH(4), foreign_procedure_inputs(16)] -pub proc copy_count +# PUBLIC INTERFACE +# ================================================================================================= + +#! Copies the count returned by the foreign counter into this account's storage. +#! +#! Inputs: [foreign_account_id_{suffix,prefix}, FOREIGN_PROC_ROOT, pad(10)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - foreign_account_id_{suffix,prefix} identifies the public counter account. +#! - FOREIGN_PROC_ROOT is the root of its get_count procedure. +#! +#! Invocation: call +@account_procedure +@locals(6) +pub proc copy_count(foreign_account_id: AccountId, foreign_proc_root: AccountProcedureRoot) + # save the foreign target while preparing its sixteen zero inputs + loc_store.4 loc_store.5 loc_storew_le.0 dropw + # => [pad(16)] + + padw padw padw padw + # => [foreign_procedure_inputs(16), pad(16)] + + padw loc_loadw_le.0 loc_load.5 loc_load.4 + # => [foreign_account_id_suffix, foreign_account_id_prefix, FOREIGN_PROC_ROOT, foreign_procedure_inputs(16), pad(16)] + exec.tx::execute_foreign_procedure - # => [count, pad(12)] + # => [[count, 0, 0, 0], pad(28)] push.COUNT_READER_SLOT[0..2] - # [slot_id_prefix, slot_id_suffix, count, pad(12)] + # => [slot_id_suffix, slot_id_prefix, [count, 0, 0, 0], pad(28)] exec.native_account::set_item - # => [OLD_VALUE, pad(12)] + # => [OLD_VALUE, pad(28)] - dropw dropw dropw dropw - # => [] + dropw + # => [pad(28)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end ``` @@ -84,22 +134,33 @@ This is what the stack state should look like before we call `tx::execute_foreig `execute_foreign_procedure` always requires exactly 16 `foreign_procedure_inputs` on the stack below the procedure hash and account ID. Since `get_count` takes no arguments, we pass 16 zero -words (`padw padw padw padw`) as the inputs. After the call, the procedure returns 16 output -elements; the count word sits at the top and we clean up the rest with `dropw dropw dropw dropw`. +felts (`padw padw padw padw`, four words) as the inputs. The reader prepares these +inputs internally after saving the account ID and procedure root in local memory. The +caller therefore passes only those six identifying felts. After the foreign call, +the count is the first of 16 output elements; the reader stores its word, discards +the previous storage value, and truncates the remaining padding. After calling the `get_count` procedure in the counter contract, we save the count into the `miden::tutorials::count_reader` storage slot. -**Note**: _The bracket symbols used in the count copy contract are not valid MASM syntax. These are simply placeholder elements that we will replace with the actual values before compilation._ - -Inside the `masm/scripts/` directory, create the `reader_script.masm` file: +The transaction script is defined in `masm/scripts/reader_script.masm`: ```masm use external_contract::count_reader_contract use miden::core::sys -begin - padw padw padw padw +#! Copies a public counter through the reader account. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) + dropw # => [pad(16)] push.{get_count_proc_hash} @@ -112,43 +173,49 @@ begin # => [account_id_suffix, account_id_prefix, GET_COUNT_HASH, pad(16)] call.count_reader_contract::copy_count - # => [] + # => [pad(22)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end ``` -**Note**: _`push.{get_count_proc_hash}` is not valid MASM, we will format the string with the value get_count_proc_hash before passing this script code to the assembler._ +The braces mark template values, not valid MASM operands. The Rust code replaces the procedure root and both account ID elements before assembling the script. -### Step 3: Set up your `src/main.rs` file: +## Step 3: Set up your `src/main.rs` file ```rust no_run -use rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc, time::Duration}; use tokio::time::sleep; use miden_client::{ + ClientError, Word, account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountId, - AccountType, StorageSlot, StorageSlotName, + AccountBuilder, AccountComponent, AccountId, AccountType, StorageSlot, StorageSlotName, + component::{AccountComponentMetadata, BasicWallet}, }, auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, - rpc::{domain::account::AccountStorageRequirements, Endpoint, GrpcClient}, + rpc::{GrpcClient, VerifyingRpcClient, domain::account::AccountStorageRequirements}, transaction::{ForeignAccount, TransactionRequestBuilder}, - ClientError, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::{FeeConfig, TutorialNetwork, fund_account_for_fees}; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); + // Initialize keystore let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); @@ -158,27 +225,30 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; // ------------------------------------------------------------------------- // STEP 1: Create the Count Reader Contract // ------------------------------------------------------------------------- println!("\n[STEP 1] Creating count reader 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 count_reader_code = include_str!("../masm/accounts/count_reader.masm"); + // Read the MASM source from the tutorials repository. + let count_reader_code = + std::fs::read_to_string("../tutorials/masm/accounts/count_reader.masm").unwrap(); let count_reader_slot_name = StorageSlotName::new("miden::tutorials::count_reader").expect("valid slot name"); let count_reader_component_code = client .code_builder() - .compile_component_code("external_contract::count_reader_contract", count_reader_code) + .compile_component_code( + "external_contract::count_reader_contract", + &count_reader_code, + ) .unwrap(); let count_reader_component = AccountComponent::new( count_reader_component_code, @@ -196,7 +266,8 @@ async fn main() -> Result<(), ClientError> { let count_reader_contract = AccountBuilder::new(init_seed) .account_type(AccountType::Public) .with_component(count_reader_component.clone()) - .with_auth_component(NoAuth) + .with_component(BasicWallet) + .with_component(NoAuth) .build() .unwrap(); @@ -204,12 +275,13 @@ async fn main() -> Result<(), ClientError> { "count_reader hash: {:?}", count_reader_contract.to_commitment() ); - println!("contract id: {:?}", count_reader_contract.id()); + println!("count_reader id: {:?}", count_reader_contract.id()); client .add_account(&count_reader_contract, false) .await .unwrap(); + fund_account_for_fees(&mut client, count_reader_contract.id(), &fee_config).await?; Ok(()) } @@ -218,22 +290,24 @@ async fn main() -> Result<(), ClientError> { Run the following command to execute src/main.rs: ```bash -cargo run --release +TUTORIAL_NETWORK=testnet cargo run --release ``` -The output of our program will look something like this: +The output includes the reader's initial commitment and ID (abridged; values vary): ```text -Latest block: 226976 +Latest block: [STEP 1] Creating count reader contract. -count_reader hash: RpoDigest([15888177100833057221, 15548657445961063290, 5580812380698193124, 9604096693288041818]) -contract id: "" +count_reader hash: Word([...]) +count_reader id: V1(AccountIdV1 { suffix: ..., prefix: ... }) ``` ## Step 4: Import the pre-deployed counter contract -The FPI call needs a counter contract already deployed on-chain. We import the counter contract that was deployed in the [counter contract tutorial](./counter_contract_tutorial.md) by its testnet address: +The FPI call needs a counter contract already deployed on-chain. Copy its `mtst1...` testnet account ID into the `MIDEN_COUNTER_ACCOUNT_ID` environment variable. Using an input avoids baking in an address that becomes invalid after a testnet reset. + +Insert this fragment inside `main`, immediately before its final `Ok(())`: ```rust ignore // ------------------------------------------------------------------------- @@ -241,9 +315,19 @@ The FPI call needs a counter contract already deployed on-chain. We import the c // ------------------------------------------------------------------------- println!("\n[STEP 2] Building counter contract from public state"); -// Define the Counter Contract account id from counter contract deploy -let (_, counter_contract_id) = - AccountId::from_bech32("mtst1apcqs7aj3a2cf5t6pnsfy0p4ns7wl7sp").unwrap(); +// Pass the account ID printed by `counter_contract_deploy` as the first argument, or via +// `MIDEN_COUNTER_ACCOUNT_ID`. +let counter_contract_bech32 = std::env::args() + .nth(1) + .or_else(|| std::env::var("MIDEN_COUNTER_ACCOUNT_ID").ok()) + .expect("pass the counter account ID from counter_contract_deploy"); +let (account_network, counter_contract_id) = + AccountId::from_bech32(&counter_contract_bech32).expect("invalid counter account ID"); +assert_eq!( + account_network, + network.network_id(), + "counter account must match the selected tutorial network" +); println!("counter contract id: {:?}", counter_contract_id); @@ -265,7 +349,7 @@ println!( ## Step 5: Call the counter contract via foreign procedure invocation -Add this snippet to the end of your file in the `main()` function: +Insert this fragment after the import step, inside `main` and before `Ok(())`: ```rust ignore // ------------------------------------------------------------------------- @@ -273,14 +357,17 @@ 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_code = include_str!("../masm/accounts/counter.masm"); +let counter_contract_code = + std::fs::read_to_string("../tutorials/masm/accounts/counter.masm").unwrap(); // 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 = client .code_builder() - .compile_component_code("external_contract::counter_contract", counter_contract_code) + .compile_component_code( + "external_contract::counter_contract", + &counter_contract_code, + ) .unwrap(); let counter_component = AccountComponent::new( counter_component_code, @@ -291,7 +378,6 @@ let counter_component = AccountComponent::new( let get_count_root = counter_component .component_code() - .as_library() .get_procedure_root_by_path("external_contract::counter_contract::get_count") .expect("get_count export not found"); let get_count_hash = format!("{}", get_count_root); @@ -300,7 +386,8 @@ 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_code = include_str!("../masm/scripts/reader_script.masm") +let script_code = std::fs::read_to_string("../tutorials/masm/scripts/reader_script.masm") + .unwrap() .replace("{get_count_proc_hash}", &get_count_hash) .replace( "{account_id_suffix}", @@ -315,7 +402,10 @@ let script_code = include_str!("../masm/scripts/reader_script.masm") // that compiles the script. let tx_script = client .code_builder() - .with_linked_module("external_contract::count_reader_contract", count_reader_code) + .with_linked_module( + "external_contract::count_reader_contract", + &count_reader_code, + ) .unwrap() .compile_tx_script(script_code.as_str()) .unwrap(); @@ -330,12 +420,13 @@ let tx_request = TransactionRequestBuilder::new() .unwrap(); let tx_id = client - .submit_new_transaction(count_reader_contract.id(), tx_request) + .submit_tutorial_transaction(count_reader_contract.id(), tx_request) .await .unwrap(); println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); @@ -365,42 +456,56 @@ println!( "count reader contract storage: {:?}", account_2.storage().get_item(&count_reader_slot_name) ); +assert_eq!( + account_2 + .storage() + .get_item(&count_reader_slot_name) + .unwrap(), + account_1.storage().get_item(&counter_slot_name).unwrap(), + "FPI must copy the current counter value", +); ``` -The key here is the use of the `.foreign_accounts()` method on the `TransactionRequestBuilder`. Using this method, it is possible to create transactions with multiple foreign procedure calls. +The `.foreign_accounts()` method declares the foreign state that the client must fetch and prove. `AccountStorageRequirements::default()` suffices here because `get_count` reads a value slot. A procedure that reads map entries must also request proofs for the specific map keys it uses. The MASM script performs the actual foreign call. ## Summary -In this tutorial created a smart contract that calls the `get_count` procedure in the counter contract using foreign procedure invocation, and then saves the returned value to its local storage. +In this tutorial, we created a smart contract that calls the counter's `get_count` procedure through FPI and saves the returned value in its own storage. The reader account pays for this transaction; the foreign counter is read-only and is not charged or modified. The final `src/main.rs` file should look like this: ```rust no_run -use rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc, time::Duration}; use tokio::time::sleep; use miden_client::{ + ClientError, Word, account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountId, - AccountType, StorageSlot, StorageSlotName, + AccountBuilder, AccountComponent, AccountId, AccountType, StorageSlot, StorageSlotName, + component::{AccountComponentMetadata, BasicWallet}, }, auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, - rpc::{domain::account::AccountStorageRequirements, Endpoint, GrpcClient}, + rpc::{GrpcClient, VerifyingRpcClient, domain::account::AccountStorageRequirements}, transaction::{ForeignAccount, TransactionRequestBuilder}, - ClientError, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::{FeeConfig, TutorialNetwork, fund_account_for_fees}; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); + // Initialize keystore let keystore_path = PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); @@ -410,21 +515,21 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; // ------------------------------------------------------------------------- // STEP 1: Create the Count Reader Contract // ------------------------------------------------------------------------- println!("\n[STEP 1] Creating count reader 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 count_reader_code = include_str!("../masm/accounts/count_reader.masm"); + // Read the MASM source from the tutorials repository. + let count_reader_code = + std::fs::read_to_string("../tutorials/masm/accounts/count_reader.masm").unwrap(); let count_reader_slot_name = StorageSlotName::new("miden::tutorials::count_reader").expect("valid slot name"); @@ -432,7 +537,7 @@ async fn main() -> Result<(), ClientError> { .code_builder() .compile_component_code( "external_contract::count_reader_contract", - count_reader_code, + &count_reader_code, ) .unwrap(); let count_reader_component = AccountComponent::new( @@ -451,7 +556,8 @@ async fn main() -> Result<(), ClientError> { let count_reader_contract = AccountBuilder::new(init_seed) .account_type(AccountType::Public) .with_component(count_reader_component.clone()) - .with_auth_component(NoAuth) + .with_component(BasicWallet) + .with_component(NoAuth) .build() .unwrap(); @@ -465,15 +571,26 @@ async fn main() -> Result<(), ClientError> { .add_account(&count_reader_contract, false) .await .unwrap(); + fund_account_for_fees(&mut client, count_reader_contract.id(), &fee_config).await?; // ------------------------------------------------------------------------- // STEP 2: Build & Get State of the Counter Contract // ------------------------------------------------------------------------- println!("\n[STEP 2] Building counter contract from public state"); - // Define the Counter Contract account id from counter contract deploy - let (_, counter_contract_id) = - AccountId::from_bech32("mtst1apcqs7aj3a2cf5t6pnsfy0p4ns7wl7sp").unwrap(); + // Pass the account ID printed by `counter_contract_deploy` as the first argument, or via + // `MIDEN_COUNTER_ACCOUNT_ID`. + let counter_contract_bech32 = std::env::args() + .nth(1) + .or_else(|| std::env::var("MIDEN_COUNTER_ACCOUNT_ID").ok()) + .expect("pass the counter account ID from counter_contract_deploy"); + let (account_network, counter_contract_id) = + AccountId::from_bech32(&counter_contract_bech32).expect("invalid counter account ID"); + assert_eq!( + account_network, + network.network_id(), + "counter account must match the selected tutorial network" + ); println!("counter contract id: {:?}", counter_contract_id); @@ -497,13 +614,17 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 3] Call counter contract with FPI from count reader contract"); - let counter_contract_code = include_str!("../masm/accounts/counter.masm"); + let counter_contract_code = + std::fs::read_to_string("../tutorials/masm/accounts/counter.masm").unwrap(); // 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 = client .code_builder() - .compile_component_code("external_contract::counter_contract", counter_contract_code) + .compile_component_code( + "external_contract::counter_contract", + &counter_contract_code, + ) .unwrap(); let counter_component = AccountComponent::new( counter_component_code, @@ -514,7 +635,6 @@ async fn main() -> Result<(), ClientError> { let get_count_root = counter_component .component_code() - .as_library() .get_procedure_root_by_path("external_contract::counter_contract::get_count") .expect("get_count export not found"); let get_count_hash = format!("{}", get_count_root); @@ -523,7 +643,8 @@ async fn main() -> Result<(), ClientError> { println!("counter id prefix: {:?}", counter_contract_id.prefix()); println!("counter id suffix: {:?}", counter_contract_id.suffix()); - let script_code = include_str!("../masm/scripts/reader_script.masm") + let script_code = std::fs::read_to_string("../tutorials/masm/scripts/reader_script.masm") + .unwrap() .replace("{get_count_proc_hash}", &get_count_hash) .replace( "{account_id_suffix}", @@ -538,14 +659,16 @@ async fn main() -> Result<(), ClientError> { // that compiles the script. let tx_script = client .code_builder() - .with_linked_module("external_contract::count_reader_contract", count_reader_code) + .with_linked_module( + "external_contract::count_reader_contract", + &count_reader_code, + ) .unwrap() .compile_tx_script(script_code.as_str()) .unwrap(); let foreign_account = - ForeignAccount::public(counter_contract_id, AccountStorageRequirements::default()) - .unwrap(); + ForeignAccount::public(counter_contract_id, AccountStorageRequirements::default()).unwrap(); let tx_request = TransactionRequestBuilder::new() .foreign_accounts([foreign_account]) @@ -554,12 +677,13 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let tx_id = client - .submit_new_transaction(count_reader_contract.id(), tx_request) + .submit_tutorial_transaction(count_reader_contract.id(), tx_request) .await .unwrap(); println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); @@ -589,22 +713,32 @@ async fn main() -> Result<(), ClientError> { "count reader contract storage: {:?}", account_2.storage().get_item(&count_reader_slot_name) ); + assert_eq!( + account_2 + .storage() + .get_item(&count_reader_slot_name) + .unwrap(), + account_1.storage().get_item(&counter_slot_name).unwrap(), + "FPI must copy the current counter value", + ); Ok(()) } ``` -The output will show the count reader contract being created, the counter contract being imported from testnet, and finally both storage slots reflecting the same count value after the FPI transaction is confirmed. +Run the standalone project with `TUTORIAL_NETWORK=testnet cargo run --release`. With `MIDEN_COUNTER_ACCOUNT_ID` set, the output shows the reader being created, the counter imported from testnet, and both storage slots containing the same count after the FPI transaction is confirmed. The final assertion assumes the counter is not concurrently incremented while the example runs; use a fresh counter for this check. ### Running the example -To run the full example, navigate to the `rust-client` directory in the [miden-tutorials](https://github.com/0xMiden/miden-tutorials/) repository and run this command: +To run the checked-in example, return to the root of the [tutorials repository](https://github.com/0xMiden/tutorials/) and run: ```bash cd rust-client -cargo run --release --bin counter_contract_fpi +TUTORIAL_NETWORK=testnet cargo run --release --bin counter_contract_fpi -- "$MIDEN_COUNTER_ACCOUNT_ID" ``` +If `MIDEN_COUNTER_ACCOUNT_ID` is exported in your shell, you can omit `--` and the final argument. + ### Continue learning Next tutorial: [How to Use Unauthenticated Notes](unauthenticated_note_how_to.md) diff --git a/docs/src/rust-client/index.md b/docs/src/rust-client/index.md index 4515a95b..51180a8b 100644 --- a/docs/src/rust-client/index.md +++ b/docs/src/rust-client/index.md @@ -15,4 +15,38 @@ The Miden Rust client can be used for a variety of things, including: This section of the docs is an overview of the different things one can achieve using the Rust client, and how to implement them. +## Running the v0.16 examples + +The examples use Rust 1.98.1 and Miden v0.16. The repository includes the +required toolchain configuration and dependency lockfiles. + +From the repository root, run the Rust tutorials on testnet with Node.js and Yarn: + +```bash +yarn tutorials --rust +``` + +For devnet validation, run `TUTORIAL_NETWORK=devnet yarn tutorials --rust` instead. + +The runner uses a fresh store for each example and deploys a counter before the +FPI and public-account interaction examples. The [oracle tutorial](./oracle_tutorial.md) +requires an external deployment and is excluded from the default run. + +Testnet transactions pay fees in the native asset. The shared +[`rust-client` helpers](https://github.com/0xMiden/tutorials/blob/next/rust-client/src/lib.rs) +fund each executing account, synchronize before submission, and wait for confirmation. +They also filter `TX_FEE` notes when selecting tutorial notes. Set +`MIDEN_FAUCET_URL` if you need to override the network's public faucet API. + +To follow a tutorial in a standalone project, clone this repository as `tutorials` +and create the project alongside it. The tutorial's `Cargo.toml` includes the +local `rust-client` dependency and development optimization profile. Follow its +commands to select the Rust toolchain and copy the repository's `Cargo.lock`. +Run the first build without `--locked` so Cargo can add the new project's package +entry to the lockfile. + +Run standalone programs from their Cargo project directory. They load the shared +MASM files from `../tutorials/masm/`; the corresponding tutorial shows and explains +those sources. No additional MASM files need to be copied into the new project. + Keep in mind that both the Rust client and the documentation are works-in-progress! 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 5053700c..be7f6127 100644 --- a/docs/src/rust-client/mappings_in_masm_how_to.md +++ b/docs/src/rust-client/mappings_in_masm_how_to.md @@ -7,6 +7,8 @@ sidebar_position: 10 _Using mappings in Miden assembly for storing key value pairs_ +For toolchain requirements and shared fee helpers, see the [Rust client setup](./index.md#running-the-v016-examples). + ## Overview In this example, we will explore how to use mappings in Miden Assembly. Mappings are essential data structures that store key-value pairs. We will demonstrate how to create an account that contains a mapping and then call a procedure in that account to update the mapping. @@ -16,8 +18,7 @@ At a high level, this example involves: - Setting up an account with a mapping stored in one of its storage slots. - Writing a smart contract in Miden Assembly that includes procedures to read from and write to the mapping. - Creating a transaction script that calls these procedures. -- Using Rust code to deploy the account and submit a transaction that updates the mapping. - After the Miden Assembly snippets, we explain that the transaction script calls a procedure in the account. This procedure then updates the mapping by modifying the mapping stored in the account's storage slot. +- Using Rust code to deploy the account and submit a transaction that updates the mapping. ## What we'll cover @@ -42,46 +43,67 @@ At a high level, this example involves: ```masm use miden::protocol::active_account use miden::protocol::native_account -use miden::core::word use miden::core::sys +use {StorageMapKey} from miden::protocol::types + +# CONSTANTS +# ================================================================================================= const MAP_SLOT = word("miden::tutorials::mapping::map") -# Inputs: [KEY, VALUE] -# Outputs: [] -pub proc write_to_map - # The storage map is in the mapping slot. +# PUBLIC INTERFACE +# ================================================================================================= + +#! Stores VALUE under KEY in the mapping. +#! +#! Inputs: [KEY, VALUE, pad(8)] +#! Outputs: [pad(16)] +#! +#! Invocation: call +@account_procedure +pub proc write_to_map(key: StorageMapKey, value: word) + # the storage map is in the mapping slot push.MAP_SLOT[0..2] - # => [slot_id_prefix, slot_id_suffix, KEY, VALUE] + # => [slot_id_suffix, slot_id_prefix, KEY, VALUE, pad(8)] - # Setting the key value pair in the map + # set the key-value pair in the map exec.native_account::set_map_item - # => [OLD_VALUE] + # => [OLD_VALUE, pad(12)] dropw - # => [] + # => [pad(16)] end -# Inputs: [KEY] -# Outputs: [VALUE] -pub proc get_value_in_map - # The storage map is in the mapping slot. +#! Returns the VALUE stored under KEY in the mapping. +#! +#! Inputs: [KEY, pad(12)] +#! Outputs: [VALUE, pad(12)] +#! +#! Invocation: call +@account_procedure +pub proc get_value_in_map(key: StorageMapKey) -> word + # the storage map is in the mapping slot push.MAP_SLOT[0..2] - # => [slot_id_prefix, slot_id_suffix, KEY] + # => [slot_id_suffix, slot_id_prefix, KEY, pad(12)] exec.active_account::get_map_item - # => [VALUE] + # => [VALUE, pad(12)] end -# Inputs: [] -# Outputs: [CURRENT_ROOT] -pub proc get_current_map_root - # Getting the current root from the mapping slot. +#! Returns the CURRENT_ROOT of the mapping. +#! +#! Inputs: [pad(16)] +#! Outputs: [CURRENT_ROOT, pad(12)] +#! +#! Invocation: call +@account_procedure +pub proc get_current_map_root() -> word + # get the current root from the mapping slot push.MAP_SLOT[0..2] exec.active_account::get_item - # => [CURRENT_ROOT] + # => [CURRENT_ROOT, pad(16)] exec.sys::truncate_stack - # => [CURRENT_ROOT] + # => [CURRENT_ROOT, pad(12)] end ``` @@ -95,7 +117,7 @@ end - **get_current_map_root:** This procedure retrieves the current root of the mapping by calling `get_item` with the mapping slot ID and then truncating the stack to leave only the mapping root. -**Security Note**: The procedure `write_to_map` calls the account procedure `incr_nonce`. This allows any external account to be able to write to the storage map of the account. Smart contract developers should know that procedures that call the `account::incr_nonce` procedure allow anyone to call the procedure and modify the state of the account. +The Rust account below uses `NoAuth`, so anyone can import its public state and submit a mapping update without a signature. `NoAuth` handles fee payment and nonce changes; incrementing a nonce does not itself grant authorization. Use an appropriate authentication component when writes should be restricted. ### Transaction script that calls the smart contract @@ -103,27 +125,42 @@ end use miden_by_example::mapping_example_contract use miden::core::sys -begin +#! Writes a mapping entry, reads it, and returns the current map root. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [CURRENT_ROOT, pad(12)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! - CURRENT_ROOT is the mapping's Merkle root after the write. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) -> word + dropw + # => [pad(16)] + push.1.2.3.4 push.0.0.0.0 - # => [KEY, VALUE] + # => [KEY, VALUE, pad(16)] call.mapping_example_contract::write_to_map - # => [] + # => [pad(24)] push.0.0.0.0 - # => [KEY] + # => [KEY, pad(24)] call.mapping_example_contract::get_value_in_map - # => [VALUE] + # => [VALUE, pad(24)] dropw - # => [] + # => [pad(24)] call.mapping_example_contract::get_current_map_root - # => [CURRENT_ROOT] + # => [CURRENT_ROOT, pad(20)] exec.sys::truncate_stack + # => [CURRENT_ROOT, pad(12)] end ``` @@ -131,7 +168,7 @@ end The transaction script does the following: -- It pushes a key (`[0.0.0.0]`) and a value (`[1.2.3.4]`) onto the stack. +- It pushes the value with `push.1.2.3.4`, then the key with `push.0.0.0.0`. The last pushed element is on top, so the stored value is `[4, 3, 2, 1]` and the key is `[0, 0, 0, 0]`. - It calls the `write_to_map` procedure, which is defined in the account’s smart contract. This updates the mapping in the account. - It then pushes the key again and calls `get_value_in_map` to retrieve the value associated with the key. - Finally, it calls `get_current_map_root` to get the current state (root) of the mapping. @@ -142,32 +179,62 @@ The script calls the `write_to_map` procedure in the account which writes the ke ### Rust code that sets everything up +From the parent directory of your `tutorials` clone, create a sibling Cargo project: + +```bash +cargo new miden-mappings +cd miden-mappings +rustup override set 1.98.1 +cp ../tutorials/rust-client/Cargo.lock Cargo.lock +``` + +Add these dependencies and the development profile to your `Cargo.toml`: + +```toml +[dependencies] +rust-client = { path = "../tutorials/rust-client" } +miden-client = { version = "=0.16.0", features = ["testing", "tonic"] } +miden-client-sqlite-store = { version = "=0.16.0", package = "miden-client-sqlite-store" } +miden-protocol = { version = "=0.16.0" } +rand = { version = "0.10" } +tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } + +[profile.dev] +opt-level = 2 +``` + 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 rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; use miden_client::{ + ClientError, account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, - AccountType, StorageMap, StorageSlot, StorageSlotName, + AccountBuilder, AccountComponent, AccountType, StorageMap, StorageMapKey, StorageSlot, + StorageSlotName, + component::{AccountComponentMetadata, BasicWallet}, }, auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, - rpc::{Endpoint, GrpcClient}, + rpc::{GrpcClient, VerifyingRpcClient}, transaction::TransactionRequestBuilder, - ClientError, Felt, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::{FeeConfig, TutorialNetwork, fund_account_for_fees}; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -179,29 +246,24 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; // ------------------------------------------------------------------------- // STEP 1: Deploy a smart contract with a mapping // ------------------------------------------------------------------------- println!("\n[STEP 1] Deploy a smart contract with a mapping"); - // 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"); + // Read the MASM source from the tutorials repository. + let account_code = + std::fs::read_to_string("../tutorials/masm/accounts/mapping_example_contract.masm") + .unwrap(); - // Using an empty storage value in slot 0 since this is usually reserved - // for the account pub_key and metadata - let empty_slot_name = - StorageSlotName::new("miden::tutorials::mapping::value").expect("valid slot name"); - let empty_storage_slot = StorageSlot::with_value(empty_slot_name.clone(), Word::default()); - - // initialize storage map + // Storage slots are named in v0.16; the component only needs its mapping slot. let storage_map = StorageMap::new(); let map_slot_name = StorageSlotName::new("miden::tutorials::mapping::map").expect("valid slot name"); @@ -210,16 +272,16 @@ async fn main() -> Result<(), ClientError> { // Compile the account code into `AccountComponent` with one storage slot let component_code = client .code_builder() - .compile_component_code("miden_by_example::mapping_example_contract", account_code) + .compile_component_code("miden_by_example::mapping_example_contract", &account_code) .unwrap(); let mapping_contract_component = AccountComponent::new( component_code, - vec![empty_storage_slot, storage_slot_map], + vec![storage_slot_map], AccountComponentMetadata::new("miden_by_example::mapping_example_contract"), ) .unwrap(); - // Init seed for the counter contract + // Init seed for the mapping contract let mut init_seed = [0_u8; 32]; client.rng().fill_bytes(&mut init_seed); @@ -227,7 +289,8 @@ async fn main() -> Result<(), ClientError> { let mapping_example_contract = AccountBuilder::new(init_seed) .account_type(AccountType::Public) .with_component(mapping_contract_component.clone()) - .with_auth_component(NoAuth) + .with_component(BasicWallet) + .with_component(NoAuth) .build() .unwrap(); @@ -235,21 +298,23 @@ async fn main() -> Result<(), ClientError> { .add_account(&mapping_example_contract, false) .await .unwrap(); + fund_account_for_fees(&mut client, mapping_example_contract.id(), &fee_config).await?; // ------------------------------------------------------------------------- // STEP 2: Call the Mapping Contract with a Script // ------------------------------------------------------------------------- println!("\n[STEP 2] Call Mapping Contract With Script"); - let script_code = include_str!("../masm/scripts/mapping_example_script.masm"); + let script_code = + std::fs::read_to_string("../tutorials/masm/scripts/mapping_example_script.masm").unwrap(); // Compile the transaction script with the account code linked as a // module on the same `CodeBuilder` chain. let tx_script = client .code_builder() - .with_linked_module("miden_by_example::mapping_example_contract", account_code) + .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 @@ -260,12 +325,13 @@ async fn main() -> Result<(), ClientError> { // Execute and submit the transaction let tx_id = client - .submit_new_transaction(mapping_example_contract.id(), tx_increment_request) + .submit_tutorial_transaction(mapping_example_contract.id(), tx_increment_request) .await .unwrap(); println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); @@ -276,19 +342,22 @@ async fn main() -> Result<(), ClientError> { .await .unwrap() .expect("mapping contract not found"); - let key = [ - Felt::new_unchecked(0), - Felt::new_unchecked(0), - Felt::new_unchecked(0), - Felt::new_unchecked(0), - ] - .into(); + let key = StorageMapKey::empty(); println!( "Mapping state\n Index: {:?}\n Key: {:?}\n Value: {:?}", map_slot_name, key, account.storage().get_map_item(&map_slot_name, key) ); + let value = account.storage().get_map_item(&map_slot_name, key).unwrap(); + assert_eq!( + value + .iter() + .map(|felt| felt.as_canonical_u64()) + .collect::>(), + vec![4, 3, 2, 1], + "the mapping must store the value written by the transaction script", + ); Ok(()) } @@ -297,10 +366,10 @@ async fn main() -> Result<(), ClientError> { ### What the Rust code does - **Client Initialization:** - The client is initialized with a connection to the Miden Testnet and a SQLite store. This sets up the environment to deploy and interact with accounts. + The client connects to Miden testnet and uses a SQLite store to track accounts, notes, and transactions. - **Deploying the Smart Contract:** - The account containing the mapping is created by reading the MASM smart contract from a file, compiling it into an `AccountComponent`, and deploying it using an `AccountBuilder`. + The account MASM is compiled into an `AccountComponent` with a named map slot. `AccountBuilder` creates the account locally; consuming its native-asset funding note publishes it on-chain. - **Creating and Executing a Transaction Script:** A separate MASM script is compiled into a `TransactionScript`. This script calls the smart contract's procedures to write to and then read from the mapping. @@ -312,11 +381,13 @@ async fn main() -> Result<(), ClientError> { ### Running the example -To run the full example, navigate to the `rust-client` directory in the [miden-tutorials](https://github.com/0xMiden/miden-tutorials/) repository and run this command: +For the standalone Cargo project, save the Rust code as `src/main.rs` and run `TUTORIAL_NETWORK=testnet cargo run --release`. + +To run the checked-in example, return to the root of the [tutorials repository](https://github.com/0xMiden/tutorials/) and run: ```bash cd rust-client -cargo run --release --bin mapping_example +TUTORIAL_NETWORK=testnet cargo run --release --bin mapping_example ``` This example shows how the script calls the procedure in the account, which then updates the mapping stored within the account. The mapping update is verified by reading the mapping’s key-value pair after the transaction completes. diff --git a/docs/src/rust-client/mint_consume_create_tutorial.md b/docs/src/rust-client/mint_consume_create_tutorial.md index b5b9377a..07e2cc2b 100644 --- a/docs/src/rust-client/mint_consume_create_tutorial.md +++ b/docs/src/rust-client/mint_consume_create_tutorial.md @@ -7,6 +7,8 @@ sidebar_position: 3 _Using the Miden client in Rust to mint, consume, and create notes_ +For toolchain requirements and shared fee helpers, see the [Rust client setup](./index.md#running-the-v016-examples). + ## Overview In the previous section, we initialized our repository and covered how to create an account and deploy a faucet. In this section, we will mint tokens from the faucet for _Alice_, consume the newly created notes, and demonstrate how to send assets to other accounts. @@ -19,13 +21,13 @@ In the previous section, we initialized our repository and covered how to create ## Step 1: Minting tokens from the faucet -To mint notes with tokens from the faucet we created, Alice needs to call the faucet with a mint transaction request. +To mint notes with tokens from the faucet we created, the client submits a mint transaction signed by the faucet's key. The faucet executes the transaction and creates a note for Alice; Alice later signs a separate transaction to consume it. _In essence, a transaction request is a structured template that outlines the data required to generate a zero-knowledge proof of a state change of an account. It specifies which input notes (if any) will be consumed, includes an optional transaction script to execute, and enumerates the set of notes expected to be created (if any)._ -Below is an example of a transaction request minting tokens from the faucet for Alice. This code snippet will create 5 transaction mint transaction requests. +Below is an example of a transaction request minting tokens from the faucet for Alice. This code snippet creates and confirms five mint transactions, each producing one note containing 100 raw units of the tutorial asset. Transaction fees are paid in the separate native fee asset. -Add this snippet to the end of your file in the `main()` function that we created in the previous chapter: +Continue the same project from [Creating Accounts and Faucets](./create_deploy_tutorial.md), keeping its `Cargo.toml` and seeded `Cargo.lock`. Insert this snippet inside `main()`, after the previous steps and immediately before its final `Ok(())`: ```rust ignore //------------------------------------------------------------ @@ -36,6 +38,7 @@ println!("\n[STEP 3] Minting 5 notes of 100 tokens each for Alice."); let amount: u64 = 100; let fungible_asset = FungibleAsset::new(faucet_account.id(), amount).unwrap(); +let mut minted_note_ids = Vec::new(); for i in 1..=5 { let transaction_request = TransactionRequestBuilder::new() .build_mint_fungible_asset( @@ -46,10 +49,16 @@ for i in 1..=5 { ) .unwrap(); + minted_note_ids.extend( + transaction_request + .expected_output_own_notes() + .iter() + .map(Note::id), + ); println!("tx request built"); let tx_id = client - .submit_new_transaction(faucet_account.id(), transaction_request) + .submit_tutorial_transaction(faucet_account.id(), transaction_request) .await?; println!( "Minted note #{} of {} tokens for Alice. TX: {:?}", @@ -68,14 +77,16 @@ Once Alice has minted a note from the faucet, she will eventually want to spend Minting a note from a faucet on Miden means a faucet account creates a new note targeted to the requesting account. The requesting account needs to consume this new note to have the assets appear in their account. -To identify consumable notes, the Miden client provides the `get_consumable_notes` function. Before calling it, ensure that the client state is synced. +To identify consumable notes, the Miden client provides `get_consumable_notes`. The `TutorialClientExt::get_consumable_tutorial_notes` wrapper used below filters out `TX_FEE` notes. Call it after syncing the client state. -_Tip: If you know how many notes to expect after a transaction, use an await or loop condition to check how many notes of the type you expect are available for consumption instead of using a set timeout before calling `get_consumable_notes`. This ensures your application isn't idle for longer than necessary._ +Track the output note IDs from each mint request and wait for those notes to be committed. Do not wait for the total consumable-note count to equal five: `TX_FEE` notes can also be consumable and make that condition impossible. The `wait_for_notes_by_id` helper in Step 3 polls for the specific minted notes with a timeout. #### Identifying which notes are available: ```rust ignore -let consumable_notes = client.get_consumable_notes(Some(alice_account.id())).await?; +let consumable_notes = client + .get_consumable_tutorial_notes(Some(alice_account.id())) + .await?; ``` ## Step 3: Consuming multiple notes in a single transaction: @@ -84,7 +95,7 @@ Now that we know how to identify notes ready to consume, let's consume the notes The following code snippet identifies consumable notes and consumes them in a single transaction. -Add this snippet to the end of your file in the `main()` function: +Insert this snippet after the preceding steps inside `main()`, immediately before its final `Ok(())`: ```rust ignore //------------------------------------------------------------ @@ -92,41 +103,17 @@ Add this snippet to the end of your file in the `main()` function: //------------------------------------------------------------ println!("\n[STEP 4] Alice will now consume all of her notes to consolidate them."); -// Consume all minted notes in a single transaction -loop { - // Resync to get the latest data - client.sync_state().await?; - - let consumable_notes = client - .get_consumable_notes(Some(alice_account.id())) - .await?; - let notes = consumable_notes - .iter() - .map(|(note, _)| note.clone().try_into()) - .collect::, _>>()?; - - if notes.len() == 5 { - println!("Found 5 consumable notes for Alice. Consuming them now..."); - let transaction_request = TransactionRequestBuilder::new() - .build_consume_notes(notes) - .unwrap(); - - let tx_id = client - .submit_new_transaction(alice_account.id(), transaction_request) - .await?; - println!( - "All of Alice's notes consumed successfully. TX: {:?}", - tx_id - ); - break; - } else { - println!( - "Currently, Alice has {} consumable notes. Waiting...", - notes.len() - ); - tokio::time::sleep(Duration::from_secs(3)).await; - } -} +// TX_FEE notes are also consumable. Select only the five P2ID notes we minted. +let notes = rust_client::wait_for_notes_by_id(&mut client, &minted_note_ids).await?; +assert_eq!(notes.len(), 5); +let transaction_request = TransactionRequestBuilder::new().build_consume_notes(notes)?; +let tx_id = client + .submit_tutorial_transaction(alice_account.id(), transaction_request) + .await?; +println!( + "All of Alice's notes consumed successfully. TX: {:?}", + tx_id +); ``` ## Step 4: Sending tokens to other accounts @@ -143,9 +130,9 @@ For the sake of the example, the first four P2ID transfers are handled in a sing To output multiple notes in a single transaction we need to create a list of our expected output notes. The expected output notes are the notes that we expect to create in our transaction request. -In the snippet below, we create an empty vector to store five P2ID output notes, loop over five iterations `(using 0..=4)` to create five unique dummy account IDs, build a P2ID note for each one, and push each note onto the vector. Finally, we build a transaction request using `.own_output_notes()`—passing in all five notes—and submit it to the node. +In the snippet below, we create an empty vector, loop over four iterations using `1..=4`, build a P2ID note for each generated dummy account ID, and push each note onto the vector. We pass all four notes to `.own_output_notes()` and submit one transaction. The following step sends the fifth note. -Add this snippet to the end of your file in the `main()` function: +Insert this snippet after the preceding steps inside `main()`, immediately before its final `Ok(())`: ```rust ignore //------------------------------------------------------------ @@ -168,30 +155,32 @@ for _ in 1..=4 { init_seed, AccountIdVersion::Version1, AccountType::Public, + AssetCallbackFlag::Disabled, ); let send_amount = 50; let fungible_asset = FungibleAsset::new(faucet_account.id(), send_amount).unwrap(); - let p2id_note = P2idNote::create( - alice_account.id(), - target_account_id, - vec![fungible_asset.into()], - NoteType::Public, - NoteAttachments::empty(), - client.rng(), - )?; + let p2id_note: Note = P2idNote::builder() + .sender(alice_account.id()) + .target(target_account_id) + .asset(fungible_asset) + .note_type(NoteType::Public) + .generate_serial_number(client.rng()) + .build()? + .into(); p2id_notes.push(p2id_note); } // Specifying output notes and creating a tx request to create them +let output_notes = p2id_notes; let transaction_request = TransactionRequestBuilder::new() - .own_output_notes(p2id_notes) + .own_output_notes(output_notes) .build() .unwrap(); let tx_id = client - .submit_new_transaction(alice_account.id(), transaction_request) + .submit_tutorial_transaction(alice_account.id(), transaction_request) .await?; println!("Submitted a transaction with 4 P2ID notes. TX: {:?}", tx_id); @@ -199,9 +188,9 @@ println!("Submitted a transaction with 4 P2ID notes. TX: {:?}", tx_id); ### Basic P2ID transfer -Now as an example, Alice will send some tokens to an account in a single transaction. +`build_pay_to_id` creates the P2ID note and transaction request for a single transfer. Alice will use it to send tokens to one more account. -Add this snippet to the end of your file in the `main()` function: +Insert this snippet after the preceding steps inside `main()`, immediately before its final `Ok(())`: ```rust ignore println!("Submitting one more single P2ID transaction..."); @@ -214,70 +203,85 @@ let target_account_id = AccountId::dummy( init_seed, AccountIdVersion::Version1, AccountType::Public, + AssetCallbackFlag::Disabled, ); let send_amount = 50; let fungible_asset = FungibleAsset::new(faucet_account.id(), send_amount).unwrap(); -let p2id_note = P2idNote::create( +let payment = PaymentNoteDescription::new( + vec![fungible_asset.into()], alice_account.id(), target_account_id, - vec![fungible_asset.into()], +); +let transaction_request = TransactionRequestBuilder::new().build_pay_to_id( + payment, NoteType::Public, - NoteAttachments::empty(), client.rng(), )?; -let transaction_request = TransactionRequestBuilder::new() - .own_output_notes(vec![p2id_note]) - .build() - .unwrap(); - let tx_id = client - .submit_new_transaction(alice_account.id(), transaction_request) + .submit_tutorial_transaction(alice_account.id(), transaction_request) .await?; println!("Submitted final P2ID transaction. TX: {:?}", tx_id); +let alice = client + .get_account(alice_account.id()) + .await? + .expect("Alice exists"); +let balance = alice + .vault() + .get_balance(AssetId::new_fungible(faucet_account.id()))?; +assert_eq!(balance.as_u64(), 250, "Alice should retain 500 - 250 MID"); + +println!("\nAll steps completed successfully!"); +println!("Alice created a wallet, a faucet was deployed,"); +println!("5 notes of 100 tokens were minted to Alice, those notes were consumed,"); +println!("and then Alice sent 5 separate 50-token notes to 5 different users."); ``` -Note: _In a production environment do not use `AccountId::dummy()`, this is simply for the sake of the tutorial example._ +Note: _`AccountId::dummy()` generates example IDs without deployable accounts or keys. These notes demonstrate creation and cannot be consumed by real recipients. Use actual recipient IDs when transferring useful assets._ ## Summary Your `src/main.rs` function should now look like this: ```rust no_run -use rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; use tokio::time::Duration; use miden_client::{ + ClientError, account::{ + AccountBuilder, AccountId, AccountType, component::{ - BasicWallet, BurnPolicyConfig, FungibleFaucet, MintPolicyConfig, PolicyRegistration, - TokenName, TokenPolicyManager, + create_singlesig_user_fungible_faucet, BasicWallet, BurnPolicy, FungibleFaucet, + MintPolicy, TokenName, TokenPolicyManager, }, - AccountBuilder, AccountId, AccountType, }, - address::NetworkId, - asset::{AssetAmount, FungibleAsset, TokenSymbol}, - auth::{AuthSchemeId, AuthSecretKey, AuthSingleSig}, + asset::{AssetAmount, AssetCallbackFlag, AssetId, FungibleAsset, TokenSymbol}, + auth::{AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, keystore::{FilesystemKeyStore, Keystore}, - note::{NoteAttachments, NoteType, P2idNote}, - rpc::{Endpoint, GrpcClient}, - transaction::TransactionRequestBuilder, - ClientError, + note::{Note, NoteType, P2idNote}, + rpc::{GrpcClient, VerifyingRpcClient}, + transaction::{PaymentNoteDescription, TransactionRequestBuilder}, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; use miden_protocol::account::AccountIdVersion; +use rust_client::{FeeConfig, TutorialNetwork, fund_account_for_fees}; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -289,12 +293,12 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; //------------------------------------------------------------ // STEP 1: Create a basic wallet for Alice @@ -310,7 +314,7 @@ async fn main() -> Result<(), ClientError> { // Build the account let alice_account = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet) .build() .unwrap(); @@ -319,11 +323,16 @@ async fn main() -> Result<(), ClientError> { client.add_account(&alice_account, false).await?; // Add the key pair to the keystore - keystore.add_key(&key_pair, alice_account.id()).await.unwrap(); + keystore + .add_key(&key_pair, alice_account.id()) + .await + .unwrap(); - let alice_account_id_bech32 = alice_account.id().to_bech32(NetworkId::Testnet); + let alice_account_id_bech32 = alice_account.id().to_bech32(network.network_id()); println!("Alice's account ID: {:?}", alice_account_id_bech32); + fund_account_for_fees(&mut client, alice_account.id(), &fee_config).await?; + //------------------------------------------------------------ // STEP 2: Deploy a fungible faucet //------------------------------------------------------------ @@ -342,40 +351,44 @@ async fn main() -> Result<(), ClientError> { let key_pair = AuthSecretKey::new_falcon512_poseidon2_with_rng(client.rng()); // Build the faucet account. - // In v0.15 the faucet is a `FungibleFaucet` component plus a `TokenPolicyManager` + // The faucet is a `FungibleFaucet` component plus a `TokenPolicyManager` // that registers an "allow all" mint (and burn) policy; minting is rejected // unless an active mint policy is present. - let faucet_account = AccountBuilder::new(init_seed) - .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) - .with_component( - FungibleFaucet::builder() - .name(TokenName::new("MID").unwrap()) - .symbol(symbol) - .decimals(decimals) - .max_supply(max_supply) - .build() - .unwrap(), - ) - .with_components( - TokenPolicyManager::new() - .with_mint_policy(MintPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap() - .with_burn_policy(BurnPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap(), - ) + let faucet = FungibleFaucet::builder() + .name(TokenName::new("MID").unwrap()) + .symbol(symbol) + .decimals(decimals) + .max_supply(max_supply) .build() .unwrap(); + let policies = TokenPolicyManager::builder() + .active_mint_policy(MintPolicy::allow_all()) + .active_burn_policy(BurnPolicy::allow_all()) + .build(); + // The SDK factory includes BasicWallet so the faucet can receive the native fee asset. + let faucet_account = create_singlesig_user_fungible_faucet( + init_seed, + faucet, + AuthSingleSig::from_public_key(key_pair.public_key()), + policies, + AccountType::Public, + ) + .unwrap(); // Add the faucet to the client client.add_account(&faucet_account, false).await?; // Add the key pair to the keystore - keystore.add_key(&key_pair, faucet_account.id()).await.unwrap(); + keystore + .add_key(&key_pair, faucet_account.id()) + .await + .unwrap(); - let faucet_account_id_bech32 = faucet_account.id().to_bech32(NetworkId::Testnet); + let faucet_account_id_bech32 = faucet_account.id().to_bech32(network.network_id()); println!("Faucet account ID: {:?}", faucet_account_id_bech32); + fund_account_for_fees(&mut client, faucet_account.id(), &fee_config).await?; + // Resync to show newly deployed faucet client.sync_state().await?; tokio::time::sleep(Duration::from_secs(2)).await; @@ -388,6 +401,7 @@ async fn main() -> Result<(), ClientError> { let amount: u64 = 100; let fungible_asset = FungibleAsset::new(faucet_account.id(), amount).unwrap(); + let mut minted_note_ids = Vec::new(); for i in 1..=5 { let transaction_request = TransactionRequestBuilder::new() .build_mint_fungible_asset( @@ -398,10 +412,16 @@ async fn main() -> Result<(), ClientError> { ) .unwrap(); + minted_note_ids.extend( + transaction_request + .expected_output_own_notes() + .iter() + .map(Note::id), + ); println!("tx request built"); let tx_id = client - .submit_new_transaction(faucet_account.id(), transaction_request) + .submit_tutorial_transaction(faucet_account.id(), transaction_request) .await?; println!( "Minted note #{} of {} tokens for Alice. TX: {:?}", @@ -418,40 +438,17 @@ async fn main() -> Result<(), ClientError> { //------------------------------------------------------------ println!("\n[STEP 4] Alice will now consume all of her notes to consolidate them."); - // Consume all minted notes in a single transaction - loop { - // Resync to get the latest data - client.sync_state().await?; - - let consumable_notes = client - .get_consumable_notes(Some(alice_account.id())) - .await?; - let notes = consumable_notes - .iter() - .map(|(note, _)| note.clone().try_into()) - .collect::, _>>()?; - - if notes.len() == 5 { - println!("Found 5 consumable notes for Alice. Consuming them now..."); - let transaction_request = - TransactionRequestBuilder::new().build_consume_notes(notes)?; - - let tx_id = client - .submit_new_transaction(alice_account.id(), transaction_request) - .await?; - println!( - "All of Alice's notes consumed successfully. TX: {:?}", - tx_id - ); - break; - } else { - println!( - "Currently, Alice has {} consumable notes. Waiting...", - notes.len() - ); - tokio::time::sleep(Duration::from_secs(3)).await; - } - } + // TX_FEE notes are also consumable. Select only the five P2ID notes we minted. + let notes = rust_client::wait_for_notes_by_id(&mut client, &minted_note_ids).await?; + assert_eq!(notes.len(), 5); + let transaction_request = TransactionRequestBuilder::new().build_consume_notes(notes)?; + let tx_id = client + .submit_tutorial_transaction(alice_account.id(), transaction_request) + .await?; + println!( + "All of Alice's notes consumed successfully. TX: {:?}", + tx_id + ); //------------------------------------------------------------ // STEP 5: Alice sends 5 notes of 50 tokens to 5 users @@ -473,19 +470,20 @@ async fn main() -> Result<(), ClientError> { init_seed, AccountIdVersion::Version1, AccountType::Public, + AssetCallbackFlag::Disabled, ); let send_amount = 50; let fungible_asset = FungibleAsset::new(faucet_account.id(), send_amount).unwrap(); - let p2id_note = P2idNote::create( - alice_account.id(), - target_account_id, - vec![fungible_asset.into()], - NoteType::Public, - NoteAttachments::empty(), - client.rng(), - )?; + let p2id_note: Note = P2idNote::builder() + .sender(alice_account.id()) + .target(target_account_id) + .asset(fungible_asset) + .note_type(NoteType::Public) + .generate_serial_number(client.rng()) + .build()? + .into(); p2id_notes.push(p2id_note); } @@ -497,7 +495,7 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let tx_id = client - .submit_new_transaction(alice_account.id(), transaction_request) + .submit_tutorial_transaction(alice_account.id(), transaction_request) .await?; println!("Submitted a transaction with 4 P2ID notes. TX: {:?}", tx_id); @@ -512,30 +510,36 @@ async fn main() -> Result<(), ClientError> { init_seed, AccountIdVersion::Version1, AccountType::Public, + AssetCallbackFlag::Disabled, ); let send_amount = 50; let fungible_asset = FungibleAsset::new(faucet_account.id(), send_amount).unwrap(); - let p2id_note = P2idNote::create( + let payment = PaymentNoteDescription::new( + vec![fungible_asset.into()], alice_account.id(), target_account_id, - vec![fungible_asset.into()], + ); + let transaction_request = TransactionRequestBuilder::new().build_pay_to_id( + payment, NoteType::Public, - NoteAttachments::empty(), client.rng(), )?; - let transaction_request = TransactionRequestBuilder::new() - .own_output_notes(vec![p2id_note]) - .build() - .unwrap(); - let tx_id = client - .submit_new_transaction(alice_account.id(), transaction_request) + .submit_tutorial_transaction(alice_account.id(), transaction_request) .await?; println!("Submitted final P2ID transaction. TX: {:?}", tx_id); + let alice = client + .get_account(alice_account.id()) + .await? + .expect("Alice exists"); + let balance = alice + .vault() + .get_balance(AssetId::new_fungible(faucet_account.id()))?; + assert_eq!(balance.as_u64(), 250, "Alice should retain 500 - 250 MID"); println!("\nAll steps completed successfully!"); println!("Alice created a wallet, a faucet was deployed,"); @@ -549,43 +553,35 @@ async fn main() -> Result<(), ClientError> { Let's run the `src/main.rs` program again: ```bash -cargo run --release +TUTORIAL_NETWORK=testnet cargo run --release ``` -The output will look like this: +The following is an abbreviated output; IDs vary and the helper also prints funding and transaction confirmations: ```text -Latest block: 226896 +Latest block: [STEP 1] Creating a new account for Alice -Alice's account ID: "" +Alice's account ID: "" [STEP 2] Deploying a new fungible faucet. -Faucet account ID: "" +Faucet account ID: "" [STEP 3] Minting 5 notes of 100 tokens each for Alice. tx request built -Minted note #1 of 100 tokens for Alice. -tx request built -Minted note #2 of 100 tokens for Alice. -tx request built -Minted note #3 of 100 tokens for Alice. -tx request built -Minted note #4 of 100 tokens for Alice. -tx request built -Minted note #5 of 100 tokens for Alice. +Minted note #1 of 100 tokens for Alice. TX: +... +Minted note #5 of 100 tokens for Alice. TX: All 5 notes minted for Alice successfully! [STEP 4] Alice will now consume all of her notes to consolidate them. -Currently, Alice has 2 consumable notes. Waiting... -Currently, Alice has 4 consumable notes. Waiting... -Found 5 consumable notes for Alice. Consuming them now... -All of Alice's notes consumed successfully. +All of Alice's notes consumed successfully. TX: [STEP 5] Alice sends 5 notes of 50 tokens each to 5 different users. Creating multiple P2ID notes for 4 target accounts in one transaction... -Submitted a transaction with 4 P2ID notes. +Submitted a transaction with 4 P2ID notes. TX: Submitting one more single P2ID transaction... +Submitted final P2ID transaction. TX: All steps completed successfully! Alice created a wallet, a faucet was deployed, @@ -595,11 +591,11 @@ and then Alice sent 5 separate 50-token notes to 5 different users. ### Running the example -To run a full working example navigate to the `rust-client` directory in the [miden-tutorials](https://github.com/0xMiden/miden-tutorials/) repository and run this command: +From the root of your `tutorials` clone, run the checked-in example: ```bash cd rust-client -cargo run --release --bin create_mint_consume_send +TUTORIAL_NETWORK=testnet cargo run --release --bin create_mint_consume_send ``` ### Continue learning diff --git a/docs/src/rust-client/network_transactions_tutorial.md b/docs/src/rust-client/network_transactions_tutorial.md index af4a239e..ef41d2d7 100644 --- a/docs/src/rust-client/network_transactions_tutorial.md +++ b/docs/src/rust-client/network_transactions_tutorial.md @@ -7,17 +7,21 @@ sidebar_position: 6 _Using the Miden client in Rust to deploy and interact with smart contracts using network transactions_ +For toolchain requirements and shared fee helpers, see the [Rust client setup](./index.md#running-the-v016-examples). + ## Overview In this tutorial, we will explore Network Transactions (NTXs) on Miden - a powerful feature that enables autonomous smart contract execution and public shared state management. Unlike local transactions that require users to execute and prove, network transactions are executed and proven by a network transaction builder. -We'll build a network counter smart contract using the same MASM code as the regular counter. In v0.15 there is no separate network storage mode. Instead, an account is a _network account_ — one the network transaction builder executes on a user's behalf — if and only if it is public (`AccountType::Public`) **and** carries the `AuthNetworkAccount` auth component with a non-empty note-script allowlist. The allowed note-script roots and transaction-script roots are pinned at account creation. Attaching a `NetworkAccountTarget` to a note is necessary but not sufficient: without the allowlist the node never classifies the account as a network account, and the note is silently orphaned. See the [account changes migration guide](https://docs.miden.xyz/builder/migration/account-changes). +We'll build a public network counter using the same MASM code as the regular counter. `AuthNetworkAccount` configures the note scripts that the network transaction builder may execute, and a fee policy prices those notes. The increment note also carries a `NetworkAccountTarget` attachment identifying its target. See the [account changes migration guide](https://docs.miden.xyz/builder/migration/account-changes). + +Deployment and subsequent updates are different operations. On a fee-enabled network, consuming the initial native-asset funding note publishes the new network account with count **0**. After publication, the public RPC rejects user-submitted transactions that directly update an existing network account. Alice must publish an increment note from her own account; the network transaction builder consumes it and changes the counter to **1**. This restriction is enforced by the [node's submission handler](https://github.com/0xMiden/node/blob/v0.16.0/crates/rpc/src/server/api/submit_proven_tx.rs#L94). ## What we'll cover - Understanding Network Transactions and when to use them - Deploying public smart contracts that the network operator can execute -- Using transaction scripts to initialize network contracts on-chain +- Publishing a new network account through its initial funding transaction - Creating network notes for user interactions - Validating network transaction results @@ -29,108 +33,134 @@ This tutorial assumes you have completed the [counter contract tutorial](counter Network transactions are executed and proven by the Miden operator rather than the client. They are useful for: -- **Public shared state**: Multiple users can interact with the same contract state without race conditions +- **Public shared state**: Multiple users can publish notes targeting the same contract; the network transaction builder orders their execution - **Autonomous execution**: Smart contracts can execute when conditions are met without user intervention - **Resource-constrained devices**: Clients that can't generate ZK proofs efficiently - **AMM applications**: Using network notes, you can build sophisticated AMMs where trades execute automatically -The main trade-off is reduced privacy since the operator can see transaction inputs. +The account state and increment notes in this example are public, so the operator can see the transaction inputs. ## Step 1: Initialize your repository -Create a new Rust repository for your Miden project and navigate to it: +From the parent directory of your `tutorials` clone, create a sibling Cargo project: ```bash cargo new miden-network-transactions cd miden-network-transactions +rustup override set 1.98.1 +cp ../tutorials/rust-client/Cargo.lock Cargo.lock ``` Add the following dependencies to your `Cargo.toml` file: ```toml [dependencies] -miden-client = { version = "0.15", features = ["testing", "tonic"] } -miden-client-sqlite-store = { version = "0.15", package = "miden-client-sqlite-store" } -miden-protocol = { version = "0.15" } -rand = { version = "0.9" } -tokio = { version = "1.46", features = ["rt-multi-thread", "net", "macros", "fs"] } +# Clone tutorials next to this Cargo project (see Rust client setup). +rust-client = { path = "../tutorials/rust-client" } +miden-client = { version = "=0.16.0", features = ["testing", "tonic"] } +miden-client-sqlite-store = { version = "=0.16.0", package = "miden-client-sqlite-store" } +miden-protocol = { version = "=0.16.0" } +rand = { version = "0.10" } +tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } + +[profile.dev] +opt-level = 2 ``` ## Step 2: Set up MASM files -Create the directory structure: - -```bash -mkdir -p masm/accounts masm/scripts masm/notes -``` +The example reads the counter and note sources from the repository’s `masm/` directory. ### Counter Contract We'll use the same counter contract MASM code as the regular counter tutorial. The key difference is in the Rust configuration, not the MASM code. -Create `masm/accounts/counter.masm`: +The counter is defined in `masm/accounts/counter.masm`: ```masm use miden::protocol::active_account use miden::protocol::native_account -use miden::core::word use miden::core::sys +# CONSTANTS +# ================================================================================================= + const COUNTER_SLOT = word("miden::tutorials::counter") -#! Inputs: [] -#! Outputs: [count] -pub proc get_count +# PUBLIC INTERFACE +# ================================================================================================= + +#! Returns the current count. +#! +#! Inputs: [pad(16)] +#! Outputs: [count, pad(15)] +#! +#! Invocation: call +@account_procedure +pub proc get_count() -> felt push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] exec.sys::truncate_stack - # => [count] + # => [count, pad(15)] end -#! Inputs: [] -#! Outputs: [] -pub proc increment_count +#! Increments the current count by one. +#! +#! Inputs: [pad(16)] +#! Outputs: [pad(16)] +#! +#! Invocation: call +@account_procedure +pub proc increment_count() push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] add.1 - # => [count+1] + # => [[count + 1, 0, 0, 0], pad(16)] push.COUNTER_SLOT[0..2] exec.native_account::set_item - # => [] + # => [OLD_VALUE, pad(16)] + + dropw + # => [pad(16)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end ``` -### Transaction Script for Deployment - -Create `masm/scripts/counter_script.masm`: - -```masm -use external_contract::counter_contract +### Initial deployment -begin - call.counter_contract::increment_count -end -``` - -This script executes a function call (increment) that creates a necessary state change for our contract to be deployed and stored on the network on-chain. In Miden, public contracts must have their state modified through a transaction to be properly registered and committed to the blockchain - simply creating the account isn't sufficient. +Creating an account locally does not publish it. The funding helper below creates +the new account's first committed transaction by consuming its native-asset note. +No separate increment transaction script is needed on a fee-enabled network. The +empty deployment request shown later is only for networks with zero fees, where +funding does not perform that initial transaction. ### Network Note for User Interaction -Create `masm/notes/network_increment_note.masm`. Note scripts are compiled as libraries; the `@note_script` attribute marks the entrypoint procedure. +The increment note is defined in `masm/notes/network_increment_note.masm`. Note scripts are compiled as libraries; the `@note_script` attribute marks the entrypoint procedure. ```masm use external_contract::counter_contract -#! Inputs: [] -#! Outputs: [] +#! Increments the network counter when this note is consumed. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused note script arguments. +#! +#! Invocation: dyncall @note_script -pub proc main +pub proc main(args: word) + dropw + # => [pad(16)] + call.counter_contract::increment_count + # => [pad(16)] end ``` @@ -143,69 +173,52 @@ 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 rust_client::TutorialClientExt; use std::{collections::BTreeSet, path::PathBuf, sync::Arc}; use miden_client::{ + Client, ClientError, Felt, Word, account::{ - component::{AccountComponentMetadata, AuthNetworkAccount, BasicWallet}, AccountBuilder, AccountComponent, - AccountType, StorageSlot, StorageSlotName, + AccountBuilder, AccountComponent, AccountType, StorageSlot, StorageSlotName, + component::{ + AccountComponentMetadata, AuthNetworkAccount, BasicConstantFeePolicy, BasicWallet, + FeePolicy, FeePolicyManager, + }, }, - address::NetworkId, - auth::{AuthSchemeId, AuthSecretKey, AuthSingleSig}, + asset::AssetAmount, + auth::{AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, crypto::FeltRng, keystore::{FilesystemKeyStore, Keystore}, note::{ NetworkAccountTarget, Note, NoteAssets, NoteAttachments, NoteError, NoteExecutionHint, - NoteRecipient, NoteStorage, NoteTag, NoteType, PartialNoteMetadata, + NoteRecipient, NoteStorage, NoteTag, NoteType, P2idNote, PartialNoteMetadata, }, - rpc::{Endpoint, GrpcClient}, - store::TransactionFilter, - transaction::{TransactionId, TransactionRequestBuilder, TransactionStatus}, - Client, ClientError, Felt, Word, + rpc::{GrpcClient, VerifyingRpcClient}, + transaction::{ExpirationTransactionScript, TransactionId, TransactionRequestBuilder}, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -use rand::RngCore; -use tokio::time::{sleep, Duration}; +use rand::Rng; +use rust_client::{FeeConfig, TutorialNetwork, fund_account_for_fees}; +use tokio::time::{Duration, sleep}; /// Waits for a specific transaction to be committed. async fn wait_for_tx( client: &mut Client, tx_id: TransactionId, ) -> Result<(), ClientError> { - loop { - client.sync_state().await?; - - // Check transaction status - let txs = client - .get_transactions(TransactionFilter::Ids(vec![tx_id])) - .await?; - let tx_committed = if !txs.is_empty() { - matches!(txs[0].status, TransactionStatus::Committed { .. }) - } else { - false - }; - - if tx_committed { - println!("✅ transaction {} committed", tx_id.to_hex()); - break; - } - - println!( - "Transaction {} not yet committed. Waiting...", - tx_id.to_hex() - ); - sleep(Duration::from_secs(2)).await; - } - Ok(()) + rust_client::wait_for_transaction(client, tx_id).await } #[tokio::main] async fn main() -> Result<(), Box> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -217,12 +230,13 @@ async fn main() -> Result<(), Box> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; + let fee_faucet_id = fee_config.native_fee_faucet_id(); // ------------------------------------------------------------------------- // STEP 1: Create Basic User Account @@ -238,7 +252,7 @@ async fn main() -> Result<(), Box> { // Build the account let alice_account = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet) .build() .unwrap(); @@ -247,11 +261,15 @@ async fn main() -> Result<(), Box> { client.add_account(&alice_account, false).await?; // Add the key pair to the keystore - keystore.add_key(&key_pair, alice_account.id()).await.unwrap(); + keystore + .add_key(&key_pair, alice_account.id()) + .await + .unwrap(); + fund_account_for_fees(&mut client, alice_account.id(), &fee_config).await?; println!( "Alice's account ID: {:?}", - alice_account.id().to_bech32(NetworkId::Testnet) + alice_account.id().to_bech32(network.network_id()) ); Ok(()) @@ -262,9 +280,17 @@ This step initializes the Miden client and creates a basic user account (Alice) ## Step 4: Create the network counter smart contract -Now we'll create the network smart contract. In v0.15 what makes an account network-executable is its auth component, not a storage mode: the contract is a public account (`AccountType::Public`) built with the `AuthNetworkAccount` component. Its note-script allowlist is what marks the account as a network account, and its transaction-script allowlist authorizes the deploy script in Step 5. Both allowlists are fixed at account creation, so we compile the note script and the deploy transaction script first and pass their MAST roots in. +Build a public account with `AuthNetworkAccount`, the counter component, and +`BasicWallet`. Compile the increment note first so its root can be allowlisted. +Also allow the P2ID funding note. Use `AuthNetworkAccount::custom` for this minimal +account and explicitly allow `ExpirationTransactionScript::script_root()`, which +the network builder uses. No configuration or sponsorship note scripts are +enabled: this account does not implement their required authority components. +There is no custom increment transaction script to allowlist. The zero per-note +policy charge does not remove the network's verification fee: the account pays +that fee from its funded native-asset balance. -Add this code to your `main()` function: +Insert this code inside `main`, immediately before its final `Ok(())`: ```rust ignore // ------------------------------------------------------------------------- @@ -272,44 +298,28 @@ Add this code to your `main()` function: // ------------------------------------------------------------------------- println!("\n[STEP 2] Creating a network counter smart 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"); -let script_code = include_str!("../masm/scripts/counter_script.masm"); -let network_note_code = include_str!("../masm/notes/network_increment_note.masm"); +// Read the MASM source from the tutorials repository. +let counter_code = std::fs::read_to_string("../tutorials/masm/accounts/counter.masm").unwrap(); +let network_note_code = + std::fs::read_to_string("../tutorials/masm/notes/network_increment_note.masm").unwrap(); -// In protocol v0.15 an account is a *network account* (one the network +// An account is a *network account* (one the network // transaction builder executes on a user's behalf) if and only if it is // public AND carries the `AuthNetworkAccount` auth component. That component -// holds two allowlists, both fixed at account creation: -// * the note-script allowlist: its presence is what marks the account as a -// network account, and the builder only executes notes whose script root -// is listed here; -// * the tx-script allowlist: the network auth procedure rejects any custom -// tx script whose root is not listed, so the STEP 3 deploy script must be -// in it. -// We therefore compile the note script and the deploy tx script now and feed -// their MAST roots into the allowlists below. Both compiled scripts are reused -// as-is in STEP 3 (tx script) and STEP 4 (note script) — nothing is compiled -// twice. +// holds an allowlist of note scripts the network builder may execute. +// Compile the increment note first so its root can be included at creation. let note_script = client .code_builder() - .with_linked_module("external_contract::counter_contract", counter_code)? - .compile_note_script(network_note_code)?; + .with_linked_module("external_contract::counter_contract", &counter_code)? + .compile_note_script(&network_note_code)?; let note_script_root = note_script.root(); -let tx_script = client - .code_builder() - .with_linked_module("external_contract::counter_contract", counter_code)? - .compile_tx_script(script_code)?; -let tx_script_root = tx_script.root(); - // Compile the counter MASM into an account component let counter_slot_name = StorageSlotName::new("miden::tutorials::counter").expect("valid slot name"); let component_code = client .code_builder() - .compile_component_code("external_contract::counter_contract", counter_code)?; + .compile_component_code("external_contract::counter_contract", &counter_code)?; let counter_component = AccountComponent::new( component_code, vec![StorageSlot::with_value( @@ -323,68 +333,83 @@ let counter_component = AccountComponent::new( let mut init_seed = [0_u8; 32]; client.rng().fill_bytes(&mut init_seed); -// Build the network account: public + `AuthNetworkAccount` with the note-script -// root allowlisted (this is what makes it a network account) and the deploy -// tx-script root allowlisted (so the auth procedure accepts the STEP 3 deploy). -let network_auth = AuthNetworkAccount::with_allowed_notes(BTreeSet::from([note_script_root]))? - .with_allowed_tx_scripts(BTreeSet::from([tx_script_root])); +// Build the public network account with the increment and funding notes allowed. +let fee_policy: FeePolicy = BasicConstantFeePolicy::new() + .with_fees( + [note_script_root, P2idNote::script_root()].map(|root| (root, AssetAmount::ZERO)), + ) + .into(); +let fee_policy_manager = FeePolicyManager::builder() + .fee_faucet_id(fee_faucet_id) + .active_fee_policy(fee_policy) + .build(); +// Match the protocol/node counter example: only permit the two note scripts +// this account implements. Config notes need Authority, which it does not have. +// The canonical expiration script is required by the network builder. +let network_auth = AuthNetworkAccount::custom( + BTreeSet::from([note_script_root, P2idNote::script_root()]), + fee_policy_manager, +)? +.with_allowed_tx_scripts([ExpirationTransactionScript::script_root()]); let counter_contract = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(network_auth) + .with_components(network_auth) .with_component(counter_component) + .with_component(BasicWallet) .build() .unwrap(); client.add_account(&counter_contract, false).await.unwrap(); +fund_account_for_fees(&mut client, counter_contract.id(), &fee_config).await?; println!( "contract id: {:?}", - counter_contract.id().to_bech32(NetworkId::Testnet) + counter_contract.id().to_bech32(network.network_id()) ); ``` -This step creates a public smart contract (`AccountType::Public`) whose `AuthNetworkAccount` component allowlists the increment note's script root — marking it as a network account the operator will execute — and the deploy transaction script's root, so the Step 5 deploy is authorized. +This step creates and funds a public network account. On a fee-enabled network, +the funding transaction also publishes it. Its counter remains zero. -## Step 5: Deploy the network account with a transaction script +## Step 5: Confirm publication of the network account -We use a transaction script to deploy the network account and ensure it's properly registered on-chain. The script calls the `increment` function, which initializes the counter to 1. +When fees are active, initial funding has already published the network account. Do not send +another direct increment transaction from the user client: the node rejects +user-submitted updates to existing network accounts. Only the zero-fee path needs +an explicit first deployment transaction here. -Add this code to your `main()` function: +Insert this code after account creation, inside `main` and before `Ok(())`: ```rust ignore // ------------------------------------------------------------------------- -// STEP 3: Deploy Network Account with Transaction Script +// STEP 3: Publish the network account // ------------------------------------------------------------------------- println!("\n[STEP 3] Deploy network counter smart contract"); -// Reuse the `tx_script` compiled in STEP 2 (its root is allowlisted on the -// account, so the network auth procedure accepts this deploy transaction). -let tx_increment_request = TransactionRequestBuilder::new() - .custom_script(tx_script) - .build() - .unwrap(); - -let tx_id = client - .submit_new_transaction(counter_contract.id(), tx_increment_request) - .await - .unwrap(); - -println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", - tx_id -); - -// Wait for the transaction to be committed -wait_for_tx(&mut client, tx_id).await.unwrap(); +// On a fee-enabled network, consuming the funding note already published this +// account. RPC permits users to deploy new network accounts, but rejects +// user-submitted transactions for existing ones. Subsequent increments must +// be requested by notes and executed by the network transaction builder. +if !fee_config.fees_are_active() { + let deployment = TransactionRequestBuilder::new().build()?; + client + .submit_tutorial_transaction(counter_contract.id(), deployment) + .await?; +} +println!("Network counter deployed; initial count is 0"); ``` -This step uses a transaction script to deploy the network account and ensure it's properly registered on-chain. The script calls the `increment` function, which initializes the counter to 1. +The initial committed count is zero. All later counter updates go through network +notes executed by the network transaction builder. ## Step 6: Create a network note for user interaction -We create a public note that the network operator can consume to execute the increment function. This increments the counter from 1 to 2. +Alice publishes a public increment note from her own funded account. The network +transaction builder then consumes that note on the counter's behalf, changing +the counter from zero to one. Confirmation of Alice's transaction alone is not +enough; the example also waits for the counter's updated state. -Add this code to your `main()` function: +Replace the final `Ok(())` in `main` with the following fragment. Its polling loop and final `Err(...)` expressions provide the function's result: ```rust ignore // ------------------------------------------------------------------------- @@ -420,11 +445,12 @@ let note_req = TransactionRequestBuilder::new() .build()?; let note_tx_id = client - .submit_new_transaction(alice_account.id(), note_req) + .submit_tutorial_transaction(alice_account.id(), note_req) .await?; println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), note_tx_id ); @@ -439,7 +465,7 @@ wait_for_tx(&mut client, note_tx_id).await.unwrap(); sleep(Duration::from_secs(6)).await; let mut last_val = None; -for _ in 0..10 { +for _ in 0..24 { client.sync_state().await?; // Checking updated state @@ -452,7 +478,7 @@ for _ in 0..10 { .unwrap() .into(); let val = count[0].as_canonical_u64(); - if val >= 2 { + if val == 1 { println!("🔢 Final counter value: {}", val); return Ok(()); } @@ -464,12 +490,12 @@ for _ in 0..10 { } // The network note was submitted, but it is executed asynchronously by the -// network transaction builder. If the counter has not reached 2 within the +// network transaction builder. If the counter has not reached 1 within the // polling window, the tutorial's final state is unconfirmed, so fail rather // than claim success. if let Some(val) = last_val { Err(format!( - "Counter did not reach the expected value 2 within the timeout (last observed {}). \ + "Counter did not reach the expected value 1 within the timeout (last observed {}). \ The network note was submitted but its execution is still pending on the network \ transaction builder; re-run or check Midenscan.", val @@ -481,78 +507,57 @@ if let Some(val) = last_val { } ``` -This step creates a public note that the network operator can consume to execute the increment function. This increments the counter from 1 to 2. +## Complete example -## Summary - -Your complete `main()` function should look like this: +Your complete `src/main.rs` file should look like this: ```rust no_run +use rust_client::TutorialClientExt; use std::{collections::BTreeSet, path::PathBuf, sync::Arc}; use miden_client::{ + Client, ClientError, Felt, Word, account::{ - component::{AccountComponentMetadata, AuthNetworkAccount, BasicWallet}, AccountBuilder, AccountComponent, - AccountType, StorageSlot, StorageSlotName, + AccountBuilder, AccountComponent, AccountType, StorageSlot, StorageSlotName, + component::{ + AccountComponentMetadata, AuthNetworkAccount, BasicConstantFeePolicy, BasicWallet, + FeePolicy, FeePolicyManager, + }, }, - address::NetworkId, - auth::{AuthSchemeId, AuthSecretKey, AuthSingleSig}, + asset::AssetAmount, + auth::{AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, crypto::FeltRng, keystore::{FilesystemKeyStore, Keystore}, note::{ NetworkAccountTarget, Note, NoteAssets, NoteAttachments, NoteError, NoteExecutionHint, - NoteRecipient, NoteStorage, NoteTag, NoteType, PartialNoteMetadata, - }, - rpc::{Endpoint, GrpcClient}, - store::TransactionFilter, - transaction::{ - TransactionId, TransactionRequestBuilder, TransactionStatus, + NoteRecipient, NoteStorage, NoteTag, NoteType, P2idNote, PartialNoteMetadata, }, - Client, ClientError, Felt, Word, + rpc::{GrpcClient, VerifyingRpcClient}, + transaction::{ExpirationTransactionScript, TransactionId, TransactionRequestBuilder}, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -use rand::RngCore; -use tokio::time::{sleep, Duration}; +use rand::Rng; +use rust_client::{FeeConfig, TutorialNetwork, fund_account_for_fees}; +use tokio::time::{Duration, sleep}; /// Waits for a specific transaction to be committed. async fn wait_for_tx( client: &mut Client, tx_id: TransactionId, ) -> Result<(), ClientError> { - loop { - client.sync_state().await?; - - // Check transaction status - let txs = client - .get_transactions(TransactionFilter::Ids(vec![tx_id])) - .await?; - let tx_committed = if !txs.is_empty() { - matches!(txs[0].status, TransactionStatus::Committed { .. }) - } else { - false - }; - - if tx_committed { - println!("✅ transaction {} committed", tx_id.to_hex()); - break; - } - - println!( - "Transaction {} not yet committed. Waiting...", - tx_id.to_hex() - ); - sleep(Duration::from_secs(2)).await; - } - Ok(()) + rust_client::wait_for_transaction(client, tx_id).await } #[tokio::main] async fn main() -> Result<(), Box> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -564,12 +569,13 @@ async fn main() -> Result<(), Box> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; + let fee_faucet_id = fee_config.native_fee_faucet_id(); // ------------------------------------------------------------------------- // STEP 1: Create Basic User Account @@ -585,7 +591,7 @@ async fn main() -> Result<(), Box> { // Build the account let alice_account = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet) .build() .unwrap(); @@ -594,11 +600,15 @@ async fn main() -> Result<(), Box> { client.add_account(&alice_account, false).await?; // Add the key pair to the keystore - keystore.add_key(&key_pair, alice_account.id()).await.unwrap(); + keystore + .add_key(&key_pair, alice_account.id()) + .await + .unwrap(); + fund_account_for_fees(&mut client, alice_account.id(), &fee_config).await?; println!( "Alice's account ID: {:?}", - alice_account.id().to_bech32(NetworkId::Testnet) + alice_account.id().to_bech32(network.network_id()) ); // ------------------------------------------------------------------------- @@ -606,44 +616,28 @@ async fn main() -> Result<(), Box> { // ------------------------------------------------------------------------- println!("\n[STEP 2] Creating a network counter smart 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"); - let script_code = include_str!("../masm/scripts/counter_script.masm"); - let network_note_code = include_str!("../masm/notes/network_increment_note.masm"); + // Read the MASM source from the tutorials repository. + let counter_code = std::fs::read_to_string("../tutorials/masm/accounts/counter.masm").unwrap(); + let network_note_code = + std::fs::read_to_string("../tutorials/masm/notes/network_increment_note.masm").unwrap(); - // In protocol v0.15 an account is a *network account* (one the network + // An account is a *network account* (one the network // transaction builder executes on a user's behalf) if and only if it is // public AND carries the `AuthNetworkAccount` auth component. That component - // holds two allowlists, both fixed at account creation: - // * the note-script allowlist: its presence is what marks the account as a - // network account, and the builder only executes notes whose script root - // is listed here; - // * the tx-script allowlist: the network auth procedure rejects any custom - // tx script whose root is not listed, so the STEP 3 deploy script must be - // in it. - // We therefore compile the note script and the deploy tx script now and feed - // their MAST roots into the allowlists below. Both compiled scripts are reused - // as-is in STEP 3 (tx script) and STEP 4 (note script) — nothing is compiled - // twice. + // holds an allowlist of note scripts the network builder may execute. + // Compile the increment note first so its root can be included at creation. let note_script = client .code_builder() - .with_linked_module("external_contract::counter_contract", counter_code)? - .compile_note_script(network_note_code)?; + .with_linked_module("external_contract::counter_contract", &counter_code)? + .compile_note_script(&network_note_code)?; let note_script_root = note_script.root(); - let tx_script = client - .code_builder() - .with_linked_module("external_contract::counter_contract", counter_code)? - .compile_tx_script(script_code)?; - let tx_script_root = tx_script.root(); - // Compile the counter MASM into an account component let counter_slot_name = StorageSlotName::new("miden::tutorials::counter").expect("valid slot name"); let component_code = client .code_builder() - .compile_component_code("external_contract::counter_contract", counter_code)?; + .compile_component_code("external_contract::counter_contract", &counter_code)?; let counter_component = AccountComponent::new( component_code, vec![StorageSlot::with_value( @@ -657,49 +651,56 @@ async fn main() -> Result<(), Box> { let mut init_seed = [0_u8; 32]; client.rng().fill_bytes(&mut init_seed); - // Build the network account: public + `AuthNetworkAccount` with the note-script - // root allowlisted (this is what makes it a network account) and the deploy - // tx-script root allowlisted (so the auth procedure accepts the STEP 3 deploy). - let network_auth = AuthNetworkAccount::with_allowed_notes(BTreeSet::from([note_script_root]))? - .with_allowed_tx_scripts(BTreeSet::from([tx_script_root])); + // Build the public network account with the increment and funding notes allowed. + let fee_policy: FeePolicy = BasicConstantFeePolicy::new() + .with_fees( + [note_script_root, P2idNote::script_root()].map(|root| (root, AssetAmount::ZERO)), + ) + .into(); + let fee_policy_manager = FeePolicyManager::builder() + .fee_faucet_id(fee_faucet_id) + .active_fee_policy(fee_policy) + .build(); + // Match the protocol/node counter example: only permit the two note scripts + // this account implements. Config notes need Authority, which it does not have. + // The canonical expiration script is required by the network builder. + let network_auth = AuthNetworkAccount::custom( + BTreeSet::from([note_script_root, P2idNote::script_root()]), + fee_policy_manager, + )? + .with_allowed_tx_scripts([ExpirationTransactionScript::script_root()]); let counter_contract = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(network_auth) + .with_components(network_auth) .with_component(counter_component) + .with_component(BasicWallet) .build() .unwrap(); client.add_account(&counter_contract, false).await.unwrap(); + fund_account_for_fees(&mut client, counter_contract.id(), &fee_config).await?; println!( "contract id: {:?}", - counter_contract.id().to_bech32(NetworkId::Testnet) + counter_contract.id().to_bech32(network.network_id()) ); // ------------------------------------------------------------------------- - // STEP 3: Deploy Network Account with Transaction Script + // STEP 3: Publish the network account // ------------------------------------------------------------------------- println!("\n[STEP 3] Deploy network counter smart contract"); - // Reuse the `tx_script` compiled in STEP 2 (its root is allowlisted on the - // account, so the network auth procedure accepts this deploy transaction). - let tx_increment_request = TransactionRequestBuilder::new() - .custom_script(tx_script) - .build() - .unwrap(); - - let tx_id = client - .submit_new_transaction(counter_contract.id(), tx_increment_request) - .await - .unwrap(); - - println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", - tx_id - ); - - // Wait for the transaction to be committed - wait_for_tx(&mut client, tx_id).await.unwrap(); + // On a fee-enabled network, consuming the funding note already published this + // account. RPC permits users to deploy new network accounts, but rejects + // user-submitted transactions for existing ones. Subsequent increments must + // be requested by notes and executed by the network transaction builder. + if !fee_config.fees_are_active() { + let deployment = TransactionRequestBuilder::new().build()?; + client + .submit_tutorial_transaction(counter_contract.id(), deployment) + .await?; + } + println!("Network counter deployed; initial count is 0"); // ------------------------------------------------------------------------- // STEP 4: Prepare & Create the Network Note @@ -734,11 +735,12 @@ async fn main() -> Result<(), Box> { .build()?; let note_tx_id = client - .submit_new_transaction(alice_account.id(), note_req) + .submit_tutorial_transaction(alice_account.id(), note_req) .await?; println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), note_tx_id ); @@ -753,7 +755,7 @@ async fn main() -> Result<(), Box> { sleep(Duration::from_secs(6)).await; let mut last_val = None; - for _ in 0..10 { + for _ in 0..24 { client.sync_state().await?; // Checking updated state @@ -766,7 +768,7 @@ async fn main() -> Result<(), Box> { .unwrap() .into(); let val = count[0].as_canonical_u64(); - if val >= 2 { + if val == 1 { println!("🔢 Final counter value: {}", val); return Ok(()); } @@ -778,12 +780,12 @@ async fn main() -> Result<(), Box> { } // The network note was submitted, but it is executed asynchronously by the - // network transaction builder. If the counter has not reached 2 within the + // network transaction builder. If the counter has not reached 1 within the // polling window, the tutorial's final state is unconfirmed, so fail rather // than claim success. if let Some(val) = last_val { Err(format!( - "Counter did not reach the expected value 2 within the timeout (last observed {}). \ + "Counter did not reach the expected value 1 within the timeout (last observed {}). \ The network note was submitted but its execution is still pending on the network \ transaction builder; re-run or check Midenscan.", val @@ -798,38 +800,33 @@ async fn main() -> Result<(), Box> { ## Step 7: Running the Example -To run the complete network transaction example: +For the standalone Cargo project, run `TUTORIAL_NETWORK=testnet cargo run --release` from `miden-network-transactions`. + +To run the checked-in example from the repository root: ```bash cd rust-client -cargo run --release --bin network_notes_counter_contract +TUTORIAL_NETWORK=testnet cargo run --release --bin network_notes_counter_contract ``` -Expected output: +Successful output has this shape (abridged; IDs and block numbers vary): ```text -Latest block: 486537 +Latest block: [STEP 1] Creating a new account for Alice -Alice's account ID: "mtst1aqcmenmxlqkw8ugn005s7r09kq0xpqp9" +Alice's account ID: "" [STEP 2] Creating a network counter smart contract -one or more warnings were emitted -one or more warnings were emitted -one or more warnings were emitted -contract id: "mtst1aqtvag789v45tvtqdaknugytf5d5gxxu" +contract id: "" [STEP 3] Deploy network counter smart contract -View transaction on MidenScan: https://testnet.midenscan.com/tx/0x37c202efb825f0c7a55bd4416858fbe2d30064a5b1e557876a0053ed5307607f -Transaction 0x37c202efb825f0c7a55bd4416858fbe2d30064a5b1e557876a0053ed5307607f not yet committed. Waiting... -✅ transaction 0x37c202efb825f0c7a55bd4416858fbe2d30064a5b1e557876a0053ed5307607f committed +Network counter deployed; initial count is 0 [STEP 4] Creating a network note for network counter contract -View transaction on MidenScan: https://testnet.midenscan.com/tx/0xa5ec0baa9443a0f5aa056bd4c0e4583c5c3f5a5163aa0536b469a0255b489f75 +View transaction on MidenScan: https://testnet.midenscan.com/tx/ network increment note creation tx submitted, waiting for onchain commitment -Transaction 0xa5ec0baa9443a0f5aa056bd4c0e4583c5c3f5a5163aa0536b469a0255b489f75 not yet committed. Waiting... -✅ transaction 0xa5ec0baa9443a0f5aa056bd4c0e4583c5c3f5a5163aa0536b469a0255b489f75 committed -🔢 Final counter value: 2 +🔢 Final counter value: 1 ``` ## Summary @@ -837,8 +834,8 @@ Transaction 0xa5ec0baa9443a0f5aa056bd4c0e4583c5c3f5a5163aa0536b469a0255b489f75 n Network transactions on Miden enable powerful use cases by allowing the operator to execute transactions on behalf of users. The key steps are: 1. **Create user account**: Standard account creation for interaction -2. **Create network account**: Build a public account (`AccountType::Public`) with the `AuthNetworkAccount` auth component, allowlisting the note-script root (this is what marks it as a network account) and the deploy transaction-script root -3. **Deploy with transaction script**: Ensures the contract is registered on-chain +2. **Create network account**: Build a public account with `AuthNetworkAccount`, allowlisting the increment and funding note scripts +3. **Publish and fund it**: The initial native-asset consumption transaction registers the new account with count zero 4. **Interact with network notes**: Users create public notes that the operator executes The same MASM code works for both regular and network contracts — the difference is purely in the Rust configuration (the `AuthNetworkAccount` auth component and its allowlists). This makes network transactions a powerful tool for building applications like AMMs where multiple users need to interact with shared state efficiently. diff --git a/docs/src/rust-client/oracle_tutorial.md b/docs/src/rust-client/oracle_tutorial.md index 865d99bc..c51119f8 100644 --- a/docs/src/rust-client/oracle_tutorial.md +++ b/docs/src/rust-client/oracle_tutorial.md @@ -7,72 +7,90 @@ sidebar_position: 13 _Using the Pragma oracle to get on chain price data_ +For toolchain requirements and shared fee helpers, see the [Rust client setup](./index.md#running-the-v016-examples). + ## Overview In this tutorial, we will build a simple “price reader” smart contract that will read Bitcoin price data from the on-chain Pragma oracle. -We will use a script to call the `read_price` function in our "price reader" smart contract, which, in turn, calls the Pragma oracle via foreign procedure invocation (FPI). This tutorial lays the foundation for how you can integrate on-chain price data into your DeFi applications on Miden. +We will use a script to call the `get_price` procedure in our reader account, which invokes Pragma through foreign procedure invocation (FPI). This example demonstrates the call plumbing and discards the returned price. An application would need to validate and use the result. ## What we'll cover - Deploying a smart contract that can read oracle price data -- Using foreign procedure invocation to get real time on-chain price data +- Using foreign procedure invocation to query published on-chain price data ## Prerequisites +:::warning Deployment required + +Pragma's [published deployment table](https://github.com/astraly-labs/pragma-miden#deployments) +lists Miden v0.15 testnet only. Running this example requires a compatible v0.16 +testnet deployment, its account ID, `get_median` procedure root, and pair identifiers. + +The reader assumes the named slots `pragma::oracle::next_publisher_index`, +`pragma::oracle::publishers`, and `pragma::publisher::entries`. Check these slots, +the publisher ID layout and index range, and the return values against that deployment. + +::: + This tutorial assumes you have a basic understanding of Miden assembly, have completed the previous tutorials on using the Rust client, and have completed the tutorial on foreign procedure invocation. To quickly get up to speed with Miden assembly (MASM), please play around with running Miden programs in the [Miden playground](https://0xMiden.github.io/examples/). ## Step 1: Initialize your repository -Create a new Rust repository for your Miden project and navigate to it with the following command: +From the parent directory of your `tutorials` clone, create a sibling Cargo project: ```bash cargo new miden-defi-app cd miden-defi-app +rustup override set 1.98.1 +cp ../tutorials/rust-client/Cargo.lock Cargo.lock ``` Add the following dependencies to your `Cargo.toml` file: ```toml [dependencies] -miden-client = { version = "0.15", features = ["testing", "tonic"] } -miden-client-sqlite-store = { version = "0.15", package = "miden-client-sqlite-store" } -miden-protocol = { version = "0.15" } -rand = { version = "0.9" } +# Clone tutorials next to this Cargo project (see Rust client setup). +rust-client = { path = "../tutorials/rust-client" } +miden-client = { version = "=0.16.0", features = ["testing", "tonic"] } +miden-client-sqlite-store = { version = "=0.16.0", package = "miden-client-sqlite-store" } +miden-protocol = { version = "=0.16.0" } +rand = { version = "0.10" } 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" +tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } + +[profile.dev] +opt-level = 2 ``` -### Step 1: Set up your `src/main.rs` file +### Set up your `src/main.rs` file Copy and paste the following code into your `src/main.rs` file: ```rust no_run use miden_client::{ + Client, ClientError, Felt, Word, ZERO, account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountId, - AccountType, StorageMapKey, StorageSlot, StorageSlotName, - }, - assembly::{ - CodeBuilder, DefaultSourceManager, Module, ModuleKind, Path as AssemblyPath, + AccountBuilder, AccountComponent, AccountId, AccountType, StorageMapKey, StorageSlot, + StorageSlotName, + component::{AccountComponentMetadata, BasicWallet}, }, + assembly::CodeBuilder, auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, - rpc::{ - domain::account::AccountStorageRequirements, - Endpoint, GrpcClient, - }, - transaction::{ForeignAccount, TransactionKernel, TransactionRequestBuilder}, - Client, ClientError, Felt, Word, ZERO, + rpc::{GrpcClient, VerifyingRpcClient, domain::account::AccountStorageRequirements}, + transaction::{ForeignAccount, TransactionRequestBuilder}, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -use rand::RngCore; -use std::{fs, path::Path, sync::Arc}; +use rand::Rng; +use rust_client::TutorialClientExt; +use rust_client::{FeeConfig, TutorialNetwork, fund_account_for_fees}; +use std::sync::Arc; /// Import the oracle + its publishers and return the ForeignAccount list /// Due to Pragma's decentralized oracle architecture, we need to get the @@ -107,7 +125,7 @@ pub async fn get_oracle_foreign_accounts( StorageSlotName::new("pragma::oracle::publishers").expect("valid slot name"); let publisher_ids: Vec = (2..next_publisher_index) .map(|index| { - let key: Word = [Felt::new_unchecked(index), ZERO, ZERO, ZERO].into(); + let key = StorageMapKey::new([Felt::new_unchecked(index), ZERO, ZERO, ZERO].into()); let publisher_word = storage .get_map_item(&publishers_slot, key) .expect("publisher entry missing from oracle storage"); @@ -118,8 +136,7 @@ pub async fn get_oracle_foreign_accounts( // Each publisher exposes its price entries in the `entries` map, keyed by // the faucet ID word of the trading pair. - let entries_slot = - StorageSlotName::new("pragma::publisher::entries").expect("valid slot name"); + let entries_slot = StorageSlotName::new("pragma::publisher::entries").expect("valid slot name"); let mut foreign_accounts = Vec::with_capacity(publisher_ids.len() + 1); for publisher_id in publisher_ids { @@ -149,29 +166,17 @@ pub async fn get_oracle_foreign_accounts( Ok(foreign_accounts) } -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 // ------------------------------------------------------------------------- - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); let keystore_path = std::path::PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); @@ -182,30 +187,55 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; println!("Latest block: {}", client.sync_state().await?.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; // ------------------------------------------------------------------------- // Get all foreign accounts for oracle data // ------------------------------------------------------------------------- - // Defaults to Pragma's current Miden v0.15 testnet oracle; pass a different - // bech32 id as the first CLI argument to point at another deployment. Pragma's - // addresses change between testnet iterations, so check their README - // (https://github.com/astraly-labs/pragma-miden) if this feed stops resolving. + // Pass a compatible oracle account ID and its `get_median` procedure root as CLI + // arguments (or through the matching environment variables). This tutorial remains skipped + // by the runner until Pragma publishes a deployment for the current protocol release. let oracle_bech32 = std::env::args() .nth(1) - .unwrap_or_else(|| "mtst1apadf2szkxqkcyt7x2znuggv9qkhccam".to_string()); - let (_, oracle_account_id) = AccountId::from_bech32(&oracle_bech32).unwrap(); + .or_else(|| std::env::var("MIDEN_ORACLE_ACCOUNT_ID").ok()) + .ok_or_else(|| ClientError::Observer(Box::new(std::io::Error::other( + "Oracle deployment is required: set MIDEN_ORACLE_ACCOUNT_ID and MIDEN_ORACLE_GET_MEDIAN_ROOT for the selected network. Use a compatible v0.16 deployment on the selected network.", + ))))?; + let get_median_proc_root = std::env::args() + .nth(2) + .or_else(|| std::env::var("MIDEN_ORACLE_GET_MEDIAN_ROOT").ok()) + .ok_or_else(|| { + ClientError::Observer(Box::new(std::io::Error::other( + "Set MIDEN_ORACLE_GET_MEDIAN_ROOT to the deployed oracle's get_median procedure root", + ))) + })?; + let (account_network, oracle_account_id) = AccountId::from_bech32(&oracle_bech32).unwrap(); + assert_eq!( + account_network, + network.network_id(), + "oracle account must match the selected tutorial network" + ); - // BTC/USD is identified by the faucet ID pair `1:0` (prefix 1, suffix 0). + // BTC/USD was identified by the faucet ID pair `1:0` in the previous deployment. Override + // either value with the optional third and fourth CLI arguments for the selected deployment. // The faucet ID word is laid out as [0, 0, suffix, prefix]. - let pair_prefix: u64 = 1; - let pair_suffix: u64 = 0; - let btc_usd_pair: Word = - [ZERO, ZERO, Felt::new_unchecked(pair_suffix), Felt::new_unchecked(pair_prefix)].into(); + let pair_prefix: u64 = std::env::args() + .nth(3) + .map_or(1, |value| value.parse().expect("pair prefix must be a u64")); + let pair_suffix: u64 = std::env::args() + .nth(4) + .map_or(0, |value| value.parse().expect("pair suffix must be a u64")); + let btc_usd_pair: Word = [ + ZERO, + ZERO, + Felt::new_unchecked(pair_suffix), + Felt::new_unchecked(pair_prefix), + ] + .into(); let foreign_accounts: Vec = get_oracle_foreign_accounts(&mut client, oracle_account_id, btc_usd_pair).await?; @@ -218,8 +248,19 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- // Create Oracle Reader contract // ------------------------------------------------------------------------- - let contract_code = - fs::read_to_string(Path::new("../masm/accounts/oracle_reader.masm")).unwrap(); + let contract_code = std::fs::read_to_string("../tutorials/masm/accounts/oracle_reader.masm") + .unwrap() + .replace("{get_median_proc_root}", &get_median_proc_root) + .replace( + "{oracle_id_prefix}", + &oracle_account_id.prefix().to_string(), + ) + .replace( + "{oracle_id_suffix}", + &oracle_account_id.suffix().to_string(), + ) + .replace("{pair_prefix}", &pair_prefix.to_string()) + .replace("{pair_suffix}", &pair_suffix.to_string()); let contract_slot_name = StorageSlotName::new("miden::tutorials::oracle_reader").expect("valid slot name"); @@ -242,7 +283,8 @@ async fn main() -> Result<(), ClientError> { let oracle_reader_contract = AccountBuilder::new(seed) .account_type(AccountType::Public) .with_component(contract_component.clone()) - .with_auth_component(NoAuth) + .with_component(BasicWallet) + .with_component(NoAuth) .build() .unwrap(); @@ -250,20 +292,17 @@ async fn main() -> Result<(), ClientError> { .add_account(&oracle_reader_contract, false) .await .unwrap(); + fund_account_for_fees(&mut client, oracle_reader_contract.id(), &fee_config).await?; // ------------------------------------------------------------------------- // Build the script that calls our `get_price` procedure // ------------------------------------------------------------------------- - let script_path = Path::new("../masm/scripts/oracle_reader_script.masm"); - let script_code = fs::read_to_string(script_path).unwrap(); - - let library_path = "external_contract::oracle_reader"; - let account_component_lib = - create_library(library_path, &contract_code).unwrap(); + let script_code = + std::fs::read_to_string("../tutorials/masm/scripts/oracle_reader_script.masm").unwrap(); let tx_script = client .code_builder() - .with_dynamically_linked_library(&account_component_lib) + .with_linked_module("external_contract::oracle_reader", &contract_code) .unwrap() .compile_tx_script(&script_code) .unwrap(); @@ -275,12 +314,13 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let tx_id = client - .submit_new_transaction(oracle_reader_contract.id(), tx_increment_request) + .submit_tutorial_transaction(oracle_reader_contract.id(), tx_increment_request) .await .unwrap(); println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); @@ -290,168 +330,137 @@ async fn main() -> Result<(), ClientError> { } ``` -_Don't run this code just yet, we still need to create our smart contract that queries the oracle_ - -In the code above, the Pragma oracle account ID is provided as a command-line argument in bech32 form, and the BTC/USD price feed is identified by the faucet ID pair `1:0` (prefix `1`, suffix `0`). The `get_oracle_foreign_accounts` function returns all of the `ForeignAccount`s that you will need to execute the transaction to get the price data from the oracle. Since Pragma's oracle aggregates data from multiple publishers, this function reads the oracle's on-chain publisher registry and collects every publisher account id required to make a successful FPI call. +The following section explains the two MASM templates loaded by the Rust example. -:::note -The oracle account ID, procedure hash, and faucet pair used in this tutorial reference Pragma's testnet deployment. These values are maintained by Pragma and may change if they redeploy their oracle. For the latest values, check the [Pragma Miden repository](https://github.com/astraly-labs/pragma-miden). -::: +In the code above, a compatible testnet oracle account ID and `get_median` procedure root are required inputs. The BTC/USD price feed used prefix `1` and suffix `0` in Pragma's earlier deployment; the optional third and fourth arguments let you supply the pair identifiers published for a new deployment. The `get_oracle_foreign_accounts` function returns every `ForeignAccount` needed to execute the transaction. Since Pragma's oracle aggregates data from multiple publishers, the function reads the on-chain publisher registry and requests the storage proofs needed by the nested FPI calls. ## Step 2: Build the price reader smart contract and script -Just like in previous tutorials, for better code organization we will separate the Miden assembly code from our Rust code. - -Create a directory named `masm` at the **root** of your `miden-counter-contract` directory. This will contain our contract and script masm code. - -Initialize the `masm` directory: - -```bash -mkdir -p masm/accounts masm/scripts -``` - -This will create: - -```text -masm/ -├── accounts/ -└── scripts/ -``` +The reader and transaction script are in the repository’s `masm/` directory. ### Oracle price reader smart contract Below is our oracle price reader contract. It has a single exported procedure: `get_price` -The import `miden::tx` contains the `tx::execute_foreign_procedure` which we will use to read the price from the oracle contract. +The `miden::protocol::tx` module exports `execute_foreign_procedure`, which the reader uses to invoke the oracle. #### Here's a breakdown of what the `get_price` procedure does: -1. Pushes the 16 foreign procedure inputs that `tx::execute_foreign_procedure` requires. The first four are the arguments to `get_median` — the BTC/USD faucet ID prefix `1`, suffix `0`, an `amount` of `0`, and a trailing `0` — and the remaining twelve are zero padding. -2. Pushes `0xaa3a12d4e9de2dad37c50dba93809b9c17226d512e642d3d620c77088a85da71` onto the stack, which is the procedure root of the `get_median` procedure in the oracle. -3. Pushes the Pragma oracle account ID prefix and suffix. -4. Calls `tx::execute_foreign_procedure`, which invokes the `get_median` procedure via foreign procedure invocation. `get_median` returns `[is_tracked, median_price, amount]` on the stack. +1. Pushes the 16 foreign procedure inputs that `tx::execute_foreign_procedure` requires. The first four contain the requested pair prefix and suffix, an `amount` of `0`, and a trailing `0`; the remaining twelve are zero padding. +2. Pushes the supplied `get_median` procedure root. +3. Pushes the supplied testnet oracle account ID prefix and suffix. +4. Calls `tx::execute_foreign_procedure`, which invokes `get_median`. The template expects `[is_tracked, median_price, amount]` at the top of the returned stack; confirm this interface against the compatible deployment. +5. Drops the sixteen foreign output elements, including the price, to restore the caller's stack. -Inside of the `masm/accounts/` directory, create the `oracle_reader.masm` file: +The reader is defined in `masm/accounts/oracle_reader.masm`: ```masm -# The oracle account ID, procedure hash, and pair ID below reference -# Pragma's Miden v0.15 testnet deployment (https://github.com/astraly-labs/pragma-miden). -# Pragma's addresses change between testnet iterations (their README is the -# source of truth), so if the oracle is redeployed these values must be updated: -# the oracle account id, the `get_median` procedure root, and (if a different -# feed) the faucet pair id. +# the Rust runner replaces these placeholders with values from a compatible +# pragma deployment before compiling this component. use miden::protocol::tx -# Fetches the current price from the `get_median` -# procedure from the Pragma oracle -# => [] -pub proc get_price +# PUBLIC INTERFACE +# ================================================================================================= + +#! Queries the configured Pragma oracle's median price through a foreign procedure. +#! +#! Inputs: [pad(16)] +#! Outputs: [pad(16)] +#! +#! Panics if: +#! - the configured oracle procedure or its required foreign state is unavailable. +#! +#! Invocation: call +@account_procedure +pub proc get_price() # `execute_foreign_procedure` requires exactly 16 foreign procedure inputs. # `get_median` only reads the first four, so the rest are zero padding. padw padw padw - # => [PAD(12)] + # => [pad(28)] - # BTC/USD pair: faucet id prefix `1`, suffix `0`, amount `0` - push.0.0.0.1 - # => [pair_prefix, pair_suffix, amount, 0, PAD(12)] + # requested pair: faucet ID prefix/suffix, amount `0`. + push.0.0.{pair_suffix}.{pair_prefix} + # => [pair_prefix, pair_suffix, amount, 0, pad(28)] - # This is the procedure root of the `get_median` procedure - push.0xaa3a12d4e9de2dad37c50dba93809b9c17226d512e642d3d620c77088a85da71 - # => [GET_MEDIAN_HASH, FOREIGN_INPUTS(16)] + # this is the procedure root of the `get_median` procedure. + push.{get_median_proc_root} + # => [GET_MEDIAN_HASH, foreign_procedure_inputs(16), pad(16)] - # The Pragma oracle account id: prefix then suffix, leaving suffix on top - push.8850886096234572817.9093477099503364096 - # => [oracle_id_suffix, oracle_id_prefix, GET_MEDIAN_HASH, FOREIGN_INPUTS(16)] + # the Pragma oracle account id: prefix then suffix, leaving suffix on top. + push.{oracle_id_prefix}.{oracle_id_suffix} + # => [oracle_id_suffix, oracle_id_prefix, GET_MEDIAN_HASH, foreign_procedure_inputs(16), pad(16)] exec.tx::execute_foreign_procedure - # => [is_tracked, median_price, amount, PAD(13)] - - debug.stack - # => [is_tracked, median_price, amount, PAD(13)] + # => [is_tracked, median_price, amount, pad(29)] dropw dropw dropw dropw + # => [pad(16)] end ``` -**Note**: _It's a good habit to add comments above each line of MASM code with the expected stack state. This improves readability and helps with debugging._ +Stack comments below instruction groups show the expected stack state after execution. The braces in this template are replaced by Rust before assembly. ### Create the script which calls the `get_price` procedure This is a Miden assembly script that will call the `get_price` procedure during the transaction. -Inside of the `masm/scripts/` directory, create the `oracle_reader_script.masm` file: +The transaction script is defined in `masm/scripts/oracle_reader_script.masm`: ```masm use external_contract::oracle_reader -begin - exec.oracle_reader::get_price +#! Queries the configured oracle through the reader account. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) + dropw + # => [pad(16)] + + call.oracle_reader::get_price + # => [pad(16)] end ``` ## Step 3: Run the program -Run the following command to execute src/main.rs: +Compile-check the standalone program with `cargo check`. To execute it once a compatible deployment is available, set `MIDEN_ORACLE_ACCOUNT_ID` and `MIDEN_ORACLE_GET_MEDIAN_ROOT` in your shell, then run: ```bash -cargo run --release +TUTORIAL_NETWORK=testnet cargo run --release -- \ + "$MIDEN_ORACLE_ACCOUNT_ID" "$MIDEN_ORACLE_GET_MEDIAN_ROOT" ``` -The output of our program will look something like this: +The command defaults to pair prefix `1` and suffix `0`. Append the deployment's pair prefix and suffix as the third and fourth arguments when those values differ. Do not assume the old pair identifies BTC/USD on a new deployment. + +With a compatible deployment, the output includes: ```text -Latest block: 489876 -Oracle accountId prefix: V1(AccountIdPrefixV1 { prefix: 8850886096234572817 }) suffix: 9093477099503364096 -Stack state before step 6324: -├── 0: 1 -├── 1: 6439689500000 -├── 2: 0 -├── 3: 0 -├── 4: 0 -├── 5: 0 -├── 6: 0 -├── 7: 0 -├── 8: 0 -├── 9: 0 -├── 10: 0 -├── 11: 0 -├── 12: 0 -├── 13: 0 -├── 14: 0 -├── 15: 0 -├── 16: 0 -├── 17: 0 -├── 18: 0 -├── 19: 0 -├── 20: 0 -├── 21: 0 -├── 22: 0 -├── 23: 0 -├── 24: 0 -├── 25: 0 -├── 26: 0 -├── 27: 0 -├── 28: 0 -├── 29: 0 -├── 30: 0 -└── 31: 0 - -View transaction on MidenScan: https://testnet.midenscan.com/tx/0xbf6048faa60c72c43ab5645d937d02d0d768ee4fdad3c64b736789fdf0ef6a44 +Latest block: +Oracle accountId prefix: suffix: +View transaction on MidenScan: https://testnet.midenscan.com/tx/ ``` -The `get_median` procedure leaves three values on the stack. Index `0` holds `is_tracked` — `1` when Pragma tracks the requested pair. Index `1` holds the median price as a raw fixed-point integer; in the output above it is `6439689500000`. The number of decimal places is defined by Pragma's feed (BTC/USD is published with 8 decimals), so this reading is about `$64,396.89`. Index `2` holds the `amount` value that was passed into the call. Pragma publishes several price feeds on testnet; this tutorial reads the `BTC/USD` feed. +The template expects `[is_tracked, median_price, amount]` on the stack, then drops those values. Before using the price in an application, check the feed's tracking status, freshness rules, and fixed-point precision, then store the value or use it within the same procedure. ### Running the tutorial -To run this tutorial end-to-end, navigate to the `rust-client` directory in the [miden-tutorials](https://github.com/0xMiden/miden-tutorials/) repository and run: +Once the deployment prerequisites are met, return to the root of the [tutorials repository](https://github.com/0xMiden/tutorials/) and run: ```bash cd rust-client -cargo run --release --bin oracle_data_query +TUTORIAL_NETWORK=testnet cargo run --release --bin oracle_data_query -- \ + "$MIDEN_ORACLE_ACCOUNT_ID" "$MIDEN_ORACLE_GET_MEDIAN_ROOT" ``` -This defaults to Pragma's current testnet oracle. To read from a different deployment, pass its bech32 account ID as an argument: `cargo run --release --bin oracle_data_query -- `. +If both variables are exported in your shell, you can omit `--` and the explicit arguments. The account must use the `mtst1...` testnet prefix. ### Continue learning diff --git a/docs/src/rust-client/public_account_interaction_tutorial.md b/docs/src/rust-client/public_account_interaction_tutorial.md index 6f9ad348..fe7695d1 100644 --- a/docs/src/rust-client/public_account_interaction_tutorial.md +++ b/docs/src/rust-client/public_account_interaction_tutorial.md @@ -7,11 +7,13 @@ sidebar_position: 5 _Using the Miden client in Rust to interact with public smart contracts on Miden_ +For toolchain requirements and shared fee helpers, see the [Rust client setup](./index.md#running-the-v016-examples). + ## Overview In the previous tutorial, we built a simple counter contract and deployed it to the Miden testnet. However, we only covered how the contract’s deployer could interact with it. Now, let’s explore how anyone can interact with a public smart contract on Miden. -We’ll retrieve the counter contract’s state from the chain and rebuild it locally so a local transaction can be executed against it. In the near future, Miden will support network transactions, making the process of submitting transactions to public smart contracts much more like traditional blockchains. +We'll import the counter contract's public state from the chain and execute a local transaction against it. Its `NoAuth` authentication component permits this without a signature; a public account with signature authentication would still require the appropriate authorization. For contracts that should execute autonomously on behalf of users, continue with the network transactions tutorial after this one. Just like in the previous tutorial, we will use a script to invoke the increment function within the counter contract to update the count. However, this tutorial demonstrates how to call a procedure in a smart contract that was deployed by a different user on Miden. @@ -22,120 +24,151 @@ Just like in the previous tutorial, we will use a script to invoke the increment ## Prerequisites -This tutorial assumes you have a basic understanding of Miden assembly and completed the previous tutorial on deploying the counter contract. Although not a requirement, it is recommended to complete the counter contract deployment tutorial before starting this tutorial. +This tutorial assumes you have a basic understanding of Miden assembly and a counter deployed with the code from the previous tutorial. Keep the `mtst1...` account ID printed by that deployment; the standalone program requires it. + +The counter deployment example also funds the contract's native fee balance. +This example spends from that existing balance when incrementing the counter; +ensure the imported contract has enough funds. The runner supplies a freshly +deployed, funded counter automatically. ## Step 1: Initialize your repository -Create a new Rust repository for your Miden project and navigate to it with the following command: +From the parent directory of your `tutorials` clone, create a sibling Cargo project: ```bash -cargo new miden-counter-contract -cd miden-counter-contract +cargo new miden-public-account-interaction +cd miden-public-account-interaction +rustup override set 1.98.1 +cp ../tutorials/rust-client/Cargo.lock Cargo.lock ``` Add the following dependencies to your `Cargo.toml` file: ```toml [dependencies] -miden-client = { version = "0.15", features = ["testing", "tonic"] } -miden-client-sqlite-store = { version = "0.15", package = "miden-client-sqlite-store" } -miden-protocol = { version = "0.15" } -rand = { version = "0.9" } -tokio = { version = "1.46", features = ["rt-multi-thread", "net", "macros", "fs"] } +# Clone tutorials next to this Cargo project (see Rust client setup). +rust-client = { path = "../tutorials/rust-client" } +miden-client = { version = "=0.16.0", features = ["testing", "tonic"] } +miden-client-sqlite-store = { version = "=0.16.0", package = "miden-client-sqlite-store" } +miden-protocol = { version = "=0.16.0" } +rand = { version = "0.10" } +tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } + +[profile.dev] +opt-level = 2 ``` -## Step 2: Build the counter contract - -For better code organization, we will separate the Miden assembly code from our Rust code. +## Step 2: Prepare the counter module and script -Create a directory named `masm` at the **root** of your `miden-counter-contract` directory. This will contain our contract and script masm code. - -Initialize the `masm` directory: - -```bash -mkdir -p masm/accounts masm/scripts -``` - -This will create: - -```text -masm/ -├── accounts/ -└── scripts/ -``` - -Inside of the `masm/accounts/` directory, create the `counter.masm` file: +The account already exists on-chain. We use the repository’s `masm/accounts/counter.masm` module to link the increment transaction script: ```masm use miden::protocol::active_account use miden::protocol::native_account -use miden::core::word use miden::core::sys +# CONSTANTS +# ================================================================================================= + const COUNTER_SLOT = word("miden::tutorials::counter") -#! Inputs: [] -#! Outputs: [count] -pub proc get_count +# PUBLIC INTERFACE +# ================================================================================================= + +#! Returns the current count. +#! +#! Inputs: [pad(16)] +#! Outputs: [count, pad(15)] +#! +#! Invocation: call +@account_procedure +pub proc get_count() -> felt push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] exec.sys::truncate_stack - # => [count] + # => [count, pad(15)] end -#! Inputs: [] -#! Outputs: [] -pub proc increment_count +#! Increments the current count by one. +#! +#! Inputs: [pad(16)] +#! Outputs: [pad(16)] +#! +#! Invocation: call +@account_procedure +pub proc increment_count() push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] add.1 - # => [count+1] + # => [[count + 1, 0, 0, 0], pad(16)] push.COUNTER_SLOT[0..2] exec.native_account::set_item - # => [] + # => [OLD_VALUE, pad(16)] + + dropw + # => [pad(16)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end ``` -Inside of the `masm/scripts/` directory, create the `counter_script.masm` file: +The transaction script is defined in `masm/scripts/counter_script.masm`: ```masm use external_contract::counter_contract -begin +#! Increments the counter. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) + dropw + # => [pad(16)] + call.counter_contract::increment_count + # => [pad(16)] end ``` **Note**: _We explained in the previous counter contract tutorial what exactly happens at each step in the `increment_count` procedure._ -### Step 3: Set up your `src/main.rs` file +## Step 3: Set up your `src/main.rs` file Copy and paste the following code into your `src/main.rs` file: ```rust no_run +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; use miden_client::{ + ClientError, account::{AccountId, StorageSlotName}, builder::ClientBuilder, keystore::FilesystemKeyStore, - rpc::{Endpoint, GrpcClient}, + rpc::{GrpcClient, VerifyingRpcClient}, transaction::TransactionRequestBuilder, - ClientError, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::TutorialNetwork; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -147,7 +180,6 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; @@ -160,11 +192,9 @@ async fn main() -> Result<(), ClientError> { ## Step 4: Reading public state from a smart contract -To read the public storage state of a smart contract on Miden we either instantiate the `TonicRpcClient` by itself, or use the `test_rpc_api()` method on the `Client` instance. In this example, we will be using the `test_rpc_api()` method. +This tutorial uses `Client::import_account_by_id` to import a public account from testnet and read its storage. First run the [counter contract tutorial](./counter_contract_tutorial.md), then copy the deployed counter's `mtst1...` account ID. Pass that ID to this program instead of hard-coding an address, because testnet is reset periodically. -We will be reading the public storage state of the counter contract deployed on the testnet at address `mtst1apcqs7aj3a2cf5t6pnsfy0p4ns7wl7sp`. - -Add the following code snippet to the end of your `src/main.rs` function: +Insert the following code inside `main`, immediately before its final `Ok(())`: ```rust ignore // ------------------------------------------------------------------------- @@ -172,9 +202,19 @@ Add the following code snippet to the end of your `src/main.rs` function: // ------------------------------------------------------------------------- println!("\n[STEP 1] Reading data from public state"); -// Define the Counter Contract account id from counter contract deploy -let (_, counter_contract_id) = - AccountId::from_bech32("mtst1apcqs7aj3a2cf5t6pnsfy0p4ns7wl7sp").unwrap(); +// Pass the account ID printed by `counter_contract_deploy` as the first argument, or via +// `MIDEN_COUNTER_ACCOUNT_ID`. +let counter_contract_bech32 = std::env::args() + .nth(1) + .or_else(|| std::env::var("MIDEN_COUNTER_ACCOUNT_ID").ok()) + .expect("pass the counter account ID from counter_contract_deploy"); +let (account_network, counter_contract_id) = + AccountId::from_bech32(&counter_contract_bech32).expect("invalid counter account ID"); +assert_eq!( + account_network, + network.network_id(), + "counter account must match the selected tutorial network" +); client .import_account_by_id(counter_contract_id) @@ -190,24 +230,29 @@ println!( "Account details: {:?}", counter_contract.storage().slots().first().unwrap() ); +let counter_slot_name = + StorageSlotName::new("miden::tutorials::counter").expect("valid slot name"); +let count_before = counter_contract + .storage() + .get_item(&counter_slot_name) + .unwrap()[0]; ``` -Run the following command to execute src/main.rs: +Set `MIDEN_COUNTER_ACCOUNT_ID` to the deployed `mtst1...` address in your shell, or replace the quoted variable below with that address. Run the following command to execute `src/main.rs`: ```bash -cargo run --release +TUTORIAL_NETWORK=testnet cargo run --release -- "$MIDEN_COUNTER_ACCOUNT_ID" ``` -After the program executes, you should see the counter contract count value and nonce printed to the terminal, for example: +The program prints the imported storage slot. For a freshly deployed counter, the abridged output is: ```text -count val: [0, 0, 0, 5] -counter nonce: 5 +Account details: StorageSlot { ... content: Value(Word([1, 0, 0, 0])) } ``` -## Step 5: Importing a public account +## Step 5: Increment the imported counter -Add the following code snippet to the end of your `src/main.rs` function: +Insert the following code after the import step, inside `main` and before `Ok(())`: ```rust ignore // ------------------------------------------------------------------------- @@ -215,18 +260,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 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"); +// Read the MASM source from the tutorials repository. +let script_code = + std::fs::read_to_string("../tutorials/masm/scripts/counter_script.masm").unwrap(); +let counter_code = std::fs::read_to_string("../tutorials/masm/accounts/counter.masm").unwrap(); // Compile the script with the counter contract code linked as a module // on the same `CodeBuilder` chain. let tx_script = client .code_builder() - .with_linked_module("external_contract::counter_contract", counter_code) + .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 @@ -237,12 +282,13 @@ let tx_increment_request = TransactionRequestBuilder::new() // Execute and submit the transaction let tx_id = client - .submit_new_transaction(counter_contract.id(), tx_increment_request) + .submit_tutorial_transaction(counter_contract_id, tx_increment_request) .await .unwrap(); println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); @@ -250,17 +296,19 @@ client.sync_state().await.unwrap(); // Retrieve updated contract data to see the incremented counter let account = client - .get_account(counter_contract.id()) + .get_account(counter_contract_id) .await .unwrap() .expect("counter contract not found"); -let counter_slot_name = - miden_client::account::StorageSlotName::new("miden::tutorials::counter") - .expect("valid slot name"); println!( "counter contract storage: {:?}", account.storage().get_item(&counter_slot_name) ); +assert_eq!( + account.storage().get_item(&counter_slot_name).unwrap()[0], + count_before + miden_client::ONE, + "the imported counter must increment exactly once", +); ``` ## Summary @@ -268,24 +316,29 @@ println!( The final `src/main.rs` file should look like this: ```rust no_run +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; use miden_client::{ + ClientError, account::{AccountId, StorageSlotName}, builder::ClientBuilder, keystore::FilesystemKeyStore, - rpc::{Endpoint, GrpcClient}, + rpc::{GrpcClient, VerifyingRpcClient}, transaction::TransactionRequestBuilder, - ClientError, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::TutorialNetwork; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -297,7 +350,6 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; @@ -309,9 +361,19 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 1] Reading data from public state"); - // Define the Counter Contract account id from counter contract deploy - let (_, counter_contract_id) = - AccountId::from_bech32("mtst1apcqs7aj3a2cf5t6pnsfy0p4ns7wl7sp").unwrap(); + // Pass the account ID printed by `counter_contract_deploy` as the first argument, or via + // `MIDEN_COUNTER_ACCOUNT_ID`. + let counter_contract_bech32 = std::env::args() + .nth(1) + .or_else(|| std::env::var("MIDEN_COUNTER_ACCOUNT_ID").ok()) + .expect("pass the counter account ID from counter_contract_deploy"); + let (account_network, counter_contract_id) = + AccountId::from_bech32(&counter_contract_bech32).expect("invalid counter account ID"); + assert_eq!( + account_network, + network.network_id(), + "counter account must match the selected tutorial network" + ); client .import_account_by_id(counter_contract_id) @@ -327,24 +389,30 @@ async fn main() -> Result<(), ClientError> { "Account details: {:?}", counter_contract.storage().slots().first().unwrap() ); + let counter_slot_name = + StorageSlotName::new("miden::tutorials::counter").expect("valid slot name"); + let count_before = counter_contract + .storage() + .get_item(&counter_slot_name) + .unwrap()[0]; // ------------------------------------------------------------------------- // STEP 2: Call the Counter Contract with a script // ------------------------------------------------------------------------- println!("\n[STEP 2] Call the increment_count procedure in the counter contract"); - // 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"); + // Read the MASM source from the tutorials repository. + let script_code = + std::fs::read_to_string("../tutorials/masm/scripts/counter_script.masm").unwrap(); + let counter_code = std::fs::read_to_string("../tutorials/masm/accounts/counter.masm").unwrap(); // Compile the script with the counter contract code linked as a module // on the same `CodeBuilder` chain. let tx_script = client .code_builder() - .with_linked_module("external_contract::counter_contract", counter_code) + .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 @@ -355,12 +423,13 @@ async fn main() -> Result<(), ClientError> { // Execute and submit the transaction let tx_id = client - .submit_new_transaction(counter_contract.id(), tx_increment_request) + .submit_tutorial_transaction(counter_contract_id, tx_increment_request) .await .unwrap(); println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); @@ -368,17 +437,19 @@ async fn main() -> Result<(), ClientError> { // Retrieve updated contract data to see the incremented counter let account = client - .get_account(counter_contract.id()) + .get_account(counter_contract_id) .await .unwrap() .expect("counter contract not found"); - let counter_slot_name = - miden_client::account::StorageSlotName::new("miden::tutorials::counter") - .expect("valid slot name"); println!( "counter contract storage: {:?}", account.storage().get_item(&counter_slot_name) ); + assert_eq!( + account.storage().get_item(&counter_slot_name).unwrap()[0], + count_before + miden_client::ONE, + "the imported counter must increment exactly once", + ); Ok(()) } ``` @@ -386,63 +457,33 @@ async fn main() -> Result<(), ClientError> { Run the following command to execute src/main.rs: ```bash -cargo run --release +TUTORIAL_NETWORK=testnet cargo run --release -- "$MIDEN_COUNTER_ACCOUNT_ID" ``` The output of our program will look something like this depending on the current count value in the smart contract: ```text -Client initialized successfully. -Latest block: 242342 +Latest block: -[STEP 1] Building counter contract from public state -count val: [0, 0, 0, 1] -counter nonce: 1 +[STEP 1] Reading data from public state +Account details: StorageSlot { ... content: Value(Word([1, 0, 0, 0])) } [STEP 2] Call the increment_count procedure in the counter contract -Procedure 1: "0x92495ca54d519eb5e4ba22350f837904d3895e48d74d8079450f19574bb84cb6" -Procedure 2: "0xecd7eb223a5524af0cc78580d96357b298bb0b3d33fe95aeb175d6dab9de2e54" -number of procedures: 2 -Final script: -begin - # => [] - call.0xecd7eb223a5524af0cc78580d96357b298bb0b3d33fe95aeb175d6dab9de2e54 -end -Stack state before step 1812: -├── 0: 2 -├── 1: 0 -├── 2: 0 -├── 3: 0 -├── 4: 0 -├── 5: 0 -├── 6: 0 -├── 7: 0 -├── 8: 0 -├── 9: 0 -├── 10: 0 -├── 11: 0 -├── 12: 0 -├── 13: 0 -├── 14: 0 -├── 15: 0 -├── 16: 0 -├── 17: 0 -├── 18: 0 -└── 19: 0 - -View transaction on MidenScan: https://testnet.midenscan.com/tx/0x8183aed150f20b9c26d4cb7840bfc92571ea45ece31116170b11cdff2649eb5c -counter contract storage: Ok(RpoDigest([0, 0, 0, 2])) +View transaction on MidenScan: https://testnet.midenscan.com/tx/ +counter contract storage: Ok(Word([2, 0, 0, 0])) ``` ### Running the example -To run the full example, navigate to the `rust-client` directory in the [miden-tutorials](https://github.com/0xMiden/miden-tutorials/) repository and run this command: +To run the checked-in example, return to the root of the [tutorials repository](https://github.com/0xMiden/tutorials/) and run: ```bash cd rust-client -cargo run --release --bin counter_contract_increment +TUTORIAL_NETWORK=testnet cargo run --release --bin counter_contract_increment -- "$MIDEN_COUNTER_ACCOUNT_ID" ``` +If `MIDEN_COUNTER_ACCOUNT_ID` is exported in your shell, you can omit `--` and the final argument. + ### Continue learning Next tutorial: [Network Transactions on Miden](network_transactions_tutorial.md) diff --git a/docs/src/rust-client/unauthenticated_note_how_to.md b/docs/src/rust-client/unauthenticated_note_how_to.md index de3597b1..d2894354 100644 --- a/docs/src/rust-client/unauthenticated_note_how_to.md +++ b/docs/src/rust-client/unauthenticated_note_how_to.md @@ -7,23 +7,25 @@ sidebar_position: 9 _Using unauthenticated notes for optimistic note consumption_ +For toolchain requirements and shared fee helpers, see the [Rust client setup](./index.md#running-the-v016-examples). + ## Overview -In this guide, we will explore how to leverage unauthenticated notes on Miden to settle transactions faster than the blocktime. Unauthenticated notes are essentially UTXOs that have not yet been fully committed into a block. This feature allows the notes to be created and consumed within the same block. +In this guide, we supply a complete note to a consuming transaction before waiting for the note's inclusion proof. Such an input is unauthenticated: the node checks the dependency on its creation transaction. This lets a note be created and consumed within the same block, although confirmation still depends on block production. -We construct a chain of transactions using the unauthenticated notes method on the transaction builder. Unauthenticated notes are also referred to as "unauthenticated notes" or "erasable notes". We also demonstrate how a note can be serialized and deserialized, highlighting the ability to transfer notes between client instances for asset transfers that can be settled between parties faster than the blocktime. +We construct a chain with `TransactionRequestBuilder::build_consume_notes`, passing the complete `Note` without an inclusion proof. We also serialize and deserialize each note to demonstrate how its details could be sent between clients. The example uses one client for all accounts and waits for each transfer and consumption to confirm before beginning the next hop. For example, our demo creates a chain of unauthenticated note transactions: ```markdown -Alice ➡ Bob ➡ Charlie ➡ Dave ➡ Eve ➡ Frank ➡ ... +Alice ➡ Bob ➡ Charlie ➡ Dave ➡ Eve ``` ## What we'll cover - **Introduction to Unauthenticated Notes:** Understand what unauthenticated notes are and how they differ from standard notes. - **Serialization Example:** See how to serialize and deserialize a note to demonstrate how notes can be propagated to client instances faster than the blocktime. -- **Performance Insights:** Observe how unauthenticated notes can reduce transaction times dramatically. +- **Confirmation and balances:** Check each transaction and verify the final balances after four transfers between five accounts. ## Step-by-step process @@ -42,7 +44,7 @@ Alice ➡ Bob ➡ Charlie ➡ Dave ➡ Eve ➡ Frank ➡ ... 4. **Minting and Transacting with Unauthenticated Notes:** - Mint tokens for one of the accounts (Alice) from the deployed faucet. - Create a note representing the minted tokens. - - Build and submit a transaction that uses the unauthenticated note via the "unauthenticated" method. + - Submit the note-creation transaction without waiting for confirmation, then pass the complete note to `.build_consume_notes(vec![note])`. This calls `input_notes` internally without extra execution arguments. - Serialize the note to demonstrate how it could be transferred to another client instance. - Consume the note in a subsequent transaction, effectively creating a chain of unauthenticated transactions. @@ -50,73 +52,81 @@ Alice ➡ Bob ➡ Charlie ➡ Dave ➡ Eve ➡ Frank ➡ ... - Measure the time taken for each transaction iteration. - Sync the client state and print account balances to verify the transactions. +## Set up the Rust project + +Start in the directory containing your `tutorials` clone and create a sibling Cargo project: + +```bash +cargo new miden-unauthenticated-notes +cd miden-unauthenticated-notes +rustup override set 1.98.1 +cp ../tutorials/rust-client/Cargo.lock Cargo.lock +``` + +Keep the generated `[package]` section in `Cargo.toml`, replace its empty `[dependencies]` section with the following, and add the development profile. The path assumes the repository clone is named `tutorials`. + +```toml +[dependencies] +# Clone tutorials next to this Cargo project (see Rust client setup). +rust-client = { path = "../tutorials/rust-client" } +miden-client = { version = "=0.16.0", features = ["testing", "tonic"] } +miden-client-sqlite-store = { version = "=0.16.0", package = "miden-client-sqlite-store" } +miden-protocol = { version = "=0.16.0" } +rand = { version = "0.10" } +tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } + +[profile.dev] +opt-level = 2 +``` + +Copy the complete Rust example below into `src/main.rs`. Run it from this new project's directory with `TUTORIAL_NETWORK=testnet cargo run --release`. The client creates `store.sqlite3` and `keystore/` here; keep both out of version control. + ## Full Rust code example ```rust no_run -use rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; -use tokio::time::{sleep, Duration, Instant}; +use tokio::time::{Duration, Instant}; use miden_client::{ + Client, ClientError, account::{ + AccountBuilder, AccountType, component::{ - BasicWallet, BurnPolicyConfig, FungibleFaucet, MintPolicyConfig, PolicyRegistration, - TokenName, TokenPolicyManager, + create_singlesig_user_fungible_faucet, BasicWallet, BurnPolicy, FungibleFaucet, + MintPolicy, TokenName, TokenPolicyManager, }, - AccountBuilder, AccountType, }, - address::NetworkId, - asset::{AssetAmount, AssetCallbackFlag, AssetVaultKey, FungibleAsset, TokenSymbol}, - auth::{AuthSchemeId, AuthSecretKey, AuthSingleSig}, + asset::{AssetAmount, AssetId, FungibleAsset, TokenSymbol}, + auth::{AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, keystore::{FilesystemKeyStore, Keystore}, - note::{Note, NoteAttachments, NoteType, P2idNote}, - rpc::{Endpoint, GrpcClient}, - store::TransactionFilter, - transaction::{TransactionId, TransactionRequestBuilder, TransactionStatus}, + note::{Note, NoteType, P2idNote}, + rpc::{GrpcClient, VerifyingRpcClient}, + transaction::{TransactionId, TransactionRequestBuilder}, utils::{Deserializable, Serializable}, - Client, ClientError, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::{FeeConfig, TutorialNetwork, fund_account_for_fees}; /// Waits for a specific transaction to be committed. async fn wait_for_tx( client: &mut Client, tx_id: TransactionId, ) -> Result<(), ClientError> { - loop { - client.sync_state().await?; - - // Check transaction status - let txs = client - .get_transactions(TransactionFilter::Ids(vec![tx_id])) - .await?; - let tx_committed = if !txs.is_empty() { - matches!(txs[0].status, TransactionStatus::Committed { .. }) - } else { - false - }; - - if tx_committed { - println!("✅ transaction {} committed", tx_id.to_hex()); - break; - } - - println!( - "Transaction {} not yet committed. Waiting...", - tx_id.to_hex() - ); - sleep(Duration::from_secs(2)).await; - } - Ok(()) + rust_client::wait_for_transaction(client, tx_id).await } #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -128,12 +138,12 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; //------------------------------------------------------------ // STEP 1: Deploy a fungible faucet @@ -153,38 +163,40 @@ async fn main() -> Result<(), ClientError> { let max_supply = AssetAmount::new(1_000_000).unwrap(); // Build the account - let faucet_account = AccountBuilder::new(init_seed) - .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) - .with_component( - FungibleFaucet::builder() - .name(TokenName::new("MID").unwrap()) - .symbol(symbol) - .decimals(decimals) - .max_supply(max_supply) - .build() - .unwrap(), - ) - .with_components( - TokenPolicyManager::new() - .with_mint_policy(MintPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap() - .with_burn_policy(BurnPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap(), - ) + let faucet = FungibleFaucet::builder() + .name(TokenName::new("MID").unwrap()) + .symbol(symbol) + .decimals(decimals) + .max_supply(max_supply) .build() .unwrap(); + let policies = TokenPolicyManager::builder() + .active_mint_policy(MintPolicy::allow_all()) + .active_burn_policy(BurnPolicy::allow_all()) + .build(); + let faucet_account = create_singlesig_user_fungible_faucet( + init_seed, + faucet, + AuthSingleSig::from_public_key(key_pair.public_key()), + policies, + AccountType::Public, + ) + .unwrap(); // Add the faucet to the client client.add_account(&faucet_account, false).await?; println!( "Faucet account ID: {}", - faucet_account.id().to_bech32(NetworkId::Testnet) + faucet_account.id().to_bech32(network.network_id()) ); // Add the key pair to the keystore - keystore.add_key(&key_pair, faucet_account.id()).await.unwrap(); + keystore + .add_key(&key_pair, faucet_account.id()) + .await + .unwrap(); + fund_account_for_fees(&mut client, faucet_account.id(), &fee_config).await?; // Resync to show newly deployed faucet tokio::time::sleep(Duration::from_secs(2)).await; @@ -196,7 +208,7 @@ async fn main() -> Result<(), ClientError> { println!("\n[STEP 2] Creating new accounts"); let mut accounts = vec![]; - let number_of_accounts = 2; + let number_of_accounts = 5; for i in 0..number_of_accounts { let mut init_seed = [0_u8; 32]; @@ -206,7 +218,7 @@ async fn main() -> Result<(), ClientError> { let account = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet) .build() .unwrap(); @@ -215,12 +227,13 @@ async fn main() -> Result<(), ClientError> { println!( "account id {:?}: {}", i, - account.id().to_bech32(NetworkId::Testnet) + account.id().to_bech32(network.network_id()) ); client.add_account(&account, true).await?; // Add the key pair to the keystore keystore.add_key(&key_pair, account.id()).await.unwrap(); + fund_account_for_fees(&mut client, account.id(), &fee_config).await?; } // For demo purposes, Alice is the first account. @@ -243,7 +256,7 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let tx_id = client - .submit_new_transaction(faucet_account.id(), transaction_request) + .submit_tutorial_transaction(faucet_account.id(), transaction_request) .await?; println!("Minted tokens. TX: {:?}", tx_id); @@ -251,16 +264,17 @@ async fn main() -> Result<(), ClientError> { wait_for_tx(&mut client, tx_id).await?; // Get the minted note and consume it - let consumable_notes = client.get_consumable_notes(Some(alice.id())).await?; + let consumable_notes = client + .get_consumable_tutorial_notes(Some(alice.id())) + .await?; if let Some((note_record, _)) = consumable_notes.first() { let note: Note = note_record.clone().try_into()?; - let transaction_request = TransactionRequestBuilder::new() - .build_consume_notes(vec![note]) - .unwrap(); + let transaction_request = + TransactionRequestBuilder::new().build_consume_notes(vec![note])?; let consume_tx_id = client - .submit_new_transaction(alice.id(), transaction_request) + .submit_tutorial_transaction(alice.id(), transaction_request) .await?; println!("Consumed minted note. TX: {:?}", consume_tx_id); @@ -277,10 +291,13 @@ async fn main() -> Result<(), ClientError> { for i in 0..number_of_accounts - 1 { let loop_start = Instant::now(); println!("\nunauthenticated tx {:?}", i + 1); - println!("sender: {}", accounts[i].id().to_bech32(NetworkId::Testnet)); + println!( + "sender: {}", + accounts[i].id().to_bech32(network.network_id()) + ); println!( "target: {}", - accounts[i + 1].id().to_bech32(NetworkId::Testnet) + accounts[i + 1].id().to_bech32(network.network_id()) ); // Time the creation of the p2id note @@ -295,26 +312,30 @@ async fn main() -> Result<(), ClientError> { NoteType::Public }; - let p2id_note = P2idNote::create( - accounts[i].id(), - accounts[i + 1].id(), - vec![fungible_asset_send_amount.into()], - note_type, - NoteAttachments::empty(), - client.rng(), - ) - .unwrap(); + let p2id_note: Note = P2idNote::builder() + .sender(accounts[i].id()) + .target(accounts[i + 1].id()) + .asset(fungible_asset_send_amount) + .note_type(note_type) + .generate_serial_number(client.rng()) + .build() + .unwrap() + .into(); + + let output_note = p2id_note.clone(); // Time transaction request building let transaction_request = TransactionRequestBuilder::new() - .own_output_notes(vec![p2id_note.clone()]) + .own_output_notes(vec![output_note]) .build() .unwrap(); - let tx_id = client + // Do not wait for inclusion: the receiver is given the complete note below. + client.sync_state().await?; + let send_tx_id = client .submit_new_transaction(accounts[i].id(), transaction_request) .await?; - println!("Created note. TX: {:?}", tx_id); + println!("Created note. TX: {:?}", send_tx_id); // Note serialization/deserialization // This demonstrates how you could send the serialized note to another client instance @@ -322,17 +343,17 @@ async fn main() -> Result<(), ClientError> { let deserialized_p2id_note = Note::read_from_bytes(&serialized).unwrap(); // Time consume note request building - let consume_note_request = TransactionRequestBuilder::new() - .input_notes([(deserialized_p2id_note, None)]) - .build() - .unwrap(); + let consume_note_request = + TransactionRequestBuilder::new().build_consume_notes(vec![deserialized_p2id_note])?; let tx_id = client - .submit_new_transaction(accounts[i + 1].id(), consume_note_request) + .submit_tutorial_transaction(accounts[i + 1].id(), consume_note_request) .await?; + rust_client::wait_for_transaction(&mut client, send_tx_id).await?; println!( - "Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "Consumed Note Tx on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); println!( @@ -350,33 +371,42 @@ async fn main() -> Result<(), ClientError> { // Final resync and display account balances tokio::time::sleep(Duration::from_secs(3)).await; client.sync_state().await?; - for account in accounts.clone() { - let new_account = client.get_account(account.id()).await.unwrap().expect("account not found"); + for (index, account) in accounts.iter().enumerate() { + let new_account = client.get_account(account.id()).await.unwrap().unwrap(); let balance = new_account .vault() - .get_balance(AssetVaultKey::new_fungible( - faucet_account.id(), - AssetCallbackFlag::Disabled, - )) + .get_balance(AssetId::new_fungible(faucet_account.id())) .unwrap(); println!( "Account: {} balance: {}", - account.id().to_bech32(NetworkId::Testnet), + account.id().to_bech32(network.network_id()), balance ); + let expected = if index == 0 { + 80 + } else if index == accounts.len() - 1 { + 20 + } else { + 0 + }; + assert_eq!( + balance.as_u64(), + expected, + "unexpected transfer-chain balance" + ); } Ok(()) } ``` -The output of our program will look something like this: +The following is an abbreviated output. IDs and timings vary; each measured iteration includes confirmation polling, and funding logs are omitted: ```text -Latest block: 227040 +Latest block: [STEP 1] Deploying a new fungible faucet. -Faucet account ID: +Faucet account ID: [STEP 2] Creating new accounts account id 0: @@ -384,101 +414,71 @@ account id 1: account id 2: account id 3: account id 4: -account id 5: -account id 6: -account id 7: -account id 8: -account id 9: [STEP 3] Mint tokens Minting tokens for Alice... +Minted tokens. TX: +Consumed minted note. TX: [STEP 4] Create unauthenticated note tx chain unauthenticated tx 1 sender: target: -Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/0x31f48117c645c5b4ccff78ef356bad764798d4f207925e492ebbae1b86ef4f55 -Total time for loop iteration 0: 1.952243542s +Created note. TX: +Transaction committed: +Transaction committed: +Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/ +Total time for loop iteration 0: unauthenticated tx 2 sender: target: -Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/0x45b4c62c6e8e79a1c7200d1c84dc6304a88debd37b20b069dd739498827354c1 -Total time for loop iteration 1: 2.091625458s +Created note. TX: +Transaction committed: +Transaction committed: +Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/ +Total time for loop iteration 1: unauthenticated tx 3 sender: target: -Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/0xb2241e10df8f6f891b910975a3b4f4fd47657c47de164138300d683cfca5dd61 -Total time for loop iteration 2: 1.846021291s +Created note. TX: +Transaction committed: +Transaction committed: +Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/ +Total time for loop iteration 2: unauthenticated tx 4 sender: target: -Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/0xd3ea6fa1da6c317f055ac4b069388d93b88d526039e01531879e75598e0f8cff -Total time for loop iteration 3: 1.877627958s - -unauthenticated tx 5 -sender: -target: -Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/0x6098638ec0ff7331432c037331ee7372977abe20af5c56315985fd314e21548d -Total time for loop iteration 4: 1.884586875s - -unauthenticated tx 6 -sender: -target: -Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/0x8258292e49e0cfdd96603450c2de6738afecb1e7482ede0fb68ea375e884e1d8 -Total time for loop iteration 5: 1.886505875s - -unauthenticated tx 7 -sender: -target: -Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/0x9e0f84e00a9393bf6e5f224d55ccdf8bd0ef32ee20c3299e2dfccf1771001dfd -Total time for loop iteration 6: 2.095149458s - -unauthenticated tx 8 -sender: -target: -Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/0xa9db6445dfaa44ccf9dd52bf4cd8d9057946571ccb5299a7a56c59faf2ed2093 -Total time for loop iteration 7: 1.935587291s - -unauthenticated tx 9 -sender: -target: -Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/0xba4bb4ae3c7aaf949cdd3be8c9ea52169f958e7dca8e9d4541fd5ac939393e41 -Total time for loop iteration 8: 1.964682833s - -Total execution time for unauthenticated note txs: 17.534611542s -blocks: [BlockNumber(227047), BlockNumber(227047), BlockNumber(227047), BlockNumber(227047), BlockNumber(227047), BlockNumber(227047), BlockNumber(227047), BlockNumber(227047), BlockNumber(227047)] +Created note. TX: +Transaction committed: +Transaction committed: +Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/ +Total time for loop iteration 3: + +Total execution time for unauthenticated note txs: Account: balance: 80 Account: balance: 0 Account: balance: 0 Account: balance: 0 -Account: balance: 0 -Account: balance: 0 -Account: balance: 0 -Account: balance: 0 -Account: balance: 0 -Account: balance: 20 +Account: balance: 20 ``` ## Conclusion -Unauthenticated notes on Miden offer a powerful mechanism for achieving faster asset settlements by allowing notes to be both created and consumed within the same block. In this guide, we walked through: - -- **Minting and Transacting with Unauthenticated Notes:** Building, serializing, and consuming notes quickly using the Miden client's "unauthenticated note" method. -- **Performance Observations:** Measuring and demonstrating how unauthenticated notes enable assets to be sent faster than the blocktime. +This example builds, serializes, and consumes complete notes through `build_consume_notes` without first waiting for their inclusion proofs. It confirms four transfers across five accounts and checks the tutorial-asset balances `[80, 0, 0, 0, 20]`; each account's native fee balance is separate. -By following this guide, you should now have a clear understanding of how to build and deploy high-performance transactions using unauthenticated notes on Miden. Unauthenticated notes are the ideal approach for applications like central limit order books (CLOBs) or other DeFi platforms where transaction speed is critical. +Applications can use this pattern to submit dependent transactions before the notes are committed. The node must still accept the creation transaction for its dependent consumption to settle. ### Running the example -To run the unauthenticated note transfer example, navigate to the `rust-client` directory in the [miden-tutorials](https://github.com/0xMiden/miden-tutorials/) repository and run this command: +From the root of your `tutorials` clone, run the checked-in example: ```bash cd rust-client -cargo run --release --bin unauthenticated_note_transfer +TUTORIAL_NETWORK=testnet cargo run --release --bin unauthenticated_note_transfer ``` ### Continue learning diff --git a/docs/src/web-client/bridging_with_epoch_tutorial.md b/docs/src/web-client/bridging_with_epoch_tutorial.md index 2dd9d20e..12f469d3 100644 --- a/docs/src/web-client/bridging_with_epoch_tutorial.md +++ b/docs/src/web-client/bridging_with_epoch_tutorial.md @@ -5,13 +5,13 @@ sidebar_position: 9 # Bridging Miden to and from EVM with Epoch -_Move assets between Miden and Sepolia testnet through the Epoch protocol intent SDK, without writing a custom bridge_ +_Move assets between Miden testnet and Sepolia testnet through the Epoch protocol intent SDK, without writing a custom bridge_ ## Overview -This is a guided tour of the runnable reference app under [`examples/bridging-app/`](https://github.com/0xMiden/tutorials/tree/main/examples/bridging-app), which bridges fungible tokens between Miden and an EVM chain (Sepolia testnet) in both directions through the [Epoch protocol](https://epochprotocol.xyz/) intent SDK. Clone and run the app, then read the steps below as annotations on the integration points you'd port into your own Miden frontend. Every fenced code block is a verbatim slice of the app; the file and line range above each block points to the source. +This is a guided tour of the reference app under [`examples/bridging-app/`](https://github.com/0xMiden/tutorials/tree/main/examples/bridging-app), which bridges fungible tokens between Miden testnet and Sepolia through the [Epoch protocol](https://epochprotocol.xyz/) intent SDK. Clone and run the app, then read the steps below as annotations on the integration points you'd port into your own Miden frontend. Every fenced code block is a verbatim slice of the app; the file and line range above each block points to the source. -> **When to use Epoch vs Agglayer.** This tutorial uses **Epoch** because it is the only Miden bridge with a working TypeScript SDK, EVM-wallet integration, and broad chain coverage today — Epoch's Compact contract is deployed on Ethereum, Polygon, Optimism, Arbitrum, Base (mainnet) and on Sepolia plus six other EVM testnets. If your app is **authored in Rust/MASM, needs Polygon CDK ecosystem compatibility, or settles on a Polygon Agglayer-connected rollup**, the Agglayer protocol surface ships in-tree at [`protocol/crates/miden-agglayer/SPEC.md`](https://github.com/0xMiden/protocol/blob/next/crates/miden-agglayer/SPEC.md); Miden testnet ↔ Sepolia bridging via Agglayer went live on 2026-04-24. +Live settlement requires an Epoch allocator and asset faucet deployed on the selected Miden network and compatible with v0.16. Devnet is available for explicit checks by setting `VITE_MIDEN_NETWORK`, `VITE_MIDEN_RPC_URL`, and `VITE_MIDEN_PROVER` to `devnet` with a matching allocator and faucet. Stack: Vite + React 19 + TypeScript, `@miden-sdk/react`, `@epoch-protocol/epoch-intents-sdk`, [RainbowKit](https://www.rainbowkit.com/) + [wagmi](https://wagmi.sh/) + [viem](https://viem.sh/). @@ -20,14 +20,14 @@ Stack: Vite + React 19 + TypeScript, `@miden-sdk/react`, `@epoch-protocol/epoch- - Wire the Epoch SDK against a wagmi `walletClient`, including the chain-id override for Miden-source intents. - Build a Miden → EVM bridge: reverse-quote, sign a P2IDE note via the MidenFi wallet adapter, submit the intent, and poll for settlement. - Build the reverse EVM → Miden bridge: deposit an ERC-20 into Epoch's Compact contract and receive a P2ID note on Miden. -- A `EpochIntentSDK` API reference card with all 11 public methods. +- An `EpochIntentSDK` API reference card for quoting, settlement, and recovery. - Inline pitfalls — the eleven traps every Epoch integration hits before the first successful round-trip. ## Prerequisites You need three things to follow along. -1. The reference app, cloned from this repo. The bridging-specific layer (Epoch SDK wiring, wagmi/RainbowKit + viem, intent forms, status panels) lives in `examples/bridging-app/`; `yarn create miden-app` (≥ 1.0.7) is the Miden + Vite + WASM scaffold it started from. Clone the repo, `cd examples/bridging-app`, then `cp .env.example .env` inside that directory and fill in: `VITE_RAINBOWKIT_PROJECT_ID` (a [WalletConnect Cloud](https://cloud.walletconnect.com/) project id — required), `VITE_ALLOCATOR_URL` (default `https://testnet-dev.epochprotocol.xyz`), `VITE_MIDEN_RPC_URL` (default `testnet`), `VITE_MIDEN_PROVER` (default `testnet`), and the optional `VITE_MIDENSCAN_URL`. See the [setup guide](./setup_guide.md) if this is your first Miden frontend. +1. The reference app, cloned from this repo. The bridging-specific layer (Epoch SDK wiring, wagmi/RainbowKit + viem, intent forms, status panels) lives in `examples/bridging-app/`; `yarn create miden-app` (≥ 1.0.7) is the Miden + Vite + WASM scaffold it started from. Clone the repo, `cd examples/bridging-app`, then `cp .env.example .env` inside that directory and fill in: `VITE_RAINBOWKIT_PROJECT_ID` (a [WalletConnect Cloud](https://cloud.walletconnect.com/) project id — required), `VITE_ALLOCATOR_URL` (an Epoch allocator compatible with the pinned SDK), `VITE_MIDEN_NETWORK` (default `testnet`), optional `VITE_MIDEN_RPC_URL` and `VITE_MIDEN_PROVER` overrides, `VITE_MIDEN_USDC_FAUCET_ID` from the selected allocator deployment, and the optional `VITE_MIDENSCAN_URL`. The wallet network, RPC, faucet, and allocator must agree. Keep native MIDEN tokens in the wallet to pay both collateral and note-consumption fees. See the [setup guide](./setup_guide.md) if this is your first Miden frontend. 2. Two wallets: an EVM wallet supported by [RainbowKit](https://www.rainbowkit.com/) (MetaMask, Rabby, Coinbase Wallet, …) and the [MidenFi browser extension](https://chromewebstore.google.com/detail/miden-wallet/ablmompanofnodfdkgchkpmphailefpb) for signing P2IDE notes on Miden. @@ -90,7 +90,7 @@ The snippet below sits inside the `useEpochIntent` hook — `walletClient` is `u ``` :::caution Do not follow the package README -The npm package ships a `# Compact SDK` README that documents a different SDK and a different surface. Treat `EpochIntentSDK`'s exported method names from `dist/index.d.ts` as the source of truth — the [API Reference Card](#api-reference-card) below lists them. +The npm package ships a `# Compact SDK` README that documents a different SDK and a different surface. Treat `EpochIntentSDK`'s exported method names from `dist/sdk/epoch-intent-sdk.d.ts` as the source of truth — the [API Reference Card](#api-reference-card) below lists them. ::: The `useWithdrawIntent` hook keeps `walletClient.chain.id` untouched — the EVM → Miden direction uses the real Sepolia chain id (`11155111`). @@ -99,9 +99,9 @@ The `useWithdrawIntent` hook keeps `walletClient.chain.id` untouched — the EVM A Miden → EVM bridge runs four stages: `getTaskData` (the allocator computes a quote envelope), `getIntentQuote` (price discovery), `solveIntent` (the user signs a P2IDE note on Miden via the wallet adapter callback), and a 5-second polling loop against `getIntentStatus` until the solver lands the EVM transfer. The reference app's `buildEpochTaskDataParams` produces the envelope and computes `midenReclaimHeight` at the call site so it stays relative to the current Miden chain tip (Pitfalls row 4 has the technical reason). -**From `examples/bridging-app/src/services/epoch-bridge.ts` (lines 141–173):** +**From `examples/bridging-app/src/services/epoch-bridge.ts` (lines 133–165):** - + ```typescript // Reclaim height must come from the call site as `currentMidenBlock + N`. @@ -139,48 +139,51 @@ A Miden → EVM bridge runs four stages: `getTaskData` (the allocator computes a }; ``` -Once the quote returns and the user clicks **Confirm & sign**, the `createMidenP2IDNote` callback fires. The reference app's callback uses `useMidenFiWallet().requestSend` to construct an explicitly `'public'` P2IDE `SendTransaction`, guards the amount under `Number.MAX_SAFE_INTEGER` (the wallet adapter's `SendTransaction` constructor takes a `number`, not a `bigint`), and awaits a 120-second `waitForTransaction(txId, 120_000)` to read the output note id. +Once the quote returns and the user clicks **Confirm & sign**, `createMidenP2IDENote` receives the allocator, relative recall window, and mandate-binding attachment from Epoch. The app builds a public P2IDE note containing those exact values, prepares a fee-aware custom request, and asks the wallet to sign it with `requestTransaction`. Amounts remain `bigint`. After confirmation it locates the exact collateral note ID, excluding any `TX_FEE` output. -**From `examples/bridging-app/src/components/crosschain/IntentForm.tsx` (lines 200–243):** +**From `examples/bridging-app/src/components/crosschain/IntentForm.tsx` (lines 202–248):** - + ```typescript - const createMidenP2IDNote: SolveIntentParams['createMidenP2IDNote'] = async ( + const createMidenP2IDENote: SolveIntentParams['createMidenP2IDENote'] = async ( faucetIdParam, amountParam, allocatorId, + recallBlocks, + bindingAttachmentFelts, ) => { setConfirmStatus('Resource lock required — creating P2IDE note on Miden…'); try { if (!midenAccountId) { throw new Error('Missing Miden account id'); } - if (!requestSend) { - throw new Error('Miden wallet adapter is not connected'); + if (!requestTransaction || !waitForTransaction || !client) { + throw new Error('Connect a Miden wallet that supports custom transactions and confirmation'); } - const normalizedAmount = BigInt(amountParam); - if (normalizedAmount > BigInt(Number.MAX_SAFE_INTEGER)) { - throw new Error('Amount too large for wallet adapter send'); - } - - const payload = new SendTransaction( - midenAccountId, - allocatorId, - faucetIdParam, - 'public', - Number(normalizedAmount), + const { request, expectedNoteId } = await runExclusive(async () => { + const head = await client.syncState(); + const note = createEpochCollateralNote({ + sender: midenAccountId, allocator: allocatorId, faucet: faucetIdParam, + amount: BigInt(amountParam), currentBlock: head.blockNum(), + recallBlocks, bindingAttachmentFelts, + }); + const builder = await client.feeAwareTransactionRequestBuilder(AccountId.fromHex(midenAccountId)); + return { + expectedNoteId: note.id().toString(), + request: builder.withOwnOutputNotes(new NoteArray([note])).build(), + }; + }); + const txId = await requestTransaction( + Transaction.createCustomTransaction(midenAccountId, allocatorId, request), ); - const txId = await requestSend(payload); - // Prefer adapter waitForTransaction to get the output note id. - if (!waitForTransaction) { - throw new Error('Miden wallet adapter is missing waitForTransaction'); - } + // Wait for the wallet to confirm the collateral before submitting it to Epoch. const finalized = await waitForTransaction(txId, 120_000); - const first = finalized.outputNotes?.[0]; - const noteId = first ? first.id().toString() : ''; + // A fee-paying transaction also creates a TX_FEE note. Match our exact + // collateral note instead of assuming outputNotes[0] is the payment. + const noteId = finalized.outputNotes?.find(note => note.id().toString() === expectedNoteId)?.id().toString(); if (!noteId) { throw new Error(`Could not read output note id for tx ${txId}`); } @@ -192,7 +195,7 @@ Once the quote returns and the user clicks **Confirm & sign**, the `createMidenP }; ``` -Success is signalled by the 5-second polling loop: `getIntentStatus` returns an `IntentTransactionStatus[]`, which the app reduces into the composite `IntentFlowStatus`. The forward bridge is settled once the destination chain reports a terminal-OK row (`evmCompleted`) and the synthetic Miden row carries a terminal `midenStatus` — the EVM transfer landed and the allocator consumed the P2IDE note. That reducer is destination-chain aware: it filters status rows to the chain the user selected, never reports completion while any destination-chain row is still `pending`, and takes the last destination-chain success — so an intermediate allocator/Compact row is never mistaken for the final settlement. The Pitfalls section below catalogues the gotchas this step inherits (public note type, awaiting `waitForTransaction`, advisory `midenFaucetDecimals`, the `Number.MAX_SAFE_INTEGER` guard). +Success is signalled by the 5-second polling loop: `getIntentStatus` returns an `IntentTransactionStatus[]`, which the app reduces into the composite `IntentFlowStatus`. The forward bridge is settled once the destination chain reports a terminal-OK row (`evmCompleted`) and the synthetic Miden row carries a terminal `midenStatus` — the EVM transfer landed and the allocator consumed the P2IDE note. That reducer is destination-chain aware: it filters status rows to the chain the user selected, never reports completion while any destination-chain row is still `pending`, and takes the last destination-chain success — so an intermediate allocator/Compact row is never mistaken for the final settlement. The Pitfalls section below catalogues the gotchas this step inherits (public note type, awaiting `waitForTransaction`, advisory `midenFaucetDecimals`, the exact collateral-note ID check). ## Step 3: EVM → Miden bridge @@ -202,9 +205,9 @@ The reverse direction lives in `buildEVMToMidenTaskDataParams` + `useWithdrawInt The Step 3 reverse quote folds a route fee into the required deposit, so a Step 2 bridge of exactly 1 USDC won't cover a 1-USDC reverse — the quote asks for ~1.01 USDC and MetaMask flags `depositERC20AndRegister` as likely to fail (the `approve` lands first; rejecting the deposit is recoverable). Set Step 2's `min output` to about `2e18` for headroom, or run a second forward bridge before retrying. ::: -**From `examples/bridging-app/src/services/epoch-bridge.ts` (lines 224–245):** +**From `examples/bridging-app/src/services/epoch-bridge.ts` (lines 216–237):** - + ```typescript const taskDataParams = { @@ -234,7 +237,7 @@ The Step 3 reverse quote folds a route fee into the required deposit, so a Step `solveIntent({ ..., collateralType: CollateralType.EVM })` then walks the user's wallet through an ERC-20 `approve` (only on the first deposit of a given token) and `depositERC20AndRegister` / `depositNativeAndRegister` against Epoch's [Compact](https://docs.epochprotocol.xyz/epoch-miden-integration/integration-guide) contract on Sepolia. The intent nonce extracted from the solve result drives the same 5-second status poll as the forward direction. :::caution Forced-withdrawal preflight -If the user cancelled a prior EVM → Miden intent on the same Compact deposit id, the next intent will revert. Call `sdk.disableForcedWithdrawal({ ... })` first; the SDK error message names the deposit id when this preflight is required. +If the user cancelled a prior EVM → Miden intent on the same Compact deposit id, the next intent will revert. Call `sdk.disableForcedWithdrawal(depositId)` first; the SDK error message names the deposit id when this preflight is required. ::: :::caution The Withdraw token is Epoch's test ERC-20, not Circle's USDC @@ -243,41 +246,41 @@ The "USDC" the Withdraw form lists is Epoch's test token (`0x2BB4FfD7…`), not ## Step 4: The bridged P2ID note is consumed by your wallet -Step 3's allocator delivers its output as a **P2ID note** addressed to your Miden account, not as a vault credit. In Miden's actor model, a note must be _consumed_ in a transaction before it becomes spendable balance. The Miden Wallet consumes incoming P2ID notes when it detects them, so the bridged funds appear as wallet balance within seconds and are immediately usable as the source for another Miden → EVM bridge. The reference app's `WithdrawConsume` component keeps this step informational: it shows the delivered note ID and links to Midenscan so you can confirm settlement. +Step 3's allocator delivers its output as a **P2ID note** addressed to your Miden account, not as a vault credit. The note must be consumed in a transaction before it becomes spendable. Wallet auto-consumption depends on the installed wallet's configuration and sufficient native MIDEN for fees: a USDC-only note cannot pay that native fee. The reference app links the delivered note to Midenscan; confirm its consumption and the final wallet balance before treating the bridge as complete. ## API Reference Card -Most apps only touch four methods (`getTaskData`, `getIntentQuote`, `solveIntent`, `getIntentStatus`); the rest cover recovery and read-only queries. Sources cite `dist/index.d.ts` from `@epoch-protocol/epoch-intents-sdk@1.0.23`. - -| Method | Signature (abridged) | Use it to | Source | -| --------------------------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------------- | -------------------- | -| `getTaskData` | `(params: GetTaskDataParams) => Promise<{ taskTypeString, intentData }>` | Construct the SIO envelope before quoting | `dist/index.d.ts:11` | -| `solveIntent` | `(params: SolveIntentParams) => Promise` | Submit the intent + run the optional Miden P2ID note callback | `dist/index.d.ts:12` | -| `getIntentQuote` | `(params: GetIntentQuoteParams) => Promise` | Reverse-quote (`tokenInAmount: '0'`) or forward quote | `dist/index.d.ts:13` | -| `retryIntentSolve` | `(id: string) => Promise` | Re-run the solver if a transient failure is observed | `dist/index.d.ts:14` | -| `initateDepositWithdrawal` | `(id: string) => Promise` | Initiate a forced withdrawal flow (verbatim misspelling; see Pitfalls) | `dist/index.d.ts:16` | -| `disableForcedWithdrawal` | `(params: DisableForcedWithdrawalParams) => Promise` | Cancel a pending forced withdrawal so a new intent can solve | `dist/index.d.ts:17` | -| `withdrawToken` | `(params: WithdrawTokenParams) => Promise` | Reclaim an unfulfilled EVM-side deposit | `dist/index.d.ts:18` | -| `getForcedWithdrawalStatus` | `(id: string) => Promise` | Observe a forced-withdrawal lifecycle | `dist/index.d.ts:19` | -| `getDepositedBalances` | `(addr: string) => Promise` | List the user's locked balances in the Compact | `dist/index.d.ts:20` | -| `getIntentStatus` | `(addr: string, nonce: string) => Promise` | Drive the 5s polling loop | `dist/index.d.ts:21` | -| `getHealthCheck` | `() => Promise` | Probe allocator availability before quoting | `dist/index.d.ts:22` | +Most apps only touch four methods. The selected signatures below come from `dist/sdk/epoch-intent-sdk.d.ts` in the pinned `@epoch-protocol/epoch-intents-sdk@1.0.38`. + +| Method | Signature (abridged) | Purpose | +| --------------------------- | ------------------------------------------------------------- | ---------------------------- | +| `getTaskData` | `(params: GetTaskDataParams)` | Build the quote envelope | +| `getIntentQuote` | `({ sponsorAddress, taskTypeString, intentData, isNative? })` | Obtain a quote | +| `solveIntent` | `(params: SolveIntentParams)` | Sign and submit the intent | +| `getIntentStatus` | `(userAddress: string, nonce: string)` | Poll settlement | +| `retryIntentSolve` | `(request: CompactRequest)` | Retry a recorded allocation | +| `initateDepositWithdrawal` | `(id: string)` | Initiate forced withdrawal | +| `disableForcedWithdrawal` | `(id: string)` | Cancel forced withdrawal | +| `withdrawToken` | `(id: string, recipient: string, amount: string)` | Withdraw a deposit | +| `getForcedWithdrawalStatus` | `(account: string, id: string)` | Inspect recovery status | +| `getDepositedBalances` | `(account: string, tokens: CompactTokenBalanceInput[])` | Inspect locked balances | +| `getHealthCheck` | `()` | Probe allocator availability | Recovery primitives (`retryIntentSolve`, `disableForcedWithdrawal`, `withdrawToken`, `initateDepositWithdrawal`) are the difference between an intent flow that "mostly works" and one that lets users recover from solver outages or network failures. ## Pitfalls -Eleven traps every Epoch integration hits before the first successful round-trip. The reference app ships mitigations for each. +Check these integration details before a live round trip: -- **Don't follow the npm package README.** It documents an unrelated SDK; the [integration guide](https://docs.epochprotocol.xyz/epoch-miden-integration/integration-guide) and `dist/index.d.ts` are the source of truth. +- **Don't follow the npm package README.** It documents an unrelated SDK; the [integration guide](https://docs.epochprotocol.xyz/epoch-miden-integration/integration-guide) and `dist/sdk/epoch-intent-sdk.d.ts` are the source of truth. - **Public notes only.** P2IDE notes for the allocator must be `'public'`; a `'private'` note is invisible to the solver. -- **Always await `waitForTransaction`.** Reading `outputNotes[0]` early returns an empty array; the 120-second timeout covers proving + testnet submission. -- **Reclaim height is `currentBlock + N`.** `midenReclaimHeight` is absolute; use `useSyncState().syncHeight + 1000` at the call site, never a literal. +- **Await confirmation and match the note ID.** A fee-paying transaction also creates a `TX_FEE` output. Do not pass `outputNotes[0]` to Epoch; locate the exact collateral note ID after `waitForTransaction`. +- **Honor Epoch’s callback window and binding.** `createMidenP2IDENote` supplies `recallBlocks` and `bindingAttachmentFelts`. Build a public P2IDE with `currentBlock + recallBlocks` after a fresh sync and include the attachment verbatim. A plain `SendTransaction` cannot represent this attachment. The quote’s preliminary reclaim-height field is not a substitute for the callback values. - **`minTokenOut` is base units.** The reverse-quote path passes it straight through — no `parseUnits`. For an 18-decimal token, `"1000000000000000000"` is one whole unit. - **Override `walletClient.chain.id` for Miden-source intents.** Set `chain.id = 999999999` for Miden → EVM only; leave it as the real EVM chain id for the reverse direction. - **`midenFaucetDecimals` is advisory.** Fall back to UI-selected decimals when the allocator value would change the displayed amount by an order of magnitude. -- **`Number.MAX_SAFE_INTEGER` guard.** The wallet adapter's `SendTransaction` constructor takes a `number`; guard the amount before casting. -- **No COOP/COEP on the dev server.** `midenVitePlugin({ crossOriginIsolation: false })` is mandatory — the default breaks gRPC-Web to `transport.miden.io`. +- **Keep collateral amounts as `bigint`.** The custom request uses `FungibleAsset` directly, avoiding a lossy `number` conversion. +- **Check browser cross-origin compatibility.** This single-threaded app uses `midenVitePlugin({ crossOriginIsolation: false })`; verify the chosen RPC and wallet support before enabling cross-origin isolation. - **Forced-withdrawal preflight.** Call `sdk.disableForcedWithdrawal` before re-running an EVM → Miden intent on a deposit id the user cancelled previously. - **`initateDepositWithdrawal` (misspelling).** The SDK exports the method with the typo — use it verbatim, do not silently rename. diff --git a/docs/src/web-client/counter_contract_tutorial.md b/docs/src/web-client/counter_contract_tutorial.md index 024c4f58..48c0cf24 100644 --- a/docs/src/web-client/counter_contract_tutorial.md +++ b/docs/src/web-client/counter_contract_tutorial.md @@ -5,6 +5,13 @@ sidebar_position: 5 _Using the Miden client to interact with a custom smart contract_ +:::note v0.16 setup + +Follow the [network and fee setup](./setup_guide.md#network-and-fee-setup) +and copy the shared support files imported by the complete example. + +::: + ## Overview In this tutorial, we will deploy a custom counter smart contract and increment its count using the Miden client. Each run creates a fresh counter account, deploys it to the network, and immediately calls its `increment_count` procedure via a transaction script — so the final count is always `1`. @@ -42,7 +49,7 @@ This tutorial assumes you have a basic understanding of Miden assembly. To quick 3. Install the Miden SDK: ```bash - yarn add @miden-sdk/miden-sdk@0.15.2 + yarn add @miden-sdk/miden-sdk@0.16.0 ``` **NOTE!**: Be sure to add the `--webpack` command to your `package.json` when running the `dev script`. The dev script should look like this: @@ -111,35 +118,53 @@ Create the file `lib/masm/counter_contract.masm` with the following Miden Assemb ```masm use miden::protocol::active_account use miden::protocol::native_account -use miden::core::word use miden::core::sys +# CONSTANTS +# ================================================================================================= + const COUNTER_SLOT = word("miden::tutorials::counter") -#! Inputs: [] -#! Outputs: [count] -pub proc get_count +# PUBLIC INTERFACE +# ================================================================================================= + +#! Returns the current count. +#! +#! Inputs: [pad(16)] +#! Outputs: [count, pad(15)] +#! +#! Invocation: call +@account_procedure +pub proc get_count() -> felt push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] exec.sys::truncate_stack - # => [count] + # => [count, pad(15)] end -#! Inputs: [] -#! Outputs: [] -pub proc increment_count +#! Increments the current count by one. +#! +#! Inputs: [pad(16)] +#! Outputs: [pad(16)] +#! +#! Invocation: call +@account_procedure +pub proc increment_count() push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] add.1 - # => [count+1] + # => [[count + 1, 0, 0, 0], pad(16)] push.COUNTER_SLOT[0..2] exec.native_account::set_item - # => [] + # => [OLD_VALUE, pad(16)] + + dropw + # => [pad(16)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end ``` @@ -193,11 +218,14 @@ Copy and paste the following code into the `lib/incrementCounterContract.ts` fil import counterContractCode from './masm/counter_contract.masm'; import { AuthSecretKey, - StorageMode, StorageSlot, StorageResult, - MidenClient, } from '@miden-sdk/miden-sdk/lazy'; +import { + createFundableContractAccount, + createTutorialClient, + fundAccountForFees, +} from './feeSupport'; export async function incrementCounterContract(): Promise { if (typeof window === 'undefined') { @@ -205,17 +233,11 @@ export async function incrementCounterContract(): Promise { return; } - // Wait for the WASM module to finish initializing before touching any - // wasm-bindgen type (see setup_guide.md "Entry points: eager vs lazy"). - await MidenClient.ready(); - - const nodeEndpoint = 'https://rpc.testnet.miden.io'; - const client = await MidenClient.create({ rpcUrl: nodeEndpoint }); + const client = await createTutorialClient({ proverUrl: 'local' }); console.log('Current block number: ', (await client.sync()).blockNum()); const counterSlotName = 'miden::tutorials::counter'; - // Compile the counter component const counterAccountComponent = await client.compile.component({ code: counterContractCode, slots: [StorageSlot.emptyValue(counterSlotName)], @@ -223,23 +245,37 @@ export async function incrementCounterContract(): Promise { const walletSeed = new Uint8Array(32); crypto.getRandomValues(walletSeed); - const auth = AuthSecretKey.rpoFalconWithRNG(walletSeed); - // Create the counter contract account - const account = await client.accounts.create({ - storage: StorageMode.Public, - seed: walletSeed, + const account = await createFundableContractAccount( + client, + walletSeed, auth, - components: [counterAccountComponent], - }); + [counterAccountComponent], + ); + + await fundAccountForFees(client, account); - // Building the transaction script which will call the counter contract const txScriptCode = ` - use external_contract::counter_contract - begin +use external_contract::counter_contract + +#! Increments the counter. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) + dropw + # => [pad(16)] + call.counter_contract::increment_count - end + # => [pad(16)] +end `; const script = await client.compile.txScript({ @@ -252,27 +288,26 @@ export async function incrementCounterContract(): Promise { ], }); - // Executing the transaction script against the counter contract — this - // deploys the counter and runs `increment_count` in a single transaction. - await client.transactions.execute({ + await client.sync(); + const { txId } = await client.transactions.execute({ account, script, + waitForConfirmation: true, + timeout: 120_000, }); + console.log(`Transaction committed: ${txId.toHex()}`); console.log('Counter contract ID:', account.id().toString()); - // Logging the count of the counter contract we just incremented const counter = await client.accounts.get(account); - // `getItem()` is typed to return a low-level `Word`, but at runtime the SDK // wraps the slot in a `StorageResult` whose `toBigInt()` reads the first // felt — the count. The cast reflects that runtime type. const count = counter?.storage().getItem(counterSlotName) as unknown as - | StorageResult - | undefined; - + StorageResult | undefined; const counterValue = Number(count!.toBigInt()); - + if (counterValue !== 1) + throw new Error(`Expected counter 1, got ${counterValue}`); console.log('Count: ', counterValue); } ``` @@ -312,52 +347,74 @@ Count: 1 4. Adds `1` to the count value returned from `active_account::get_item`. 5. Pushes the slot ID prefix and suffix again so we can write the updated count. 6. Calls `native_account::set_item` which saves the incremented count to storage. -7. Calls `sys::truncate_stack` to truncate the stack to size 16. +7. Drops the previous storage word returned by `set_item`. +8. Calls `sys::truncate_stack` to leave only the 16 padding elements. ```masm use miden::protocol::active_account use miden::protocol::native_account -use miden::core::word use miden::core::sys +# CONSTANTS +# ================================================================================================= + const COUNTER_SLOT = word("miden::tutorials::counter") -#! Inputs: [] -#! Outputs: [count] -pub proc get_count +# PUBLIC INTERFACE +# ================================================================================================= + +#! Returns the current count. +#! +#! Inputs: [pad(16)] +#! Outputs: [count, pad(15)] +#! +#! Invocation: call +@account_procedure +pub proc get_count() -> felt push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] exec.sys::truncate_stack - # => [count] + # => [count, pad(15)] end -#! Inputs: [] -#! Outputs: [] -pub proc increment_count +#! Increments the current count by one. +#! +#! Inputs: [pad(16)] +#! Outputs: [pad(16)] +#! +#! Invocation: call +@account_procedure +pub proc increment_count() push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] add.1 - # => [count+1] + # => [[count + 1, 0, 0, 0], pad(16)] push.COUNTER_SLOT[0..2] exec.native_account::set_item - # => [] + # => [OLD_VALUE, pad(16)] + + dropw + # => [pad(16)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end ``` -**Note**: _It's a good habit to add comments below each line of MASM code with the expected stack state. This improves readability and helps with debugging._ +The examples follow the [protocol MASM conventions](https://github.com/0xMiden/protocol/tree/next/.claude/skills): public procedures declare typed signatures and invocation style, and stack comments list the top element first. Calls return 16 stack elements, including `pad(N)` padding; storage values are four-element words. ### Authentication Component -**Important**: All accounts must have an authentication component. For smart contracts that do not require authentication (like our counter contract), we use a `NoAuth` component. - -This `NoAuth` component allows any user to interact with the smart contract without requiring signature verification. +The counter uses a Falcon single-signature authentication component. The client +stores the secret key and signs transactions that increment the counter. Public +storage lets other accounts read its state through FPI; it does not grant them +permission to update it. -**Note**: _Adding the `account::incr_nonce` to a state changing procedure allows any user to call the procedure._ +The account also includes `BasicWallet` so it can consume a native-asset funding +note and pay transaction fees. The `createFundableContractAccount` helper adds +both components and registers the account and key in the client. ### Compiling the account component @@ -372,17 +429,19 @@ const counterAccountComponent = await client.compile.component({ ### Creating the contract account -Use `client.accounts.create()` to build and register the contract. Passing `components` makes this a contract account, so no account type is needed — `storage` selects visibility (`StorageMode.Public` here). You must supply a `seed` (for deterministic ID derivation) and a raw `AuthSecretKey` — the client stores the key automatically: +Use the repository helper to build the account with authentication, the custom +counter component, and `BasicWallet`, then fund it before executing a script: ```ts const auth = AuthSecretKey.rpoFalconWithRNG(walletSeed); -const account = await client.accounts.create({ - storage: StorageMode.Public, - seed: walletSeed, +const account = await createFundableContractAccount( + client, + walletSeed, auth, - components: [counterAccountComponent], -}); + [counterAccountComponent], +); +await fundAccountForFees(client, account); ``` ### Compiling and executing the custom script @@ -401,12 +460,15 @@ const script = await client.compile.txScript({ }); ``` -Then execute it with `client.transactions.execute()`: +Synchronize, execute the script, and wait for commitment: ```ts +await client.sync(); await client.transactions.execute({ account, script, + waitForConfirmation: true, + timeout: 120_000, }); ``` @@ -417,8 +479,22 @@ This is the Miden assembly script that calls the `increment_count` procedure dur ```masm use external_contract::counter_contract -begin +#! Increments the counter. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) + dropw + # => [pad(16)] + call.counter_contract::increment_count + # => [pad(16)] end ``` @@ -429,7 +505,7 @@ To run a full working example navigate to the `web-client` directory in the [mid ```bash cd web-client yarn install -yarn start +yarn dev ``` ### Resetting the `MidenClientDB` diff --git a/docs/src/web-client/create_deploy_tutorial.md b/docs/src/web-client/create_deploy_tutorial.md index 8ef72419..a1f39cc3 100644 --- a/docs/src/web-client/create_deploy_tutorial.md +++ b/docs/src/web-client/create_deploy_tutorial.md @@ -7,6 +7,15 @@ import { CodeSdkTabs } from '@site/src/components'; _Using the Miden client in TypeScript to create accounts and deploy faucets_ +:::note v0.16 setup + +Follow the [network and fee setup](./setup_guide.md#network-and-fee-setup) +and copy the shared support files imported by the complete example. +For React snippets, initialize `authScheme` with `await tutorialAuthScheme()` +as shown in the complete example. + +::: + ## Overview In this tutorial, we'll build a simple Next.js application that demonstrates the fundamentals of interacting with the Miden blockchain using the Miden SDK. We'll walk through creating a Miden account for Alice and deploying a fungible faucet contract that can mint tokens. This sets the foundation for more complex operations like issuing assets and transferring them between accounts. @@ -56,8 +65,8 @@ It is useful to think of notes on Miden as "cryptographic cashier's checks" that 3. Install the Miden SDK: **NOTE!**: Be sure to add the `--webpack` command to your `package.json` when running the `dev script`. The dev script should look like this: @@ -129,9 +138,9 @@ export async function createMintConsume(): Promise { .// wasm-bindgen type (see setup_guide.md "Entry points: eager vs lazy"). .await MidenClient.ready(); -.// Connect to Miden testnet RPC endpoint -.const client = await MidenClient.create({ -..rpcUrl: 'https://rpc.testnet.miden.io', +.// Connect to Miden testnet with local proving +.const client = await MidenClient.createTestnet({ +..proverUrl: 'local', .}); .// 1. Sync with the latest blockchain state @@ -215,7 +224,7 @@ Back in your library file, extend the function: react: { code: `const run = async () => { .// 1. Create Alice's wallet (public, mutable) .console.log('Creating account for Alice…'); -.const alice = await createWallet({ storageMode: StorageMode.Public }); +.const alice = await createWallet({ storageMode: StorageMode.Public, authScheme }); .console.log('Alice ID:', alice.id().toString()); };` }, typescript: { code: `// lib/createMintConsume.ts @@ -231,8 +240,8 @@ export async function createMintConsume(): Promise { .// wasm-bindgen type (see setup_guide.md "Entry points: eager vs lazy"). .await MidenClient.ready(); -.const client = await MidenClient.create({ -..rpcUrl: 'https://rpc.testnet.miden.io', +.const client = await MidenClient.createTestnet({ +..proverUrl: 'local', .}); .// 1. Sync with the latest blockchain state @@ -258,6 +267,7 @@ Add this code after creating Alice's account: react: { code: `// 2. Deploy a fungible faucet console.log('Creating faucet…'); const faucet = await createFaucet({ +.authScheme, .tokenSymbol: 'MID', // Token symbol (like ETH, BTC, etc.) .decimals: 8, // Decimals (8 means 1 MID = 100,000,000 base units) .maxSupply: BigInt(1_000_000), // Max supply: total tokens that can ever be minted @@ -296,7 +306,7 @@ console.log('Setup complete.');` }, In this tutorial, we've successfully: 1. Set up a Next.js application with the Miden SDK -2. Connected to the Miden testnet +2. Connected to Miden testnet 3. Created a wallet account for Alice 4. Deployed a fungible faucet that can mint custom tokens @@ -305,51 +315,123 @@ Your final `lib/react/createMintConsume.tsx` (React) or `lib/createMintConsume.t { -..// 1. Create Alice's wallet (public, mutable) -..console.log('Creating account for Alice…'); -..const alice = await createWallet({ storageMode: StorageMode.Public }); +..console.log('Synchronizing before creating accounts…'); +..await sync(); +..console.log('Creating Alice with useCreateWallet…'); +..const authScheme = await tutorialAuthScheme(); +..// Native fee tokens and the tutorial's MID token are separate assets. +..const alice = await createWallet({ +...storageMode: StorageMode.Public, +...authScheme, +..}); ..console.log('Alice ID:', alice.id().toString()); +..await fundAccount(alice); -..// 2. Deploy a fungible faucet -..console.log('Creating faucet…'); +..// v0.16 faucets include BasicWallet, so they can receive fee funding. ..const faucet = await createFaucet({ ...tokenSymbol: 'MID', ...decimals: 8, ...maxSupply: BigInt(1_000_000), ...storageMode: StorageMode.Public, +...authScheme, ..}); ..console.log('Faucet ID:', faucet.id().toString()); +..await fundAccount(faucet); + +..await sync(); +..const minted = await mint({ +...faucetId: faucet, +...targetAccountId: alice, +...amount: BigInt(1000), +...noteType: NoteVisibility.Public, +..}); +..await committed(minted.transactionId); +..const notes = await waitForTokenNotes(alice, faucet); +..const consumed = await consume({ accountId: alice.id().toString(), notes }); +..await committed(consumed.transactionId); +..await assertBalance(alice, faucet, BigInt(1000)); -..console.log('Setup complete.'); +..const bob = await createWallet({ +...storageMode: StorageMode.Public, +...authScheme, +..}); +..const sent = await send({ +...from: alice, +...to: bob, +...assetId: faucet, +...amount: BigInt(100), +...noteType: NoteVisibility.Public, +...returnNote: true, +..}); +..await committed(sent.txId); +..if (!sent.note) throw new Error('Send did not return its output note'); +..await waitForNote(sent.note.id().toString()); +..await assertBalance(alice, faucet, BigInt(900)); +..console.log('Tokens sent successfully!'); .}; .return ( -..
-... -..
+.. .); } export default function CreateMintConsume() { .return ( -.. +.. ... .. .); }`}, - typescript: { code:`// lib/createMintConsume.ts -import { MidenClient, StorageMode } from '@miden-sdk/miden-sdk/lazy'; + typescript: { code: `// lib/createMintConsume.ts +import { NoteVisibility, StorageMode } from '@miden-sdk/miden-sdk/lazy'; +import { +.consumeAllFeeAware, +.createTutorialClient, +.fundAccountForFees, +} from './feeSupport'; export async function createMintConsume(): Promise { .if (typeof window === 'undefined') { @@ -357,12 +439,8 @@ export async function createMintConsume(): Promise { ..return; .} -.// Wait for the WASM module to finish initializing before touching any -.// wasm-bindgen type (see setup_guide.md "Entry points: eager vs lazy"). -.await MidenClient.ready(); - -.const client = await MidenClient.create({ -..rpcUrl: 'https://rpc.testnet.miden.io', +.const client = await createTutorialClient({ +..proverUrl: 'local', .}); .// 1. Sync with the latest blockchain state @@ -376,7 +454,8 @@ export async function createMintConsume(): Promise { .}); .console.log('Alice ID:', alice.id().toString()); -.// 3. Deploy a fungible faucet +.// 3. Create our own fungible faucet. SDK v0.16 includes BasicWallet, +.// allowing both accounts to consume native fee funding before minting MID. .console.log('Creating faucet…'); .const faucet = await client.accounts.create({ ..type: 0, // 0 = FungibleFaucet @@ -386,8 +465,48 @@ export async function createMintConsume(): Promise { ..storage: StorageMode.Public, .}); .console.log('Faucet ID:', faucet.id().toString()); +.await fundAccountForFees(client, alice); +.await fundAccountForFees(client, faucet); + +.// 4. Mint tokens to Alice. +.console.log('Minting tokens to Alice...'); +.await client.sync(); +.const { txId: mintTxId } = await client.transactions.mint({ +..account: faucet, +..to: alice, +..amount: BigInt(1000), +..type: NoteVisibility.Public, +.}); +.console.log('Waiting for transaction confirmation...'); +.await client.transactions.waitFor(mintTxId, { timeout: 120_000 }); + +.// 5-6. Consume all available notes for Alice. +.console.log('Consuming minted notes...'); +.await consumeAllFeeAware(client, alice); + +.console.log('Notes consumed.'); -.console.log('Setup complete.'); +.// 7. Send tokens to Bob +.const bob = await client.accounts.create({ +..storage: StorageMode.Public, +.}); +.console.log("Sending tokens to Bob's account..."); +.await client.sync(); +.const { txId: sendTxId } = await client.transactions.send({ +..account: alice, +..to: bob, +..token: faucet, +..amount: BigInt(100), +..type: NoteVisibility.Public, +..waitForConfirmation: true, +..timeout: 120_000, +.}); +.console.log(\`Transaction committed: \${sendTxId.toHex()}\`); +.const updatedAlice = await client.accounts.get(alice); +.const balance = updatedAlice?.vault().getBalance(faucet.id()); +.if (balance !== BigInt(900)) +..throw new Error(\`Expected Alice to retain 900 MID, got \${balance}\`); +.console.log('Tokens sent successfully!'); }` }, }} reactFilename="lib/react/createMintConsume.tsx" tsFilename="lib/createMintConsume.ts" /> diff --git a/docs/src/web-client/creating_multiple_notes_tutorial.md b/docs/src/web-client/creating_multiple_notes_tutorial.md index bb6ba85e..98073b7d 100644 --- a/docs/src/web-client/creating_multiple_notes_tutorial.md +++ b/docs/src/web-client/creating_multiple_notes_tutorial.md @@ -7,6 +7,15 @@ import { CodeSdkTabs } from '@site/src/components'; _Using the Miden client in TypeScript to create several P2ID notes in a single transaction_ +:::note v0.16 setup + +Follow the [network and fee setup](./setup_guide.md#network-and-fee-setup) +and copy the shared support files imported by the complete example. +For React snippets, initialize `authScheme` with `await tutorialAuthScheme()` +as shown in the complete example. + +::: + ## Overview In the previous sections we learned how to create accounts, deploy faucets, and mint tokens. In this tutorial we will: @@ -61,8 +70,8 @@ proving service. This means your browser never has to generate the full ZK proof 3. Install the Miden SDK: **NOTE!**: Be sure to add the `--webpack` command to your `package.json` when running the `dev script`. The dev script should look like this: @@ -193,9 +202,7 @@ export async function multiSendWithDelegatedProver(): Promise { .// Wait for WASM to be ready before touching any wasm-bindgen type. .await MidenClient.ready(); -.const client = await MidenClient.create({ -..rpcUrl: 'https://rpc.testnet.miden.io', -.}); +.const client = await MidenClient.createTestnet(); .console.log('Latest block:', (await client.sync()).blockNum()); }` }, @@ -208,12 +215,13 @@ Add the code snippet below to the function. This code creates a wallet and fauce +..createWallet({ storageMode: StorageMode.Public, authScheme }), +.), +); + await sendMany({ .from: alice, .assetId: faucet, -.recipients: [ -..{ to: 'mtst1arqeemdpnzu4k52wlpd3xekl5uklfjl5', amount: BigInt(100) }, -..{ to: 'mtst1arqk5qt3kms0cut9rdtqdaz8y5xmj245', amount: BigInt(100) }, -..{ to: 'mtst1aq6kyfrh23n9gvt6jkg0z7fyts99hdqr', amount: BigInt(100) }, -.], +.recipients: recipients.map((account) => ({ +..to: account.id().toString(), +..amount: BigInt(100), +.})), .noteType: NoteVisibility.Public, }); console.log('All notes created ✅');`}, typescript: { code:`// ── build 3 P2ID notes (100 MID each) ───────────────────────────────────────────── -const recipientAddresses = [ -.'mtst1arqeemdpnzu4k52wlpd3xekl5uklfjl5', -.'mtst1arqk5qt3kms0cut9rdtqdaz8y5xmj245', -.'mtst1aq6kyfrh23n9gvt6jkg0z7fyts99hdqr', -]; +const recipients = await Promise.all( +.Array.from({ length: 3 }, () => +..client.accounts.create({ storage: StorageMode.Public }), +.), +); +const recipientAddresses = recipients.map((account) => +.account.id().toString(), +); const p2idNotes = recipientAddresses.map((addr) => .createP2IDNote({ @@ -319,107 +335,133 @@ Your library file should now look like this: { -..// 1. Create Alice's wallet -..console.log('Creating account for Alice…'); -..const alice = await createWallet({ storageMode: StorageMode.Public }); -..const aliceId = alice.id().toString(); -..console.log('Alice account ID:', aliceId); - -..// 2. Deploy a fungible faucet +..await sync(); +..const authScheme = await tutorialAuthScheme(); +..const alice = await createWallet({ +...storageMode: StorageMode.Public, +...authScheme, +..}); +..console.log('Alice ID:', alice.id().toString()); +..await fundAccount(alice); ..const faucet = await createFaucet({ ...tokenSymbol: 'MID', ...decimals: 8, ...maxSupply: BigInt(1_000_000), ...storageMode: StorageMode.Public, +...authScheme, ..}); -..const faucetId = faucet.id().toString(); -..console.log('Faucet ID:', faucetId); +..console.log('Faucet ID:', faucet.id().toString()); +..await fundAccount(faucet); -..// 3. Mint 10,000 MID to Alice -..const mintResult = await mint({ -...faucetId, -...targetAccountId: aliceId, +..await sync(); +..const minted = await mint({ +...faucetId: faucet, +...targetAccountId: alice, ...amount: BigInt(10_000), ...noteType: NoteVisibility.Public, ..}); - -..console.log('Waiting for settlement…'); -..await waitForCommit(mintResult.transactionId); - -..// 4. Consume the freshly minted notes -..const notes = await waitForConsumableNotes({ accountId: aliceId }); -..await consume({ accountId: aliceId, notes }); - -..// 5. Send 100 MID to three recipients in a single transaction -..await sendMany({ +..await committed(minted.transactionId); +..const notes = await waitForTokenNotes(alice, faucet); +..const consumed = await consume({ accountId: alice.id().toString(), notes }); +..await committed(consumed.transactionId); + +..const recipients = []; +..for (let index = 0; index < 3; index += 1) { +...recipients.push( +....await createWallet({ storageMode: StorageMode.Public, authScheme }), +...); +..} +..const sent = await sendMany({ ...from: alice, ...assetId: faucet, -...recipients: [ -....{ to: 'mtst1arqeemdpnzu4k52wlpd3xekl5uklfjl5', amount: BigInt(100) }, -....{ to: 'mtst1arqk5qt3kms0cut9rdtqdaz8y5xmj245', amount: BigInt(100) }, -....{ to: 'mtst1aq6kyfrh23n9gvt6jkg0z7fyts99hdqr', amount: BigInt(100) }, -...], +...recipients: recipients.map((account) => ({ +....to: account, +....amount: BigInt(100), +...})), ...noteType: NoteVisibility.Public, ..}); - +..await committed(sent.transactionId); +..for (const recipient of recipients) { +...const outputs = await waitForTokenNotes(recipient, faucet); +...if ( +....outputs.length !== 1 || +....outputs[0].details().assets().fungibleAssets()[0]?.amount() !== +.....BigInt(100) +...) { +....throw new Error(\`Expected one 100 MID note for \${recipient.id()}\`); +...} +..} +..await assertBalance(alice, faucet, BigInt(9700)); ..console.log('All notes created ✅'); .}; .return ( -..
-... -..
+.. .); } export default function MultiSendWithDelegatedProver() { .return ( -.. +.. ... .. .); }`}, - typescript: { code:`import { -.MidenClient, + typescript: { code: `import { +.NoteArray, .NoteVisibility, .StorageMode, .createP2IDNote, -.NoteArray, -.TransactionRequestBuilder, } from '@miden-sdk/miden-sdk/lazy'; +import { +.consumeAllFeeAware, +.createTutorialClient, +.fundAccountForFees, +} from './feeSupport'; -/\*\* -.\* Demonstrates multi-send functionality with delegated proving on the Miden Network -.\* Creates multiple P2ID (Pay to ID) notes for different recipients -.\* -.\* @throws {Error} If the function cannot be executed in a browser environment -.\*/ export async function multiSendWithDelegatedProver(): Promise { .// Ensure this runs only in a browser context .if (typeof window === 'undefined') return console.warn('Run in browser'); -.// Wait for WASM to be ready before touching any wasm-bindgen type. -.await MidenClient.ready(); - -.const client = await MidenClient.create({ -..rpcUrl: 'https://rpc.testnet.miden.io', -.}); +.const client = await createTutorialClient(); .console.log('Latest block:', (await client.sync()).blockNum()); @@ -430,7 +472,7 @@ export async function multiSendWithDelegatedProver(): Promise { .}); .console.log('Alice account ID:', alice.id().toString()); -.// ── Creating new faucet ────────────────────────────────────────────────────── +.// ── Creating new faucet ──────────────────────────────────────────────────── .const faucet = await client.accounts.create({ ..type: 0, // 0 = FungibleFaucet ..symbol: 'MID', @@ -439,29 +481,30 @@ export async function multiSendWithDelegatedProver(): Promise { ..storage: StorageMode.Public, .}); .console.log('Faucet ID:', faucet.id().toString()); +.await fundAccountForFees(client, alice); +.await fundAccountForFees(client, faucet); -.// ── mint 10 000 MID to Alice ────────────────────────────────────────────────────── +.// ── mint 10 000 MID to Alice ─────────────────────────────────────────────── +.await client.sync(); .const { txId: mintTxId } = await client.transactions.mint({ ..account: faucet, ..to: alice, ..amount: BigInt(10_000), ..type: NoteVisibility.Public, .}); - .console.log('waiting for settlement'); -.await client.transactions.waitFor(mintTxId); - -.// ── consume the freshly minted notes ────────────────────────────────────────────── -.await client.transactions.consumeAll({ -..account: alice, -.}); +.await client.transactions.waitFor(mintTxId, { timeout: 120_000 }); +.await consumeAllFeeAware(client, alice); .// ── build 3 P2ID notes (100 MID each) ───────────────────────────────────────────── -.const recipientAddresses = [ -..'mtst1arqeemdpnzu4k52wlpd3xekl5uklfjl5', -..'mtst1arqk5qt3kms0cut9rdtqdaz8y5xmj245', -..'mtst1aq6kyfrh23n9gvt6jkg0z7fyts99hdqr', -.]; +.const recipients = await Promise.all( +..Array.from({ length: 3 }, () => +...client.accounts.create({ storage: StorageMode.Public }), +..), +.); +.const recipientAddresses = recipients.map((account) => +..account.id().toString(), +.); .const p2idNotes = recipientAddresses.map((addr) => ..createP2IDNote({ @@ -473,9 +516,18 @@ export async function multiSendWithDelegatedProver(): Promise { .); .// ── create all P2ID notes ─────────────────────────────────────────────────────────────── -.const builder = new TransactionRequestBuilder(); -.const txRequest = builder.withOwnOutputNotes(new NoteArray(p2idNotes)).build(); -.await client.transactions.submit(alice, txRequest); +.await client.sync(); +.const builder = await client.feeAwareTransactionRequestBuilder(alice); +.const outputs = new NoteArray(); +.for (const note of p2idNotes) outputs.push(note); +.const request = builder.withOwnOutputNotes(outputs).build(); +.const { txId } = await client.transactions.submit(alice, request); +.await client.transactions.waitFor(txId, { timeout: 120_000 }); +.console.log(\`Transaction committed: \${txId.toHex()}\`); +.const updatedAlice = await client.accounts.get(alice); +.const balance = updatedAlice?.vault().getBalance(faucet.id()); +.if (balance !== BigInt(9_700)) +..throw new Error(\`Expected Alice to retain 9700 MID, got \${balance}\`); .console.log('All notes created ✅'); }` }, @@ -488,7 +540,7 @@ To run a full working example navigate to the `web-client` directory in the [mid ```bash cd web-client yarn install -yarn start +yarn dev ``` ### Resetting the `MidenClientDB` diff --git a/docs/src/web-client/foreign_procedure_invocation_tutorial.md b/docs/src/web-client/foreign_procedure_invocation_tutorial.md index 641d1b14..1082de9d 100644 --- a/docs/src/web-client/foreign_procedure_invocation_tutorial.md +++ b/docs/src/web-client/foreign_procedure_invocation_tutorial.md @@ -7,6 +7,13 @@ sidebar_position: 7 _Using foreign procedure invocation to craft read-only cross-contract calls with the Miden client_ +:::note v0.16 setup + +Follow the [network and fee setup](./setup_guide.md#network-and-fee-setup) +and copy the shared support files imported by the complete example. + +::: + ## Overview In the previous tutorial we deployed a fresh counter smart contract and incremented its count with a transaction script. @@ -57,7 +64,7 @@ This tutorial assumes you have a basic understanding of Miden assembly and compl 3. Install the Miden SDK: ```bash - yarn add @miden-sdk/miden-sdk@0.15.2 + yarn add @miden-sdk/miden-sdk@0.16.0 ``` **NOTE!**: Be sure to add the `--webpack` command to your `package.json` when running the `dev script`. The dev script should look like this: @@ -128,35 +135,53 @@ Create the file `lib/masm/counter_contract.masm`. This is the same counter contr ```masm use miden::protocol::active_account use miden::protocol::native_account -use miden::core::word use miden::core::sys +# CONSTANTS +# ================================================================================================= + const COUNTER_SLOT = word("miden::tutorials::counter") -#! Inputs: [] -#! Outputs: [count] -pub proc get_count +# PUBLIC INTERFACE +# ================================================================================================= + +#! Returns the current count. +#! +#! Inputs: [pad(16)] +#! Outputs: [count, pad(15)] +#! +#! Invocation: call +@account_procedure +pub proc get_count() -> felt push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] exec.sys::truncate_stack - # => [count] + # => [count, pad(15)] end -#! Inputs: [] -#! Outputs: [] -pub proc increment_count +#! Increments the current count by one. +#! +#! Inputs: [pad(16)] +#! Outputs: [pad(16)] +#! +#! Invocation: call +@account_procedure +pub proc increment_count() push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] add.1 - # => [count+1] + # => [[count + 1, 0, 0, 0], pad(16)] push.COUNTER_SLOT[0..2] exec.native_account::set_item - # => [] + # => [OLD_VALUE, pad(16)] + + dropw + # => [pad(16)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end ``` @@ -165,30 +190,56 @@ end Create the file `lib/masm/count_reader.masm`. This is the new "count copy" contract that reads the counter value via FPI and stores it locally: ```masm -use miden::protocol::active_account use miden::protocol::native_account use miden::protocol::tx -use miden::core::word use miden::core::sys +use {AccountId, AccountProcedureRoot} from miden::protocol::types + +# CONSTANTS +# ================================================================================================= const COUNT_READER_SLOT = word("miden::tutorials::count_reader") -# => [account_id_suffix, account_id_prefix, PROC_HASH(4), foreign_procedure_inputs(16)] -pub proc copy_count +# PUBLIC INTERFACE +# ================================================================================================= + +#! Copies the count returned by the foreign counter into this account's storage. +#! +#! Inputs: [foreign_account_id_{suffix,prefix}, FOREIGN_PROC_ROOT, pad(10)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - foreign_account_id_{suffix,prefix} identifies the public counter account. +#! - FOREIGN_PROC_ROOT is the root of its get_count procedure. +#! +#! Invocation: call +@account_procedure +@locals(6) +pub proc copy_count(foreign_account_id: AccountId, foreign_proc_root: AccountProcedureRoot) + # save the foreign target while preparing its sixteen zero inputs + loc_store.4 loc_store.5 loc_storew_le.0 dropw + # => [pad(16)] + + padw padw padw padw + # => [foreign_procedure_inputs(16), pad(16)] + + padw loc_loadw_le.0 loc_load.5 loc_load.4 + # => [foreign_account_id_suffix, foreign_account_id_prefix, FOREIGN_PROC_ROOT, foreign_procedure_inputs(16), pad(16)] + exec.tx::execute_foreign_procedure - # => [count, pad(12)] + # => [[count, 0, 0, 0], pad(28)] push.COUNT_READER_SLOT[0..2] - # [slot_id_prefix, slot_id_suffix, count, pad(12)] + # => [slot_id_suffix, slot_id_prefix, [count, 0, 0, 0], pad(28)] exec.native_account::set_item - # => [OLD_VALUE, pad(12)] + # => [OLD_VALUE, pad(28)] - dropw dropw dropw dropw - # => [] + dropw + # => [pad(28)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end ``` @@ -245,11 +296,14 @@ import counterContractCode from './masm/counter_contract.masm'; import countReaderCode from './masm/count_reader.masm'; import { AuthSecretKey, - StorageMode, StorageSlot, StorageResult, - MidenClient, } from '@miden-sdk/miden-sdk/lazy'; +import { + createFundableContractAccount, + createTutorialClient, + fundAccountForFees, +} from './feeSupport'; export async function foreignProcedureInvocation(): Promise { if (typeof window === 'undefined') { @@ -257,12 +311,7 @@ export async function foreignProcedureInvocation(): Promise { return; } - // Wait for the WASM module to finish initializing before touching any - // wasm-bindgen type (see setup_guide.md "Entry points: eager vs lazy"). - await MidenClient.ready(); - - const nodeEndpoint = 'https://rpc.testnet.miden.io'; - const client = await MidenClient.create({ rpcUrl: nodeEndpoint }); + const client = await createTutorialClient({ proverUrl: 'local' }); console.log('Current block number: ', (await client.sync()).blockNum()); const counterSlotName = 'miden::tutorials::counter'; @@ -282,21 +331,38 @@ export async function foreignProcedureInvocation(): Promise { crypto.getRandomValues(counterSeed); const counterAuth = AuthSecretKey.rpoFalconWithRNG(counterSeed); - const counterAccount = await client.accounts.create({ - storage: StorageMode.Public, - seed: counterSeed, - auth: counterAuth, - components: [counterComponent], - }); + const counterAccount = await createFundableContractAccount( + client, + counterSeed, + counterAuth, + [counterComponent], + ); + + await fundAccountForFees(client, counterAccount); // Deploy the counter to the node by executing a transaction on it const deployScript = await client.compile.txScript({ code: ` - use external_contract::counter_contract - begin - call.counter_contract::increment_count - end - `, +use external_contract::counter_contract + +#! Increments the counter. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) + dropw + # => [pad(16)] + + call.counter_contract::increment_count + # => [pad(16)] +end +`, libraries: [ { namespace: 'external_contract::counter_contract', @@ -307,10 +373,12 @@ export async function foreignProcedureInvocation(): Promise { // Wait for the deploy transaction to be committed to a block // before using it as a foreign account in FPI + await client.sync(); await client.transactions.execute({ account: counterAccount, script: deployScript, waitForConfirmation: true, + timeout: 120_000, }); console.log('Counter contract ID:', counterAccount.id().toString()); @@ -328,12 +396,14 @@ export async function foreignProcedureInvocation(): Promise { crypto.getRandomValues(readerSeed); const readerAuth = AuthSecretKey.rpoFalconWithRNG(readerSeed); - const countReaderAccount = await client.accounts.create({ - storage: StorageMode.Public, - seed: readerSeed, - auth: readerAuth, - components: [countReaderComponent], - }); + const countReaderAccount = await createFundableContractAccount( + client, + readerSeed, + readerAuth, + [countReaderComponent], + ); + + await fundAccountForFees(client, countReaderAccount); console.log('Count reader contract ID:', countReaderAccount.id().toString()); @@ -347,11 +417,21 @@ export async function foreignProcedureInvocation(): Promise { const getCountProcHash = counterComponent.getProcedureHash('get_count'); const fpiScriptCode = ` - use external_contract::count_reader_contract - use miden::core::sys +use external_contract::count_reader_contract +use miden::core::sys - begin - padw padw padw padw +#! Copies a public counter through the reader account. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) + dropw # => [pad(16)] push.${getCountProcHash} @@ -364,12 +444,11 @@ export async function foreignProcedureInvocation(): Promise { # => [account_id_suffix, account_id_prefix, GET_COUNT_HASH, pad(16)] call.count_reader_contract::copy_count - # => [] + # => [pad(16)] exec.sys::truncate_stack - # => [] - - end + # => [pad(16)] +end `; const script = await client.compile.txScript({ @@ -382,11 +461,15 @@ export async function foreignProcedureInvocation(): Promise { ], }); - await client.transactions.execute({ + await client.sync(); + const { txId } = await client.transactions.execute({ account: countReaderAccount, script, foreignAccounts: [counterAccount], + waitForConfirmation: true, + timeout: 120_000, }); + console.log(`Transaction committed: ${txId.toHex()}`); const updatedCountReader = await client.accounts.get(countReaderAccount); // `getItem()` is typed to return a low-level `Word`, but at runtime the SDK @@ -398,7 +481,11 @@ export async function foreignProcedureInvocation(): Promise { if (countReaderStorage) { const countValue = Number(countReaderStorage.toBigInt()); + if (countValue !== 1) + throw new Error(`Expected copied counter 1, got ${countValue}`); console.log('Count copied via Foreign Procedure Invocation:', countValue); + } else { + throw new Error('Count reader storage was not available after commitment'); } console.log('\nForeign Procedure Invocation Transaction completed!'); @@ -435,30 +522,56 @@ Foreign Procedure Invocation Transaction completed! The count reader smart contract contains a `copy_count` procedure that uses `tx::execute_foreign_procedure` to call the `get_count` procedure in the counter contract. ```masm -use miden::protocol::active_account use miden::protocol::native_account use miden::protocol::tx -use miden::core::word use miden::core::sys +use {AccountId, AccountProcedureRoot} from miden::protocol::types + +# CONSTANTS +# ================================================================================================= const COUNT_READER_SLOT = word("miden::tutorials::count_reader") -# => [account_id_suffix, account_id_prefix, PROC_HASH(4), foreign_procedure_inputs(16)] -pub proc copy_count +# PUBLIC INTERFACE +# ================================================================================================= + +#! Copies the count returned by the foreign counter into this account's storage. +#! +#! Inputs: [foreign_account_id_{suffix,prefix}, FOREIGN_PROC_ROOT, pad(10)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - foreign_account_id_{suffix,prefix} identifies the public counter account. +#! - FOREIGN_PROC_ROOT is the root of its get_count procedure. +#! +#! Invocation: call +@account_procedure +@locals(6) +pub proc copy_count(foreign_account_id: AccountId, foreign_proc_root: AccountProcedureRoot) + # save the foreign target while preparing its sixteen zero inputs + loc_store.4 loc_store.5 loc_storew_le.0 dropw + # => [pad(16)] + + padw padw padw padw + # => [foreign_procedure_inputs(16), pad(16)] + + padw loc_loadw_le.0 loc_load.5 loc_load.4 + # => [foreign_account_id_suffix, foreign_account_id_prefix, FOREIGN_PROC_ROOT, foreign_procedure_inputs(16), pad(16)] + exec.tx::execute_foreign_procedure - # => [count, pad(12)] + # => [[count, 0, 0, 0], pad(28)] push.COUNT_READER_SLOT[0..2] - # [slot_id_prefix, slot_id_suffix, count, pad(12)] + # => [slot_id_suffix, slot_id_prefix, [count, 0, 0, 0], pad(28)] exec.native_account::set_item - # => [OLD_VALUE, pad(12)] + # => [OLD_VALUE, pad(28)] - dropw dropw dropw dropw - # => [] + dropw + # => [pad(28)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end ``` @@ -467,10 +580,10 @@ To call the `get_count` procedure, we push its hash along with the counter contr The stack state before calling `tx::execute_foreign_procedure` should look like this: ``` -# => [account_id_suffix, account_id_prefix, PROC_HASH(4), foreign_procedure_inputs(16)] +# => [foreign_account_id_suffix, foreign_account_id_prefix, FOREIGN_PROC_ROOT, foreign_procedure_inputs(16), pad(16)] ``` -`execute_foreign_procedure` always requires exactly 16 `foreign_procedure_inputs` on the stack below the procedure hash and account ID. Since `get_count` takes no arguments, we pass 16 zero words (`padw padw padw padw`) as the inputs. +`execute_foreign_procedure` always requires exactly 16 `foreign_procedure_inputs` on the stack below the procedure hash and account ID. Since `get_count` takes no arguments, `copy_count` prepares 16 zero field elements (four words: `padw padw padw padw`) as the inputs. The transaction script only passes the account ID and procedure root; the reader saves them in local memory while preparing those inputs. After calling the `get_count` procedure in the counter contract, we save the count into the `miden::tutorials::count_reader` storage slot. @@ -483,8 +596,18 @@ The transaction script that executes the foreign procedure invocation looks like use external_contract::count_reader_contract use miden::core::sys -begin - padw padw padw padw +#! Copies a public counter through the reader account. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) + dropw # => [pad(16)] push.${getCountProcHash} @@ -497,19 +620,20 @@ begin # => [account_id_suffix, account_id_prefix, GET_COUNT_HASH, pad(16)] call.count_reader_contract::copy_count - # => [] + # => [pad(16)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end ``` This script: -1. Pushes the procedure hash of the `get_count` function -2. Pushes the counter contract's account ID suffix and prefix -3. Calls the `copy_count` procedure in our count reader contract -4. Truncates the stack +1. Discards the unused transaction script arguments. +2. Pushes the procedure root of `get_count`. +3. Pushes the counter account ID prefix, then suffix, leaving the suffix on top. +4. Calls `copy_count`, which prepares the foreign call and stores the result. +5. Truncates the stack. ## Key Miden Client Concepts for FPI @@ -575,7 +699,7 @@ To run a full working example navigate to the `web-client` directory in the [mid ```bash cd web-client yarn install -yarn start +yarn dev ``` ### Resetting the `MidenClientDB` diff --git a/docs/src/web-client/mint_consume_create_tutorial.md b/docs/src/web-client/mint_consume_create_tutorial.md index 9aff6a2f..c3d19bbc 100644 --- a/docs/src/web-client/mint_consume_create_tutorial.md +++ b/docs/src/web-client/mint_consume_create_tutorial.md @@ -7,6 +7,15 @@ import { CodeSdkTabs } from '@site/src/components'; _Using the Miden client in TypeScript to mint, consume, and transfer assets_ +:::note v0.16 setup + +Follow the [network and fee setup](./setup_guide.md#network-and-fee-setup) +and copy the shared support files imported by the complete example. +For React snippets, initialize `authScheme` with `await tutorialAuthScheme()` +as shown in the complete example. + +::: + ## Overview In the previous tutorial, we set up the foundation - creating Alice's wallet and deploying a faucet. Now we'll put these to use by minting and transferring assets. @@ -102,8 +111,9 @@ _The standard asset transfer note on Miden is the P2ID note (Pay-to-Id). There i Now that Alice has tokens in her account, she can send some to Bob: { -..// 1. Create Alice's wallet (public, mutable) -..console.log('Creating account for Alice…'); -..const alice = await createWallet({ storageMode: StorageMode.Public }); -..const aliceId = alice.id().toString(); -..console.log('Alice ID:', aliceId); - -..// 2. Deploy a fungible faucet -..console.log('Creating faucet…'); +..console.log('Synchronizing before creating accounts…'); +..await sync(); +..console.log('Creating Alice with useCreateWallet…'); +..const authScheme = await tutorialAuthScheme(); +..// Native fee tokens and the tutorial's MID token are separate assets. +..const alice = await createWallet({ +...storageMode: StorageMode.Public, +...authScheme, +..}); +..console.log('Alice ID:', alice.id().toString()); +..await fundAccount(alice); + +..// v0.16 faucets include BasicWallet, so they can receive fee funding. ..const faucet = await createFaucet({ ...tokenSymbol: 'MID', ...decimals: 8, ...maxSupply: BigInt(1_000_000), ...storageMode: StorageMode.Public, +...authScheme, ..}); -..const faucetId = faucet.id().toString(); -..console.log('Faucet ID:', faucetId); - -..// 3. Mint 1000 tokens to Alice -..console.log('Minting tokens to Alice...'); -..const mintResult = await mint({ -...faucetId, -...targetAccountId: aliceId, +..console.log('Faucet ID:', faucet.id().toString()); +..await fundAccount(faucet); + +..await sync(); +..const minted = await mint({ +...faucetId: faucet, +...targetAccountId: alice, ...amount: BigInt(1000), ...noteType: NoteVisibility.Public, ..}); -..console.log('Mint tx:', mintResult.transactionId); - -..// 4. Wait for the mint transaction to be committed -..await waitForCommit(mintResult.transactionId); - -..// 5. Wait for consumable notes to appear, then consume them -..const notes = await waitForConsumableNotes({ accountId: alice }); -..console.log('Consumable notes:', notes.length); - -..console.log('Consuming minted notes...'); -..await consume({ accountId: alice.id().toString(), notes }); -..console.log('Notes consumed.'); +..await committed(minted.transactionId); +..const notes = await waitForTokenNotes(alice, faucet); +..const consumed = await consume({ accountId: alice.id().toString(), notes }); +..await committed(consumed.transactionId); +..await assertBalance(alice, faucet, BigInt(1000)); -..// 7. Send 100 tokens to Bob -..const bobAddress = 'mtst1arpsz3jlmjxl7u2jjzfsc0wyqyaas6a9'; -..console.log("Sending tokens to Bob's account..."); -..await send({ +..const bob = await createWallet({ +...storageMode: StorageMode.Public, +...authScheme, +..}); +..const sent = await send({ ...from: alice, -...to: bobAddress, +...to: bob, ...assetId: faucet, ...amount: BigInt(100), ...noteType: NoteVisibility.Public, +...returnNote: true, ..}); +..await committed(sent.txId); +..if (!sent.note) throw new Error('Send did not return its output note'); +..await waitForNote(sent.note.id().toString()); +..await assertBalance(alice, faucet, BigInt(900)); ..console.log('Tokens sent successfully!'); .}; .return ( -..
-... -..
+.. .); } export default function CreateMintConsume() { .return ( -.. +.. ... .. .); }`}, - typescript: { code:`// lib/createMintConsume.ts -import { MidenClient, NoteVisibility, StorageMode } from '@miden-sdk/miden-sdk/lazy'; + typescript: { code: `// lib/createMintConsume.ts +import { NoteVisibility, StorageMode } from '@miden-sdk/miden-sdk/lazy'; +import { +.consumeAllFeeAware, +.createTutorialClient, +.fundAccountForFees, +} from './feeSupport'; export async function createMintConsume(): Promise { .if (typeof window === 'undefined') { @@ -233,11 +280,8 @@ export async function createMintConsume(): Promise { ..return; .} -.// Wait for WASM to be ready before touching any wasm-bindgen type. -.await MidenClient.ready(); - -.const client = await MidenClient.create({ -..rpcUrl: 'https://rpc.testnet.miden.io', +.const client = await createTutorialClient({ +..proverUrl: 'local', .}); .// 1. Sync with the latest blockchain state @@ -251,7 +295,8 @@ export async function createMintConsume(): Promise { .}); .console.log('Alice ID:', alice.id().toString()); -.// 3. Deploy a fungible faucet +.// 3. Create our own fungible faucet. SDK v0.16 includes BasicWallet, +.// allowing both accounts to consume native fee funding before minting MID. .console.log('Creating faucet…'); .const faucet = await client.accounts.create({ ..type: 0, // 0 = FungibleFaucet @@ -261,38 +306,47 @@ export async function createMintConsume(): Promise { ..storage: StorageMode.Public, .}); .console.log('Faucet ID:', faucet.id().toString()); +.await fundAccountForFees(client, alice); +.await fundAccountForFees(client, faucet); -.// 4. Mint tokens to Alice - +.// 4. Mint tokens to Alice. .console.log('Minting tokens to Alice...'); +.await client.sync(); .const { txId: mintTxId } = await client.transactions.mint({ ..account: faucet, ..to: alice, ..amount: BigInt(1000), ..type: NoteVisibility.Public, .}); - .console.log('Waiting for transaction confirmation...'); -.await client.transactions.waitFor(mintTxId); +.await client.transactions.waitFor(mintTxId, { timeout: 120_000 }); -.// 5-6. Consume all available notes for Alice in a single transaction +.// 5-6. Consume all available notes for Alice. .console.log('Consuming minted notes...'); -.await client.transactions.consumeAll({ -..account: alice, -.}); +.await consumeAllFeeAware(client, alice); .console.log('Notes consumed.'); .// 7. Send tokens to Bob -.const bobAddress = 'mtst1arpsz3jlmjxl7u2jjzfsc0wyqyaas6a9'; +.const bob = await client.accounts.create({ +..storage: StorageMode.Public, +.}); .console.log("Sending tokens to Bob's account..."); -.await client.transactions.send({ +.await client.sync(); +.const { txId: sendTxId } = await client.transactions.send({ ..account: alice, -..to: bobAddress, +..to: bob, ..token: faucet, ..amount: BigInt(100), ..type: NoteVisibility.Public, +..waitForConfirmation: true, +..timeout: 120_000, .}); +.console.log(\`Transaction committed: \${sendTxId.toHex()}\`); +.const updatedAlice = await client.accounts.get(alice); +.const balance = updatedAlice?.vault().getBalance(faucet.id()); +.if (balance !== BigInt(900)) +..throw new Error(\`Expected Alice to retain 900 MID, got \${balance}\`); .console.log('Tokens sent successfully!'); }` }, }} reactFilename="lib/react/createMintConsume.tsx" tsFilename="lib/createMintConsume.ts" /> diff --git a/docs/src/web-client/react_wallet_tutorial.md b/docs/src/web-client/react_wallet_tutorial.md index a8ed7a19..636c0e73 100644 --- a/docs/src/web-client/react_wallet_tutorial.md +++ b/docs/src/web-client/react_wallet_tutorial.md @@ -34,6 +34,17 @@ By the end of this tutorial, you will have a working wallet that can: - Familiarity with React and TypeScript - `yarn` +:::note v0.16 testnet and fees + +A new wallet needs native fee tokens before sending assets. Request and claim a +funding note from the testnet faucet, as described in the +[fee setup](./setup_guide.md#network-and-fee-setup). Claim the returned +note ID and wait for confirmation before sending. + +Select testnet in both the client and any external wallet adapter. + +::: + --- ## Step 1: Project Setup and MidenProvider @@ -50,7 +61,7 @@ First, create a new Vite + React project and install the Miden React SDK. 2. Install the Miden React SDK: ```bash - yarn add @miden-sdk/react + yarn add @miden-sdk/miden-sdk@0.16.0 @miden-sdk/react@0.16.0 ``` 3. Configure the `MidenProvider` in your `main.tsx` file. The provider initializes the Miden client and makes it available to all child components: @@ -78,8 +89,8 @@ ReactDOM.createRoot(document.getElementById('root')!).render( The `MidenProvider` accepts a `config` object with the following options: -- `rpcUrl`: The RPC endpoint to connect to (`"testnet"` or a custom URL) -- `prover`: The prover to use (`"testnet"` for delegated proving, or `"local"` for local proving) +- `rpcUrl`: The RPC endpoint to connect to (`"testnet"`, `"devnet"`, or a custom URL) +- `prover`: The prover to use (`"testnet"` for testnet delegated proving, or `"local"` for local proving) --- @@ -146,6 +157,7 @@ The `useCreateWallet()` hook provides a function to create new wallet accounts. ```tsx import { useMiden, useAccounts, useCreateWallet } from '@miden-sdk/react/lazy'; +import { getWasmOrThrow } from '@miden-sdk/miden-sdk/lazy'; export default function App() { const { isReady, error } = useMiden(); @@ -161,7 +173,12 @@ export default function App() { return (

Wallet

-
@@ -176,6 +193,10 @@ function Wallet({ accountId }: { accountId: string }) { } ``` +Pass the low-level Falcon enum explicitly with the pinned lazy React SDK. The +high-level client's authentication enum is not interchangeable with the numeric +enum expected by this hook. + The `useCreateWallet()` hook returns: - `createWallet(options?)`: Function to create a new wallet @@ -465,7 +486,7 @@ import { useConsume, useSend, } from '@miden-sdk/react/lazy'; -import { NoteVisibility } from '@miden-sdk/miden-sdk/lazy'; +import { NoteVisibility, getWasmOrThrow } from '@miden-sdk/miden-sdk/lazy'; const Panel = ({ title, children }: { title: string; children: ReactNode }) => (
@@ -478,7 +499,9 @@ export default function App() { const { isReady, error } = useMiden(); const { wallets, isLoading } = useAccounts(); const { createWallet, isCreating } = useCreateWallet(); - const handleCreate = () => createWallet(); + const handleCreate = async () => createWallet({ + authScheme: (await getWasmOrThrow()).AuthScheme.AuthRpoFalcon512, + }); const createLabel = isCreating ? 'Creating...' : 'Create wallet'; if (error) return
Error: {error.message}
; @@ -633,27 +656,42 @@ function Wallet({ accountId }: { accountId: string }) { ## Running the Example -To run a full working example, navigate to the `packages/react-sdk/examples/wallet` directory in the [miden-client](https://github.com/0xMiden/miden-client/) repository: +The complete upstream wallet example lives in +[`packages/react-sdk/examples/wallet` in the web-sdk v0.16.0 release](https://github.com/0xMiden/web-sdk/tree/v0.16.0/packages/react-sdk/examples/wallet). +Follow that example's README for its workspace setup and select testnet in its +provider configuration. + +To exercise this repository's three React transaction examples on testnet: ```bash -git clone https://github.com/0xMiden/miden-client.git -cd miden-client/packages/react-sdk/examples/wallet +cd web-client yarn install yarn dev ``` +Open `/react-tutorials` and select an example. These examples create and fund their +own accounts; the wallet UI above starts with an empty wallet that needs funding. + ### Resetting the MidenClientDB -The Miden client stores account and note data in the browser's IndexedDB. To clear this data, paste the following into your browser console: +The Miden client stores account and note data in the browser's IndexedDB. +Upgrading from v0.15 automatically recreates the Miden store; export private +notes and any other local data you need before upgrading. To manually reset only +Miden databases on the current origin, close other tabs using the client and run: ```javascript (async () => { const dbs = await indexedDB.databases(); for (const db of dbs) { - await indexedDB.deleteDatabase(db.name); - console.log(`Deleted database: ${db.name}`); + if (!db.name?.startsWith('MidenClientDB')) continue; + await new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase(db.name); + request.onsuccess = () => resolve(); + request.onerror = () => reject(request.error); + request.onblocked = () => reject(new Error('Close other Miden tabs and retry')); + }); + console.log(`Deleted Miden database: ${db.name}`); } - console.log('All databases deleted.'); })(); ``` @@ -701,13 +739,15 @@ This unified interface means your wallet UI code works the same regardless of wh [Para](https://para.space/) provides a modal-based authentication flow that allows users to sign in with their EVM wallets (MetaMask, WalletConnect, etc.). -**Installation:** +:::note Compatible Para release required -```bash -yarn add @miden-sdk/use-miden-para-react -``` +`@miden-sdk/use-miden-para-react@0.15.1` requires v0.15 SDK packages. +The pattern below needs an adapter release with v0.16-compatible peer dependencies; +check the [package metadata](https://registry.npmjs.org/@miden-sdk/use-miden-para-react) before installing. -**Usage:** +::: + +**Integration pattern (requires a compatible adapter):** ```tsx import { ParaSignerProvider } from '@miden-sdk/use-miden-para-react'; @@ -753,13 +793,15 @@ function Wallet() { [Turnkey](https://turnkey.com/) provides programmatic key management, giving your application full control over the authentication flow. -**Installation:** +:::note Compatible Turnkey release required -```bash -yarn add @miden-sdk/miden-turnkey-react @turnkey/sdk-browser -``` +`@miden-sdk/miden-turnkey-react@1.15.1` requires v0.15 SDK packages. +The pattern below needs an adapter release with v0.16-compatible peer dependencies; +check the [package metadata](https://registry.npmjs.org/@miden-sdk/miden-turnkey-react) before installing. -**Usage:** +::: + +**Integration pattern (requires a compatible adapter):** ```tsx import { TurnkeySignerProvider } from '@miden-sdk/miden-turnkey-react'; @@ -809,18 +851,19 @@ The `useTurnkeySigner()` hook is available for advanced use cases where you need **Installation:** ```bash -yarn add @miden-sdk/miden-wallet-adapter-react +yarn add @miden-sdk/miden-wallet-adapter-react@0.16.0 @miden-sdk/miden-wallet-adapter-base@0.16.0 ``` **Usage:** ```tsx import { MidenFiSignerProvider } from '@miden-sdk/miden-wallet-adapter-react'; +import { WalletAdapterNetwork } from '@miden-sdk/miden-wallet-adapter-base'; import { MidenProvider, useSigner } from '@miden-sdk/react/lazy'; function App() { return ( - + @@ -845,11 +888,14 @@ function Wallet() { **MidenFiSignerProvider Props:** -| Prop | Type | Description | -| ----------------------- | ------------------------- | -------------------------------------- | -| `network` | `"testnet" \| "localnet"` | Target network | -| `privateDataPermission` | `boolean` | Whether to request private data access | -| `allowedPrivateData` | `string[]` | List of allowed private data types | +| Prop | Type | Description | +| ----------------------- | ----------------------- | ---------------------------------------- | +| `network` | `WalletAdapterNetwork` | `Testnet`, `Devnet`, or `Localnet` | +| `privateDataPermission` | `PrivateDataPermission` | Permission level for private data access | +| `allowedPrivateData` | `AllowedPrivateData` | Private-data categories the app requests | + +Import the enums from `@miden-sdk/miden-wallet-adapter-base`. Do not pass raw +network strings, booleans, or string arrays in place of these enum values. --- @@ -934,5 +980,5 @@ The `SignerContextValue` interface requires: Now that you've built a React wallet, explore these related topics: - [Creating Multiple Notes in a Single Transaction](./creating_multiple_notes_tutorial.md) - Learn about batch operations -- [Miden React SDK Reference](https://github.com/0xMiden/miden-client/tree/main/packages/react-sdk) - Full API documentation +- [Miden React SDK Reference](https://github.com/0xMiden/web-sdk/tree/v0.16.0/packages/react-sdk) - Full API documentation - [Miden Documentation](https://docs.miden.io/) - Core Miden concepts diff --git a/docs/src/web-client/setup_guide.md b/docs/src/web-client/setup_guide.md index bf5fc4d3..25e93f09 100644 --- a/docs/src/web-client/setup_guide.md +++ b/docs/src/web-client/setup_guide.md @@ -16,13 +16,13 @@ This guide covers the configuration required to use the Miden web SDK (`@miden-s ## Install the SDK ```bash -yarn add @miden-sdk/miden-sdk +yarn add @miden-sdk/miden-sdk@0.16.0 ``` For React hook support: ```bash -yarn add @miden-sdk/react +yarn add @miden-sdk/miden-sdk@0.16.0 @miden-sdk/react@0.16.0 ``` These tutorials use Next.js, so all code examples import from the SDK's `/lazy` subpath — see [Entry points: eager vs lazy](#entry-points-eager-vs-lazy) below for why that's required. @@ -109,9 +109,7 @@ export async function doSomething() { if (typeof window === 'undefined') return; await MidenClient.ready(); // Safe to construct wasm-bindgen types from here. - const client = await MidenClient.create({ - rpcUrl: 'https://rpc.testnet.miden.io', - }); + const client = await MidenClient.createTestnet(); // … } ``` @@ -120,15 +118,16 @@ In React, the `@miden-sdk/react/lazy` provider manages WASM readiness for you vi ```tsx import { useMiden, useCreateWallet } from '@miden-sdk/react/lazy'; +import { getWasmOrThrow } from '@miden-sdk/miden-sdk/lazy'; function Component() { const { isReady } = useMiden(); const { createWallet } = useCreateWallet(); return ( -..
+.. .); } export default function UnauthenticatedNoteTransfer() { .return ( -.. +.. ... .. .); }`}, - typescript: { code:`import { -.MidenClient, -.NoteVisibility, -.StorageMode, -} from '@miden-sdk/miden-sdk/lazy'; - -/\*\* -.\* Demonstrates unauthenticated note transfer chain against Miden testnet -.\* Creates a chain of P2ID (Pay to ID) notes: Alice → wallet 1 → wallet 2 → wallet 3 → wallet 4 -.\* -.\* @throws {Error} If the function cannot be executed in a browser environment -.\*/ + typescript: { code: `import { NoteVisibility, StorageMode } from '@miden-sdk/miden-sdk/lazy'; +import { +.consumeAllFeeAware, +.createTutorialClient, +.fundAccountForFees, +.tutorialExplorerUrl, +} from './feeSupport'; + export async function unauthenticatedNoteTransfer(): Promise { .// Ensure this runs only in a browser context .if (typeof window === 'undefined') return console.warn('Run in browser'); -.// Wait for WASM to be ready before touching any wasm-bindgen type. -.await MidenClient.ready(); - -.const client = await MidenClient.create({ -..rpcUrl: 'https://rpc.testnet.miden.io', +.const client = await createTutorialClient({ +..proverUrl: 'local', .}); .console.log('Latest block:', (await client.sync()).blockNum()); -.// ── Creating accounts ────────────────────────────────────────────────────── +.// ── Creating new account ────────────────────────────────────────────────────── +.console.log('Creating accounts'); + .console.log('Creating account for Alice…'); .const alice = await client.accounts.create({ ..storage: StorageMode.Public, @@ -293,7 +329,6 @@ export async function unauthenticatedNoteTransfer(): Promise { ..console.log('wallet ', i.toString(), wallet.id().toString()); .} -.// ── Creating new faucet ────────────────────────────────────────────────────── .const faucet = await client.accounts.create({ ..type: 0, // 0 = FungibleFaucet ..symbol: 'MID', @@ -302,22 +337,23 @@ export async function unauthenticatedNoteTransfer(): Promise { ..storage: StorageMode.Public, .}); .console.log('Faucet ID:', faucet.id().toString()); +.await fundAccountForFees(client, alice); +.await fundAccountForFees(client, faucet); -.// ── Mint 10,000 MID to Alice ────────────────────────────────────────────────────── +.await client.sync(); .const { txId: mintTxId } = await client.transactions.mint({ ..account: faucet, ..to: alice, ..amount: BigInt(10_000), ..type: NoteVisibility.Public, .}); - .console.log('Waiting for settlement'); -.await client.transactions.waitFor(mintTxId); +.await client.transactions.waitFor(mintTxId, { timeout: 120_000 }); +.await consumeAllFeeAware(client, alice); -.// ── Consume the freshly minted note ────────────────────────────────────────────── -.await client.transactions.consumeAll({ -..account: alice, -.}); +.for (const wallet of wallets) { +..await fundAccountForFees(client, wallet); +.} .// ── Create unauthenticated note transfer chain ───────────────────────────────────────────── .// Alice → wallet 1 → wallet 2 → wallet 3 → wallet 4 @@ -330,25 +366,37 @@ export async function unauthenticatedNoteTransfer(): Promise { ..console.log('Sender:', sender.id().toString()); ..console.log('Receiver:', receiver.id().toString()); -..const { note } = await client.transactions.send({ +..await client.sync(); +..const { note, txId: sendTxId } = await client.transactions.send({ ...account: sender, ...to: receiver, ...token: faucet, ...amount: BigInt(50), ...type: NoteVisibility.Public, ...returnNote: true, +...waitForConfirmation: false, ..}); +..// Pass the full note before waiting for the sender's transaction. +..await client.sync(); ..const { txId: consumeTxId } = await client.transactions.consume({ ...account: receiver, ...notes: [note], +...waitForConfirmation: true, +...timeout: 120_000, ..}); +..await client.transactions.waitFor(sendTxId, { timeout: 120_000 }); +..console.log(\`Transaction committed: \${consumeTxId.toHex()}\`); ..console.log( -...\`Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/\${consumeTxId.toHex()}\`, +...\`Consumed Note Tx on MidenScan: \${tutorialExplorerUrl()}/tx/\${consumeTxId.toHex()}\`, ..); .} +.const lastWallet = await client.accounts.get(wallets[wallets.length - 1]); +.const balance = lastWallet?.vault().getBalance(faucet.id()); +.if (balance !== BigInt(50)) +..throw new Error(\`Expected last wallet to hold 50 MID, got \${balance}\`); .console.log('Asset transfer chain completed ✅'); }` }, }} reactFilename="lib/react/unauthenticatedNoteTransfer.tsx" tsFilename="lib/unauthenticatedNoteTransfer.ts" /> @@ -454,7 +502,7 @@ To run a full working example navigate to the `web-client` directory in the [mid ```bash cd web-client yarn install -yarn start +yarn dev ``` ### Continue learning diff --git a/examples/bridging-app/.env.example b/examples/bridging-app/.env.example index 65a1139a..72680d80 100644 --- a/examples/bridging-app/.env.example +++ b/examples/bridging-app/.env.example @@ -1,15 +1,21 @@ # Miden SDK network configuration -# Supported values: devnet | testnet | local | https://your-rpc-url +# Wallet network: devnet | testnet | local +VITE_MIDEN_NETWORK=testnet +# RPC: devnet | testnet | local | https://your-rpc-url VITE_MIDEN_RPC_URL=testnet # Prover configuration # Supported values: devnet | testnet | local | https://your-prover-url VITE_MIDEN_PROVER=testnet -# Epoch allocator service URL (Sepolia <-> Miden testnet bridging). +# Epoch allocator compatible with v0.16 on the selected Miden network. VITE_ALLOCATOR_URL=https://testnet-dev.epochprotocol.xyz -# Optional: override the Miden testnet explorer used for tx links. +# Obtain the USDC faucet ID from an allocator deployed on the selected network. +# When unset, enter the faucet ID manually in the form. +VITE_MIDEN_USDC_FAUCET_ID= + +# Optional: override the selected network's explorer used for tx links. # Default if unset: https://testnet.midenscan.com # VITE_MIDENSCAN_URL=https://testnet.midenscan.com diff --git a/examples/bridging-app/README.md b/examples/bridging-app/README.md index 3aa95331..bf17ca0f 100644 --- a/examples/bridging-app/README.md +++ b/examples/bridging-app/README.md @@ -15,24 +15,30 @@ yarn install yarn dev ``` -Open [http://localhost:5173](http://localhost:5173). The app exposes two tabs — `Bridge to EVM` (Miden → Sepolia) and `Withdraw to Miden` (Sepolia → Miden) — wired to the Epoch testnet allocator (`testnet-dev.epochprotocol.xyz`). +Open [http://localhost:5173](http://localhost:5173). The app exposes two tabs — `Bridge to EVM` (Miden → Sepolia) and `Withdraw to Miden` (Sepolia → Miden). It defaults to Miden **testnet**. A live round trip requires an Epoch allocator and asset faucet deployed on that same network, plus both wallets. ## Environment Copy `.env.example` to `.env` and supply the required values: -| Variable | Required | Description | -| ---------------------------- | -------- | --------------------------------------------------------------------------- | -| `VITE_RAINBOWKIT_PROJECT_ID` | yes | WalletConnect Cloud project id from . | -| `VITE_ALLOCATOR_URL` | yes | Epoch allocator endpoint (default `https://testnet-dev.epochprotocol.xyz`). | -| `VITE_MIDEN_RPC_URL` | no | Miden RPC; defaults to `testnet`. | -| `VITE_MIDEN_PROVER` | no | Miden prover; defaults to `testnet`. | -| `VITE_MIDENSCAN_URL` | no | Override block-explorer base; defaults to `https://testnet.midenscan.com`. | +| Variable | Required | Description | +| ---------------------------- | ------------ | ----------------------------------------------------------------------------------------------------------------- | +| `VITE_RAINBOWKIT_PROJECT_ID` | yes | WalletConnect Cloud project id from . | +| `VITE_ALLOCATOR_URL` | yes | An Epoch allocator compatible with v0.16 on the selected Miden network. | +| `VITE_MIDEN_NETWORK` | no | `testnet` (default), `devnet`, or `local`; selects the wallet network and RPC/prover defaults. | +| `VITE_MIDEN_RPC_URL` | no | Override Miden RPC; must match the selected wallet network. | +| `VITE_MIDEN_PROVER` | no | Override the prover; `local` uses local proving. | +| `VITE_MIDEN_USDC_FAUCET_ID` | yes for USDC | Allocator-approved faucet on the selected network. If unset, enter it manually in the form; no old ID is assumed. | +| `VITE_MIDENSCAN_URL` | no | Override block-explorer base; defaults to the selected network's Midenscan. | + +For explicit devnet checks, set `VITE_MIDEN_NETWORK`, `VITE_MIDEN_RPC_URL`, and +`VITE_MIDEN_PROVER` to `devnet` and use a matching allocator and faucet. ## Prerequisites - An EVM wallet supported by [RainbowKit](https://www.rainbowkit.com/) (MetaMask, Rabby, Coinbase Wallet, …). - The [MidenFi browser extension](https://chromewebstore.google.com/detail/miden-wallet/ablmompanofnodfdkgchkpmphailefpb) to sign the P2IDE note on Miden. +- Native MIDEN tokens in the Miden wallet to pay transaction fees. - A small Sepolia ETH balance for gas; grab some from the [pk910 PoW faucet](https://sepolia-faucet.pk910.de/) or the [Google Cloud Sepolia faucet](https://cloud.google.com/application/web3/faucet/ethereum/sepolia). ## Scripts @@ -41,7 +47,7 @@ Copy `.env.example` to `.env` and supply the required values: yarn dev # Vite dev server (http://localhost:5173) yarn build # tsc -b && vite build yarn preview # Serve the production build locally -yarn test # Vitest (scaffold-inherited tests) +yarn test # Vitest yarn lint # ESLint ``` diff --git a/examples/bridging-app/package.json b/examples/bridging-app/package.json index 81c11533..122000c2 100644 --- a/examples/bridging-app/package.json +++ b/examples/bridging-app/package.json @@ -14,11 +14,11 @@ "test:coverage": "vitest --run --coverage" }, "dependencies": { - "@epoch-protocol/epoch-intents-sdk": "^1.0.23", - "@miden-sdk/miden-sdk": "0.14.4", - "@miden-sdk/miden-wallet-adapter-base": "0.14.3", - "@miden-sdk/miden-wallet-adapter-react": "0.14.3", - "@miden-sdk/react": "0.14.4", + "@epoch-protocol/epoch-intents-sdk": "1.0.38", + "@miden-sdk/miden-sdk": "0.16.0", + "@miden-sdk/miden-wallet-adapter-base": "0.16.0", + "@miden-sdk/miden-wallet-adapter-react": "0.16.0", + "@miden-sdk/react": "0.16.0", "@phosphor-icons/react": "^2.1.10", "@rainbow-me/rainbowkit": "^2.2.10", "@tanstack/react-query": "^5.90.20", @@ -34,7 +34,7 @@ }, "devDependencies": { "@eslint/js": "^9.36.0", - "@miden-sdk/vite-plugin": "0.14.4", + "@miden-sdk/vite-plugin": "0.16.0", "@testing-library/dom": "^10.4.1", "@testing-library/jest-dom": "^6.9.1", "@testing-library/react": "^16.3.2", @@ -58,4 +58,4 @@ "vite-plugin-wasm": "^3.5.0", "vitest": "^4.0.18" } -} \ No newline at end of file +} diff --git a/examples/bridging-app/src/components/__tests__/IntentForm.test.tsx b/examples/bridging-app/src/components/__tests__/IntentForm.test.tsx index 2a2ec0cf..1ff4ce6c 100644 --- a/examples/bridging-app/src/components/__tests__/IntentForm.test.tsx +++ b/examples/bridging-app/src/components/__tests__/IntentForm.test.tsx @@ -37,12 +37,8 @@ vi.mock('@miden-sdk/miden-wallet-adapter-react', () => ({ }), })); vi.mock('@miden-sdk/miden-wallet-adapter-base', () => ({ - // IntentForm constructs a `SendTransaction` only in the Confirm-&-sign flow, - // which these tests do not exercise. A minimal class stub keeps imports - // resolvable without dragging in the real WASM-backed SDK. - SendTransaction: class { - constructor(public sender: string, public recipient: string, public faucet: string, public note: string, public amount: number) {} - }, + // These rendering tests do not submit the custom collateral transaction. + Transaction: { createCustomTransaction: vi.fn() }, })); vi.mock('wagmi', () => ({ useAccount: () => ({ address: undefined, isConnected: false }), diff --git a/examples/bridging-app/src/components/__tests__/WithdrawConsume.test.tsx b/examples/bridging-app/src/components/__tests__/WithdrawConsume.test.tsx index c6b91e7c..bd269f47 100644 --- a/examples/bridging-app/src/components/__tests__/WithdrawConsume.test.tsx +++ b/examples/bridging-app/src/components/__tests__/WithdrawConsume.test.tsx @@ -30,7 +30,7 @@ describe('WithdrawConsume', () => { expect( screen.getByRole('heading', { name: /Note delivered to your Miden wallet/i }), ).toBeInTheDocument(); - expect(screen.getByText(/Miden Wallet auto-consumes incoming notes/i)).toBeInTheDocument(); + expect(screen.getByText(/sufficient native MIDEN to pay the consumption fee/i)).toBeInTheDocument(); // Truncated note id (head of the hex string) is rendered. expect(screen.getByText(/0xnote1234/i)).toBeInTheDocument(); // Midenscan link points at the right path. diff --git a/examples/bridging-app/src/components/crosschain/IntentForm.tsx b/examples/bridging-app/src/components/crosschain/IntentForm.tsx index 32017f5b..d4813a3e 100644 --- a/examples/bridging-app/src/components/crosschain/IntentForm.tsx +++ b/examples/bridging-app/src/components/crosschain/IntentForm.tsx @@ -3,8 +3,9 @@ import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { SelectContent, SelectItem, SelectRoot, SelectTrigger, SelectValue } from '@/components/ui/select'; import { useMidenFiWallet } from '@miden-sdk/miden-wallet-adapter-react'; -import { SendTransaction } from '@miden-sdk/miden-wallet-adapter-base'; -import { useSyncState } from '@miden-sdk/react'; +import { Transaction } from '@miden-sdk/miden-wallet-adapter-base'; +import { AccountId, NoteArray } from '@miden-sdk/miden-sdk'; +import { useMiden, useSyncState } from '@miden-sdk/react'; import { useState } from 'react'; import { toast } from 'sonner'; import type { CrossChainIntentParams } from '../../types/miden'; @@ -16,6 +17,8 @@ import { DEFAULT_SEPOLIA_CHAIN_ID_STR } from '../../constants/chains'; import { useAccount } from 'wagmi'; import { useIntentTransactionStatus } from '../../hooks/useIntentTransactionStatus'; import { selectDestinationSettlement } from '../../lib/intentSettlement'; +import { createEpochCollateralNote } from '../../services/epoch-collateral'; +import { midenscanNoteUrl } from '../../lib/explorers'; const SEPOLIA_TOKENS = [ { symbol: 'USDC', address: '0x2BB4FfD7E2c6D432b697554Efd77fA13bdbefd69', decimals: 18 }, @@ -41,7 +44,7 @@ interface Props { }>; isLoadingMidenAssets: boolean; onFetchQuote: (params: CrossChainIntentParams) => Promise; - onConfirmIntent: (createMidenP2IDNote: SolveIntentParams['createMidenP2IDNote']) => Promise; + onConfirmIntent: (createMidenP2IDENote: SolveIntentParams['createMidenP2IDENote']) => Promise; onClearQuote: () => void; pendingQuote: CrossChainQuote | null; isFetchingQuote: boolean; @@ -65,7 +68,8 @@ export function IntentForm({ intentNonce, intentUserAddress, }: Props) { - const { requestSend, waitForTransaction } = useMidenFiWallet(); + const { requestTransaction, waitForTransaction } = useMidenFiWallet(); + const { client, runExclusive } = useMiden(); const { syncHeight } = useSyncState(); const [selectedAssetId, setSelectedAssetId] = useState(''); @@ -103,10 +107,8 @@ export function IntentForm({ const evmTransactionHash = evmCompletedStatus?.transactionHash; const evmTxChainId = evmCompletedStatus?.chainId ?? destinationChainIdNum; - const midenScanBase = - (import.meta as any).env?.VITE_MIDENSCAN_URL || 'https://testnet.midenscan.com'; const midenNoteUrl = localMidenNoteId - ? `${midenScanBase}/note/${localMidenNoteId}` + ? midenscanNoteUrl(localMidenNoteId) : undefined; const explorerTxUrl = (() => { @@ -197,41 +199,44 @@ export function IntentForm({ const handleConfirm = () => { if (!pendingQuote) return; - const createMidenP2IDNote: SolveIntentParams['createMidenP2IDNote'] = async ( + const createMidenP2IDENote: SolveIntentParams['createMidenP2IDENote'] = async ( faucetIdParam, amountParam, allocatorId, + recallBlocks, + bindingAttachmentFelts, ) => { setConfirmStatus('Resource lock required — creating P2IDE note on Miden…'); try { if (!midenAccountId) { throw new Error('Missing Miden account id'); } - if (!requestSend) { - throw new Error('Miden wallet adapter is not connected'); + if (!requestTransaction || !waitForTransaction || !client) { + throw new Error('Connect a Miden wallet that supports custom transactions and confirmation'); } - const normalizedAmount = BigInt(amountParam); - if (normalizedAmount > BigInt(Number.MAX_SAFE_INTEGER)) { - throw new Error('Amount too large for wallet adapter send'); - } - - const payload = new SendTransaction( - midenAccountId, - allocatorId, - faucetIdParam, - 'public', - Number(normalizedAmount), + const { request, expectedNoteId } = await runExclusive(async () => { + const head = await client.syncState(); + const note = createEpochCollateralNote({ + sender: midenAccountId, allocator: allocatorId, faucet: faucetIdParam, + amount: BigInt(amountParam), currentBlock: head.blockNum(), + recallBlocks, bindingAttachmentFelts, + }); + const builder = await client.feeAwareTransactionRequestBuilder(AccountId.fromHex(midenAccountId)); + return { + expectedNoteId: note.id().toString(), + request: builder.withOwnOutputNotes(new NoteArray([note])).build(), + }; + }); + const txId = await requestTransaction( + Transaction.createCustomTransaction(midenAccountId, allocatorId, request), ); - const txId = await requestSend(payload); - // Prefer adapter waitForTransaction to get the output note id. - if (!waitForTransaction) { - throw new Error('Miden wallet adapter is missing waitForTransaction'); - } + // Wait for the wallet to confirm the collateral before submitting it to Epoch. const finalized = await waitForTransaction(txId, 120_000); - const first = finalized.outputNotes?.[0]; - const noteId = first ? first.id().toString() : ''; + // A fee-paying transaction also creates a TX_FEE note. Match our exact + // collateral note instead of assuming outputNotes[0] is the payment. + const noteId = finalized.outputNotes?.find(note => note.id().toString() === expectedNoteId)?.id().toString(); if (!noteId) { throw new Error(`Could not read output note id for tx ${txId}`); } @@ -245,7 +250,7 @@ export function IntentForm({ void toast.promise( (async () => { setConfirmStatus('Submitting intent…'); - const result = await onConfirmIntent(createMidenP2IDNote); + const result = await onConfirmIntent(createMidenP2IDENote); if (result && typeof result === 'object' && 'error' in result && (result as { error?: string }).error) { throw new Error((result as { error: string }).error); } diff --git a/examples/bridging-app/src/components/crosschain/WithdrawConsume.tsx b/examples/bridging-app/src/components/crosschain/WithdrawConsume.tsx index 83574d87..1ca43e51 100644 --- a/examples/bridging-app/src/components/crosschain/WithdrawConsume.tsx +++ b/examples/bridging-app/src/components/crosschain/WithdrawConsume.tsx @@ -12,9 +12,9 @@ interface Props { * Post-withdraw informational panel. * * The Epoch allocator delivers bridged funds as a P2ID note addressed to the - * user's Miden wallet account. The Miden Wallet consumes that note when it - * detects it, so this panel reports delivery and links to Midenscan instead of - * initiating a second transaction from the page. + * user's Miden wallet account. Its consumption is handled by the wallet and + * requires native fees, so this panel reports delivery and links to Midenscan + * instead of initiating a second transaction from the page. */ export function WithdrawConsume({ noteId }: Props) { if (!noteId) return null; @@ -26,10 +26,10 @@ export function WithdrawConsume({ noteId }: Props) {

The allocator delivered the bridged funds as a P2ID note to your Miden wallet account. In Miden's actor model the note must be{' '} - consumed before it becomes spendable balance — but the Miden Wallet auto-consumes - incoming notes on detection, so no action is required here. Open your wallet to confirm - the new balance; the bridged USDC is ready to use as the source for another - Miden → EVM bridge or any other Miden transaction. + consumed before it becomes spendable balance. Wallet auto-consumption depends + on your wallet settings and sufficient native MIDEN to pay the consumption fee. + A USDC note does not itself fund that native fee. Open your wallet to confirm + consumption and the new balance before spending the bridged funds.

@@ -54,7 +54,7 @@ export function WithdrawConsume({ noteId }: Props) {

If your wallet does not show the credited balance, the note may still be propagating - through testnet — refresh the wallet after a few seconds. Some wallet builds let you + through the network — refresh the wallet after a few seconds. Some wallet builds let you disable auto-consume; in that case, consume the note manually from the wallet's Notes tab.

diff --git a/examples/bridging-app/src/components/crosschain/WithdrawForm.tsx b/examples/bridging-app/src/components/crosschain/WithdrawForm.tsx index d87488e2..b77d5278 100644 --- a/examples/bridging-app/src/components/crosschain/WithdrawForm.tsx +++ b/examples/bridging-app/src/components/crosschain/WithdrawForm.tsx @@ -8,6 +8,7 @@ import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { SelectContent, SelectItem, SelectRoot, SelectTrigger, SelectValue } from '@/components/ui/select'; +import { MIDEN_USDC_FAUCET_ID } from '@/config'; // EVM-side token decimals + the Miden-side faucet account ID for each known // token. The Epoch test ERC-20s on Sepolia are 18-decimal (verified on-chain); @@ -27,7 +28,7 @@ const SEPOLIA_TOKENS: ReadonlyArray<{ symbol: 'USDC', address: '0x2BB4FfD7E2c6D432b697554Efd77fA13bdbefd69', decimals: 18, - midenFaucetId: '0x0a7d175ed63ec5200fb2ced86f6aa5', + midenFaucetId: MIDEN_USDC_FAUCET_ID, }, { symbol: 'USDT', address: '0xc04d2869665Be874881133943523723Be5782720', decimals: 18 }, { symbol: 'Custom', address: '', decimals: 18 }, diff --git a/examples/bridging-app/src/components/layout/Header.tsx b/examples/bridging-app/src/components/layout/Header.tsx index d4b09aea..7568a9e1 100644 --- a/examples/bridging-app/src/components/layout/Header.tsx +++ b/examples/bridging-app/src/components/layout/Header.tsx @@ -1,3 +1,5 @@ +import { MIDEN_NETWORK } from '@/config'; + export function Header() { return (
@@ -9,7 +11,7 @@ export function Header() { M

Miden × Epoch

- Testnet + Miden {MIDEN_NETWORK}
); diff --git a/examples/bridging-app/src/config.ts b/examples/bridging-app/src/config.ts index 8676fb24..a0211dbf 100644 --- a/examples/bridging-app/src/config.ts +++ b/examples/bridging-app/src/config.ts @@ -2,7 +2,15 @@ export const APP_NAME = "Miden x Epoch Bridge"; // Miden SDK configuration — override via environment variables. +export const MIDEN_NETWORK = import.meta.env.VITE_MIDEN_NETWORK || "testnet"; +if (!["devnet", "testnet", "local"].includes(MIDEN_NETWORK)) { + throw new Error("VITE_MIDEN_NETWORK must be devnet, testnet, or local"); +} export const MIDEN_RPC_URL = - import.meta.env.VITE_MIDEN_RPC_URL ?? "testnet"; + import.meta.env.VITE_MIDEN_RPC_URL || MIDEN_NETWORK; export const MIDEN_PROVER = - (import.meta.env.VITE_MIDEN_PROVER as "devnet" | "testnet" | "local") ?? "testnet"; + (import.meta.env.VITE_MIDEN_PROVER || MIDEN_NETWORK) as "devnet" | "testnet" | "local"; + +// Faucet IDs change across networks and resets. Configure the allocator-approved +// asset for the selected network. +export const MIDEN_USDC_FAUCET_ID = import.meta.env.VITE_MIDEN_USDC_FAUCET_ID?.trim(); diff --git a/examples/bridging-app/src/hooks/useEpochIntent.ts b/examples/bridging-app/src/hooks/useEpochIntent.ts index 507af3b8..bd175e9e 100644 --- a/examples/bridging-app/src/hooks/useEpochIntent.ts +++ b/examples/bridging-app/src/hooks/useEpochIntent.ts @@ -61,9 +61,9 @@ export function useEpochIntent() { } }, [sdk, address]); - /** Step 2: execute the stored quote by creating the P2ID note and submitting the intent. */ + /** Step 2: execute the stored quote by creating the P2IDE note and submitting the intent. */ const confirmIntent = useCallback(async ( - createMidenP2IDNote: SolveIntentParams['createMidenP2IDNote'], + createMidenP2IDENote: SolveIntentParams['createMidenP2IDENote'], ) => { if (!sdk) throw new Error('Epoch SDK not ready'); if (!pendingQuote) throw new Error('Fetch a quote first'); @@ -75,7 +75,7 @@ export function useEpochIntent() { ...pendingQuote.params, collateralType: CollateralType.Miden, midenSourceAccount: pendingQuote.params.midenAccountId, - createMidenP2IDNote, + createMidenP2IDENote, preFetchedQuote: pendingQuote, }); if (result?.error) { @@ -99,7 +99,7 @@ export function useEpochIntent() { /** Direct-bridge path: skip quote, call buildCrossChainIntent with explicit midenAmount. */ const submitDirectIntent = useCallback(async ( params: CrossChainIntentParams, - createMidenP2IDNote: SolveIntentParams['createMidenP2IDNote'], + createMidenP2IDENote: SolveIntentParams['createMidenP2IDENote'], ) => { if (!sdk) throw new Error('Epoch SDK not ready'); setIsLoading(true); @@ -110,7 +110,7 @@ export function useEpochIntent() { ...params, collateralType: CollateralType.Miden, midenSourceAccount: params.midenAccountId, - createMidenP2IDNote, + createMidenP2IDENote, }); setIntentResult(result); return result; diff --git a/examples/bridging-app/src/lib/__tests__/network.test.ts b/examples/bridging-app/src/lib/__tests__/network.test.ts new file mode 100644 index 00000000..31aac9fc --- /dev/null +++ b/examples/bridging-app/src/lib/__tests__/network.test.ts @@ -0,0 +1,35 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; + +beforeEach(() => { + for (const key of ['VITE_MIDEN_NETWORK', 'VITE_MIDEN_RPC_URL', 'VITE_MIDEN_PROVER', 'VITE_MIDENSCAN_URL', 'VITE_MIDEN_USDC_FAUCET_ID']) { + vi.stubEnv(key, undefined); + } + vi.resetModules(); +}); + +afterEach(() => { vi.unstubAllEnvs(); vi.resetModules(); }); + +describe('bridge network configuration', () => { + it('defaults RPC, prover, and explorer to testnet', async () => { + const config = await import('../../config'); + const explorers = await import('../explorers'); + expect(config.MIDEN_NETWORK).toBe('testnet'); + expect(config.MIDEN_RPC_URL).toBe('testnet'); + expect(config.MIDEN_PROVER).toBe('testnet'); + expect(config.MIDEN_USDC_FAUCET_ID).toBeUndefined(); + expect(explorers.midenscanNoteUrl('abc')).toBe('https://testnet.midenscan.com/note/abc'); + }); + + it('uses explicitly selected devnet and explorer override', async () => { + vi.stubEnv('VITE_MIDEN_NETWORK', 'devnet'); + vi.stubEnv('VITE_MIDENSCAN_URL', 'https://example.com/'); + vi.stubEnv('VITE_MIDEN_USDC_FAUCET_ID', '0xapproved'); + const config = await import('../../config'); + const explorers = await import('../explorers'); + expect(config.MIDEN_NETWORK).toBe('devnet'); + expect(config.MIDEN_RPC_URL).toBe('devnet'); + expect(config.MIDEN_PROVER).toBe('devnet'); + expect(config.MIDEN_USDC_FAUCET_ID).toBe('0xapproved'); + expect(explorers.midenscanNoteUrl('abc')).toBe('https://example.com/note/abc'); + }); +}); diff --git a/examples/bridging-app/src/lib/explorers.ts b/examples/bridging-app/src/lib/explorers.ts index 97a8a05f..4bd384c3 100644 --- a/examples/bridging-app/src/lib/explorers.ts +++ b/examples/bridging-app/src/lib/explorers.ts @@ -2,9 +2,13 @@ // row using `chainId === MIDEN_CHAIN_ID` (999_999_999); everything else is an // EVM chain mapped here. +import { MIDEN_NETWORK } from '../config'; + export const MIDEN_CHAIN_ID = 999_999_999; -export const MIDENSCAN_BASE = 'https://testnet.midenscan.com'; +export const MIDENSCAN_BASE = ( + import.meta.env.VITE_MIDENSCAN_URL || `https://${MIDEN_NETWORK}.midenscan.com` +).replace(/\/+$/, ''); const EVM_EXPLORERS: Record = { 1: 'https://etherscan.io', diff --git a/examples/bridging-app/src/providers.tsx b/examples/bridging-app/src/providers.tsx index c185d097..f2a0a962 100644 --- a/examples/bridging-app/src/providers.tsx +++ b/examples/bridging-app/src/providers.tsx @@ -10,7 +10,7 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { RainbowKitProvider, lightTheme } from "@rainbow-me/rainbowkit"; import "@rainbow-me/rainbowkit/styles.css"; import { Toaster } from "sonner"; -import { APP_NAME, MIDEN_RPC_URL, MIDEN_PROVER } from "@/config"; +import { APP_NAME, MIDEN_NETWORK, MIDEN_RPC_URL, MIDEN_PROVER } from "@/config"; import { wagmiConfig } from "@/config/wagmi"; // Provider chain for the bridging-app: @@ -43,7 +43,8 @@ export function AppProviders({ children }: { children: ReactNode }) { diff --git a/examples/bridging-app/src/services/__tests__/epoch-collateral.test.ts b/examples/bridging-app/src/services/__tests__/epoch-collateral.test.ts new file mode 100644 index 00000000..8f39796d --- /dev/null +++ b/examples/bridging-app/src/services/__tests__/epoch-collateral.test.ts @@ -0,0 +1,47 @@ +// @vitest-environment node +import { describe, expect, it, vi } from 'vitest'; + +// The native export omits the typed-array normalization that the browser +// binding accepts. Adapt only its input container; all validation, note +// construction, and serialization still execute in the real native SDK. +vi.mock('@miden-sdk/miden-sdk', async importOriginal => { + const sdk = await importOriginal(); + return { + ...sdk, + NoteAttachment: new Proxy(sdk.NoteAttachment, { + construct(target, args) { + return Reflect.construct(target, args.map(value => value instanceof BigUint64Array ? Array.from(value) : value)); + }, + }), + }; +}); +import { createEpochCollateralNote } from '../epoch-collateral'; + +const params = { + sender: '0xfc442ceb5d7303b15da44080c20044', + allocator: '0xfc442ceb5d7303b15da44080c20044', + faucet: '0xfc90f0f4da30e51168453b60eafed7', + amount: 1_000_000n, + currentBlock: 51_337, + recallBlocks: 2_000, + bindingAttachmentFelts: [1n, 2n, 3n, 4n, 5n], +}; + +describe('Epoch collateral with the real v0.16 SDK', () => { + it('builds and serializes a public P2IDE note without publishing it', () => { + const note = createEpochCollateralNote(params); + expect(note.serialize().length).toBeGreaterThan(0); + expect(note.assets().fungibleAssets()[0].amount()).toBe(1_000_000n); + const attachmentValues = note.attachments()[0].toWords().flatMap(word => Array.from(word.toU64s())); + expect(attachmentValues).toEqual([1n, 2n, 3n, 4n, 5n, 0n, 0n, 0n]); + expect(note.recipient().storage().items().map(felt => felt.asInt())).toContain(53_337n); + }); + it('rejects an obsolete pre-v0.16 faucet account ID', () => { + expect(() => createEpochCollateralNote({ ...params, faucet: '0x0a7d175ed63ec5200fb2ced86f6aa5' })).toThrow(); + }); + it('requires a positive recall window and mandate attachment', () => { + expect(() => createEpochCollateralNote({ ...params, recallBlocks: 0 })).toThrow(/reclaim/); + expect(() => createEpochCollateralNote({ ...params, bindingAttachmentFelts: [] })).toThrow(/attachment/); + expect(() => createEpochCollateralNote({ ...params, bindingAttachmentFelts: [1n << 64n] })).toThrow(/canonical/); + }); +}); diff --git a/examples/bridging-app/src/services/epoch-bridge.ts b/examples/bridging-app/src/services/epoch-bridge.ts index 4b63bc8e..e756b835 100644 --- a/examples/bridging-app/src/services/epoch-bridge.ts +++ b/examples/bridging-app/src/services/epoch-bridge.ts @@ -57,16 +57,16 @@ export function formatQuoteTokenIn( } /** - * Cross-chain bridge architecture using P2ID notes: + * Cross-chain bridge architecture using reclaimable P2IDE collateral notes: * - * 1. User creates a P2ID note on Miden targeting the trusted allocator service - * 2. The allocator service (holding the P2ID note) builds an Epoch intent via SIO + * 1. User creates a mandate-bound P2IDE note targeting the trusted allocator + * 2. The allocator service validates the note and routes the intent via SIO * 3. SIO solver fulfills the intent on the destination EVM chain - * 4. On successful execution, the allocator consumes the P2ID note (claiming the Miden funds) - * 5. If the intent fails/expires, the P2ID note can be recalled by the user + * 4. On successful execution, the allocator consumes the note (claiming the Miden funds) + * 5. After the reclaim height, the user can recall an unconsumed collateral note * - * This keeps funds locked in a P2ID note (not custodied) until the cross-chain - * intent is fulfilled — privacy-preserving on the Miden side, trustless on EVM side. + * The allocator is a trusted participant: the note's reclaim path does not by + * itself enforce EVM settlement or prevent the target from consuming the note. */ const ZERO_ADDRESS = '0x0000000000000000000000000000000000000000'; @@ -74,24 +74,16 @@ const ZERO_HASH = '0x00000000000000000000000000000000000000000000000000000000000 function normalizeMidenIdToHex(id: string): string { const raw = (id ?? '').trim(); - if (!raw) return raw; + if (!raw) throw new Error('A Miden account or faucet ID is required'); // Already hex. if (raw.startsWith('0x') || raw.startsWith('0X')) { - try { - return AccountId.fromHex(raw).toString(); - } catch { - return raw; - } + return AccountId.fromHex(raw).toString(); } // Plain hex without 0x. if (/^[0-9a-fA-F]+$/.test(raw) && raw.length % 2 === 0) { - try { - return AccountId.fromHex(`0x${raw}`).toString(); - } catch { - return raw; - } + return AccountId.fromHex(`0x${raw}`).toString(); } // Bech32 (address or account). Wallet adapter often returns `mtst..._...`. @@ -105,8 +97,8 @@ function normalizeMidenIdToHex(id: string): string { try { return AccountId.fromBech32(raw).toString(); - } catch { - return raw; + } catch (cause) { + throw new Error(`Invalid Miden account or faucet ID: ${raw}`, { cause }); } } @@ -344,7 +336,7 @@ export async function buildCrossChainIntent( params: CrossChainIntentParams & { collateralType?: CollateralType; midenSourceAccount?: string; - createMidenP2IDNote?: SolveIntentParams['createMidenP2IDNote']; + createMidenP2IDENote?: SolveIntentParams['createMidenP2IDENote']; /** Pre-fetched quote from getCrossChainQuote — skips getTaskData step. */ preFetchedQuote?: CrossChainQuote; }, @@ -374,7 +366,7 @@ export async function buildCrossChainIntent( collateralType: (params.collateralType ?? 'miden') as CollateralType, midenFaucetId: midenFaucetIdHex, midenSourceAccount: midenSourceHex, - createMidenP2IDNote: params.createMidenP2IDNote, + createMidenP2IDENote: params.createMidenP2IDENote, }); console.log('[EpochBridge] SDK.solveIntent() response:', solveResult); diff --git a/examples/bridging-app/src/services/epoch-collateral.ts b/examples/bridging-app/src/services/epoch-collateral.ts new file mode 100644 index 00000000..e19c2f36 --- /dev/null +++ b/examples/bridging-app/src/services/epoch-collateral.ts @@ -0,0 +1,34 @@ +import { AccountId, FungibleAsset, Note, NoteAssets, NoteAttachment, NoteType } from '@miden-sdk/miden-sdk'; + +/** Build the public, reclaimable note required by the current Epoch allocator. */ +export function createEpochCollateralNote(params: { + sender: string; + allocator: string; + faucet: string; + amount: bigint; + currentBlock: number; + recallBlocks: number; + bindingAttachmentFelts: bigint[]; +}): Note { + if (!Number.isSafeInteger(params.currentBlock) || params.currentBlock < 0 || + !Number.isSafeInteger(params.recallBlocks) || params.recallBlocks <= 0 || + params.currentBlock + params.recallBlocks > 0xffff_ffff) { + throw new Error('Invalid Epoch reclaim window'); + } + if (params.amount <= 0n) throw new Error('Epoch collateral amount must be positive'); + if (params.bindingAttachmentFelts.length === 0) { + throw new Error('Epoch mandate-binding attachment is required'); + } + if (params.bindingAttachmentFelts.some(value => value < 0n || value >= 18_446_744_069_414_584_321n)) { + throw new Error('Epoch attachment values must be canonical field elements'); + } + return Note.createP2IDENote( + AccountId.fromHex(params.sender), + AccountId.fromHex(params.allocator), + new NoteAssets([new FungibleAsset(AccountId.fromHex(params.faucet), params.amount)]), + params.currentBlock + params.recallBlocks, + null, + NoteType.Public, + new NoteAttachment(BigUint64Array.from(params.bindingAttachmentFelts)), + ); +} diff --git a/examples/bridging-app/yarn.lock b/examples/bridging-app/yarn.lock index d0b64aa5..b7fc7230 100644 --- a/examples/bridging-app/yarn.lock +++ b/examples/bridging-app/yarn.lock @@ -341,21 +341,22 @@ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.2.tgz#ff9221b9f58b4dfe61e619a7788734bd63f6898b" integrity sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g== -"@epoch-protocol/epoch-commons-sdk@^0.1.11": - version "0.1.11" - resolved "https://registry.yarnpkg.com/@epoch-protocol/epoch-commons-sdk/-/epoch-commons-sdk-0.1.11.tgz#09cd5de0739b63e5550004e3c9407a1060a7ad08" - integrity sha512-4UvhAHpL/llcrONfuyffoZtnaCNf6D60A/gfHbz1tkpcfrq8pPynZbRL1jknU4YdOYQ+K+ZL4NaQb4mFOnS8QQ== +"@epoch-protocol/epoch-commons-sdk@^0.1.19": + version "0.1.19" + resolved "https://registry.yarnpkg.com/@epoch-protocol/epoch-commons-sdk/-/epoch-commons-sdk-0.1.19.tgz#c6cab788f16582db707579a23e61284eddb24973" + integrity sha512-M1ZSzK5LQyTWFPx4gHLVVOaAFHT23DKKP3c2G3cPsavmnyckxFayoIXIS9UyMTDn1g0QPeoL5R1YmKBmP7HE8Q== dependencies: ethers "^6.0.0" viem "2.42.0" -"@epoch-protocol/epoch-intents-sdk@^1.0.23": - version "1.0.23" - resolved "https://registry.yarnpkg.com/@epoch-protocol/epoch-intents-sdk/-/epoch-intents-sdk-1.0.23.tgz#ad8656bf26376c9772f2cc5a04bd76ee2f813854" - integrity sha512-vWKc4BGD4+ihirV89nNssagQZGyeCHcfU9T3eXtAbkiloXbX9IcT6h75QBajjoSvIqxGFU1hkJlYN4YZN2zElQ== +"@epoch-protocol/epoch-intents-sdk@1.0.38": + version "1.0.38" + resolved "https://registry.yarnpkg.com/@epoch-protocol/epoch-intents-sdk/-/epoch-intents-sdk-1.0.38.tgz#c2a8e902253a77d61b5b96545502fc6ac7acf56d" + integrity sha512-DS/JltAxR1cb5relGrssrj6EenIaVfWw/y4n4BkmiAODG/jhEf4qHFacn+ydZnJaQCxKjNdAvdNmbUYqevNW4g== dependencies: - "@epoch-protocol/epoch-commons-sdk" "^0.1.11" - viem "^2.29.2" + "@epoch-protocol/epoch-commons-sdk" "^0.1.19" + "@metamask/smart-accounts-kit" "^1.6.0" + viem "^2.31.4" "@esbuild/aix-ppc64@0.25.12": version "0.25.12" @@ -709,6 +710,41 @@ dependencies: "@lit-labs/ssr-dom-shim" "^1.5.0" +"@metamask/7715-permission-types@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@metamask/7715-permission-types/-/7715-permission-types-1.0.0.tgz#aa5f6f881c77c8aca6788ac22eadc210ff82e838" + integrity sha512-KhdKsT35pmBNTNpYcp+14gECPxmP4bX2eLA56riDr6pCjf6U7kEqPBoN6gz1CULNywEMp+p9UIMpdiTzFCyelg== + dependencies: + "@metamask/delegation-core" "^2.2.1" + "@metamask/utils" "^11.4.0" + +"@metamask/abi-utils@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@metamask/abi-utils/-/abi-utils-3.0.0.tgz#2eab9cb895922b94305364d9111b6dde724f6f9b" + integrity sha512-a/l0DiSIr7+CBYVpHygUa3ztSlYLFCQMsklLna+t6qmNY9+eIO5TedNxhyIyvaJ+4cN7TLy0NQFbp9FV3X2ktg== + dependencies: + "@metamask/superstruct" "^3.1.0" + "@metamask/utils" "^11.0.1" + +"@metamask/delegation-abis@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@metamask/delegation-abis/-/delegation-abis-1.1.0.tgz#b34dd3d796c08e3262b23b46458977dc3d68f235" + integrity sha512-n7XgRAM+pKUqmw4X+nAxM9a9HTBGe049WCAbpnHV6WoT6JnHhurMSUiqpAwMh69RhEykBtJPYSVPTVlJu6pEPg== + +"@metamask/delegation-core@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@metamask/delegation-core/-/delegation-core-2.2.1.tgz#1691ec33114274cc57de9ee56a903495231671df" + integrity sha512-fpB25AgmBxTJYhHj92tFS4dJe63x6wz71c8dPTwUin12dAvFMWM3PH+rm4C34iPb5ZrQzkAPi4e9z2njmwEZUA== + dependencies: + "@metamask/abi-utils" "^3.0.0" + "@metamask/utils" "^11.4.0" + "@noble/hashes" "^1.8.0" + +"@metamask/delegation-deployments@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@metamask/delegation-deployments/-/delegation-deployments-1.4.0.tgz#e83d01239fbfcf6c7423419204bbdd575c2de111" + integrity sha512-QuO4Fiz3GsP7nwcUpXFEVTxmRGBTkriYeZ7DBLxUAqbUQx7Kg630eR1SgvTn/eBMkmXB2tZJW9am/iGuAcySlw== + "@metamask/eth-json-rpc-provider@^1.0.0": version "1.0.1" resolved "https://registry.yarnpkg.com/@metamask/eth-json-rpc-provider/-/eth-json-rpc-provider-1.0.1.tgz#3fd5316c767847f4ca107518b611b15396a5a32c" @@ -805,6 +841,14 @@ resolved "https://registry.yarnpkg.com/@metamask/safe-event-emitter/-/safe-event-emitter-3.1.2.tgz#bfac8c7a1a149b5bbfe98f59fbfea512dfa3bad4" integrity sha512-5yb2gMI1BDm0JybZezeoX/3XhPDOtTbcFvpTXM9kxsoZjPZFh4XciqRbpD6N86HYZqWDhEaKUDuOyR0sQHEjMA== +"@metamask/scure-bip39@^2.0.3": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@metamask/scure-bip39/-/scure-bip39-2.1.1.tgz#071ddbaea7afe13886996c3bec22f472d79a4d34" + integrity sha512-1K8aBsAqr6+8jWhguVl06n8e+zjV9sUnys+5PLyVU4mb8LbulQ60F6cq7iQys3xX/yCwKt1+7c7j2nuTEpW+ZQ== + dependencies: + "@noble/hashes" "~1.3.2" + "@scure/base" "~1.1.3" + "@metamask/sdk-analytics@0.0.5": version "0.0.5" resolved "https://registry.yarnpkg.com/@metamask/sdk-analytics/-/sdk-analytics-0.0.5.tgz#ea10b15730d015af1da2225c8fe4fcf85b3fa77b" @@ -857,6 +901,19 @@ util "^0.12.4" uuid "^8.3.2" +"@metamask/smart-accounts-kit@^1.6.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@metamask/smart-accounts-kit/-/smart-accounts-kit-1.7.0.tgz#d22ac321376a0db4fea79fad4e38e2a95d5fe256" + integrity sha512-zypiFPDkJ12fpXENmPIqFQr4H35b3LttwIhB+PfQpP9sGHWKUIz0CnhSurkl6vZ6GyKC+RNcl0Kq0QyPqSExXQ== + dependencies: + "@metamask/7715-permission-types" "^1.0.0" + "@metamask/delegation-abis" "^1.1.0" + "@metamask/delegation-core" "^2.2.1" + "@metamask/delegation-deployments" "^1.4.0" + "@metamask/utils" "^11.4.0" + openapi-fetch "^0.13.5" + ox "0.8.1" + "@metamask/superstruct@^3.0.0", "@metamask/superstruct@^3.1.0": version "3.2.1" resolved "https://registry.yarnpkg.com/@metamask/superstruct/-/superstruct-3.2.1.tgz#fca933017c5b78529f8f525560cef32c57e889d2" @@ -879,6 +936,24 @@ semver "^7.5.4" uuid "^9.0.1" +"@metamask/utils@^11.4.0": + version "11.12.1" + resolved "https://registry.yarnpkg.com/@metamask/utils/-/utils-11.12.1.tgz#b62c3adfd3d8ee81d52cd9cadcb2ba2863f22c09" + integrity sha512-X97J5AEcaKDTIAfKb4X93ZTLfvOahzDVadlveQW+7OZ7yhXjMxXoFmhX2d9UKv48iS2Dxq9kbGJ1lUfphu9ebQ== + dependencies: + "@ethereumjs/tx" "^4.2.0" + "@metamask/scure-bip39" "^2.0.3" + "@metamask/superstruct" "^3.1.0" + "@noble/hashes" "^1.3.1" + "@scure/base" "^1.1.3" + "@types/debug" "^4.1.7" + "@types/lodash" "^4.17.20" + debug "^4.3.4" + lodash "^4.17.21" + pony-cause "^2.1.10" + semver "^7.5.4" + uuid "^9.0.1" + "@metamask/utils@^5.0.1": version "5.0.2" resolved "https://registry.yarnpkg.com/@metamask/utils/-/utils-5.0.2.tgz#140ba5061d90d9dac0280c19cab101bc18c8857c" @@ -920,49 +995,66 @@ semver "^7.5.4" uuid "^9.0.1" -"@miden-sdk/miden-sdk@0.14.4": - version "0.14.4" - resolved "https://registry.yarnpkg.com/@miden-sdk/miden-sdk/-/miden-sdk-0.14.4.tgz#be7496e6d2622b7f478768972f9896536db154cb" - integrity sha512-Qt+3NfGRCyHP5zcD+m9bBqQz01zuAwZRUBkls09mi+tOPVT17sFWKLglQEtKdr3gPAFHLwz2Ja4Hp4adUKfLuA== +"@miden-sdk/miden-sdk@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@miden-sdk/miden-sdk/-/miden-sdk-0.16.0.tgz#a54e095b3fc2aa36ebf249b24eeb9f280b4fbc75" + integrity sha512-APdct6zmuoGRPQaZ3kf2ovpUQ1a9C8VxV2MrJcGS3DelupiV34WBNNvIXhGE+I6DnSV9t2NzAHvokPVYhUq+kQ== dependencies: - "@rollup/plugin-typescript" "^12.3.0" dexie "^4.0.1" glob "^11.0.0" + optionalDependencies: + "@miden-sdk/node-darwin-arm64" "0.16.0" + "@miden-sdk/node-darwin-x64" "0.16.0" + "@miden-sdk/node-linux-x64-gnu" "0.16.0" -"@miden-sdk/miden-wallet-adapter-base@0.14.3", "@miden-sdk/miden-wallet-adapter-base@^0.14.3": - version "0.14.3" - resolved "https://registry.yarnpkg.com/@miden-sdk/miden-wallet-adapter-base/-/miden-wallet-adapter-base-0.14.3.tgz#3ab7960d314e467a3f1d5bfbd70583fc93e647ab" - integrity sha512-SfoIMnzP4OD4u6I8GyYvlbghXuXInw6vkQMmE+s8xTcshEiZk38MbVmmlPTtSFAhz7Z+K3nAOsW84EMn83d52A== +"@miden-sdk/miden-wallet-adapter-base@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@miden-sdk/miden-wallet-adapter-base/-/miden-wallet-adapter-base-0.16.0.tgz#ce020b7507aa0d1fd9015e66186b16d0734bcb43" + integrity sha512-rQF/eaRL2bfQTV5C8p7TRo2vMzkUeViQ77/gczWEuXaWrKh7qIxQEhIo3ksQGAQhMFt1tix985cjZg+rmc/okQ== dependencies: eventemitter3 "^5.0.1" -"@miden-sdk/miden-wallet-adapter-miden@^0.14.3": - version "0.14.3" - resolved "https://registry.yarnpkg.com/@miden-sdk/miden-wallet-adapter-miden/-/miden-wallet-adapter-miden-0.14.3.tgz#8718028f1a27bc843c43b581e3197cdee169ba2d" - integrity sha512-amZsYB41XZ/RyMgokygU99VqGwwWd+bmHbHPbOnoOMMHvPlskc+9Zn2IowNE13qzjzOfn4BhWG2jQErrg8m12g== +"@miden-sdk/miden-wallet-adapter-miden@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@miden-sdk/miden-wallet-adapter-miden/-/miden-wallet-adapter-miden-0.16.0.tgz#142fa7090adb4856f3995b01f32d784458678181" + integrity sha512-UlTh2ycLCgL1fDJH5FZ1PweErtMvPDMUvKoO7HYWnP0TZmoNUmmG2ptROEukOKznAP+fJXrY1Iqwl+K2YDOI2Q== dependencies: - "@miden-sdk/miden-wallet-adapter-base" "^0.14.3" - nanoid "^5.0.9" + "@miden-sdk/miden-wallet-adapter-base" "0.16.0" -"@miden-sdk/miden-wallet-adapter-react@0.14.3": - version "0.14.3" - resolved "https://registry.yarnpkg.com/@miden-sdk/miden-wallet-adapter-react/-/miden-wallet-adapter-react-0.14.3.tgz#bb654000fd96ef3b4e568d78ec320da26cf397f6" - integrity sha512-PqweUFoWf6YJaVx1FW2s6gc6vp6oz2pey0wmMzYpjxH24TZMQ+hooRYhql7FgGkfYo1VMQkXlVzCLyymgmn8SQ== +"@miden-sdk/miden-wallet-adapter-react@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@miden-sdk/miden-wallet-adapter-react/-/miden-wallet-adapter-react-0.16.0.tgz#5d455ced0df968f68d38b56ae61c47239dee4c59" + integrity sha512-Ev1FpBd8MGUPqX74LT7BoMxt8oXCC3virhHxy9p418bMD+eBK7jji32u91wdLWc3XiCHIcTXSeO9AGRNwdMBlg== dependencies: - "@miden-sdk/miden-wallet-adapter-base" "^0.14.3" - "@miden-sdk/miden-wallet-adapter-miden" "^0.14.3" + "@miden-sdk/miden-wallet-adapter-base" "0.16.0" + "@miden-sdk/miden-wallet-adapter-miden" "0.16.0" + +"@miden-sdk/node-darwin-arm64@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@miden-sdk/node-darwin-arm64/-/node-darwin-arm64-0.16.0.tgz#0ce84fa029899820674557b8b92690d25fb21b0c" + integrity sha512-uxwzouQkVG91/pU9o0wajLqzq2yqdZSttzzHmQtpl2hlpyFZJ8lucMwMFKOLCzU04+87PutBiUQ18Xfir2et6w== + +"@miden-sdk/node-darwin-x64@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@miden-sdk/node-darwin-x64/-/node-darwin-x64-0.16.0.tgz#1f2aa253398984cda42a1bfd6888a7ba512c1b11" + integrity sha512-vqKtB5xw8iE5OkmEE31KMVuTWxJ006EwrFFSBFEsZNuGGWHyZXlpSqCA3y3azstu2RX3FEYoViBFPwu0fLJVzg== -"@miden-sdk/react@0.14.4": - version "0.14.4" - resolved "https://registry.yarnpkg.com/@miden-sdk/react/-/react-0.14.4.tgz#6bb6e05572f6a4a63806e580bffc6156658e52f4" - integrity sha512-ASTcH1nge7hgH9OcV22nb1nrB9ccdkTsgVIioY+6y2wt0NcnTwu9RGrq8heJu4VyPcnl0g0LVFPcubvkmzXyjw== +"@miden-sdk/node-linux-x64-gnu@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@miden-sdk/node-linux-x64-gnu/-/node-linux-x64-gnu-0.16.0.tgz#2618859bfc526a0ec67e79eaaa4d9290ad675aff" + integrity sha512-+gFdLiRcAcv77QX3n4/0BoAecho9lbMxQR87sKH8oIIwP70+1ux0DFCE2Uf1nR8RK/rsbSSk/57R+0QBRY1kgw== + +"@miden-sdk/react@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@miden-sdk/react/-/react-0.16.0.tgz#c2ecc5d68425acbb17d03c13b6f1e193a8470f57" + integrity sha512-p4Blni66CPcZnyt1GNGh2I+OfbmIBQPSOqahsEzjfaZcP6P6k3XhhNt/sqxsoTr08QvVoxpwhXyosKyJNLQBvA== dependencies: zustand "^5.0.0" -"@miden-sdk/vite-plugin@0.14.4": - version "0.14.4" - resolved "https://registry.yarnpkg.com/@miden-sdk/vite-plugin/-/vite-plugin-0.14.4.tgz#b6d4b45f60120c2c65ba5afdf47cef9ec7e8077d" - integrity sha512-E9y0dJVsrWzgoB06y9+8MibOjzoS37apBwbTa9AEloaFPPOxsJnlrprZG2dbm2xwhc3HQNzVRI9NkJ1ijFpALQ== +"@miden-sdk/vite-plugin@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@miden-sdk/vite-plugin/-/vite-plugin-0.16.0.tgz#83f3c2b1b78cd02967ac5ee89aed1f8ac4f53a2f" + integrity sha512-5aBPdx0aYpyYKwhm49ftaoc0scxvGCrr2FPzVzrp6hIWr9QzE1AA4nMeA/qXewBK05mK4B4/7jhV8KwTC/+D1w== "@napi-rs/wasm-runtime@^1.1.4": version "1.1.4" @@ -1016,7 +1108,7 @@ dependencies: "@noble/hashes" "1.8.0" -"@noble/curves@^1.6.0", "@noble/curves@^1.9.7", "@noble/curves@~1.9.0": +"@noble/curves@^1.6.0", "@noble/curves@^1.9.1", "@noble/curves@^1.9.7", "@noble/curves@~1.9.0": version "1.9.7" resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.9.7.tgz#79d04b4758a43e4bca2cbdc62e7771352fa6b951" integrity sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw== @@ -1060,6 +1152,11 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.8.0.tgz#cee43d801fcef9644b11b8194857695acd5f815a" integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== +"@noble/hashes@~1.3.2": + version "1.3.3" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.3.tgz#39908da56a4adc270147bb07968bf3b16cfe1699" + integrity sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -1968,28 +2065,11 @@ resolved "https://registry.yarnpkg.com/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.16.tgz#bc27c8f906309b57c6c10eddb21043fd8e86b87e" integrity sha512-45+YtqxLYKDWQouLKCrpIZhke+nXxhsw+qAHVzHDVwttyBlHNBVs2K25rDXrZzhpTp9w1FlAlvweV1H++fdZoA== -"@rollup/plugin-typescript@^12.3.0": - version "12.3.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-12.3.0.tgz#cc51b830973bc14c9456fe6532f322f2a40f5f12" - integrity sha512-7DP0/p7y3t67+NabT9f8oTBFE6gGkto4SA6Np2oudYmZE/m1dt8RB0SjL1msMxFpLo631qjRCcBlAbq1ml/Big== - dependencies: - "@rollup/pluginutils" "^5.1.0" - resolve "^1.22.1" - "@rollup/plugin-virtual@^3.0.2": version "3.0.2" resolved "https://registry.yarnpkg.com/@rollup/plugin-virtual/-/plugin-virtual-3.0.2.tgz#17e17eeecb4c9fa1c0a6e72c9e5f66382fddbb82" integrity sha512-10monEYsBp3scM4/ND4LNH5Rxvh3e/cVeL3jWTgZ2SrQ+BmUoQcopVQvnaMcOnykb1VkxUFuDAN+0FnpTFRy2A== -"@rollup/pluginutils@^5.1.0": - version "5.3.0" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.3.0.tgz#57ba1b0cbda8e7a3c597a4853c807b156e21a7b4" - integrity sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q== - dependencies: - "@types/estree" "^1.0.0" - estree-walker "^2.0.2" - picomatch "^4.0.2" - "@rollup/rollup-android-arm-eabi@4.60.2": version "4.60.2" resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz#a19c645c375158cd5c50a344106f0fa18eb821c4" @@ -2141,7 +2221,7 @@ resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.2.6.tgz#ca917184b8231394dd8847509c67a0be522e59f6" integrity sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg== -"@scure/base@~1.1.6": +"@scure/base@~1.1.3", "@scure/base@~1.1.6": version "1.1.9" resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.9.tgz#e5e142fbbfe251091f9c5f1dd4c834ac04c3dbd1" integrity sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg== @@ -3479,6 +3559,11 @@ abitype@^1.0.6, abitype@^1.0.9, abitype@^1.2.3: resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.2.4.tgz#8aab72949bcad4107031862ae998e5bd20eec76e" integrity sha512-dpKH+N27vRjarMVTFFkeY445VTKftzGWpL0FiT7xmVmzQRKazZexzC5uHG0f6XKsVLAuUlndnbGau6lRejClxg== +abitype@^1.0.8: + version "1.3.0" + resolved "https://registry.yarnpkg.com/abitype/-/abitype-1.3.0.tgz#39de89010dd7390ece44d5242a3aa80901cc193d" + integrity sha512-fk6Te+bojIFrMvMZrnOO+SxCB+RUksTGOzq/60ZRvs1L+BVzvi2bqt9L3W/17ZLdZsyM1FuYf65P5nlmoiH1Bg== + abort-controller@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" @@ -4414,11 +4499,6 @@ estraverse@^5.1.0, estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== -estree-walker@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" - integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== - estree-walker@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" @@ -5419,11 +5499,6 @@ nanoid@^3.3.11: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== -nanoid@^5.0.9: - version "5.1.9" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.1.9.tgz#aac959acf7d685269fb1be7f70a90d9db0848948" - integrity sha512-ZUvP7KeBLe3OZ1ypw6dI/TzYJuvHP77IM4Ry73waSQTLn8/g8rpdjfyVAh7t1/+FjBtG4lCP42MEbDxOsRpBMw== - natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" @@ -5549,6 +5624,20 @@ ox@0.14.20: abitype "^1.2.3" eventemitter3 "5.0.1" +ox@0.14.44: + version "0.14.44" + resolved "https://registry.yarnpkg.com/ox/-/ox-0.14.44.tgz#58cda086c7e2d4c3ba39f08a33778c47de5e2dee" + integrity sha512-O54qXXHEk4ySamMSyBpI0AeBegS5frxU6+LA6Jb9Sf6kMOxcTNaxYmwZfpOu22DIQsdKfgQxHq8EsAGaoBQScA== + dependencies: + "@adraffy/ens-normalize" "^1.11.0" + "@noble/ciphers" "^1.3.0" + "@noble/curves" "1.9.1" + "@noble/hashes" "^1.8.0" + "@scure/bip32" "^1.7.0" + "@scure/bip39" "^1.6.0" + abitype "^1.2.3" + eventemitter3 "5.0.1" + ox@0.6.7: version "0.6.7" resolved "https://registry.yarnpkg.com/ox/-/ox-0.6.7.tgz#afd53f2ecef68b8526660e9d29dee6e6b599a832" @@ -5575,6 +5664,20 @@ ox@0.6.9: abitype "^1.0.6" eventemitter3 "5.0.1" +ox@0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/ox/-/ox-0.8.1.tgz#c1328e4c890583b9c19d338126aef4b796d53543" + integrity sha512-e+z5epnzV+Zuz91YYujecW8cF01mzmrUtWotJ0oEPym/G82uccs7q0WDHTYL3eiONbTUEvcZrptAKLgTBD3u2A== + dependencies: + "@adraffy/ens-normalize" "^1.11.0" + "@noble/ciphers" "^1.3.0" + "@noble/curves" "^1.9.1" + "@noble/hashes" "^1.8.0" + "@scure/bip32" "^1.7.0" + "@scure/bip39" "^1.6.0" + abitype "^1.0.8" + eventemitter3 "5.0.1" + ox@0.9.6: version "0.9.6" resolved "https://registry.yarnpkg.com/ox/-/ox-0.9.6.tgz#5cf02523b6db364c10ee7f293ff1e664e0e1eab7" @@ -6134,7 +6237,7 @@ resolve-from@^4.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve@^1.1.7, resolve@^1.22.1, resolve@^1.22.8: +resolve@^1.1.7, resolve@^1.22.8: version "1.22.12" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.12.tgz#f5b2a680897c69c238a13cd16b15671f8b73549f" integrity sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA== @@ -6827,7 +6930,7 @@ viem@2.42.0: ox "0.9.6" ws "8.18.3" -viem@>=2.29.0, viem@^2.1.1, viem@^2.27.2, viem@^2.29.2, viem@^2.31.7, viem@^2.45.2, viem@^2.47.0: +viem@>=2.29.0, viem@^2.1.1, viem@^2.27.2, viem@^2.31.7, viem@^2.45.2, viem@^2.47.0: version "2.49.0" resolved "https://registry.yarnpkg.com/viem/-/viem-2.49.0.tgz#97d44fd91ad6782ef7925bec17ba613e03f4034b" integrity sha512-vaasyOBFiCWYtw9JD8iRoaHPppk14kQH140qgVmrxkDEgv4qTX9Hwi6F+wF+s3Y7SStV5OtnN2ulJev+NQ7KDw== @@ -6841,6 +6944,20 @@ viem@>=2.29.0, viem@^2.1.1, viem@^2.27.2, viem@^2.29.2, viem@^2.31.7, viem@^2.45 ox "0.14.20" ws "8.18.3" +viem@^2.31.4: + version "2.56.3" + resolved "https://registry.yarnpkg.com/viem/-/viem-2.56.3.tgz#d76da19f71a9e70863c1288b2836903bc43b3425" + integrity sha512-vUObq3GO7D3lz9gPNEE/xd5jIUnMbeVDWewh252o54pDEDlW4pDe6FEd/qTGL5RyK52cGHMM7kQ3wjxhilEvkQ== + dependencies: + "@noble/curves" "1.9.1" + "@noble/hashes" "1.8.0" + "@scure/bip32" "1.7.0" + "@scure/bip39" "1.6.0" + abitype "1.2.3" + isows "1.0.7" + ox "0.14.44" + ws "8.21.0" + vite-plugin-top-level-await@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/vite-plugin-top-level-await/-/vite-plugin-top-level-await-1.6.0.tgz#c6ed0be438a1c14f48b4f9a56da859c12821a7c2" @@ -7034,6 +7151,11 @@ ws@8.18.3, ws@~8.18.3: resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472" integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== +ws@8.21.0: + version "8.21.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.21.0.tgz#012e413fc07429945121b0c153158c4343086951" + integrity sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g== + ws@^7.5.1: version "7.5.10" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" diff --git a/masm/accounts/auth/no_auth.masm b/masm/accounts/auth/no_auth.masm index c22205db..d8950a90 100644 --- a/masm/accounts/auth/no_auth.masm +++ b/masm/accounts/auth/no_auth.masm @@ -1,6 +1,37 @@ use miden::protocol::native_account +use miden::standards::fee +# CONSTANTS +# ================================================================================================= + +const POST_FEE_CYCLES = 1024 + +# PUBLIC INTERFACE +# ================================================================================================= + +#! Pays the native transaction fee and increments the account nonce without a signature. +#! +#! Inputs: [AUTH_ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - AUTH_ARGS contains unused authentication arguments. +#! +#! Panics if: +#! - the account cannot pay the transaction fee from its native asset balance. +#! +#! Invocation: call @auth_script -pub proc auth__basic +pub proc auth__basic(auth_args: word) + dropw + # => [pad(16)] + + exec.fee::native_conversion_info + # => [CONVERSION_INFO, pad(16)] + + push.POST_FEE_CYCLES exec.fee::pay_fee drop + # => [pad(16)] + exec.native_account::incr_nonce drop + # => [pad(16)] end diff --git a/masm/accounts/count_reader.masm b/masm/accounts/count_reader.masm index 5d92db91..7eed5e0a 100644 --- a/masm/accounts/count_reader.masm +++ b/masm/accounts/count_reader.masm @@ -1,26 +1,51 @@ -use miden::protocol::active_account use miden::protocol::native_account use miden::protocol::tx -use miden::core::word use miden::core::sys +use {AccountId, AccountProcedureRoot} from miden::protocol::types + +# CONSTANTS +# ================================================================================================= -# The storage slot where the copied count is stored. const COUNT_READER_SLOT = word("miden::tutorials::count_reader") -# => [account_id_suffix, account_id_prefix, PROC_HASH(4), foreign_procedure_inputs(16)] -pub proc copy_count +# PUBLIC INTERFACE +# ================================================================================================= + +#! Copies the count returned by the foreign counter into this account's storage. +#! +#! Inputs: [foreign_account_id_{suffix,prefix}, FOREIGN_PROC_ROOT, pad(10)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - foreign_account_id_{suffix,prefix} identifies the public counter account. +#! - FOREIGN_PROC_ROOT is the root of its get_count procedure. +#! +#! Invocation: call +@account_procedure +@locals(6) +pub proc copy_count(foreign_account_id: AccountId, foreign_proc_root: AccountProcedureRoot) + # save the foreign target while preparing its sixteen zero inputs + loc_store.4 loc_store.5 loc_storew_le.0 dropw + # => [pad(16)] + + padw padw padw padw + # => [foreign_procedure_inputs(16), pad(16)] + + padw loc_loadw_le.0 loc_load.5 loc_load.4 + # => [foreign_account_id_suffix, foreign_account_id_prefix, FOREIGN_PROC_ROOT, foreign_procedure_inputs(16), pad(16)] + exec.tx::execute_foreign_procedure - # => [count, pad(12)] + # => [[count, 0, 0, 0], pad(28)] push.COUNT_READER_SLOT[0..2] - # [slot_id_prefix, slot_id_suffix, count, pad(12)] + # => [slot_id_suffix, slot_id_prefix, [count, 0, 0, 0], pad(28)] exec.native_account::set_item - # => [OLD_VALUE, pad(12)] + # => [OLD_VALUE, pad(28)] - dropw dropw dropw dropw - # => [] + dropw + # => [pad(28)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end diff --git a/masm/accounts/counter.masm b/masm/accounts/counter.masm index 8ac3bbc5..d14dd300 100644 --- a/masm/accounts/counter.masm +++ b/masm/accounts/counter.masm @@ -1,32 +1,50 @@ use miden::protocol::active_account use miden::protocol::native_account -use miden::core::word use miden::core::sys +# CONSTANTS +# ================================================================================================= + const COUNTER_SLOT = word("miden::tutorials::counter") -#! Inputs: [] -#! Outputs: [count] -pub proc get_count +# PUBLIC INTERFACE +# ================================================================================================= + +#! Returns the current count. +#! +#! Inputs: [pad(16)] +#! Outputs: [count, pad(15)] +#! +#! Invocation: call +@account_procedure +pub proc get_count() -> felt push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] exec.sys::truncate_stack - # => [count] + # => [count, pad(15)] end -#! Inputs: [] -#! Outputs: [] -pub proc increment_count +#! Increments the current count by one. +#! +#! Inputs: [pad(16)] +#! Outputs: [pad(16)] +#! +#! Invocation: call +@account_procedure +pub proc increment_count() push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] add.1 - # => [count+1] + # => [[count + 1, 0, 0, 0], pad(16)] push.COUNTER_SLOT[0..2] exec.native_account::set_item - # => [] + # => [OLD_VALUE, pad(16)] + + dropw + # => [pad(16)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end diff --git a/masm/accounts/mapping_example_contract.masm b/masm/accounts/mapping_example_contract.masm index 8f1b3ac2..764449c9 100644 --- a/masm/accounts/mapping_example_contract.masm +++ b/masm/accounts/mapping_example_contract.masm @@ -1,43 +1,64 @@ use miden::protocol::active_account use miden::protocol::native_account -use miden::core::word use miden::core::sys +use {StorageMapKey} from miden::protocol::types + +# CONSTANTS +# ================================================================================================= const MAP_SLOT = word("miden::tutorials::mapping::map") -# Inputs: [KEY, VALUE] -# Outputs: [] -pub proc write_to_map - # The storage map is in the mapping slot. +# PUBLIC INTERFACE +# ================================================================================================= + +#! Stores VALUE under KEY in the mapping. +#! +#! Inputs: [KEY, VALUE, pad(8)] +#! Outputs: [pad(16)] +#! +#! Invocation: call +@account_procedure +pub proc write_to_map(key: StorageMapKey, value: word) + # the storage map is in the mapping slot push.MAP_SLOT[0..2] - # => [slot_id_prefix, slot_id_suffix, KEY, VALUE] + # => [slot_id_suffix, slot_id_prefix, KEY, VALUE, pad(8)] - # Setting the key value pair in the map + # set the key-value pair in the map exec.native_account::set_map_item - # => [OLD_VALUE] + # => [OLD_VALUE, pad(12)] dropw - # => [] + # => [pad(16)] end -# Inputs: [KEY] -# Outputs: [VALUE] -pub proc get_value_in_map - # The storage map is in the mapping slot. +#! Returns the VALUE stored under KEY in the mapping. +#! +#! Inputs: [KEY, pad(12)] +#! Outputs: [VALUE, pad(12)] +#! +#! Invocation: call +@account_procedure +pub proc get_value_in_map(key: StorageMapKey) -> word + # the storage map is in the mapping slot push.MAP_SLOT[0..2] - # => [slot_id_prefix, slot_id_suffix, KEY] + # => [slot_id_suffix, slot_id_prefix, KEY, pad(12)] exec.active_account::get_map_item - # => [VALUE] + # => [VALUE, pad(12)] end -# Inputs: [] -# Outputs: [CURRENT_ROOT] -pub proc get_current_map_root - # Getting the current root from the mapping slot. +#! Returns the CURRENT_ROOT of the mapping. +#! +#! Inputs: [pad(16)] +#! Outputs: [CURRENT_ROOT, pad(12)] +#! +#! Invocation: call +@account_procedure +pub proc get_current_map_root() -> word + # get the current root from the mapping slot push.MAP_SLOT[0..2] exec.active_account::get_item - # => [CURRENT_ROOT] + # => [CURRENT_ROOT, pad(16)] exec.sys::truncate_stack - # => [CURRENT_ROOT] + # => [CURRENT_ROOT, pad(12)] end diff --git a/masm/accounts/oracle_reader.masm b/masm/accounts/oracle_reader.masm index b9fc82d1..246abfb6 100644 --- a/masm/accounts/oracle_reader.masm +++ b/masm/accounts/oracle_reader.masm @@ -1,38 +1,42 @@ -# The oracle account ID, procedure hash, and pair ID below reference -# Pragma's Miden v0.15 testnet deployment (https://github.com/astraly-labs/pragma-miden). -# Pragma's addresses change between testnet iterations (their README is the -# source of truth), so if the oracle is redeployed these values must be updated: -# the oracle account id, the `get_median` procedure root, and (if a different -# feed) the faucet pair id. +# the Rust runner replaces these placeholders with values from a compatible +# pragma deployment before compiling this component. use miden::protocol::tx -# Fetches the current price from the `get_median` -# procedure from the Pragma oracle -# => [] -pub proc get_price +# PUBLIC INTERFACE +# ================================================================================================= + +#! Queries the configured Pragma oracle's median price through a foreign procedure. +#! +#! Inputs: [pad(16)] +#! Outputs: [pad(16)] +#! +#! Panics if: +#! - the configured oracle procedure or its required foreign state is unavailable. +#! +#! Invocation: call +@account_procedure +pub proc get_price() # `execute_foreign_procedure` requires exactly 16 foreign procedure inputs. # `get_median` only reads the first four, so the rest are zero padding. padw padw padw - # => [PAD(12)] + # => [pad(28)] - # BTC/USD pair: faucet id prefix `1`, suffix `0`, amount `0` - push.0.0.0.1 - # => [pair_prefix, pair_suffix, amount, 0, PAD(12)] + # requested pair: faucet ID prefix/suffix, amount `0`. + push.0.0.{pair_suffix}.{pair_prefix} + # => [pair_prefix, pair_suffix, amount, 0, pad(28)] - # This is the procedure root of the `get_median` procedure - push.0xaa3a12d4e9de2dad37c50dba93809b9c17226d512e642d3d620c77088a85da71 - # => [GET_MEDIAN_HASH, FOREIGN_INPUTS(16)] + # this is the procedure root of the `get_median` procedure. + push.{get_median_proc_root} + # => [GET_MEDIAN_HASH, foreign_procedure_inputs(16), pad(16)] - # The Pragma oracle account id: prefix then suffix, leaving suffix on top - push.8850886096234572817.9093477099503364096 - # => [oracle_id_suffix, oracle_id_prefix, GET_MEDIAN_HASH, FOREIGN_INPUTS(16)] + # the Pragma oracle account id: prefix then suffix, leaving suffix on top. + push.{oracle_id_prefix}.{oracle_id_suffix} + # => [oracle_id_suffix, oracle_id_prefix, GET_MEDIAN_HASH, foreign_procedure_inputs(16), pad(16)] exec.tx::execute_foreign_procedure - # => [is_tracked, median_price, amount, PAD(13)] - - debug.stack - # => [is_tracked, median_price, amount, PAD(13)] + # => [is_tracked, median_price, amount, pad(29)] dropw dropw dropw dropw + # => [pad(16)] end diff --git a/masm/notes/hash_preimage_note.masm b/masm/notes/hash_preimage_note.masm index ad82081e..ed04a3da 100644 --- a/masm/notes/hash_preimage_note.masm +++ b/masm/notes/hash_preimage_note.masm @@ -1,47 +1,57 @@ use miden::protocol::active_note -use miden::standards::wallets::basic->wallet +use miden::standards::wallets::basic as wallet # CONSTANTS # ================================================================================================= -const EXPECTED_DIGEST_PTR=0 +const EXPECTED_DIGEST_PTR = 0 # ERRORS # ================================================================================================= -const ERROR_DIGEST_MISMATCH="Expected digest does not match computed digest" +const ERROR_DIGEST_MISMATCH = "Expected digest does not match computed digest" -#! Inputs (arguments): [HASH_PREIMAGE_SECRET] -#! Outputs: [] +# PUBLIC INTERFACE +# ================================================================================================= + +#! Consumes the note's assets when the secret hashes to its stored digest. +#! +#! Inputs: [HASH_PREIMAGE_SECRET, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - HASH_PREIMAGE_SECRET is the four-felt secret supplied as note arguments. +#! +#! Panics if: +#! - the supplied secret does not match the digest stored in the note. #! -#! Note storage is assumed to be as follows: -#! => EXPECTED_DIGEST +#! Invocation: dyncall @note_script -pub proc main - # => HASH_PREIMAGE_SECRET - # Hashing the secret number +pub proc main(hash_preimage_secret: word) + # => [HASH_PREIMAGE_SECRET, pad(12)] + # hashing the secret number hash - # => [DIGEST] + # => [DIGEST, pad(12)] - # Writing the note storage to memory. + # writing the note storage to memory. # get_storage leaves only [num_storage_items], so drop a single element # here, not two, to keep the computed DIGEST intact. push.EXPECTED_DIGEST_PTR exec.active_note::get_storage drop - # Pad stack and load expected digest from memory (LE: mem[addr] ends up on top) + # pad stack and load expected digest from memory (LE: mem[addr] ends up on top) padw push.EXPECTED_DIGEST_PTR mem_loadw_le - # => [EXPECTED_DIGEST, DIGEST] + # => [EXPECTED_DIGEST, DIGEST, pad(12)] - # Assert that the note input matches the digest - # Will fail if the two hashes do not match + # assert that the note input matches the digest + # will fail if the two hashes do not match assert_eqw.err=ERROR_DIGEST_MISMATCH - # => [] + # => [pad(16)] # --------------------------------------------------------------------------------------------- - # If the check is successful, we allow for the asset to be consumed + # if the check is successful, we allow for the asset to be consumed # --------------------------------------------------------------------------------------------- - # Add all assets from the note to the account - exec.wallet::add_assets_to_account - # => [] + # add all assets from the note to the account + exec.wallet::move_note_assets_to_account + # => [pad(16)] end diff --git a/masm/notes/iterative_output_note.masm b/masm/notes/iterative_output_note.masm index 7c072562..d34b270c 100644 --- a/masm/notes/iterative_output_note.masm +++ b/masm/notes/iterative_output_note.masm @@ -1,102 +1,128 @@ use miden::protocol::active_note use miden::protocol::note -use miden::protocol::output_note use miden::core::sys -use miden::standards::wallets::basic->wallet - -# Memory Addresses -# get_assets writes: ASSET_KEY at ASSET_KEY_PTR, ASSET_VALUE at ASSET_KEY_PTR+4 (ASSET_SIZE=8) -const ASSET_KEY_PTR=0 -const ASSET_VALUE_PTR=4 -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 - -#! Inputs: [] -#! Outputs: [] +use miden::standards::wallets::basic as wallet +use miden::standards::note::note_creator + +# CONSTANTS +# ================================================================================================= + +# get_initial_assets writes the eight-felt asset as ASSET_ID followed by ASSET_VALUE +const ASSET_ID_PTR = 0 +const ASSET_VALUE_PTR = 4 +const ASSET_HALF_VALUE_PTR = 8 +const ACCOUNT_ID_PREFIX = 12 # storage: [prefix, suffix, tag, 0] +const TAG = 14 # ACCOUNT_ID_PREFIX + 2 + +# PUBLIC INTERFACE +# ================================================================================================= + +#! Receives this note's assets and creates a successor with half its fungible amount. +#! +#! This example expects exactly one fungible asset with a positive, even amount. Field division +#! by two is not integer rounding, so an odd amount does not produce a valid half-amount transfer. +#! Any account exposing the wallet and note-creator procedures may consume the note; the account +#! ID in storage is copied into the successor's storage and does not restrict consumption. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused note arguments. +#! - note storage contains a copied account ID and the successor's note tag. +#! +#! Panics if: +#! - the account cannot receive the note's assets or move the computed half amount to the successor. +#! +#! Invocation: dyncall @note_script -pub proc main - # Drop word if user accidentally pushes note_args +pub proc main(args: word) + # discard the unused note arguments dropw - # => [] + # => [pad(16)] - # Get asset contained in note into memory (ASSET_KEY at 0, ASSET_VALUE at 4) - # get_assets leaves [num_assets] on the stack in v0.15; drop it. - push.ASSET_KEY_PTR exec.active_note::get_assets drop - # => [] + # get asset contained in note into memory (ASSET_ID at 0, ASSET_VALUE at 4) + # get_initial_assets leaves [num_assets] on the stack; drop it. + push.ASSET_ID_PTR exec.active_note::get_initial_assets drop + # => [pad(16)] - # Load ASSET_VALUE and compute half amount + # load ASSET_VALUE and compute half amount padw push.ASSET_VALUE_PTR mem_loadw_le - # => [av0, av1, av2, av3] (av0 = amount for fungible asset, av1/av2/av3 = 0) + # => [[amount, 0, 0, 0], pad(16)] - # Halve the amount (av0 is the amount for fungible assets) + # halve the even fungible amount push.2 div - # => [av0/2, av1, av2, av3] + # => [[amount / 2, 0, 0, 0], pad(16)] - # Store as ASSET_HALF_VALUE + # store as ASSET_HALF_VALUE mem_storew_le.ASSET_HALF_VALUE_PTR dropw - # => [] + # => [pad(16)] - # Receive all assets from note into the account wallet - exec.wallet::add_assets_to_account - # => [] + # receive all assets from note into the account wallet + exec.wallet::move_note_assets_to_account + # => [pad(16)] - # Push script hash + # push script hash exec.active_note::get_script_root - # => [SCRIPT_HASH] + # => [SCRIPT_ROOT, pad(16)] - # Get the current note serial number + # get the current note serial number exec.active_note::get_serial_number - # => [SERIAL_NUM, SCRIPT_HASH] + # => [SERIAL_NUM, SCRIPT_ROOT, pad(16)] - # Increment the last element of the serial number by 1 + # increment the last element of the serial number by 1 # (serial_num[3] is at depth 3; matches Rust: serial_num[3] + 1) swap.3 push.1 add swap.3 - # => [SERIAL_NUM+1, SCRIPT_HASH] + # => [NEXT_SERIAL_NUM, SCRIPT_ROOT, pad(16)] - # Load note storage into memory for recipient construction. - # get_storage consumes dest_ptr and leaves only [num_storage_items], - # so re-push the storage_ptr for the recipient call rather than swapping. + # load note storage into memory for recipient construction push.ACCOUNT_ID_PREFIX exec.active_note::get_storage - # => [num_storage_items, SERIAL_NUM+1, SCRIPT_HASH] + # => [num_storage_items, NEXT_SERIAL_NUM, SCRIPT_ROOT, pad(16)] push.ACCOUNT_ID_PREFIX - # => [storage_ptr, num_storage_items, SERIAL_NUM+1, SCRIPT_HASH] + # => [storage_ptr, num_storage_items, NEXT_SERIAL_NUM, SCRIPT_ROOT, pad(16)] - # v0.15 renamed note::build_recipient -> note::compute_and_store_recipient - # (arg shape [storage_ptr, num_storage_items, SERIAL_NUM, SCRIPT_ROOT]). + # argument shape: [storage_ptr, num_storage_items, SERIAL_NUM, SCRIPT_ROOT]. exec.note::compute_and_store_recipient - # => [RECIPIENT] + # => [RECIPIENT, pad(16)] - # Push note type to stack (public note = 1) + # push note type to stack (public note = 1) push.1 - # => [note_type, RECIPIENT] + # => [note_type, RECIPIENT, pad(16)] - # Load tag from memory + # load tag from memory mem_load.TAG - # => [tag, note_type, RECIPIENT] + # => [tag, note_type, RECIPIENT, pad(16)] + + # note creation from a note script must call the account's note-creator procedure. + # pad the stack for the account procedure call convention. + push.0 movdn.6 push.0 movdn.6 padw padw swapdw + # => [tag, note_type, RECIPIENT, pad(26)] - exec.output_note::create - # => [note_idx] + call.note_creator::create_note + # => [note_idx, pad(31)] - # Build [ASSET_KEY, ASSET_HALF_VALUE, note_idx] for move_asset_to_note - # Inputs: [ASSET_KEY, ASSET_VALUE, note_idx, pad(7)] + movdn.15 dropw dropw dropw drop drop drop + # => [note_idx, pad(16)] - # Push ASSET_HALF_VALUE (note_idx moves to depth 4) + # build [ASSET_ID, ASSET_HALF_VALUE, note_idx] for move_asset_to_note + # inputs: [ASSET_ID, ASSET_VALUE, note_idx, pad(7)] + + # push ASSET_HALF_VALUE (note_idx moves to depth 4) padw push.ASSET_HALF_VALUE_PTR mem_loadw_le - # => [ASSET_HALF_VALUE, note_idx] + # => [ASSET_HALF_VALUE, note_idx, pad(16)] - # Push ASSET_KEY (ASSET_HALF_VALUE moves to depth 4, note_idx to depth 8) - padw push.ASSET_KEY_PTR mem_loadw_le - # => [ASSET_KEY, ASSET_HALF_VALUE, note_idx] + # push ASSET_ID (ASSET_HALF_VALUE moves to depth 4, note_idx to depth 8) + padw push.ASSET_ID_PTR mem_loadw_le + # => [ASSET_ID, ASSET_HALF_VALUE, note_idx, pad(16)] call.wallet::move_asset_to_note - # => [pad(16)] + # => [pad(25)] dropw dropw dropw dropw - # => [] + # => [pad(16)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end diff --git a/masm/notes/network_increment_note.masm b/masm/notes/network_increment_note.masm index 3b26cecd..96b12629 100644 --- a/masm/notes/network_increment_note.masm +++ b/masm/notes/network_increment_note.masm @@ -1,8 +1,19 @@ use external_contract::counter_contract -#! Inputs: [] -#! Outputs: [] +#! Increments the network counter when this note is consumed. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused note script arguments. +#! +#! Invocation: dyncall @note_script -pub proc main +pub proc main(args: word) + dropw + # => [pad(16)] + call.counter_contract::increment_count + # => [pad(16)] end diff --git a/masm/scripts/counter_script.masm b/masm/scripts/counter_script.masm index a0e1a0c7..d8aefd08 100644 --- a/masm/scripts/counter_script.masm +++ b/masm/scripts/counter_script.masm @@ -1,5 +1,19 @@ use external_contract::counter_contract -begin +#! Increments the counter. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) + dropw + # => [pad(16)] + call.counter_contract::increment_count + # => [pad(16)] end diff --git a/masm/scripts/mapping_example_script.masm b/masm/scripts/mapping_example_script.masm index df432ced..37215b72 100644 --- a/masm/scripts/mapping_example_script.masm +++ b/masm/scripts/mapping_example_script.masm @@ -1,25 +1,40 @@ use miden_by_example::mapping_example_contract use miden::core::sys -begin +#! Writes a mapping entry, reads it, and returns the current map root. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [CURRENT_ROOT, pad(12)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! - CURRENT_ROOT is the mapping's Merkle root after the write. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) -> word + dropw + # => [pad(16)] + push.1.2.3.4 push.0.0.0.0 - # => [KEY, VALUE] + # => [KEY, VALUE, pad(16)] call.mapping_example_contract::write_to_map - # => [] + # => [pad(24)] push.0.0.0.0 - # => [KEY] + # => [KEY, pad(24)] call.mapping_example_contract::get_value_in_map - # => [VALUE] + # => [VALUE, pad(24)] dropw - # => [] + # => [pad(24)] call.mapping_example_contract::get_current_map_root - # => [CURRENT_ROOT] + # => [CURRENT_ROOT, pad(20)] exec.sys::truncate_stack + # => [CURRENT_ROOT, pad(12)] end diff --git a/masm/scripts/oracle_reader_script.masm b/masm/scripts/oracle_reader_script.masm index 9aef181e..f3135cad 100644 --- a/masm/scripts/oracle_reader_script.masm +++ b/masm/scripts/oracle_reader_script.masm @@ -1,5 +1,19 @@ use external_contract::oracle_reader -begin - exec.oracle_reader::get_price +#! Queries the configured oracle through the reader account. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) + dropw + # => [pad(16)] + + call.oracle_reader::get_price + # => [pad(16)] end diff --git a/masm/scripts/reader_script.masm b/masm/scripts/reader_script.masm index c314ff3d..a0e575d3 100644 --- a/masm/scripts/reader_script.masm +++ b/masm/scripts/reader_script.masm @@ -1,8 +1,18 @@ use external_contract::count_reader_contract use miden::core::sys -begin - padw padw padw padw +#! Copies a public counter through the reader account. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) + dropw # => [pad(16)] push.{get_count_proc_hash} @@ -15,8 +25,8 @@ begin # => [account_id_suffix, account_id_prefix, GET_COUNT_HASH, pad(16)] call.count_reader_contract::copy_count - # => [] + # => [pad(22)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end diff --git a/rust-client/Cargo.lock b/rust-client/Cargo.lock index 1049eb92..5139c6e1 100644 --- a/rust-client/Cargo.lock +++ b/rust-client/Cargo.lock @@ -19,28 +19,28 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aead" -version = "0.5.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +checksum = "1973cfbc1a2daf9cf550e74e1f088c28e7f7d8c1e1418fb6c9dc5184b7e84c99" dependencies = [ - "crypto-common", - "generic-array", + "crypto-common 0.2.2", + "inout", ] [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] [[package]] name = "alloy-primitives" -version = "1.5.7" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3b431b4e72cd8bd0ec7a50b4be18e73dab74de0dba180eef171055e5d5926e" +checksum = "f007e257069855bdf21d27762fd3f3705a613f805c9a08309bf353503f081d71" dependencies = [ "bytes", "cfg-if", @@ -49,47 +49,56 @@ dependencies = [ "itoa", "paste", "ruint", - "rustc-hash", - "sha3", + "sha3 0.11.0", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24671b1f62edcf0f9b62994c7bf72cd621a04a4b99f5020ece1a647b40e2f103" +dependencies = [ + "arrayvec", + "bytes", ] [[package]] name = "alloy-sol-macro" -version = "1.5.7" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab81bab693da9bb79f7a95b64b394718259fdd7e41dceeced4cad57cb71c4f6a" +checksum = "b5655c38d5f84955bf727b2eeb62fddd91ebb98fd1d7ae6eb77f73ea88f9b9cf" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", - "proc-macro-error2", + "proc-macro-error3", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "alloy-sol-macro-expander" -version = "1.5.7" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489f1620bb7e2483fb5819ed01ab6edc1d2f93939dce35a5695085a1afd1d699" +checksum = "6277c780e07b76951e09a59788dde230d1582612324177d11a43a61e21a6bb83" dependencies = [ "alloy-sol-macro-input", "const-hex", "heck", - "indexmap", - "proc-macro-error2", + "indexmap 2.14.0", + "proc-macro-error3", "proc-macro2", "quote", - "sha3", - "syn 2.0.117", + "sha3 0.11.0", + "syn 2.0.119", "syn-solidity", ] [[package]] name = "alloy-sol-macro-input" -version = "1.5.7" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56cef806ad22d4392c5fc83cf8f2089f988eb99c7067b4e0c6f1971fc1cca318" +checksum = "9762b2ad3e5a0c09886de54fe549ab0056681df843cb082e2df7e1c0eb270d30" dependencies = [ "const-hex", "dunce", @@ -97,15 +106,15 @@ dependencies = [ "macro-string", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", "syn-solidity", ] [[package]] name = "alloy-sol-types" -version = "1.5.7" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64612d29379782a5dde6f4b6570d9c756d734d760c0c94c254d361e678a6591f" +checksum = "d96e74d6213180f78dbdccddce8af02a639c160c94b0a543fa35c77c58b8a7fc" dependencies = [ "alloy-primitives", "alloy-sol-macro", @@ -113,9 +122,9 @@ dependencies = [ [[package]] name = "android_system_properties" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" dependencies = [ "libc", ] @@ -172,40 +181,288 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] -name = "arrayref" -version = "0.3.9" +name = "ark-ff" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint 0.4.8", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] [[package]] -name = "arrayvec" -version = "0.7.6" +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint 0.4.8", + "num-traits", + "paste", + "rustc_version 0.4.1", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" +dependencies = [ + "ark-ff-asm 0.5.0", + "ark-ff-macros 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "educe", + "itertools 0.13.0", + "num-bigint 0.4.8", + "num-traits", + "paste", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7a806ac6c8307b929df4645776290a50ee2aac754ad09d8bdf73391309e43af" +dependencies = [ + "ark-ff-asm 0.6.0", + "ark-ff-macros 0.6.0", + "ark-serialize 0.6.0", + "ark-std 0.6.0", + "digest 0.10.7", + "educe", + "num-bigint 0.4.8", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] [[package]] -name = "ascii-canvas" -version = "4.0.0" +name = "ark-ff-asm" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" dependencies = [ - "term", + "quote", + "syn 1.0.109", ] +[[package]] +name = "ark-ff-asm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-ff-asm" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1479009684adc073dff49a1025d3a7065b317a9ead25aaaca38cdc70058ba8a2" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint 0.4.8", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint 0.4.8", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" +dependencies = [ + "num-bigint 0.4.8", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-ff-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0691ed21ef00ef89c1e9bda832eba493dda3ec2f8d892fb25b705f73f06bb8" +dependencies = [ + "num-bigint 0.4.8", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint 0.4.8", +] + +[[package]] +name = "ark-serialize" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" +dependencies = [ + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "num-bigint 0.4.8", +] + +[[package]] +name = "ark-serialize" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a74dd304fd536fb95d0a328e72be759209cc496a9da094c5bc56e5fea4f9e86b" +dependencies = [ + "ark-serialize-derive", + "ark-std 0.6.0", + "digest 0.10.7", + "num-bigint 0.4.8", + "serde_with", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f153690697a2b91e5e1251ff98411ee5371500a111a0fd317a70e588eb300f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand 0.8.7", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.7", +] + +[[package]] +name = "ark-std" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" +dependencies = [ + "num-traits", + "rand 0.8.7", +] + +[[package]] +name = "ark-std" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "367c9c827ed431bff6868b7aa926e05b16eb46603cc8b6e768e4a5553fa1d155" +dependencies = [ + "num-traits", + "rand 0.8.7", +] + +[[package]] +name = "arrayvec" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" + [[package]] name = "async-trait" -version = "0.1.89" +version = "0.1.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] @@ -214,11 +471,22 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "auto_impl" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "backtrace" @@ -246,9 +514,9 @@ dependencies = [ [[package]] name = "base16ct" -version = "0.2.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" [[package]] name = "base64" @@ -275,42 +543,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" [[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bit-set" -version = "0.8.0" +name = "bitflags" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" -dependencies = [ - "bit-vec", -] +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "bit-vec" -version = "0.8.0" +name = "bitflags" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] -name = "bitflags" -version = "2.11.1" +name = "bitvec" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] [[package]] name = "blake3" -version = "1.8.4" +version = "1.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d2d5991425dfd0785aed03aedcf0b321d61975c9b5b3689c774a2610ae0b51e" +checksum = "6d9e454fc11f76977dc803893aff6304ed33d6a26efae8696573bea74baa27ae" dependencies = [ - "arrayref", "arrayvec", "cc", "cfg-if", @@ -327,6 +588,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + [[package]] name = "bon" version = "3.9.3" @@ -349,23 +619,38 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.117", + "syn 2.0.119", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", ] [[package]] name = "build-rs" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe808acca98fccf920154ee7833e791bfb683299be4aae7ec222ddffad8cd4f8" +checksum = "87a490fb7ec2896b97a4c721c03a2b2dc5c2b9b75b2a57ca396db4470dea0381" dependencies = [ "unicode-ident", ] [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "byte-slice-cast" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" [[package]] name = "byteorder" @@ -375,15 +660,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cc" -version = "1.2.60" +version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" +checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" dependencies = [ "find-msvc-tools", "jobserver", @@ -397,61 +682,74 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "cfg_aliases" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527" + [[package]] name = "chacha20" -version = "0.9.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" dependencies = [ "cfg-if", "cipher", - "cpufeatures 0.2.17", + "cpufeatures 0.3.0", + "rand_core 0.10.1", ] [[package]] name = "chacha20poly1305" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +checksum = "9b89e1c441e926b9c82a8d023f6e1b7ae0adcfaa7d621814e4d60789bac751cb" dependencies = [ "aead", "chacha20", "cipher", "poly1305", - "zeroize", ] [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", "windows-link", ] [[package]] name = "cipher" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ - "crypto-common", + "block-buffer 0.12.1", + "crypto-common 0.2.2", "inout", - "zeroize", ] +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "codegen" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "573800db6c3319bc125ddbf9b9cb001ad1602957f53642ba8d09ff3ddd4da7f1" dependencies = [ - "indexmap", + "indexmap 2.14.0", ] [[package]] @@ -462,9 +760,9 @@ checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "const-hex" -version = "1.18.1" +version = "1.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531185e432bb31db1ecda541e9e7ab21468d4d844ad7505e0546a49b4945d49b" +checksum = "33e2a781ebdf4467d1428dc4593067825fb646f6871475098d8577421af73558" dependencies = [ "cfg-if", "cpufeatures 0.2.17", @@ -474,9 +772,30 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.6" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + +[[package]] +name = "const_format" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" +dependencies = [ + "const_format_proc_macros", + "konst", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] [[package]] name = "constant_time_eq" @@ -509,6 +828,12 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "cpubits" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -535,9 +860,9 @@ checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-deque" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +checksum = "5181e0de7b61eb03a81e347d6dd8797bae9da5146707b51077e2d71a54ec0ceb" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -545,18 +870,18 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "2d6914041f254d6e9176c01941b21115dcfb7089e55135a35411081bd106ef3f" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "61803da095bee82a81bb1a452ecc25d3b2f1416d1897eb86430c6159ef717c17" [[package]] name = "crunchy" @@ -566,12 +891,15 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" -version = "0.5.5" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +checksum = "1a52aa3fcda4e6302a9f48734f234d35d4721b96f8fe07d073f07ce9df4f0271" dependencies = [ - "generic-array", - "rand_core 0.6.4", + "cpubits", + "ctutils", + "hybrid-array", + "num-traits", + "rand_core 0.10.1", "subtle", "zeroize", ] @@ -583,20 +911,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", - "rand_core 0.6.4", "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", + "rand_core 0.10.1", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", + "subtle", +] + [[package]] name = "curve25519-dalek" -version = "4.1.3" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "b5eed333089e2e1c1ac8c6c0398e5e2497b4c9926ca6d0365ed1e099afa5bc23" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures 0.3.0", "curve25519-dalek-derive", - "digest", + "digest 0.11.3", "fiat-crypto", "rustc_version 0.4.1", "subtle", @@ -611,7 +958,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -634,7 +981,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -645,7 +992,7 @@ checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" dependencies = [ "darling_core", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -678,16 +1025,67 @@ dependencies = [ "deadpool-runtime", ] +[[package]] +name = "defmt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror", +] + [[package]] name = "der" -version = "0.7.10" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "a69dedd701da44b0536442edf09c81a64b0ab97a7a4a5e3d1971f00027cbc63d" dependencies = [ "const-oid", "zeroize", ] +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "serde_core", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive_more" version = "2.1.1" @@ -707,20 +1105,50 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.117", + "syn 2.0.119", "unicode-xid", ] +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", + "crypto-common 0.1.7", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", "const-oid", - "crypto-common", - "subtle", + "crypto-common 0.2.2", + "ctutils", +] + +[[package]] +name = "displaydoc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6232dd377dcc64799954cbd3a9bb882e9cdc1308ccd87b1c098f1fb2eaf82a8" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", ] [[package]] @@ -735,25 +1163,32 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + [[package]] name = "ecdsa" -version = "0.16.9" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +checksum = "c0681a4fc24c767085329728d8dfba959af91228aa4610cca4f8ce317ba46ae0" dependencies = [ "der", - "digest", + "digest 0.11.3", "elliptic-curve", "rfc6979", "signature", "spki", + "zeroize", ] [[package]] name = "ed25519" -version = "2.2.3" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +checksum = "29fcf32e6c73d1079f83ab4d782de2d81620346a5f38c6237a86a22f8368980a" dependencies = [ "pkcs8", "signature", @@ -761,58 +1196,83 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +checksum = "6ebaa1a2bf1290ab3bfe5a7b771d050ebffab2711c19a81691c683a5144a25de" dependencies = [ "curve25519-dalek", "ed25519", "serde", - "sha2", + "sha2 0.11.0", + "signature", "subtle", "zeroize", ] +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "either" -version = "1.15.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "elliptic-curve" -version = "0.13.8" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "9d65aa39b3a5c1c9c1b745c9a019234bb7a21b77abcb4f4d266d706e2d577d65" dependencies = [ "base16ct", "crypto-bigint", - "digest", + "crypto-common 0.2.2", + "digest 0.11.3", "ff", - "generic-array", "group", "hkdf", + "hybrid-array", "pkcs8", - "rand_core 0.6.4", + "rand_core 0.10.1", "sec1", "subtle", "zeroize", ] [[package]] -name = "ena" -version = "0.14.4" +name = "enum-ordinalize" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" +checksum = "89dd01549b09589510cf0647475075d12071456586d70f5c75c98ae2a5537677" dependencies = [ - "log", + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65863d15a4ce2888bd2f0f543cc963d3879c3a022c8ee43f6141d479a3ac815" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", ] [[package]] name = "env_filter" -version = "1.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" +checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217" dependencies = [ "log", "regex", @@ -820,9 +1280,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.10" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" +checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6" dependencies = [ "anstream", "anstyle", @@ -872,31 +1332,53 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fastrand" -version = "2.4.1" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" + +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "fastrlp" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce8dba4714ef14b8274c371879b175aa55b16b30f269663f19d576f380018dc4" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] [[package]] name = "ff" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +checksum = "a1f686ab92a9fb0eaf188f6c6c87b89490baa6fdb0db4544ba4dc47f7942489f" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" [[package]] name = "fixed-hash" @@ -904,6 +1386,9 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ + "byteorder", + "rand 0.8.7", + "rustc-hex", "static_assertions", ] @@ -915,14 +1400,11 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flume" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "spin 0.9.8", + "spin 0.9.9", ] [[package]] @@ -937,20 +1419,41 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + [[package]] name = "fs-err" -version = "3.3.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fde052dbfc920003cfd2c8e2c6e6d4cc7c1091538c3a24226cec0665ab08c0" +checksum = "b91aa448ca50d7e79433bdf3ee8d99215430d2ec02ade5aefab2a073a1822e8a" dependencies = [ "autocfg", ] +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "futures" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" dependencies = [ "futures-channel", "futures-core", @@ -963,9 +1466,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -973,15 +1476,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-executor" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" dependencies = [ "futures-core", "futures-task", @@ -990,38 +1493,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-macro" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] name = "futures-sink" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-channel", "futures-core", @@ -1036,9 +1539,9 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f04ae4152da20c76fe800fa48659201d5cf627c5149ca0b707b69d7eef6cf9" +checksum = "b3b854b0e584ead1a33f18b2fcad7cf7be18b3875c78816b753639aa501513ae" dependencies = [ "cc", "cfg-if", @@ -1057,7 +1560,6 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", - "zeroize", ] [[package]] @@ -1089,16 +1591,15 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "js-sys", "libc", "r-efi 6.0.0", - "wasip2", - "wasip3", + "rand_core 0.10.1", "wasm-bindgen", ] @@ -1110,9 +1611,9 @@ checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" [[package]] name = "glob" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" [[package]] name = "gloo-timers" @@ -1128,20 +1629,20 @@ dependencies = [ [[package]] name = "group" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] [[package]] name = "h2" -version = "0.4.13" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "839c0e8a181239723652be9062bb56ca5bf5f64011f73b623f6f4fc59086a228" dependencies = [ "atomic-waker", "bytes", @@ -1149,27 +1650,36 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap", + "indexmap 2.14.0", "slab", "tokio", "tokio-util", "tracing", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "foldhash", + "foldhash 0.1.5", ] [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" +dependencies = [ + "foldhash 0.2.0", +] [[package]] name = "hashlink" @@ -1200,27 +1710,27 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hkdf" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" dependencies = [ "hmac", ] [[package]] name = "hmac" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "digest", + "digest 0.11.3", ] [[package]] name = "http" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" dependencies = [ "bytes", "itoa", @@ -1228,9 +1738,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" dependencies = [ "bytes", "http", @@ -1238,9 +1748,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" dependencies = [ "bytes", "futures-core", @@ -1261,11 +1771,22 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hybrid-array" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" +dependencies = [ + "subtle", + "typenum", + "zeroize", +] + [[package]] name = "hyper" -version = "1.9.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "d22053281f852e11534f5198498373cbb59295120a20771d90f7ed1897490a72" dependencies = [ "atomic-waker", "bytes", @@ -1283,6 +1804,22 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + [[package]] name = "hyper-timeout" version = "0.5.2" @@ -1302,13 +1839,16 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ + "base64", "bytes", "futures-channel", "futures-util", "http", "http-body", "hyper", + "ipnet", "libc", + "percent-encoding", "pin-project-lite", "socket2", "tokio", @@ -1341,10 +1881,87 @@ dependencies = [ ] [[package]] -name = "id-arena" +name = "icu_collections" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa68d21081c4a05d5a901a1c62add574c77048b6a1c67be3b50ce0b60d4ca513" +dependencies = [ + "displaydoc", + "potential_utf", + "utf8_iter", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56e28588da92eee5c3201a6eff33fabdd49b62269c8938d4ff050ce4d900deb" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12f9cf5f235641ed274641dd81c3f28d870e276763d0797aeeab72317b1c646f" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1563da1ed3e0b3bf3d74c9b85917ac9c56464d2f57242270c09c9e752f8021a0" + +[[package]] +name = "icu_properties" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e7ca276ad3145661a65914e6daf131ca5120cd3dcee8f8f3214b8875184a148" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" +checksum = "e590f038c1464a96894fd6d10127e90a8be4509f56ff7ecef851b15cee0b7caa" + +[[package]] +name = "icu_provider" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27bbb9d3abbefac45d55f647c9de1d44aafcd1186eb91879afef17c396c3e73" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] [[package]] name = "ident_case" @@ -1352,12 +1969,64 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "indenter" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + [[package]] name = "indexmap" version = "2.14.0" @@ -1365,20 +2034,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.17.1", "serde", "serde_core", ] [[package]] name = "inout" -version = "0.1.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" dependencies = [ - "generic-array", + "hybrid-array", ] +[[package]] +name = "ipnet" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a756c3fac73139e83f14c2d742155dd2b78d3ee56597b419a0579b7bdd6dd78" + [[package]] name = "is_ci" version = "1.2.0" @@ -1391,6 +2066,24 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.14.0" @@ -1400,6 +2093,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.18" @@ -1408,102 +2110,116 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.23" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" dependencies = [ + "defmt", + "jiff-core", "jiff-static", + "jiff-tzdb-platform", "log", "portable-atomic", "portable-atomic-util", "serde_core", + "windows-link", +] + +[[package]] +name = "jiff-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +dependencies = [ + "defmt", ] [[package]] name = "jiff-static" -version = "0.2.23" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" dependencies = [ + "jiff-core", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", ] [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.95" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] [[package]] name = "k256" -version = "0.13.4" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +checksum = "93f50113171a713f4a4231ef82eb26703607139b35dcb56241f0ceab2ae1f7d8" dependencies = [ - "cfg-if", + "cpubits", "ecdsa", "elliptic-curve", - "once_cell", - "sha2", - "signature", + "primeorder", + "sha2 0.11.0", + "wnaf", ] [[package]] name = "keccak" -version = "0.1.6" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +checksum = "ffd9697dc4a9a62e2da93389f34400b77a28f0287711263cabb203b3ccb9c0e4" dependencies = [ - "cpufeatures 0.2.17", + "cfg-if", + "cpufeatures 0.3.0", ] [[package]] -name = "lalrpop" -version = "0.22.2" +name = "konst" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" +checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" dependencies = [ - "ascii-canvas", - "bit-set", - "ena", - "itertools", - "lalrpop-util", - "petgraph 0.7.1", - "regex", - "regex-syntax", - "sha3", - "string_cache", - "term", - "unicode-xid", - "walkdir", + "konst_macro_rules", ] [[package]] -name = "lalrpop-util" -version = "0.22.2" +name = "konst_macro_rules" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" -dependencies = [ - "rustversion", -] +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" [[package]] name = "lazy_static" @@ -1511,17 +2227,11 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "libc" -version = "0.2.185" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libm" @@ -1546,6 +2256,12 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" +[[package]] +name = "litemap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d9d19d1d6efa0109d2f65ff4c85cddd50bd572e5a00127ab10987290bcefae" + [[package]] name = "lock_api" version = "0.4.14" @@ -1557,9 +2273,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "logos" @@ -1567,7 +2283,16 @@ version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff472f899b4ec2d99161c51f60ff7075eeb3097069a36050d8037a6325eb8154" dependencies = [ - "logos-derive", + "logos-derive 0.15.1", +] + +[[package]] +name = "logos" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb2c55a318a87600ea870ff8c2012148b44bf18b74fad48d0f835c38c7d07c5f" +dependencies = [ + "logos-derive 0.16.1", ] [[package]] @@ -1583,7 +2308,21 @@ dependencies = [ "quote", "regex-syntax", "rustc_version 0.4.1", - "syn 2.0.117", + "syn 2.0.119", +] + +[[package]] +name = "logos-codegen" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58b3ffaa284e1350d017a57d04ada118c4583cf260c8fb01e0fe28a2e9cf8970" +dependencies = [ + "fnv", + "proc-macro2", + "quote", + "regex-automata", + "regex-syntax", + "syn 2.0.119", ] [[package]] @@ -1592,7 +2331,16 @@ version = "0.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "605d9697bcd5ef3a42d38efc51541aa3d6a4a25f7ab6d1ed0da5ac632a26b470" dependencies = [ - "logos-codegen", + "logos-codegen 0.15.1", +] + +[[package]] +name = "logos-derive" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52d3a9855747c17eaf4383823f135220716ab49bea5fbea7dd42cc9a92f8aa31" +dependencies = [ + "logos-codegen 0.16.1", ] [[package]] @@ -1608,15 +2356,21 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "macro-string" -version = "0.1.4" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" +checksum = "59a9dbbfc75d2688ed057456ce8a3ee3f48d12eec09229f560f3643b9f275653" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -1630,16 +2384,17 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "miden-ace-codegen" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd45076fe4fef71f0f8b30aa0f018eb39c3086eeb5f3cafc0e12d60cd28339e" +checksum = "1219d5caa6fcb00a96e1ec0ffc66bc03d86fc3e6367d5d8021e7ed420973d64e" dependencies = [ + "miden-constraint-compiler", "miden-core", "miden-crypto", "thiserror", @@ -1647,37 +2402,38 @@ dependencies = [ [[package]] name = "miden-agglayer" -version = "0.15.3" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ead17cc16651de0fea5fc3ea67109ad449c7bb274ca8ff91c5b25e2be4a0c9f8" +checksum = "3664d9d786b69d3ddef13eda4a2d8eb1138ad381ddb740367167fe721dd9cb76" dependencies = [ "alloy-sol-types", "fs-err", "miden-assembly", "miden-core", + "miden-core-lib", "miden-crypto", + "miden-mast-package", + "miden-package-registry", "miden-protocol", + "miden-protocol-build-utils", "miden-standards", "miden-utils-sync", - "primitive-types", - "regex", "serde", "serde_json", "thiserror", - "walkdir", ] [[package]] name = "miden-air" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f1a80330b3e3d3f98e08817dc6a5e3d90d11ab5e88aa9c0dad5d3b4202598b" +checksum = "20a825f5e8b687969ad32107a669b9ae254ba780c18f2e43869407aa010bc5e8" dependencies = [ "miden-ace-codegen", "miden-core", "miden-crypto", - "miden-lifted-stark", "miden-utils-indexing", + "p3-field", "proptest", "thiserror", "tracing", @@ -1685,9 +2441,9 @@ dependencies = [ [[package]] name = "miden-assembly" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8582d184360be35eb2111a99245f556f43e1066ed09192fbcd0f218c466862a5" +checksum = "3f1487a11b83df90e74469fdf61ee0b27831562972c3a4689e0c9bb7b0158ba5" dependencies = [ "env_logger", "log", @@ -1703,15 +2459,13 @@ dependencies = [ [[package]] name = "miden-assembly-syntax" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffa307bc2cbd1f0cb74ed58981823f400a433900fb8f963762331fbb8389d5dc" +checksum = "e77f0289745bb1887147ee67acfb47e14443579b7c7d0655660599f62545bc34" dependencies = [ - "aho-corasick", "env_logger", - "lalrpop", - "lalrpop-util", "log", + "miden-assembly-syntax-cst", "miden-core", "miden-debug-types", "miden-utils-diagnostics", @@ -1726,11 +2480,23 @@ dependencies = [ "thiserror", ] +[[package]] +name = "miden-assembly-syntax-cst" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f41c6c73726eb40149ca2d174c5dd5ac9fcbcd738d851bc4c7ddb7b7f6d4561" +dependencies = [ + "miden-debug-types", + "miden-rowan", + "miden-utils-diagnostics", + "thiserror", +] + [[package]] name = "miden-block-prover" -version = "0.15.3" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "292ded918a0ddd056dc34db471f0bef6ac7991467d513ba505a4fcc0b1ecfac4" +checksum = "286198b93e8ada957dc89fa920fdd442066c02bb0f28efbe0172fce03119545f" dependencies = [ "miden-protocol", "thiserror", @@ -1738,9 +2504,9 @@ dependencies = [ [[package]] name = "miden-client" -version = "0.15.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eb783623b8f55d013833c4eef35190f44da3629d0d13a13693285004f8d3fe2" +checksum = "c9862fde2ef60a6a1f1066834c9920f50973a2012465c451ec64381fea4654fc" dependencies = [ "anyhow", "async-trait", @@ -1750,18 +2516,19 @@ dependencies = [ "gloo-timers", "hex", "miden-agglayer", + "miden-assembly-syntax", "miden-node-proto-build", "miden-note-transport-proto-build", + "miden-processor", "miden-protocol", - "miden-remote-prover-client", "miden-standards", "miden-testing", "miden-tx", - "miden-tx-batch-prover", + "miden-tx-batch", "miette", "prost", "prost-types", - "rand 0.9.4", + "rand 0.10.2", "serde", "serde_json", "tempfile", @@ -1778,9 +2545,9 @@ dependencies = [ [[package]] name = "miden-client-sqlite-store" -version = "0.15.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb7f78f6ce83e114c49c601aa563df2863ebebea471023d70c3577177356b39" +checksum = "b1bdb490a10753418209cf9efcb8d923b3b0a39105b9cba987e9674dd1528b66" dependencies = [ "anyhow", "async-trait", @@ -1793,13 +2560,24 @@ dependencies = [ "rusqlite_migration", "thiserror", "tokio", + "tracing", +] + +[[package]] +name = "miden-constraint-compiler" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec5809dc0c9bc973f90cdb76116bfc3f5463d1e1ef9ce73a671141ba9f6d89a" +dependencies = [ + "miden-core", + "miden-crypto", ] [[package]] name = "miden-core" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80657c32850817f5f67dcf114866495a4b055531778b7c26d0602646ce777eb8" +checksum = "e8727b184f044ca41e61c9c2c345336d0e570f29c041bb49575520aade3c8f2d" dependencies = [ "derive_more", "log", @@ -1809,36 +2587,47 @@ dependencies = [ "miden-utils-core-derive", "miden-utils-indexing", "miden-utils-sync", - "num-derive", - "num-traits", "proptest", - "proptest-derive", "serde", "thiserror", ] [[package]] name = "miden-core-lib" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16410655f32f98537afc9ddf57b71cb6d1ca9d980da5f4eea164cafcaf891b2e" +checksum = "e48b2c62c2c0144717e4219cb42aaf427d58ccd730a18ba97f2e37387a3c3193" dependencies = [ "env_logger", "fs-err", "miden-assembly", + "miden-assembly-syntax", "miden-core", + "miden-core-lib-codegen", "miden-crypto", + "miden-mast-package", "miden-package-registry", + "miden-precompiles", "miden-processor", "miden-utils-sync", "thiserror", ] +[[package]] +name = "miden-core-lib-codegen" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0a0787b5fd63be0e6f5ee96bc531c075e96c0a787b3608fbaf60db0d82c47ed" +dependencies = [ + "miden-core", + "miden-precompiles", +] + [[package]] name = "miden-crypto" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35198bebd353cddc25ad4aafb5f4ef9e71b283d71c787b8938c575c16974135d" +checksum = "8202e1536816c254332798e27f5d46f4940766e01322826553b77489b78ce44d" dependencies = [ "blake3", "cc", @@ -1865,14 +2654,12 @@ dependencies = [ "p3-maybe-rayon", "p3-symmetric", "p3-util", - "rand 0.9.4", - "rand_chacha", - "rand_core 0.9.5", - "rand_hc", + "rand 0.10.2", + "rand_chacha 0.10.0", "rayon", "serde", - "sha2", - "sha3", + "sha2 0.11.0", + "sha3 0.12.0", "subtle", "thiserror", "x25519-dalek", @@ -1880,19 +2667,19 @@ dependencies = [ [[package]] name = "miden-crypto-derive" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9068c6554db0e051f62913575de9949841a46b96ae92d4b7d28e1fed5d8f052b" +checksum = "dcdc897827882684b76ac4b45cae93885cc252ee69c578e6b8ce0e3954043674" dependencies = [ "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "miden-debug-types" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956708ccb2f643db398b4b3d4f8d0baf199b1bfb5e34c8be1cd1bc811c005e8e" +checksum = "da1533b6a269126a48dbcb14ce22c3e31be0d0284b516b84f0954261c79f1756" dependencies = [ "memchr", "miden-crypto", @@ -1905,22 +2692,23 @@ dependencies = [ "serde", "serde_spanned", "thiserror", + "zerocopy", ] [[package]] name = "miden-field" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379a39db52cd932a95d4017a18b712ee53ed0f86cfedf8c63ed72d687a18a191" +checksum = "8d9c9b62982fcb18fa1b6c3bcaefc7956da30859d5e881a7f88f77dcf972db99" dependencies = [ "miden-serde-utils", - "num-bigint", + "num-bigint 0.5.1", "p3-challenger", "p3-field", "p3-goldilocks", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", "subtle", "thiserror", @@ -1937,11 +2725,12 @@ dependencies = [ [[package]] name = "miden-lifted-air" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789e0e469d1731012d8a018057317f31580611535c20d2a47c022213228cb733" +checksum = "8314dec43170ef8549a7a00ae6dd016975d772c9bdf03c06fb8a69d39fed300f" dependencies = [ "p3-air", + "p3-challenger", "p3-field", "p3-matrix", "p3-util", @@ -1950,9 +2739,9 @@ dependencies = [ [[package]] name = "miden-lifted-stark" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f62cca91182917b22a47e150028b7c785df620a15b2974a39c64e2b1b7a889d3" +checksum = "48166c2c8ee308ecbaea6ec8db07981973ff42f99bb39c09b914c30510942a9b" dependencies = [ "miden-lifted-air", "miden-stark-transcript", @@ -1965,7 +2754,7 @@ dependencies = [ "p3-maybe-rayon", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", "serde", "thiserror", "tracing", @@ -1973,15 +2762,20 @@ dependencies = [ [[package]] name = "miden-mast-package" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f37c21836b40785ce297d363c57740d4e33edcc411f84185a524eddadd5f53c7" +checksum = "3e99190edc3ae5a8be14aa77aa38df7a06d28455f8e9c02f4486a653f92e21cc" dependencies = [ + "hashbrown 0.17.1", + "log", "miden-assembly-syntax", "miden-core", "miden-debug-types", + "miden-utils-indexing", + "rustc-hash", "serde", "thiserror", + "zerocopy", ] [[package]] @@ -2000,9 +2794,9 @@ dependencies = [ "rustc_version 0.2.3", "rustversion", "serde_json", - "spin 0.9.8", + "spin 0.9.9", "strip-ansi-escapes", - "syn 2.0.117", + "syn 2.0.119", "textwrap", "thiserror", "trybuild", @@ -2017,14 +2811,14 @@ checksum = "86a905f3ea65634dd4d1041a4f0fd0a3e77aa4118341d265af1a94339182222f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "miden-node-proto-build" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef3b301741cedd6d0b532583690bc21dbf856d4e14218c591f3924bc905c660a" +checksum = "724a79e7663157e73de1fc19fcd6e30c7cee4e4c4189d44477922a3969797acb" dependencies = [ "build-rs", "codegen", @@ -2036,9 +2830,9 @@ dependencies = [ [[package]] name = "miden-note-transport-proto-build" -version = "0.4.1" +version = "0.5.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7399c2999453c781601f16d82f328ecc695f9375e2415a05147449990f32f71f" +checksum = "5a9d736051a42941788c6534caf8cf779b388c0ae72c9d5f0d729d2a9872d833" dependencies = [ "fs-err", "miette", @@ -2048,9 +2842,9 @@ dependencies = [ [[package]] name = "miden-package-registry" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ece6064beb0582d1c64ba30d0c548c4b7a45f87abae6d69e22fd49c8b343258" +checksum = "5a4b2c12e20f45e74c24ef88819c1ba36724519ce3b76d367a72e1d958df62b8" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -2062,16 +2856,51 @@ dependencies = [ "thiserror", ] +[[package]] +name = "miden-precompiles" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "823d3e418adcbe5a8cea6843f2a167f6f5b521ab827075261974b807ef979ccf" +dependencies = [ + "miden-core", + "miden-crypto", +] + +[[package]] +name = "miden-precompiles-prover" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "467e9fb8d805d8c4621af093a31f0a2465eefd68d63208b49f5663eaf030f89f" +dependencies = [ + "miden-ace-codegen", + "miden-air", + "miden-core", + "miden-crypto", + "miden-lifted-air", + "miden-lifted-stark", + "miden-precompiles", + "miden-serde-utils", + "ruint", + "serde", + "serde-wincode", + "thiserror", + "tracing", + "wincode", +] + [[package]] name = "miden-processor" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea972ca9e45dbf26aa396367e8508db0f7292adea6f6ddf8d39d0e334285fe2b" +checksum = "1a350061ef4f412639475c5bd8d68ae665ce9fd34ffc768c6082acd3972f791c" dependencies = [ - "itertools", + "hashbrown 0.17.1", + "itertools 0.15.0", "miden-air", "miden-core", "miden-debug-types", + "miden-mast-package", + "miden-precompiles", "miden-utils-diagnostics", "miden-utils-indexing", "paste", @@ -2082,9 +2911,9 @@ dependencies = [ [[package]] name = "miden-project" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5320e7e5b562359bd6161ac752dfe43dd4f69bb06e87f94a21a27bb656e5a20d" +checksum = "dbfb83107a2016867e3650e0b34bb8bc356ab2a039dce1992b808bab73da7385" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -2099,13 +2928,13 @@ dependencies = [ [[package]] name = "miden-protocol" -version = "0.15.3" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66340243e37da5936cb278a8dd11037813f1dc6731c2fc866703b76ed465ebc3" +checksum = "46b3c270a0fabe3618006176f1b9600e9b5b59a53a8e26ce6afcf65f1b02cb16" dependencies = [ "bech32", "fs-err", - "getrandom 0.3.4", + "getrandom 0.4.3", "miden-assembly", "miden-assembly-syntax", "miden-core", @@ -2113,89 +2942,96 @@ dependencies = [ "miden-crypto", "miden-crypto-derive", "miden-mast-package", + "miden-package-registry", "miden-processor", + "miden-protocol-build-utils", "miden-utils-sync", "miden-verifier", - "rand 0.9.4", - "rand_chacha", + "rand 0.10.2", + "rand_chacha 0.10.0", "rand_xoshiro", "regex", "semver 1.0.28", "serde", "thiserror", "toml", +] + +[[package]] +name = "miden-protocol-build-utils" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffb3076db13d4b6d12bf01d96ffc3fea400f415fce26467d81081400dcdc59c9" +dependencies = [ + "fs-err", + "miden-assembly", + "miden-core", + "miden-mast-package", + "miden-package-registry", + "miden-project", + "regex", "walkdir", ] [[package]] name = "miden-prover" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a91bcc00840b01126cd54e3b68ce3235def2ed48803f2eeb36a035d6951fbc1" +checksum = "65268275b38d5add4cb2542b2e2f2047047a96d6f7bac3b43678e78e36d51794" dependencies = [ - "bincode", "miden-air", "miden-core", "miden-crypto", + "miden-precompiles-prover", "miden-processor", "serde", + "serde-wincode", "tracing", ] [[package]] -name = "miden-remote-prover-client" -version = "0.15.0" +name = "miden-rowan" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2acdb9494689feeec0f60e3b61901b5eb2362b49b993b4cbc3eb75ad83514dd" +checksum = "c13695bf99aabaa21d6572b807c66bb26251aa3d9b75e828b3c99b97a3b1ce7e" dependencies = [ - "build-rs", - "fs-err", - "getrandom 0.4.2", - "miden-node-proto-build", - "miden-protocol", - "miden-tx", - "miette", - "prost", - "thiserror", - "tokio", - "tonic", - "tonic-prost", - "tonic-prost-build", - "tonic-web-wasm-client", + "hashbrown 0.17.1", + "rustc-hash", ] [[package]] name = "miden-serde-utils" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78cd1d4fcad937312e544f7d53423485e453598aa4fb989d2b6374027a8c136" +checksum = "e1f37aa58c6ec69c19ed0edbdba0322c2112356fbbc131a42b5994462a2b794d" dependencies = [ "p3-field", "p3-goldilocks", + "wincode", ] [[package]] name = "miden-standards" -version = "0.15.3" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c7146b028e637f4079b5bdefeefc54d7d6e47a805451fa0a18859d19efa2ff" +checksum = "6be6c71d2114157431f3d5860450b189e902a1fdf3351c8a7d91be8906fd35ce" dependencies = [ "bon", - "fs-err", "miden-assembly", "miden-core-lib", + "miden-package-registry", "miden-protocol", - "rand 0.9.4", - "regex", + "miden-protocol-build-utils", + "primitive-types 0.14.0", + "rand 0.10.2", "thiserror", - "walkdir", ] [[package]] name = "miden-stark-transcript" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05901db2e30d3954243960fe21cea7fbec39f97c27774b56fd5031c28c4881ba" +checksum = "5b3238f74844f9826a9ee41d39b1d726426fd298a5aba16c34346471d7d184db" dependencies = [ "p3-challenger", "p3-field", @@ -2205,9 +3041,9 @@ dependencies = [ [[package]] name = "miden-stateful-hasher" -version = "0.25.1" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faeb47a90c55c5d45051d23cf691588804dd531995b4582c79108b64e445a905" +checksum = "88a5545db3e83e041e365c7bb1ba5b8c5953b45a7ad32d698d3b4c30e45727a8" dependencies = [ "p3-field", "p3-symmetric", @@ -2215,12 +3051,12 @@ dependencies = [ [[package]] name = "miden-testing" -version = "0.15.3" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4096fc44a4c88f37405be284e25efdce194d6051e9472ae136ab9249659433c" +checksum = "dba121f560380c4cf70ba422098feedc512d897f41130163255a7dfd94c9aab3" dependencies = [ "anyhow", - "itertools", + "itertools 0.15.0", "miden-block-prover", "miden-core-lib", "miden-crypto", @@ -2228,41 +3064,45 @@ dependencies = [ "miden-protocol", "miden-standards", "miden-tx", - "miden-tx-batch-prover", - "rand 0.9.4", - "rand_chacha", + "miden-tx-batch", + "rand 0.10.2", + "rand_chacha 0.10.0", "thiserror", ] [[package]] name = "miden-tx" -version = "0.15.3" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94092b45bc0abc656af25473c9807d1e6cee8e682c58d3b1186f0bd0fb6471fb" +checksum = "9dcc3e4708af1d15dc13baec1162fd9c1b9663fd4eeac1c2d2f79ef4202d018c" dependencies = [ + "bon", + "miden-agglayer", "miden-processor", "miden-protocol", "miden-prover", "miden-standards", - "miden-verifier", "thiserror", ] [[package]] -name = "miden-tx-batch-prover" -version = "0.15.3" +name = "miden-tx-batch" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60add2b40559352661bc86970541f88ffcf98c528f301295f9dc3bf15481b46" +checksum = "5db9201b5b56c96dbed1cd5540e7344530a83348fe82e31cabce2b0d963c1dbe" dependencies = [ + "miden-processor", "miden-protocol", - "miden-tx", + "miden-prover", + "miden-verifier", + "thiserror", ] [[package]] name = "miden-utils-core-derive" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0b1ee4662beb049a824e11bb21f95a79746c52874967983c9999f1b19a2f471" +checksum = "d0e529fda0dc73e1fdb56d0c29ca92780a4f3d766cf5bf2bc688b95b0f8a8623" dependencies = [ "proc-macro2", "quote", @@ -2271,11 +3111,10 @@ dependencies = [ [[package]] name = "miden-utils-diagnostics" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fdc1cd4eda372e1c4b99b9c3677e9b1f87a4d2e362a9f4b8f904273d395efc9" +checksum = "197029df3c899525204f4a1f7e5b6e82c69427489b36032ae56fbcf53f9d6b2f" dependencies = [ - "miden-crypto", "miden-debug-types", "miden-miette", "tracing", @@ -2283,11 +3122,11 @@ dependencies = [ [[package]] name = "miden-utils-indexing" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31444125649f4dad9cde647f614309b6be4f918fed276ada4eb99c01e8b9ca7" +checksum = "5b87e9b3f949c27e56dc390d9c9e679f2886e6ea6adfbc7158de7f377c1b6940" dependencies = [ - "miden-crypto", + "miden-serde-utils", "proptest", "serde", "thiserror", @@ -2295,9 +3134,9 @@ dependencies = [ [[package]] name = "miden-utils-sync" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "807c8ae625b7652ae7246b225c907c05da72927c31a0fd71c835c4f80931e92e" +checksum = "e9e911afc22a03dcf439a0d1d20a67631169a6757100230b257c57e546dd5c3a" dependencies = [ "lock_api", "loom", @@ -2307,24 +3146,26 @@ dependencies = [ [[package]] name = "miden-verifier" -version = "0.23.4" +version = "0.29.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec5556dac919a1c13edeb2bd7181fc6a4c2ce52764a3e518bcdcd9ed48e5b38e" +checksum = "6aaf6b63aa6300832a302207f3e93932faae299679e75a0c993de6b1c02f5cde" dependencies = [ - "bincode", "miden-air", "miden-core", "miden-crypto", + "miden-precompiles", + "miden-precompiles-prover", + "miden-serde-utils", "serde", + "serde-wincode", "thiserror", - "tracing", ] [[package]] name = "midenc-hir-type" -version = "0.6.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff0511aa2201f7098995e38a3c97a319d379c3b2d26fb83677b21b71f61a7b4" +checksum = "f72909a4bae8dca4bbd34c28dcbcdff595afc47e48c312a683108f7452bd270b" dependencies = [ "miden-formatting", "miden-serde-utils", @@ -2361,7 +3202,7 @@ checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2375,9 +3216,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" dependencies = [ "libc", "wasi", @@ -2390,21 +3231,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom 0.2.17", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -2420,7 +3246,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "num-bigint", + "num-bigint 0.4.8", "num-complex", "num-integer", "num-iter", @@ -2430,9 +3256,19 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "93e7820bc0a80a0238e650327316f929ba18d5be054b647490a3a6a339f3e7c0" dependencies = [ "num-integer", "num-traits", @@ -2448,32 +3284,26 @@ dependencies = [ ] [[package]] -name = "num-derive" -version = "0.4.2" +name = "num-conv" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-integer" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" dependencies = [ "num-traits", ] [[package]] name = "num-iter" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -2484,7 +3314,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "num-bigint", + "num-bigint 0.4.8", "num-integer", "num-traits", ] @@ -2534,12 +3364,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "openssl-probe" version = "0.2.1" @@ -2554,9 +3378,9 @@ checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" [[package]] name = "p3-air" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c824e8d7c7ddf208b742eac8d48e0b2d52d22fa013578a7762bf6931dbab1f46" +checksum = "ddb1be05c0d6f691afe0c9f468018a9a37cfa904dee78a8081ec96eb3cdd88e8" dependencies = [ "p3-field", "p3-matrix", @@ -2565,9 +3389,9 @@ dependencies = [ [[package]] name = "p3-blake3" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2733229a713bd83ccf5eb749e8f8e7380c1052674394a25c0422a772204a20af" +checksum = "6f202f5fbcceb6f56f783d98efb5de27e5a171470e3364de97b0923b39c87ab5" dependencies = [ "blake3", "p3-symmetric", @@ -2576,9 +3400,9 @@ dependencies = [ [[package]] name = "p3-challenger" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8972ccd1d5dc90e46cdb1f2ab4ee2bae49b3917e5e98aa533f0c2b779c010445" +checksum = "84d5d5e1ecf2c80b09b48ce870e8abd08b643454101c5dc9d0fd71bfbd78224d" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -2590,42 +3414,42 @@ dependencies = [ [[package]] name = "p3-dft" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17771aca44632f9cc11f2718d7ea7ec06794946c4190ef3a985bfc893f14c18a" +checksum = "4321a952da2721ecd85ca593ea189798dfb4e439a2cc1378ce1442091880f173" dependencies = [ - "itertools", + "itertools 0.15.0", "p3-field", "p3-matrix", "p3-maybe-rayon", "p3-util", - "spin 0.10.0", + "spin 0.12.3", "tracing", ] [[package]] name = "p3-field" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3eb24d0591fd4d282d89cbe4e4efba5571c699375006f80b2cbf53ce83461c" +checksum = "53db75d38e04fc255826f388eca9d05976733dc9754aa3db411bc9ea1a37c1a0" dependencies = [ - "itertools", - "num-bigint", + "itertools 0.15.0", + "num-bigint 0.5.1", "p3-maybe-rayon", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", "tracing", ] [[package]] name = "p3-goldilocks" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5751c6591a0d2397d726620c2c29a7436ec6c5e19d2ed74ca5d078d4fbb18eb5" +checksum = "d03b3f31080df31be723b876709246f8f1e532e1c5b82efb5281d705c8304c63" dependencies = [ - "num-bigint", + "num-bigint 0.5.1", "p3-challenger", "p3-dft", "p3-field", @@ -2635,15 +3459,16 @@ dependencies = [ "p3-symmetric", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", + "spin 0.12.3", ] [[package]] name = "p3-keccak" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a7df174ff0c19a8742eb4698eaa1667c5f858d018e2faf09c55f1f24a6f9c3" +checksum = "ae50c8c37eb847c660298fb275e53c025c49b2623a8cfabf67f5322258b2b4db" dependencies = [ "p3-symmetric", "p3-util", @@ -2652,49 +3477,49 @@ dependencies = [ [[package]] name = "p3-matrix" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9c94c0714944e7b8a9a62e6340b1e3e1d3f8ecfd3e35c08798360200e73eff" +checksum = "473eb920c446a6f4536e0d3528fbdca2a23c0e24e1d0d7767452e6d385dd335c" dependencies = [ - "itertools", + "itertools 0.15.0", "p3-field", "p3-maybe-rayon", "p3-util", - "rand 0.10.1", + "rand 0.10.2", "serde", "tracing", ] [[package]] name = "p3-maybe-rayon" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebc233a34b1ab0273f35b4052fa2eeb3114b22ba4575bd7da00716e878ffb77" +checksum = "e6fddfd435f96394769414cf5590b77058aa506659bf20d6592e9d1989e04440" dependencies = [ "rayon", ] [[package]] name = "p3-mds" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b5441fa8116246ec9e6c835f15273cb27777ca572960ec87476b67fef13e01e" +checksum = "551ba0ab2cccd89f85a99450224898aff224e323bbf61f777ba6344f0896ef10" dependencies = [ "p3-dft", "p3-field", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-monty-31" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8724f330ea6d19dd4f2436aa0f88b5fcbf88f0f55ca7fccd3fea8b736dbcddad" +checksum = "871f635f7340cd0868b17e43e0c98fefdafdaed90469d0725caf6d8372a2a47c" dependencies = [ - "itertools", - "num-bigint", + "itertools 0.15.0", + "num-bigint 0.5.1", "p3-dft", "p3-field", "p3-matrix", @@ -2705,43 +3530,44 @@ dependencies = [ "p3-symmetric", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", - "spin 0.10.0", + "spin 0.12.3", "tracing", ] [[package]] name = "p3-poseidon1" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e2a562fea210baae390a32f9ecf0dd8724ae3f4352d1c8e413077b6f00a162" +checksum = "8d0d304e9a1f29c0d66534aa84e69528e2118351fdce08dcf5898af4e0fecc32" dependencies = [ "p3-field", + "p3-mds", "p3-symmetric", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-poseidon2" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06394851c161d17e4aa4ad2aad5557d32f14cadd1dc838f965d8e1821a63b8c5" +checksum = "43eb8a73a26d14becaed1c67c3e8a047e4311d7909b402383c82ca9643ba17c6" dependencies = [ "p3-field", "p3-mds", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-symmetric" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac1a276d421f8ef3361bb7d8c39a02c93c6b3f10eeaa559cc4c50222f9a5b82" +checksum = "2015ea80cad969b6aabf27a04884286fe1354393b166d968ee0d80a95126b2a4" dependencies = [ - "itertools", + "itertools 0.15.0", "p3-field", "p3-util", "serde", @@ -2749,13 +3575,40 @@ dependencies = [ [[package]] name = "p3-util" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d08a58162a4c264269ef454f0b28dcda89939490eecacb2b2cf5b00f719b80f6" +checksum = "6c5466fc40e6df89d3b291a2eff16b33e68e8571207790370137ec18090aadab" dependencies = [ "rayon", "serde", - "transpose", +] + +[[package]] +name = "parity-scale-codec" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "const_format", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "rustversion", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] @@ -2787,6 +3640,12 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pastey" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" + [[package]] name = "percent-encoding" version = "2.3.2" @@ -2794,13 +3653,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] -name = "petgraph" -version = "0.7.1" +name = "pest" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +checksum = "5a07a60cc7a4d00c91f95c685609d1d2f79050e6804b70ebedd7650f0b839bcf" dependencies = [ - "fixedbitset", - "indexmap", + "memchr", + "ucd-trie", ] [[package]] @@ -2811,36 +3670,27 @@ checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" dependencies = [ "fixedbitset", "hashbrown 0.15.5", - "indexmap", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher", + "indexmap 2.14.0", ] [[package]] name = "pin-project" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2851,9 +3701,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkcs8" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ "der", "spki", @@ -2861,26 +3711,25 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" [[package]] name = "poly1305" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +checksum = "6e2d0073b297041425c7c3df6eb4792d598a15323fe63346852b092eca02904c" dependencies = [ - "cpufeatures 0.2.17", - "opaque-debug", + "cpufeatures 0.3.0", "universal-hash", ] [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "portable-atomic-util" @@ -2891,6 +3740,21 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "potential_utf" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d83eb9bc6d8e5cf568e7a1101d60ee05e81ed50ea106026f3d18deeb046d7661" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.21" @@ -2900,12 +3764,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - [[package]] name = "prettyplease" version = "0.2.37" @@ -2913,7 +3771,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.117", + "syn 2.0.119", +] + +[[package]] +name = "primefield" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c555a6e4eb7d4e158fcb028c835c3b8642206ddc279b5c6b202ef9a8bdb592f4" +dependencies = [ + "crypto-bigint", + "crypto-common 0.2.2", + "ff", + "rand_core 0.10.1", + "subtle", + "zeroize", +] + +[[package]] +name = "primeorder" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c9f42978c78a00e3d68f69fc03e57a234debae69da4020a4fb588fcdcd07b06" +dependencies = [ + "elliptic-curve", + "primefield", + "serdect", + "wnaf", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "uint 0.9.5", ] [[package]] @@ -2923,7 +3818,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "721a1da530b5a2633218dc9f75713394c983c352be88d2d7c9ee85e2c4c21794" dependencies = [ "fixed-hash", - "uint", + "uint 0.10.1", ] [[package]] @@ -2933,37 +3828,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" dependencies = [ "equivalent", - "indexmap", + "indexmap 2.14.0", "serde", ] [[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error-attr3" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +checksum = "82366fd7d8b7a440d66d13418820c69df9b3908bcb1a0476d7f5ce5d12f5a04d" dependencies = [ "proc-macro2", "quote", ] [[package]] -name = "proc-macro-error2" -version = "2.0.1" +name = "proc-macro-error3" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +checksum = "b511283ea8a74b4b39447b128c5d00f03a356b7424554b13e298a5550100d9ac" dependencies = [ - "proc-macro-error-attr2", + "proc-macro-error-attr3", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -2974,10 +3878,10 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ - "bitflags", + "bitflags 2.13.1", "num-traits", - "rand 0.9.4", - "rand_chacha", + "rand 0.9.5", + "rand_chacha 0.9.0", "rand_xorshift", "regex-syntax", "unarray", @@ -2991,14 +3895,14 @@ checksum = "fb6dc647500e84a25a85b100e76c85b8ace114c209432dc174f20aac11d4ed6c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "prost" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1" dependencies = [ "bytes", "prost-derive", @@ -3006,45 +3910,45 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" +checksum = "03da047801ff44bb6a4d407d4860c05fd70bb81714e6b2f3812603d5b145b042" dependencies = [ "heck", - "itertools", + "itertools 0.14.0", "log", "multimap", - "petgraph 0.8.3", + "petgraph", "prettyplease", "prost", "prost-types", "pulldown-cmark", "pulldown-cmark-to-cmark", "regex", - "syn 2.0.117", + "syn 2.0.119", "tempfile", ] [[package]] name = "prost-derive" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" dependencies = [ "anyhow", - "itertools", + "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "prost-reflect" -version = "0.16.3" +version = "0.16.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89455ef41ed200cafc47c76c552ee7792370ac420497e551f16123a9135f76e" +checksum = "01b80ea363c31af2de2b92e3c07ed1156628f7838c4afb4df75ee78a37fedbd1" dependencies = [ - "logos", + "logos 0.16.1", "miette", "prost", "prost-types", @@ -3052,9 +3956,9 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +checksum = "f94967dc7688f3054c7fac87473ffae4cc4c3904800e2d9f5b857246d8963b0a" dependencies = [ "prost", ] @@ -3080,7 +3984,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "072eee358134396a4643dff81cfff1c255c9fbd3fb296be14bdb6a26f9156366" dependencies = [ - "logos", + "logos 0.15.1", "miette", "prost-types", "thiserror", @@ -3092,7 +3996,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f5df7e552bc7edd075f5783a87fbfc21d6a546e32c16985679c488c18192d83" dependencies = [ - "indexmap", + "indexmap 2.14.0", "log", "priority-queue", "rustc-hash", @@ -3102,29 +4006,85 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a14896dfa883796f1cb410461aef38810ea05f2b2c33c5aded3649095fdad" +checksum = "e9f068eba8e7071c5f9511831b44f32c740d5adf574e990f946ddb53db2f314e" dependencies = [ - "bitflags", + "bitflags 2.13.1", "memchr", "unicase", ] [[package]] name = "pulldown-cmark-to-cmark" -version = "22.0.0" +version = "22.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50793def1b900256624a709439404384204a5dc3a6ec580281bfaac35e882e90" +checksum = "ab1ad36992cead65f02aa399a373a42730922f1525d988172634fdefdecb8a60" dependencies = [ "pulldown-cmark", ] +[[package]] +name = "quinn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04759210543be93709136e28212294a659ef5001836ff4eab4d663e4529bba83" +dependencies = [ + "bytes", + "getrandom 0.4.3", + "lru-slab", + "rand 0.10.2", + "rand_pcg", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.61.2", +] + [[package]] name = "quote" -version = "1.0.45" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -3141,34 +4101,54 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" dependencies = [ + "libc", + "rand_chacha 0.3.1", "rand_core 0.6.4", ] [[package]] name = "rand" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ - "rand_chacha", + "rand_chacha 0.9.0", "rand_core 0.9.5", ] [[package]] name = "rand" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ + "chacha20", + "getrandom 0.4.3", "rand_core 0.10.1", ] +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + [[package]] name = "rand_chacha" version = "0.9.0" @@ -3179,6 +4159,16 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand_chacha" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e6af7f3e25ded52c41df4e0b1af2d047e45896c2f3281792ed68a1c243daedb" +dependencies = [ + "ppv-lite86", + "rand_core 0.10.1", +] + [[package]] name = "rand_core" version = "0.6.4" @@ -3204,12 +4194,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" [[package]] -name = "rand_hc" -version = "0.3.2" +name = "rand_pcg" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b363d4f6370f88d62bf586c80405657bde0f0e1b8945d47d2ad59b906cb4f54" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.10.1", ] [[package]] @@ -3223,11 +4213,11 @@ dependencies = [ [[package]] name = "rand_xoshiro" -version = "0.7.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" +checksum = "662effc7698e08ea324d3acccf8d9d7f7bf79b9785e270a174ea36e56900c91d" dependencies = [ - "rand_core 0.9.5", + "rand_core 0.10.1", ] [[package]] @@ -3256,14 +4246,34 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags", + "bitflags 2.13.1", +] + +[[package]] +name = "ref-cast" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -3273,9 +4283,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -3284,18 +4294,56 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" + +[[package]] +name = "reqwest" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64", + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] [[package]] name = "rfc6979" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +checksum = "b4a459cddafb3fe76b31fd8f1108007566c40301feb64dc7b54656eb7388172b" dependencies = [ + "crypto-bigint", "hmac", - "subtle", ] [[package]] @@ -3312,15 +4360,39 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + [[package]] name = "ruint" -version = "1.17.2" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c141e807189ad38a07276942c6623032d3753c8859c146104ac2e4d68865945a" +checksum = "f5e99bff0393163bb25029a6af25d3d8d202ba5b5438a74d1bd8789f5c822970" dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "ark-ff 0.5.0", + "ark-ff 0.6.0", + "bytes", + "fastrlp 0.3.1", + "fastrlp 0.4.0", + "num-bigint 0.4.8", + "num-integer", + "num-traits", + "parity-scale-codec", + "primitive-types 0.12.2", "proptest", - "rand 0.8.6", - "rand 0.9.4", + "rand 0.8.7", + "rand 0.9.5", + "rlp", "ruint-macro", "serde_core", "valuable", @@ -3339,7 +4411,7 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f" dependencies = [ - "bitflags", + "bitflags 2.13.1", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -3361,24 +4433,34 @@ dependencies = [ name = "rust-client" version = "0.1.0" dependencies = [ + "hex", "miden-client", "miden-client-sqlite-store", "miden-protocol", - "rand 0.9.4", + "rand 0.10.2", + "reqwest", + "serde", + "sha2 0.10.9", "tokio", ] [[package]] name = "rustc-demangle" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" +checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" + +[[package]] +name = "rustc-hex" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" [[package]] name = "rustc_version" @@ -3389,6 +4471,15 @@ dependencies = [ "semver 0.9.0", ] +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + [[package]] name = "rustc_version" version = "0.4.1" @@ -3404,7 +4495,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags", + "bitflags 2.13.1", "errno", "libc", "linux-raw-sys", @@ -3413,9 +4504,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.38" +version = "0.23.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f9466fb2c14ea04357e91413efb882e2a6d4a406e625449bc0a5d360d53a21" +checksum = "0283386ce02abc0151e1761d08802dfe86c173b0b494af5cbc086574e453da06" dependencies = [ "log", "once_cell", @@ -3428,9 +4519,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" dependencies = [ "openssl-probe", "rustls-pki-types", @@ -3440,18 +4531,19 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" dependencies = [ + "web-time", "zeroize", ] [[package]] name = "rustls-webpki" -version = "0.103.12" +version = "0.103.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06" +checksum = "0527518605e68109d875e248ea259b6758801cf165e4b2c2733ae3b51f12535a" dependencies = [ "ring", "rustls-pki-types", @@ -3460,9 +4552,15 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "ryu" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" [[package]] name = "same-file" @@ -3482,6 +4580,30 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -3496,14 +4618,14 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sec1" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" dependencies = [ "base16ct", + "ctutils", "der", - "generic-array", - "pkcs8", + "hybrid-array", "subtle", "zeroize", ] @@ -3514,7 +4636,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags", + "bitflags 2.13.1", "core-foundation", "core-foundation-sys", "libc", @@ -3537,7 +4659,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser", + "semver-parser 0.7.0", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser 0.10.3", ] [[package]] @@ -3556,11 +4687,20 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "semver-parser" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" +dependencies = [ + "pest", +] + [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -3578,31 +4718,42 @@ dependencies = [ "typeid", ] +[[package]] +name = "serde-wincode" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa9d3a86c66cf10ce79df36f555a5a4c8d72a82515d9ea8ca420e02c925c30f" +dependencies = [ + "serde", + "thiserror", + "wincode", +] + [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -3613,13 +4764,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] @@ -3631,6 +4782,48 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee78f1fbe43ac4a0e47aadb3dbd357b69eb0d3793e948624cd03dd2750ab1c0a" +dependencies = [ + "base64", + "bs58", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.14.0", + "jiff", + "schemars 0.9.0", + "schemars 1.2.2", + "serde_core", + "serde_json", + "time", +] + +[[package]] +name = "serdect" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66cf8fedced2fcf12406bcb34223dffb92eaf34908ede12fed414c82b7f00b3e" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "sha2" version = "0.10.9" @@ -3639,19 +4832,41 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures 0.2.17", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] name = "sha3" -version = "0.10.9" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +checksum = "be176f1a57ce4e3d31c1a166222d9768de5954f811601fb7ca06fc8203905ce1" dependencies = [ - "digest", + "digest 0.11.3", "keccak", ] +[[package]] +name = "sha3" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc9bad02c26382724b2d2692c6f179285e4b54eeecd7968f52a50059c3c11759" +dependencies = [ + "digest 0.11.3", + "keccak", + "sponge-cursor", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -3663,26 +4878,20 @@ dependencies = [ [[package]] name = "shlex" -version = "1.3.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signature" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" dependencies = [ - "digest", - "rand_core 0.6.4", + "digest 0.11.3", + "rand_core 0.10.1", ] -[[package]] -name = "siphasher" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" - [[package]] name = "slab" version = "0.4.12" @@ -3691,24 +4900,24 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.1" +version = "1.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" dependencies = [ "serde", ] [[package]] name = "smawk" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +checksum = "e8e2fb0f499abb4d162f2bedad68f5ef91a1682b5a03596ddb67efd37768d100" [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", "windows-sys 0.61.2", @@ -3716,55 +4925,49 @@ dependencies = [ [[package]] name = "spin" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" dependencies = [ "lock_api", ] [[package]] name = "spin" -version = "0.10.0" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +checksum = "0134f9043ed38b087ac4f7d4af44c79e2c9e5094421fe3164f435ce585953b10" dependencies = [ "lock_api", ] [[package]] name = "spki" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" dependencies = [ "base64ct", "der", ] [[package]] -name = "static_assertions" -version = "1.1.0" +name = "sponge-cursor" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +checksum = "3a0219bd7d979d58245a4f41f695e1ac9f8befdffadd7f61f1bae9e39abc6620" [[package]] -name = "strength_reduce" -version = "0.2.4" +name = "stable_deref_trait" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] -name = "string_cache" -version = "0.8.9" +name = "static_assertions" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" -dependencies = [ - "new_debug_unreachable", - "parking_lot", - "phf_shared", - "precomputed-hash", -] +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "strip-ansi-escapes" @@ -3821,9 +5024,20 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" dependencies = [ "proc-macro2", "quote", @@ -3832,14 +5046,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "1.5.7" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53f425ae0b12e2f5ae65542e00898d500d4d318b4baf09f40fd0d410454e9947" +checksum = "083be3061e64d362cbe6ef12cfe1307ba3884326d8856448fe8a120fa2c44ebf" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -3847,12 +5061,32 @@ name = "sync_wrapper" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-triple" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" +checksum = "c3a6bfce3d99adfa72d24750a61f782f3036a81e7f86d8841ee1326deaebd171" [[package]] name = "tempfile" @@ -3861,21 +5095,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.2", + "getrandom 0.4.3", "once_cell", "rustix", "windows-sys 0.61.2", ] -[[package]] -name = "term" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1" -dependencies = [ - "windows-sys 0.61.2", -] - [[package]] name = "termcolor" version = "1.4.1" @@ -3908,33 +5133,63 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "time-macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -3944,11 +5199,36 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinystr" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e27c91459209c2986af3dcf603a5a74a4368754ce37414f59acc971167f643" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" -version = "1.52.1" +version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ "bytes", "libc", @@ -3961,13 +5241,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.7.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.3", ] [[package]] @@ -3982,9 +5262,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b" dependencies = [ "futures-core", "pin-project-lite", @@ -3994,24 +5274,25 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" dependencies = [ "bytes", "futures-core", "futures-sink", + "libc", "pin-project-lite", "tokio", ] [[package]] name = "toml" -version = "1.1.2+spec-1.1.0" +version = "1.1.4+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +checksum = "3aace63f4bbcdfc2c965b059de67119c89c4017a70d633be6c104910f67056f5" dependencies = [ - "indexmap", + "indexmap 2.14.0", "serde_core", "serde_spanned", "toml_datetime", @@ -4029,26 +5310,38 @@ dependencies = [ "serde_core", ] +[[package]] +name = "toml_edit" +version = "0.25.13+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b" +dependencies = [ + "indexmap 2.14.0", + "toml_datetime", + "toml_parser", + "winnow", +] + [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ "winnow", ] [[package]] name = "toml_writer" -version = "1.1.1+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" [[package]] name = "tonic" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec" +checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" dependencies = [ "async-trait", "base64", @@ -4076,21 +5369,21 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1882ac3bf5ef12877d7ed57aad87e75154c11931c2ba7e6cde5e22d63522c734" +checksum = "c68f61875ac5293cf72e6c8cf0158086428c82c37229e98c840878f1706b0322" dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "tonic-health" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ff0636fef47afb3ec02818f5bceb4377b8abb9d6a386aeade18bd6212f8eb7" +checksum = "fcfab99db777fba2802f0dfa861d1628d1ae916fb199d29819941f139ae85082" dependencies = [ "prost", "tokio", @@ -4101,9 +5394,9 @@ dependencies = [ [[package]] name = "tonic-prost" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309" +checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" dependencies = [ "bytes", "prost", @@ -4112,16 +5405,16 @@ dependencies = [ [[package]] name = "tonic-prost-build" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3144df636917574672e93d0f56d7edec49f90305749c668df5101751bb8f95a" +checksum = "654e5643eff75d7f8c99197ce1440ed19a3474eada74c12bbac488b2cafdae27" dependencies = [ "prettyplease", "proc-macro2", "prost-build", "prost-types", "quote", - "syn 2.0.117", + "syn 2.0.119", "tempfile", "tonic-build", ] @@ -4159,7 +5452,7 @@ checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", - "indexmap", + "indexmap 2.14.0", "pin-project-lite", "slab", "sync_wrapper", @@ -4170,6 +5463,24 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "bitflags 2.13.1", + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "url", +] + [[package]] name = "tower-layer" version = "0.3.3" @@ -4201,7 +5512,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -4243,16 +5554,6 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "transpose" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" -dependencies = [ - "num-integer", - "strength_reduce", -] - [[package]] name = "try-lock" version = "0.2.5" @@ -4261,9 +5562,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" -version = "1.0.116" +version = "1.0.120" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c635f0191bd3a2941013e5062667100969f8c4e9cd787c14f977265d73616e" +checksum = "1e605bf6b39357663d8ba4e984f8be8da8df6bb32e81031d6889024ea8fd68e4" dependencies = [ "dissimilar", "glob", @@ -4283,15 +5584,33 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "ucd-trie" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "uint" -version = "0.10.0" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "uint" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909988d098b2f738727b161a106cfc7cab00c539c2687a8836f8e565976fb53e" +checksum = "6f9227a75a5a540a464c832ad4a4195dbdbecd8787610a56262721fde6f04f90" dependencies = [ "byteorder", "crunchy", @@ -4325,9 +5644,9 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-segmentation" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-width" @@ -4349,12 +5668,12 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" dependencies = [ - "crypto-common", - "subtle", + "crypto-common 0.2.2", + "ctutils", ] [[package]] @@ -4363,6 +5682,24 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -4371,11 +5708,11 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.1" +version = "1.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "2cefc03fd367c0c6d4305de1b312cf00248c4114f4a0418ce6a6af769e3b0bd9" dependencies = [ - "getrandom 0.4.2", + "getrandom 0.4.3", "js-sys", "serde_core", "wasm-bindgen", @@ -4444,27 +5781,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.3+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" -dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "wit-bindgen 0.51.0", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.118" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" dependencies = [ "cfg-if", "once_cell", @@ -4475,9 +5803,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.68" +version = "0.4.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" +checksum = "6b7777d5cc23d0e91404e53ce2d5e8ec7acae3026b16233dba62cd3246457950" dependencies = [ "js-sys", "wasm-bindgen", @@ -4485,9 +5813,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.118" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4495,48 +5823,26 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.118" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.118" +version = "0.2.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder", - "wasmparser", -] - [[package]] name = "wasm-streams" version = "0.5.0" @@ -4551,27 +5857,34 @@ dependencies = [ ] [[package]] -name = "wasmparser" -version = "0.244.0" +name = "web-sys" +version = "0.3.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +checksum = "c435338968042f4f59a557f690a253676d47ce13ceb55d70100e7facf6620a30" dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap", - "semver 1.0.28", + "js-sys", + "wasm-bindgen", ] [[package]] -name = "web-sys" -version = "0.3.95" +name = "web-time" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" dependencies = [ "js-sys", "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcd9d09a39985f5344844e66b0c530a33843579125f23e21e9f0f220850f22a" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi-util" version = "0.1.11" @@ -4581,6 +5894,18 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "wincode" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfc6339f1ba427bf7ad7c42403b28e524832ba2ddb5eef1bb2cc3b85db6b7b75" +dependencies = [ + "pastey", + "proc-macro2", + "quote", + "thiserror", +] + [[package]] name = "windows-core" version = "0.62.2" @@ -4602,7 +5927,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -4613,7 +5938,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -4724,142 +6049,174 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" +dependencies = [ + "memchr", +] [[package]] name = "wit-bindgen" -version = "0.51.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "wnaf" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab12e7090f27e2ffd9322651492942d50c2926094af30601e1964337db39daf1" dependencies = [ - "wit-bindgen-rust-macro", + "ff", + "group", + "hybrid-array", ] [[package]] -name = "wit-bindgen" -version = "0.57.1" +name = "writeable" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" +checksum = "3ad82d2a33cdc9674dc7465672f271e096168fcdbe0f799d9e6db8c5892679dc" [[package]] -name = "wit-bindgen-core" -version = "0.51.0" +name = "wyz" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" dependencies = [ - "anyhow", - "heck", - "wit-parser", + "tap", +] + +[[package]] +name = "x25519-dalek" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7e8131a03190127fb2263afc72b322ecadae46b6ff8c6f399ff5d02f5559af6" +dependencies = [ + "curve25519-dalek", + "rand_core 0.10.1", ] [[package]] -name = "wit-bindgen-rust" -version = "0.51.0" +name = "yoke" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +checksum = "709fe23a0424b6a435d82152b1bd3fdfb0833487d5fa90d05d42762a9891fef5" dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn 2.0.117", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", + "stable_deref_trait", + "yoke-derive", + "zerofrom", ] [[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" +name = "yoke-derive" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ - "anyhow", - "prettyplease", "proc-macro2", "quote", - "syn 2.0.117", - "wit-bindgen-core", - "wit-bindgen-rust", + "syn 2.0.119", + "synstructure", ] [[package]] -name = "wit-component" -version = "0.244.0" +name = "zerocopy" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" dependencies = [ - "anyhow", - "bitflags", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder", - "wasm-metadata", - "wasmparser", - "wit-parser", + "zerocopy-derive", ] [[package]] -name = "wit-parser" -version = "0.244.0" +name = "zerocopy-derive" +version = "0.8.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver 1.0.28", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser", + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] -name = "x25519-dalek" -version = "2.0.1" +name = "zerofrom" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ - "curve25519-dalek", - "rand_core 0.6.4", + "zerofrom-derive", ] [[package]] -name = "zerocopy" -version = "0.8.48" +name = "zerofrom-derive" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ - "zerocopy-derive", + "proc-macro2", + "quote", + "syn 2.0.119", + "synstructure", ] [[package]] -name = "zerocopy-derive" -version = "0.8.48" +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] -name = "zeroize" -version = "1.8.2" +name = "zerotrie" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea269c3bd32f0a32c321907a2ae912ba6f4649bb0fc764a15627e99a7095a3f" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0464e17806c1d976d5cba29399c7f08e516e279e2ba493f63123b5fca67dd8" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "34df6fc39dbd26ddc9c10e6a2984476e13acce22e64e4487636ef494369225da" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/rust-client/Cargo.toml b/rust-client/Cargo.toml index b1311c69..6c19896e 100644 --- a/rust-client/Cargo.toml +++ b/rust-client/Cargo.toml @@ -4,8 +4,16 @@ version = "0.1.0" edition = "2021" [dependencies] -miden-client = { version = "0.15", features = ["testing", "tonic"] } -miden-client-sqlite-store = { version = "0.15", package = "miden-client-sqlite-store" } -miden-protocol = { version = "0.15" } -rand = { version = "0.9" } +hex = "0.4" +miden-client = { version = "=0.16.0", features = ["testing", "tonic"] } +miden-client-sqlite-store = { version = "=0.16.0", package = "miden-client-sqlite-store" } +miden-protocol = { version = "=0.16.0" } +rand = { version = "0.10" } +reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } +serde = { version = "1", features = ["derive"] } +sha2 = "0.10" tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } + +# Local proving in an unoptimized build can outlive the network's historical-state window. +[profile.dev] +opt-level = 2 diff --git a/rust-client/src/bin/counter_contract_deploy.rs b/rust-client/src/bin/counter_contract_deploy.rs index 4557782e..93e672f0 100644 --- a/rust-client/src/bin/counter_contract_deploy.rs +++ b/rust-client/src/bin/counter_contract_deploy.rs @@ -1,27 +1,31 @@ -use rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; use miden_client::{ account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, - AccountType, StorageSlot, StorageSlotName, + component::{AccountComponentMetadata, BasicWallet}, + AccountBuilder, AccountComponent, AccountType, StorageSlot, StorageSlotName, }, - address::NetworkId, auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, - rpc::{Endpoint, GrpcClient}, + rpc::{GrpcClient, VerifyingRpcClient}, transaction::TransactionRequestBuilder, ClientError, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::{fund_account_for_fees, FeeConfig, TutorialNetwork}; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -33,12 +37,12 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; // ------------------------------------------------------------------------- // STEP 1: Create a basic counter contract @@ -75,7 +79,8 @@ async fn main() -> Result<(), ClientError> { let counter_contract = AccountBuilder::new(seed) .account_type(AccountType::Public) .with_component(counter_component.clone()) - .with_auth_component(NoAuth) + .with_component(BasicWallet) + .with_component(NoAuth) .build() .unwrap(); @@ -87,6 +92,7 @@ async fn main() -> Result<(), ClientError> { println!("counter_contract storage: {:?}", counter_contract.storage()); client.add_account(&counter_contract, false).await.unwrap(); + fund_account_for_fees(&mut client, counter_contract.id(), &fee_config).await?; // ------------------------------------------------------------------------- // STEP 2: Call the Counter Contract with a script @@ -113,18 +119,19 @@ async fn main() -> Result<(), ClientError> { // Execute and submit the transaction let tx_id = client - .submit_new_transaction(counter_contract.id(), tx_increment_request) + .submit_tutorial_transaction(counter_contract.id(), tx_increment_request) .await .unwrap(); println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); println!( "Counter contract id: {:?}", - counter_contract.id().to_bech32(NetworkId::Testnet) + counter_contract.id().to_bech32(network.network_id()) ); client.sync_state().await.unwrap(); @@ -139,6 +146,11 @@ async fn main() -> Result<(), ClientError> { "counter contract storage: {:?}", account.storage().get_item(&counter_slot_name) ); + assert_eq!( + account.storage().get_item(&counter_slot_name).unwrap()[0].as_canonical_u64(), + 1, + "the deployed counter must increment from zero to one", + ); Ok(()) } diff --git a/rust-client/src/bin/counter_contract_fpi.rs b/rust-client/src/bin/counter_contract_fpi.rs index ae58c75f..f58935a0 100644 --- a/rust-client/src/bin/counter_contract_fpi.rs +++ b/rust-client/src/bin/counter_contract_fpi.rs @@ -1,27 +1,32 @@ -use rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc, time::Duration}; use tokio::time::sleep; use miden_client::{ account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountId, - AccountType, StorageSlot, StorageSlotName, + component::{AccountComponentMetadata, BasicWallet}, + AccountBuilder, AccountComponent, AccountId, AccountType, StorageSlot, StorageSlotName, }, auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, - rpc::{domain::account::AccountStorageRequirements, Endpoint, GrpcClient}, + rpc::{domain::account::AccountStorageRequirements, GrpcClient, VerifyingRpcClient}, transaction::{ForeignAccount, TransactionRequestBuilder}, ClientError, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::{fund_account_for_fees, FeeConfig, TutorialNetwork}; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -33,12 +38,12 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; // ------------------------------------------------------------------------- // STEP 1: Create the Count Reader Contract @@ -74,7 +79,8 @@ async fn main() -> Result<(), ClientError> { let count_reader_contract = AccountBuilder::new(init_seed) .account_type(AccountType::Public) .with_component(count_reader_component.clone()) - .with_auth_component(NoAuth) + .with_component(BasicWallet) + .with_component(NoAuth) .build() .unwrap(); @@ -88,15 +94,26 @@ async fn main() -> Result<(), ClientError> { .add_account(&count_reader_contract, false) .await .unwrap(); + fund_account_for_fees(&mut client, count_reader_contract.id(), &fee_config).await?; // ------------------------------------------------------------------------- // STEP 2: Build & Get State of the Counter Contract // ------------------------------------------------------------------------- println!("\n[STEP 2] Building counter contract from public state"); - // Define the Counter Contract account id from counter contract deploy - let (_, counter_contract_id) = - AccountId::from_bech32("mtst1apcqs7aj3a2cf5t6pnsfy0p4ns7wl7sp").unwrap(); + // Pass the account ID printed by `counter_contract_deploy` as the first argument, or via + // `MIDEN_COUNTER_ACCOUNT_ID`. + let counter_contract_bech32 = std::env::args() + .nth(1) + .or_else(|| std::env::var("MIDEN_COUNTER_ACCOUNT_ID").ok()) + .expect("pass the counter account ID from counter_contract_deploy"); + let (account_network, counter_contract_id) = + AccountId::from_bech32(&counter_contract_bech32).expect("invalid counter account ID"); + assert_eq!( + account_network, + network.network_id(), + "counter account must match the selected tutorial network" + ); println!("counter contract id: {:?}", counter_contract_id); @@ -137,7 +154,6 @@ async fn main() -> Result<(), ClientError> { let get_count_root = counter_component .component_code() - .as_library() .get_procedure_root_by_path("external_contract::counter_contract::get_count") .expect("get_count export not found"); let get_count_hash = format!("{}", get_count_root); @@ -161,14 +177,16 @@ async fn main() -> Result<(), ClientError> { // that compiles the script. let tx_script = client .code_builder() - .with_linked_module("external_contract::count_reader_contract", count_reader_code) + .with_linked_module( + "external_contract::count_reader_contract", + count_reader_code, + ) .unwrap() .compile_tx_script(script_code.as_str()) .unwrap(); let foreign_account = - ForeignAccount::public(counter_contract_id, AccountStorageRequirements::default()) - .unwrap(); + ForeignAccount::public(counter_contract_id, AccountStorageRequirements::default()).unwrap(); let tx_request = TransactionRequestBuilder::new() .foreign_accounts([foreign_account]) @@ -177,12 +195,13 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let tx_id = client - .submit_new_transaction(count_reader_contract.id(), tx_request) + .submit_tutorial_transaction(count_reader_contract.id(), tx_request) .await .unwrap(); println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); @@ -212,6 +231,14 @@ async fn main() -> Result<(), ClientError> { "count reader contract storage: {:?}", account_2.storage().get_item(&count_reader_slot_name) ); + assert_eq!( + account_2 + .storage() + .get_item(&count_reader_slot_name) + .unwrap(), + account_1.storage().get_item(&counter_slot_name).unwrap(), + "FPI must copy the current counter value", + ); Ok(()) } diff --git a/rust-client/src/bin/counter_contract_increment.rs b/rust-client/src/bin/counter_contract_increment.rs index ec008a45..a1a0f95e 100644 --- a/rust-client/src/bin/counter_contract_increment.rs +++ b/rust-client/src/bin/counter_contract_increment.rs @@ -1,21 +1,26 @@ +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; use miden_client::{ account::{AccountId, StorageSlotName}, builder::ClientBuilder, keystore::FilesystemKeyStore, - rpc::{Endpoint, GrpcClient}, + rpc::{GrpcClient, VerifyingRpcClient}, transaction::TransactionRequestBuilder, ClientError, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::TutorialNetwork; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -27,7 +32,6 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; @@ -39,9 +43,19 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 1] Reading data from public state"); - // Define the Counter Contract account id from counter contract deploy - let (_, counter_contract_id) = - AccountId::from_bech32("mtst1apcqs7aj3a2cf5t6pnsfy0p4ns7wl7sp").unwrap(); + // Pass the account ID printed by `counter_contract_deploy` as the first argument, or via + // `MIDEN_COUNTER_ACCOUNT_ID`. + let counter_contract_bech32 = std::env::args() + .nth(1) + .or_else(|| std::env::var("MIDEN_COUNTER_ACCOUNT_ID").ok()) + .expect("pass the counter account ID from counter_contract_deploy"); + let (account_network, counter_contract_id) = + AccountId::from_bech32(&counter_contract_bech32).expect("invalid counter account ID"); + assert_eq!( + account_network, + network.network_id(), + "counter account must match the selected tutorial network" + ); client .import_account_by_id(counter_contract_id) @@ -57,6 +71,12 @@ async fn main() -> Result<(), ClientError> { "Account details: {:?}", counter_contract.storage().slots().first().unwrap() ); + let counter_slot_name = + StorageSlotName::new("miden::tutorials::counter").expect("valid slot name"); + let count_before = counter_contract + .storage() + .get_item(&counter_slot_name) + .unwrap()[0]; // ------------------------------------------------------------------------- // STEP 2: Call the Counter Contract with a script @@ -85,12 +105,13 @@ async fn main() -> Result<(), ClientError> { // Execute and submit the transaction let tx_id = client - .submit_new_transaction(counter_contract_id, tx_increment_request) + .submit_tutorial_transaction(counter_contract_id, tx_increment_request) .await .unwrap(); println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); @@ -102,11 +123,14 @@ async fn main() -> Result<(), ClientError> { .await .unwrap() .expect("counter contract not found"); - let counter_slot_name = - StorageSlotName::new("miden::tutorials::counter").expect("valid slot name"); println!( "counter contract storage: {:?}", account.storage().get_item(&counter_slot_name) ); + assert_eq!( + account.storage().get_item(&counter_slot_name).unwrap()[0], + count_before + miden_client::ONE, + "the imported counter must increment exactly once", + ); Ok(()) } diff --git a/rust-client/src/bin/create_mint_consume_send.rs b/rust-client/src/bin/create_mint_consume_send.rs index 924d15f3..4febea46 100644 --- a/rust-client/src/bin/create_mint_consume_send.rs +++ b/rust-client/src/bin/create_mint_consume_send.rs @@ -1,34 +1,38 @@ -use rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; use tokio::time::Duration; use miden_client::{ account::{ component::{ - BasicWallet, BurnPolicyConfig, FungibleFaucet, MintPolicyConfig, PolicyRegistration, - TokenName, TokenPolicyManager, + create_singlesig_user_fungible_faucet, BasicWallet, BurnPolicy, FungibleFaucet, + MintPolicy, TokenName, TokenPolicyManager, }, AccountBuilder, AccountId, AccountType, }, - address::NetworkId, - asset::{AssetAmount, FungibleAsset, TokenSymbol}, - auth::{AuthSchemeId, AuthSecretKey, AuthSingleSig}, + asset::{AssetAmount, AssetCallbackFlag, AssetId, FungibleAsset, TokenSymbol}, + auth::{AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, keystore::{FilesystemKeyStore, Keystore}, - note::{NoteAttachments, NoteType, P2idNote}, - rpc::{Endpoint, GrpcClient}, - transaction::TransactionRequestBuilder, + note::{Note, NoteType, P2idNote}, + rpc::{GrpcClient, VerifyingRpcClient}, + transaction::{PaymentNoteDescription, TransactionRequestBuilder}, ClientError, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; use miden_protocol::account::AccountIdVersion; +use rust_client::{fund_account_for_fees, FeeConfig, TutorialNetwork}; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -40,12 +44,12 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; //------------------------------------------------------------ // STEP 1: Create a basic wallet for Alice @@ -61,7 +65,7 @@ async fn main() -> Result<(), ClientError> { // Build the account let alice_account = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet) .build() .unwrap(); @@ -70,11 +74,16 @@ async fn main() -> Result<(), ClientError> { client.add_account(&alice_account, false).await?; // Add the key pair to the keystore - keystore.add_key(&key_pair, alice_account.id()).await.unwrap(); + keystore + .add_key(&key_pair, alice_account.id()) + .await + .unwrap(); - let alice_account_id_bech32 = alice_account.id().to_bech32(NetworkId::Testnet); + let alice_account_id_bech32 = alice_account.id().to_bech32(network.network_id()); println!("Alice's account ID: {:?}", alice_account_id_bech32); + fund_account_for_fees(&mut client, alice_account.id(), &fee_config).await?; + //------------------------------------------------------------ // STEP 2: Deploy a fungible faucet //------------------------------------------------------------ @@ -93,40 +102,44 @@ async fn main() -> Result<(), ClientError> { let key_pair = AuthSecretKey::new_falcon512_poseidon2_with_rng(client.rng()); // Build the faucet account. - // In v0.15 the faucet is a `FungibleFaucet` component plus a `TokenPolicyManager` + // The faucet is a `FungibleFaucet` component plus a `TokenPolicyManager` // that registers an "allow all" mint (and burn) policy; minting is rejected // unless an active mint policy is present. - let faucet_account = AccountBuilder::new(init_seed) - .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) - .with_component( - FungibleFaucet::builder() - .name(TokenName::new("MID").unwrap()) - .symbol(symbol) - .decimals(decimals) - .max_supply(max_supply) - .build() - .unwrap(), - ) - .with_components( - TokenPolicyManager::new() - .with_mint_policy(MintPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap() - .with_burn_policy(BurnPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap(), - ) + let faucet = FungibleFaucet::builder() + .name(TokenName::new("MID").unwrap()) + .symbol(symbol) + .decimals(decimals) + .max_supply(max_supply) .build() .unwrap(); + let policies = TokenPolicyManager::builder() + .active_mint_policy(MintPolicy::allow_all()) + .active_burn_policy(BurnPolicy::allow_all()) + .build(); + // The SDK factory includes BasicWallet so the faucet can receive the native fee asset. + let faucet_account = create_singlesig_user_fungible_faucet( + init_seed, + faucet, + AuthSingleSig::from_public_key(key_pair.public_key()), + policies, + AccountType::Public, + ) + .unwrap(); // Add the faucet to the client client.add_account(&faucet_account, false).await?; // Add the key pair to the keystore - keystore.add_key(&key_pair, faucet_account.id()).await.unwrap(); + keystore + .add_key(&key_pair, faucet_account.id()) + .await + .unwrap(); - let faucet_account_id_bech32 = faucet_account.id().to_bech32(NetworkId::Testnet); + let faucet_account_id_bech32 = faucet_account.id().to_bech32(network.network_id()); println!("Faucet account ID: {:?}", faucet_account_id_bech32); + fund_account_for_fees(&mut client, faucet_account.id(), &fee_config).await?; + // Resync to show newly deployed faucet client.sync_state().await?; tokio::time::sleep(Duration::from_secs(2)).await; @@ -139,6 +152,7 @@ async fn main() -> Result<(), ClientError> { let amount: u64 = 100; let fungible_asset = FungibleAsset::new(faucet_account.id(), amount).unwrap(); + let mut minted_note_ids = Vec::new(); for i in 1..=5 { let transaction_request = TransactionRequestBuilder::new() .build_mint_fungible_asset( @@ -149,10 +163,16 @@ async fn main() -> Result<(), ClientError> { ) .unwrap(); + minted_note_ids.extend( + transaction_request + .expected_output_own_notes() + .iter() + .map(Note::id), + ); println!("tx request built"); let tx_id = client - .submit_new_transaction(faucet_account.id(), transaction_request) + .submit_tutorial_transaction(faucet_account.id(), transaction_request) .await?; println!( "Minted note #{} of {} tokens for Alice. TX: {:?}", @@ -169,40 +189,17 @@ async fn main() -> Result<(), ClientError> { //------------------------------------------------------------ println!("\n[STEP 4] Alice will now consume all of her notes to consolidate them."); - // Consume all minted notes in a single transaction - loop { - // Resync to get the latest data - client.sync_state().await?; - - let consumable_notes = client - .get_consumable_notes(Some(alice_account.id())) - .await?; - let notes = consumable_notes - .iter() - .map(|(note, _)| note.clone().try_into()) - .collect::, _>>()?; - - if notes.len() == 5 { - println!("Found 5 consumable notes for Alice. Consuming them now..."); - let transaction_request = - TransactionRequestBuilder::new().build_consume_notes(notes)?; - - let tx_id = client - .submit_new_transaction(alice_account.id(), transaction_request) - .await?; - println!( - "All of Alice's notes consumed successfully. TX: {:?}", - tx_id - ); - break; - } else { - println!( - "Currently, Alice has {} consumable notes. Waiting...", - notes.len() - ); - tokio::time::sleep(Duration::from_secs(3)).await; - } - } + // TX_FEE notes are also consumable. Select only the five P2ID notes we minted. + let notes = rust_client::wait_for_notes_by_id(&mut client, &minted_note_ids).await?; + assert_eq!(notes.len(), 5); + let transaction_request = TransactionRequestBuilder::new().build_consume_notes(notes)?; + let tx_id = client + .submit_tutorial_transaction(alice_account.id(), transaction_request) + .await?; + println!( + "All of Alice's notes consumed successfully. TX: {:?}", + tx_id + ); //------------------------------------------------------------ // STEP 5: Alice sends 5 notes of 50 tokens to 5 users @@ -224,19 +221,20 @@ async fn main() -> Result<(), ClientError> { init_seed, AccountIdVersion::Version1, AccountType::Public, + AssetCallbackFlag::Disabled, ); let send_amount = 50; let fungible_asset = FungibleAsset::new(faucet_account.id(), send_amount).unwrap(); - let p2id_note = P2idNote::create( - alice_account.id(), - target_account_id, - vec![fungible_asset.into()], - NoteType::Public, - NoteAttachments::empty(), - client.rng(), - )?; + let p2id_note: Note = P2idNote::builder() + .sender(alice_account.id()) + .target(target_account_id) + .asset(fungible_asset) + .note_type(NoteType::Public) + .generate_serial_number(client.rng()) + .build()? + .into(); p2id_notes.push(p2id_note); } @@ -248,7 +246,7 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let tx_id = client - .submit_new_transaction(alice_account.id(), transaction_request) + .submit_tutorial_transaction(alice_account.id(), transaction_request) .await?; println!("Submitted a transaction with 4 P2ID notes. TX: {:?}", tx_id); @@ -263,30 +261,36 @@ async fn main() -> Result<(), ClientError> { init_seed, AccountIdVersion::Version1, AccountType::Public, + AssetCallbackFlag::Disabled, ); let send_amount = 50; let fungible_asset = FungibleAsset::new(faucet_account.id(), send_amount).unwrap(); - let p2id_note = P2idNote::create( + let payment = PaymentNoteDescription::new( + vec![fungible_asset.into()], alice_account.id(), target_account_id, - vec![fungible_asset.into()], + ); + let transaction_request = TransactionRequestBuilder::new().build_pay_to_id( + payment, NoteType::Public, - NoteAttachments::empty(), client.rng(), )?; - let transaction_request = TransactionRequestBuilder::new() - .own_output_notes(vec![p2id_note]) - .build() - .unwrap(); - let tx_id = client - .submit_new_transaction(alice_account.id(), transaction_request) + .submit_tutorial_transaction(alice_account.id(), transaction_request) .await?; println!("Submitted final P2ID transaction. TX: {:?}", tx_id); + let alice = client + .get_account(alice_account.id()) + .await? + .expect("Alice exists"); + let balance = alice + .vault() + .get_balance(AssetId::new_fungible(faucet_account.id()))?; + assert_eq!(balance.as_u64(), 250, "Alice should retain 500 - 250 MID"); println!("\nAll steps completed successfully!"); println!("Alice created a wallet, a faucet was deployed,"); diff --git a/rust-client/src/bin/delegated_prover.rs b/rust-client/src/bin/delegated_prover.rs index ea4d3e66..84b4c651 100644 --- a/rust-client/src/bin/delegated_prover.rs +++ b/rust-client/src/bin/delegated_prover.rs @@ -1,23 +1,27 @@ -use rand::RngCore; +use rand::Rng; use std::{path::PathBuf, sync::Arc}; use miden_client::{ account::{component::BasicWallet, AccountBuilder, AccountType}, - auth::{AuthSchemeId, AuthSecretKey, AuthSingleSig}, + auth::{AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, keystore::{FilesystemKeyStore, Keystore}, - rpc::{Endpoint, GrpcClient}, + rpc::{GrpcClient, VerifyingRpcClient}, transaction::{TransactionProver, TransactionRequestBuilder}, ClientError, RemoteTransactionProver, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::{fund_account_for_fees, FeeConfig, TutorialNetwork}; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -29,12 +33,12 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; // Create Alice's account let mut init_seed = [0_u8; 32]; @@ -44,29 +48,37 @@ async fn main() -> Result<(), ClientError> { let alice_account = AccountBuilder::new(init_seed) .account_type(AccountType::Private) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet) .build() .unwrap(); client.add_account(&alice_account, false).await?; - keystore.add_key(&key_pair, alice_account.id()).await.unwrap(); + keystore + .add_key(&key_pair, alice_account.id()) + .await + .unwrap(); + fund_account_for_fees(&mut client, alice_account.id(), &fee_config).await?; // ------------------------------------------------------------------------- // Set up the delegated (remote) tx prover // ------------------------------------------------------------------------- // Delegated proving outsources ZK proof generation to a remote service. This is - // the public Miden testnet prover; run your own + // the public prover for the selected network; run your own // (https://crates.io/crates/miden-remote-prover) and swap the URL to use it. - // The constant `miden_client::grpc_support::TESTNET_PROVER_ENDPOINT` holds this - // same URL. - let remote_tx_prover = RemoteTransactionProver::new("https://tx-prover.testnet.miden.io"); + // The upstream constant keeps this URL synchronized with the selected network. + let remote_tx_prover = RemoteTransactionProver::new(network.remote_prover_url()); let tx_prover: Arc = Arc::new(remote_tx_prover); // We use a dummy transaction request to showcase delegated proving. - // The only effect of this tx should be increasing Alice's nonce. - println!("Alice nonce initial: {:?}", alice_account.nonce()); - let script_code = "begin push.1 drop end"; + // In addition to paying the network fee, this transaction increments Alice's nonce. + let initial_nonce = client + .get_account(alice_account.id()) + .await? + .expect("Alice exists") + .nonce(); + println!("Alice nonce initial: {:?}", initial_nonce); + let script_code = "@transaction_script pub proc main push.1 drop end"; let tx_script = client .code_builder() .compile_tx_script(script_code) @@ -79,6 +91,7 @@ async fn main() -> Result<(), ClientError> { // Step 1: Execute the transaction locally println!("Executing transaction..."); + client.sync_state().await?; let tx_result = client .execute_transaction(alice_account.id(), transaction_request) .await?; @@ -97,6 +110,7 @@ async fn main() -> Result<(), ClientError> { client .apply_transaction(&tx_result, submission_height) .await?; + rust_client::wait_for_transaction(&mut client, tx_result.id()).await?; println!("Transaction submitted successfully using the delegated prover!"); @@ -109,6 +123,7 @@ async fn main() -> Result<(), ClientError> { .expect("alice account not found"); println!("Alice nonce has increased: {:?}", account.nonce()); + assert_eq!(account.nonce(), initial_nonce + miden_client::Felt::ONE); Ok(()) } diff --git a/rust-client/src/bin/hash_preimage_note.rs b/rust-client/src/bin/hash_preimage_note.rs index 1385cb1e..30746e47 100644 --- a/rust-client/src/bin/hash_preimage_note.rs +++ b/rust-client/src/bin/hash_preimage_note.rs @@ -1,29 +1,28 @@ -use rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; -use tokio::time::{sleep, Duration}; use miden_client::{ account::{ component::{ - BasicWallet, BurnPolicyConfig, FungibleFaucet, MintPolicyConfig, PolicyRegistration, - TokenName, TokenPolicyManager, + create_singlesig_user_fungible_faucet, BasicWallet, BurnPolicy, FungibleFaucet, + MintPolicy, TokenName, TokenPolicyManager, }, Account, AccountBuilder, AccountType, }, - address::NetworkId, - asset::{AssetAmount, FungibleAsset, TokenSymbol}, - auth::{AuthSchemeId, AuthSecretKey, AuthSingleSig}, + asset::{AssetAmount, AssetId, FungibleAsset, TokenSymbol}, + auth::{AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, crypto::FeltRng, keystore::{FilesystemKeyStore, Keystore}, note::{Note, NoteAssets, NoteRecipient, NoteStorage, NoteTag, NoteType, PartialNoteMetadata}, - rpc::{Endpoint, GrpcClient}, - store::TransactionFilter, - transaction::{TransactionId, TransactionRequestBuilder, TransactionStatus}, + rpc::{GrpcClient, VerifyingRpcClient}, + transaction::{TransactionId, TransactionRequestBuilder}, Client, ClientError, Felt, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; use miden_protocol::Hasher; +use rust_client::{fund_account_for_fees, FeeConfig, TutorialNetwork}; // Helper to create a basic account async fn create_basic_account( @@ -37,7 +36,7 @@ async fn create_basic_account( let account = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet) .build() .unwrap(); @@ -60,27 +59,25 @@ async fn create_basic_faucet( let decimals = 8; let max_supply = AssetAmount::new(1_000_000).unwrap(); - let account = AccountBuilder::new(init_seed) - .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) - .with_component( - FungibleFaucet::builder() - .name(TokenName::new("MID").unwrap()) - .symbol(symbol) - .decimals(decimals) - .max_supply(max_supply) - .build() - .unwrap(), - ) - .with_components( - TokenPolicyManager::new() - .with_mint_policy(MintPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap() - .with_burn_policy(BurnPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap(), - ) + let faucet = FungibleFaucet::builder() + .name(TokenName::new("MID").unwrap()) + .symbol(symbol) + .decimals(decimals) + .max_supply(max_supply) .build() .unwrap(); + let policies = TokenPolicyManager::builder() + .active_mint_policy(MintPolicy::allow_all()) + .active_burn_policy(BurnPolicy::allow_all()) + .build(); + let account = create_singlesig_user_fungible_faucet( + init_seed, + faucet, + AuthSingleSig::from_public_key(key_pair.public_key()), + policies, + AccountType::Public, + ) + .unwrap(); client.add_account(&account, false).await?; keystore.add_key(&key_pair, account.id()).await.unwrap(); @@ -93,39 +90,18 @@ async fn wait_for_tx( client: &mut Client, tx_id: TransactionId, ) -> Result<(), ClientError> { - loop { - client.sync_state().await?; - - // Check transaction status - let txs = client - .get_transactions(TransactionFilter::Ids(vec![tx_id])) - .await?; - let tx_committed = if !txs.is_empty() { - matches!(txs[0].status, TransactionStatus::Committed { .. }) - } else { - false - }; - - if tx_committed { - println!("✅ transaction {} committed", tx_id.to_hex()); - break; - } - - println!( - "Transaction {} not yet committed. Waiting...", - tx_id.to_hex() - ); - sleep(Duration::from_secs(2)).await; - } - Ok(()) + rust_client::wait_for_transaction(client, tx_id).await } #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -137,12 +113,12 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; // ------------------------------------------------------------------------- // STEP 1: Create accounts and deploy faucet @@ -151,20 +127,23 @@ async fn main() -> Result<(), ClientError> { let alice_account = create_basic_account(&mut client, &keystore).await?; println!( "Alice's account ID: {:?}", - alice_account.id().to_bech32(NetworkId::Testnet) + alice_account.id().to_bech32(network.network_id()) ); let bob_account = create_basic_account(&mut client, &keystore).await?; println!( "Bob's account ID: {:?}", - bob_account.id().to_bech32(NetworkId::Testnet) + bob_account.id().to_bech32(network.network_id()) ); println!("\nDeploying a new fungible faucet."); let faucet = create_basic_faucet(&mut client, &keystore).await?; println!( "Faucet account ID: {:?}", - faucet.id().to_bech32(NetworkId::Testnet) + faucet.id().to_bech32(network.network_id()) ); + for account_id in [alice_account.id(), bob_account.id(), faucet.id()] { + fund_account_for_fees(&mut client, account_id, &fee_config).await?; + } client.sync_state().await?; // ------------------------------------------------------------------------- @@ -184,7 +163,7 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let tx_id = client - .submit_new_transaction(faucet.id(), tx_request) + .submit_tutorial_transaction(faucet.id(), tx_request) .await?; println!("Minted tokens. TX: {:?}", tx_id); @@ -194,7 +173,7 @@ async fn main() -> Result<(), ClientError> { // Consume the minted note let consumable_notes = client - .get_consumable_notes(Some(alice_account.id())) + .get_consumable_tutorial_notes(Some(alice_account.id())) .await?; if let Some((note_record, _)) = consumable_notes.first() { @@ -202,7 +181,7 @@ async fn main() -> Result<(), ClientError> { let consume_request = TransactionRequestBuilder::new().build_consume_notes(vec![note])?; let tx_id = client - .submit_new_transaction(alice_account.id(), consume_request) + .submit_tutorial_transaction(alice_account.id(), consume_request) .await?; println!("Consumed minted note. TX: {:?}", tx_id); } @@ -213,7 +192,12 @@ async fn main() -> Result<(), ClientError> { // STEP 3: Create custom note // ------------------------------------------------------------------------- println!("\n[STEP 3] Create custom note"); - let secret_vals = vec![Felt::new_unchecked(1), Felt::new_unchecked(2), Felt::new_unchecked(3), Felt::new_unchecked(4)]; + let secret_vals = vec![ + Felt::new_unchecked(1), + Felt::new_unchecked(2), + Felt::new_unchecked(3), + Felt::new_unchecked(4), + ]; let digest = Hasher::hash_elements(&secret_vals); println!("digest: {:?}", digest); @@ -237,10 +221,11 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let tx_id = client - .submit_new_transaction(alice_account.id(), note_request) + .submit_tutorial_transaction(alice_account.id(), note_request) .await?; println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); @@ -251,21 +236,39 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- println!("\n[STEP 4] Bob consumes the Custom Note with Correct Secret"); - let secret = [Felt::new_unchecked(1), Felt::new_unchecked(2), Felt::new_unchecked(3), Felt::new_unchecked(4)]; + let secret = [ + Felt::new_unchecked(1), + Felt::new_unchecked(2), + Felt::new_unchecked(3), + Felt::new_unchecked(4), + ]; let consume_custom_request = TransactionRequestBuilder::new() .input_notes([(custom_note, Some(secret.into()))]) .build() .unwrap(); let tx_id = client - .submit_new_transaction(bob_account.id(), consume_custom_request) + .submit_tutorial_transaction(bob_account.id(), consume_custom_request) .await?; println!( - "Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/{:?} \n", + "Consumed Note Tx on MidenScan: {}/tx/{:?} \n", + network.explorer_url(), tx_id ); wait_for_tx(&mut client, tx_id).await?; + let bob = client + .get_account(bob_account.id()) + .await? + .expect("Bob's account must exist after consuming the note"); + let balance = bob.vault().get_balance(AssetId::new_fungible(faucet_id))?; + assert_eq!( + balance.as_u64(), + amount, + "Bob must receive all assets from the hash-preimage note", + ); + println!("Bob's custom-note token balance: {balance}"); + Ok(()) } diff --git a/rust-client/src/bin/mapping_example.rs b/rust-client/src/bin/mapping_example.rs index 036f7e3d..e2372ad8 100644 --- a/rust-client/src/bin/mapping_example.rs +++ b/rust-client/src/bin/mapping_example.rs @@ -1,26 +1,32 @@ -use rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; use miden_client::{ account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, - AccountType, StorageMap, StorageSlot, StorageSlotName, + component::{AccountComponentMetadata, BasicWallet}, + AccountBuilder, AccountComponent, AccountType, StorageMap, StorageMapKey, StorageSlot, + StorageSlotName, }, auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, - rpc::{Endpoint, GrpcClient}, + rpc::{GrpcClient, VerifyingRpcClient}, transaction::TransactionRequestBuilder, - ClientError, Felt, Word, + ClientError, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::{fund_account_for_fees, FeeConfig, TutorialNetwork}; #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -32,29 +38,23 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; // ------------------------------------------------------------------------- // STEP 1: Deploy a smart contract with a mapping // ------------------------------------------------------------------------- println!("\n[STEP 1] Deploy a smart contract with a mapping"); - // Load the MASM file for the counter contract. `include_str!` resolves at + // Load the MASM file for the mapping 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 - let empty_slot_name = - StorageSlotName::new("miden::tutorials::mapping::value").expect("valid slot name"); - let empty_storage_slot = StorageSlot::with_value(empty_slot_name.clone(), Word::default()); - - // initialize storage map + // Storage slots are named in v0.16; the component only needs its mapping slot. let storage_map = StorageMap::new(); let map_slot_name = StorageSlotName::new("miden::tutorials::mapping::map").expect("valid slot name"); @@ -67,7 +67,7 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let mapping_contract_component = AccountComponent::new( component_code, - vec![empty_storage_slot, storage_slot_map], + vec![storage_slot_map], AccountComponentMetadata::new("miden_by_example::mapping_example_contract"), ) .unwrap(); @@ -80,7 +80,8 @@ async fn main() -> Result<(), ClientError> { let mapping_example_contract = AccountBuilder::new(init_seed) .account_type(AccountType::Public) .with_component(mapping_contract_component.clone()) - .with_auth_component(NoAuth) + .with_component(BasicWallet) + .with_component(NoAuth) .build() .unwrap(); @@ -88,6 +89,7 @@ async fn main() -> Result<(), ClientError> { .add_account(&mapping_example_contract, false) .await .unwrap(); + fund_account_for_fees(&mut client, mapping_example_contract.id(), &fee_config).await?; // ------------------------------------------------------------------------- // STEP 2: Call the Mapping Contract with a Script @@ -113,12 +115,13 @@ async fn main() -> Result<(), ClientError> { // Execute and submit the transaction let tx_id = client - .submit_new_transaction(mapping_example_contract.id(), tx_increment_request) + .submit_tutorial_transaction(mapping_example_contract.id(), tx_increment_request) .await .unwrap(); println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); @@ -129,19 +132,22 @@ async fn main() -> Result<(), ClientError> { .await .unwrap() .expect("mapping contract not found"); - let key = [ - Felt::new_unchecked(0), - Felt::new_unchecked(0), - Felt::new_unchecked(0), - Felt::new_unchecked(0), - ] - .into(); + let key = StorageMapKey::empty(); println!( "Mapping state\n Index: {:?}\n Key: {:?}\n Value: {:?}", map_slot_name, key, account.storage().get_map_item(&map_slot_name, key) ); + let value = account.storage().get_map_item(&map_slot_name, key).unwrap(); + assert_eq!( + value + .iter() + .map(|felt| felt.as_canonical_u64()) + .collect::>(), + vec![4, 3, 2, 1], + "the mapping must store the value written by the transaction script", + ); Ok(()) } diff --git a/rust-client/src/bin/network_notes_counter_contract.rs b/rust-client/src/bin/network_notes_counter_contract.rs index b48a51a5..9e6e8464 100644 --- a/rust-client/src/bin/network_notes_counter_contract.rs +++ b/rust-client/src/bin/network_notes_counter_contract.rs @@ -1,28 +1,30 @@ +use rust_client::TutorialClientExt; use std::{collections::BTreeSet, path::PathBuf, sync::Arc}; use miden_client::{ account::{ - component::{AccountComponentMetadata, AuthNetworkAccount, BasicWallet}, AccountBuilder, AccountComponent, - AccountType, StorageSlot, StorageSlotName, + component::{ + AccountComponentMetadata, AuthNetworkAccount, BasicConstantFeePolicy, BasicWallet, + FeePolicy, FeePolicyManager, + }, + AccountBuilder, AccountComponent, AccountType, StorageSlot, StorageSlotName, }, - address::NetworkId, - auth::{AuthSchemeId, AuthSecretKey, AuthSingleSig}, + asset::AssetAmount, + auth::{AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, crypto::FeltRng, keystore::{FilesystemKeyStore, Keystore}, note::{ NetworkAccountTarget, Note, NoteAssets, NoteAttachments, NoteError, NoteExecutionHint, - NoteRecipient, NoteStorage, NoteTag, NoteType, PartialNoteMetadata, - }, - rpc::{Endpoint, GrpcClient}, - store::TransactionFilter, - transaction::{ - TransactionId, TransactionRequestBuilder, TransactionStatus, + NoteRecipient, NoteStorage, NoteTag, NoteType, P2idNote, PartialNoteMetadata, }, + rpc::{GrpcClient, VerifyingRpcClient}, + transaction::{ExpirationTransactionScript, TransactionId, TransactionRequestBuilder}, Client, ClientError, Felt, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -use rand::RngCore; +use rand::Rng; +use rust_client::{fund_account_for_fees, FeeConfig, TutorialNetwork}; use tokio::time::{sleep, Duration}; /// Waits for a specific transaction to be committed. @@ -30,39 +32,18 @@ async fn wait_for_tx( client: &mut Client, tx_id: TransactionId, ) -> Result<(), ClientError> { - loop { - client.sync_state().await?; - - // Check transaction status - let txs = client - .get_transactions(TransactionFilter::Ids(vec![tx_id])) - .await?; - let tx_committed = if !txs.is_empty() { - matches!(txs[0].status, TransactionStatus::Committed { .. }) - } else { - false - }; - - if tx_committed { - println!("✅ transaction {} committed", tx_id.to_hex()); - break; - } - - println!( - "Transaction {} not yet committed. Waiting...", - tx_id.to_hex() - ); - sleep(Duration::from_secs(2)).await; - } - Ok(()) + rust_client::wait_for_transaction(client, tx_id).await } #[tokio::main] async fn main() -> Result<(), Box> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -74,12 +55,13 @@ async fn main() -> Result<(), Box> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; + let fee_faucet_id = fee_config.native_fee_faucet_id(); // ------------------------------------------------------------------------- // STEP 1: Create Basic User Account @@ -95,7 +77,7 @@ async fn main() -> Result<(), Box> { // Build the account let alice_account = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet) .build() .unwrap(); @@ -104,11 +86,15 @@ async fn main() -> Result<(), Box> { client.add_account(&alice_account, false).await?; // Add the key pair to the keystore - keystore.add_key(&key_pair, alice_account.id()).await.unwrap(); + keystore + .add_key(&key_pair, alice_account.id()) + .await + .unwrap(); + fund_account_for_fees(&mut client, alice_account.id(), &fee_config).await?; println!( "Alice's account ID: {:?}", - alice_account.id().to_bech32(NetworkId::Testnet) + alice_account.id().to_bech32(network.network_id()) ); // ------------------------------------------------------------------------- @@ -119,35 +105,19 @@ async fn main() -> Result<(), Box> { // `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"); - let script_code = include_str!("../../../masm/scripts/counter_script.masm"); let network_note_code = include_str!("../../../masm/notes/network_increment_note.masm"); - // In protocol v0.15 an account is a *network account* (one the network + // An account is a *network account* (one the network // transaction builder executes on a user's behalf) if and only if it is // public AND carries the `AuthNetworkAccount` auth component. That component - // holds two allowlists, both fixed at account creation: - // * the note-script allowlist: its presence is what marks the account as a - // network account, and the builder only executes notes whose script root - // is listed here; - // * the tx-script allowlist: the network auth procedure rejects any custom - // tx script whose root is not listed, so the STEP 3 deploy script must be - // in it. - // We therefore compile the note script and the deploy tx script now and feed - // their MAST roots into the allowlists below. Both compiled scripts are reused - // as-is in STEP 3 (tx script) and STEP 4 (note script) — nothing is compiled - // twice. + // holds an allowlist of note scripts the network builder may execute. + // Compile the increment note first so its root can be included at creation. let note_script = client .code_builder() .with_linked_module("external_contract::counter_contract", counter_code)? .compile_note_script(network_note_code)?; let note_script_root = note_script.root(); - let tx_script = client - .code_builder() - .with_linked_module("external_contract::counter_contract", counter_code)? - .compile_tx_script(script_code)?; - let tx_script_root = tx_script.root(); - // Compile the counter MASM into an account component let counter_slot_name = StorageSlotName::new("miden::tutorials::counter").expect("valid slot name"); @@ -167,49 +137,56 @@ async fn main() -> Result<(), Box> { let mut init_seed = [0_u8; 32]; client.rng().fill_bytes(&mut init_seed); - // Build the network account: public + `AuthNetworkAccount` with the note-script - // root allowlisted (this is what makes it a network account) and the deploy - // tx-script root allowlisted (so the auth procedure accepts the STEP 3 deploy). - let network_auth = AuthNetworkAccount::with_allowed_notes(BTreeSet::from([note_script_root]))? - .with_allowed_tx_scripts(BTreeSet::from([tx_script_root])); + // Build the public network account with the increment and funding notes allowed. + let fee_policy: FeePolicy = BasicConstantFeePolicy::new() + .with_fees( + [note_script_root, P2idNote::script_root()].map(|root| (root, AssetAmount::ZERO)), + ) + .into(); + let fee_policy_manager = FeePolicyManager::builder() + .fee_faucet_id(fee_faucet_id) + .active_fee_policy(fee_policy) + .build(); + // Match the protocol/node counter example: only permit the two note scripts + // this account implements. Config notes need Authority, which it does not have. + // The canonical expiration script is required by the network builder. + let network_auth = AuthNetworkAccount::custom( + BTreeSet::from([note_script_root, P2idNote::script_root()]), + fee_policy_manager, + )? + .with_allowed_tx_scripts([ExpirationTransactionScript::script_root()]); let counter_contract = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(network_auth) + .with_components(network_auth) .with_component(counter_component) + .with_component(BasicWallet) .build() .unwrap(); client.add_account(&counter_contract, false).await.unwrap(); + fund_account_for_fees(&mut client, counter_contract.id(), &fee_config).await?; println!( "contract id: {:?}", - counter_contract.id().to_bech32(NetworkId::Testnet) + counter_contract.id().to_bech32(network.network_id()) ); // ------------------------------------------------------------------------- - // STEP 3: Deploy Network Account with Transaction Script + // STEP 3: Publish the network account // ------------------------------------------------------------------------- println!("\n[STEP 3] Deploy network counter smart contract"); - // Reuse the `tx_script` compiled in STEP 2 (its root is allowlisted on the - // account, so the network auth procedure accepts this deploy transaction). - let tx_increment_request = TransactionRequestBuilder::new() - .custom_script(tx_script) - .build() - .unwrap(); - - let tx_id = client - .submit_new_transaction(counter_contract.id(), tx_increment_request) - .await - .unwrap(); - - println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", - tx_id - ); - - // Wait for the transaction to be committed - wait_for_tx(&mut client, tx_id).await.unwrap(); + // On a fee-enabled network, consuming the funding note already published this + // account. RPC permits users to deploy new network accounts, but rejects + // user-submitted transactions for existing ones. Subsequent increments must + // be requested by notes and executed by the network transaction builder. + if !fee_config.fees_are_active() { + let deployment = TransactionRequestBuilder::new().build()?; + client + .submit_tutorial_transaction(counter_contract.id(), deployment) + .await?; + } + println!("Network counter deployed; initial count is 0"); // ------------------------------------------------------------------------- // STEP 4: Prepare & Create the Network Note @@ -244,11 +221,12 @@ async fn main() -> Result<(), Box> { .build()?; let note_tx_id = client - .submit_new_transaction(alice_account.id(), note_req) + .submit_tutorial_transaction(alice_account.id(), note_req) .await?; println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), note_tx_id ); @@ -263,7 +241,7 @@ async fn main() -> Result<(), Box> { sleep(Duration::from_secs(6)).await; let mut last_val = None; - for _ in 0..10 { + for _ in 0..24 { client.sync_state().await?; // Checking updated state @@ -276,7 +254,7 @@ async fn main() -> Result<(), Box> { .unwrap() .into(); let val = count[0].as_canonical_u64(); - if val >= 2 { + if val == 1 { println!("🔢 Final counter value: {}", val); return Ok(()); } @@ -288,12 +266,12 @@ async fn main() -> Result<(), Box> { } // The network note was submitted, but it is executed asynchronously by the - // network transaction builder. If the counter has not reached 2 within the + // network transaction builder. If the counter has not reached 1 within the // polling window, the tutorial's final state is unconfirmed, so fail rather // than claim success. if let Some(val) = last_val { Err(format!( - "Counter did not reach the expected value 2 within the timeout (last observed {}). \ + "Counter did not reach the expected value 1 within the timeout (last observed {}). \ The network note was submitted but its execution is still pending on the network \ transaction builder; re-run or check Midenscan.", val diff --git a/rust-client/src/bin/note_creation_in_masm.rs b/rust-client/src/bin/note_creation_in_masm.rs index db7a144d..8c26add1 100644 --- a/rust-client/src/bin/note_creation_in_masm.rs +++ b/rust-client/src/bin/note_creation_in_masm.rs @@ -1,18 +1,19 @@ -use rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; use tokio::time::{sleep, Duration}; use miden_client::{ account::{ component::{ - BasicWallet, BurnPolicyConfig, FungibleFaucet, MintPolicyConfig, PolicyRegistration, - TokenName, TokenPolicyManager, + create_singlesig_user_fungible_faucet, BasicWallet, BurnPolicy, FungibleFaucet, + MintPolicy, TokenName, TokenPolicyManager, }, Account, AccountBuilder, AccountType, }, address::NetworkId, - asset::{AssetAmount, FungibleAsset, TokenSymbol}, - auth::{AuthSchemeId, AuthSecretKey, AuthSingleSig}, + asset::{AssetAmount, AssetId, FungibleAsset, TokenSymbol}, + auth::{AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, crypto::FeltRng, keystore::{FilesystemKeyStore, Keystore}, @@ -20,12 +21,12 @@ use miden_client::{ Note, NoteAssets, NoteDetails, NoteRecipient, NoteStorage, NoteTag, NoteType, PartialNoteMetadata, }, - rpc::{Endpoint, GrpcClient}, - store::TransactionFilter, - transaction::{TransactionId, TransactionRequestBuilder, TransactionStatus}, + rpc::{GrpcClient, VerifyingRpcClient}, + transaction::{TransactionId, TransactionRequestBuilder}, Client, ClientError, Felt, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::{fund_account_for_fees, FeeConfig, TutorialNetwork}; // Helper to create a basic account async fn create_basic_account( @@ -39,7 +40,7 @@ async fn create_basic_account( let account = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet) .build() .unwrap(); @@ -62,27 +63,25 @@ async fn create_basic_faucet( let decimals = 8; let max_supply = AssetAmount::new(1_000_000).unwrap(); - let account = AccountBuilder::new(init_seed) - .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) - .with_component( - FungibleFaucet::builder() - .name(TokenName::new("MID").unwrap()) - .symbol(symbol) - .decimals(decimals) - .max_supply(max_supply) - .build() - .unwrap(), - ) - .with_components( - TokenPolicyManager::new() - .with_mint_policy(MintPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap() - .with_burn_policy(BurnPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap(), - ) + let faucet = FungibleFaucet::builder() + .name(TokenName::new("MID").unwrap()) + .symbol(symbol) + .decimals(decimals) + .max_supply(max_supply) .build() .unwrap(); + let policies = TokenPolicyManager::builder() + .active_mint_policy(MintPolicy::allow_all()) + .active_burn_policy(BurnPolicy::allow_all()) + .build(); + let account = create_singlesig_user_fungible_faucet( + init_seed, + faucet, + AuthSingleSig::from_public_key(key_pair.public_key()), + policies, + AccountType::Public, + ) + .unwrap(); client.add_account(&account, false).await?; keystore.add_key(&key_pair, account.id()).await.unwrap(); @@ -95,21 +94,29 @@ async fn wait_for_notes( client: &mut Client, account_id: &Account, expected: usize, + network_id: NetworkId, ) -> Result<(), ClientError> { - loop { + for _ in 0..24 { client.sync_state().await?; - let notes = client.get_consumable_notes(Some(account_id.id())).await?; + let notes = client + .get_consumable_tutorial_notes(Some(account_id.id())) + .await?; if notes.len() >= expected { - break; + return Ok(()); } println!( "{} consumable notes found for account {}. Waiting...", notes.len(), - account_id.id().to_bech32(NetworkId::Testnet) + account_id.id().to_bech32(network_id.clone()) ); sleep(Duration::from_secs(3)).await; } - Ok(()) + Err(ClientError::Observer(Box::new(std::io::Error::other( + format!( + "timed out waiting for {expected} tutorial notes for {}", + account_id.id() + ), + )))) } /// Waits for a specific transaction to be committed. @@ -117,39 +124,18 @@ async fn wait_for_tx( client: &mut Client, tx_id: TransactionId, ) -> Result<(), ClientError> { - loop { - client.sync_state().await?; - - // Check transaction status - let txs = client - .get_transactions(TransactionFilter::Ids(vec![tx_id])) - .await?; - let tx_committed = if !txs.is_empty() { - matches!(txs[0].status, TransactionStatus::Committed { .. }) - } else { - false - }; - - if tx_committed { - println!("✅ transaction {} committed", tx_id.to_hex()); - break; - } - - println!( - "Transaction {} not yet committed. Waiting...", - tx_id.to_hex() - ); - sleep(Duration::from_secs(2)).await; - } - Ok(()) + rust_client::wait_for_transaction(client, tx_id).await } #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -161,12 +147,12 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; // ------------------------------------------------------------------------- // STEP 1: Create accounts and deploy faucet @@ -175,20 +161,23 @@ async fn main() -> Result<(), ClientError> { let alice_account = create_basic_account(&mut client, &keystore).await?; println!( "Alice's account ID: {:?}", - alice_account.id().to_bech32(NetworkId::Testnet) + alice_account.id().to_bech32(network.network_id()) ); let bob_account = create_basic_account(&mut client, &keystore).await?; println!( "Bob's account ID: {:?}", - bob_account.id().to_bech32(NetworkId::Testnet) + bob_account.id().to_bech32(network.network_id()) ); println!("\nDeploying a new fungible faucet."); let faucet = create_basic_faucet(&mut client, &keystore).await?; println!( "Faucet account ID: {:?}", - faucet.id().to_bech32(NetworkId::Testnet) + faucet.id().to_bech32(network.network_id()) ); + for account_id in [alice_account.id(), bob_account.id(), faucet.id()] { + fund_account_for_fees(&mut client, account_id, &fee_config).await?; + } client.sync_state().await?; // ------------------------------------------------------------------------- @@ -208,14 +197,16 @@ async fn main() -> Result<(), ClientError> { ) .unwrap(); - let tx_id = client.submit_new_transaction(faucet.id(), tx_req).await?; + let tx_id = client + .submit_tutorial_transaction(faucet.id(), tx_req) + .await?; println!("Minted tokens. TX: {:?}", tx_id); - wait_for_notes(&mut client, &alice_account, 1).await?; + wait_for_notes(&mut client, &alice_account, 1, network.network_id()).await?; // Consume the minted note let consumable_notes = client - .get_consumable_notes(Some(alice_account.id())) + .get_consumable_tutorial_notes(Some(alice_account.id())) .await?; if let Some((note_record, _)) = consumable_notes.first() { @@ -223,7 +214,7 @@ async fn main() -> Result<(), ClientError> { let consume_req = TransactionRequestBuilder::new().build_consume_notes(vec![note])?; let tx_id = client - .submit_new_transaction(alice_account.id(), consume_req) + .submit_tutorial_transaction(alice_account.id(), consume_req) .await?; println!("Consumed minted note. TX: {:?}", tx_id); } @@ -262,10 +253,11 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let tx_id = client - .submit_new_transaction(alice_account.id(), note_req) + .submit_tutorial_transaction(alice_account.id(), note_req) .await?; println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); @@ -307,14 +299,40 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let tx_id = client - .submit_new_transaction(bob_account.id(), consume_custom_req) + .submit_tutorial_transaction(bob_account.id(), consume_custom_req) .await?; println!( - "Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "Consumed Note Tx on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); wait_for_tx(&mut client, tx_id).await?; + // The SDK verifies expected recipients; also check the actual successor's assets and metadata. + let successor = client + .get_output_note(output_note.id()) + .await? + .expect("the transaction must create the expected successor note"); + assert!(successor.is_committed(), "the successor must be committed"); + assert_eq!(successor.assets(), output_note.assets()); + assert_eq!(successor.metadata(), output_note.metadata()); + println!( + "Successor note committed with 50 tokens: {}", + successor.id() + ); + + let bob = client + .get_account(bob_account.id()) + .await? + .expect("Bob's account must exist after consuming the note"); + let balance = bob.vault().get_balance(AssetId::new_fungible(faucet_id))?; + assert_eq!( + balance.as_u64(), + 50, + "Bob must retain the other half of the note's tokens", + ); + println!("Bob's retained token balance: {balance}"); + Ok(()) } diff --git a/rust-client/src/bin/oracle_data_query.rs b/rust-client/src/bin/oracle_data_query.rs index 28472742..c9e4f1c2 100644 --- a/rust-client/src/bin/oracle_data_query.rs +++ b/rust-client/src/bin/oracle_data_query.rs @@ -1,24 +1,22 @@ use miden_client::{ account::{ - component::AccountComponentMetadata, AccountBuilder, AccountComponent, AccountId, - AccountType, StorageMapKey, StorageSlot, StorageSlotName, - }, - assembly::{ - CodeBuilder, DefaultSourceManager, Module, ModuleKind, Path as AssemblyPath, + component::{AccountComponentMetadata, BasicWallet}, + AccountBuilder, AccountComponent, AccountId, AccountType, StorageMapKey, StorageSlot, + StorageSlotName, }, + assembly::CodeBuilder, auth::NoAuth, builder::ClientBuilder, keystore::FilesystemKeyStore, - rpc::{ - domain::account::AccountStorageRequirements, - Endpoint, GrpcClient, - }, - transaction::{ForeignAccount, TransactionKernel, TransactionRequestBuilder}, + rpc::{domain::account::AccountStorageRequirements, GrpcClient, VerifyingRpcClient}, + transaction::{ForeignAccount, TransactionRequestBuilder}, Client, ClientError, Felt, Word, ZERO, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -use rand::RngCore; -use std::{fs, path::Path, sync::Arc}; +use rand::Rng; +use rust_client::TutorialClientExt; +use rust_client::{fund_account_for_fees, FeeConfig, TutorialNetwork}; +use std::sync::Arc; /// Import the oracle + its publishers and return the ForeignAccount list /// Due to Pragma's decentralized oracle architecture, we need to get the @@ -53,7 +51,7 @@ pub async fn get_oracle_foreign_accounts( StorageSlotName::new("pragma::oracle::publishers").expect("valid slot name"); let publisher_ids: Vec = (2..next_publisher_index) .map(|index| { - let key: Word = [Felt::new_unchecked(index), ZERO, ZERO, ZERO].into(); + let key = StorageMapKey::new([Felt::new_unchecked(index), ZERO, ZERO, ZERO].into()); let publisher_word = storage .get_map_item(&publishers_slot, key) .expect("publisher entry missing from oracle storage"); @@ -64,8 +62,7 @@ pub async fn get_oracle_foreign_accounts( // Each publisher exposes its price entries in the `entries` map, keyed by // the faucet ID word of the trading pair. - let entries_slot = - StorageSlotName::new("pragma::publisher::entries").expect("valid slot name"); + let entries_slot = StorageSlotName::new("pragma::publisher::entries").expect("valid slot name"); let mut foreign_accounts = Vec::with_capacity(publisher_ids.len() + 1); for publisher_id in publisher_ids { @@ -95,29 +92,17 @@ pub async fn get_oracle_foreign_accounts( Ok(foreign_accounts) } -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 // ------------------------------------------------------------------------- - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); let keystore_path = std::path::PathBuf::from("./keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).unwrap()); @@ -128,30 +113,55 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; println!("Latest block: {}", client.sync_state().await?.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; // ------------------------------------------------------------------------- // Get all foreign accounts for oracle data // ------------------------------------------------------------------------- - // Defaults to Pragma's current Miden v0.15 testnet oracle; pass a different - // bech32 id as the first CLI argument to point at another deployment. Pragma's - // addresses change between testnet iterations, so check their README - // (https://github.com/astraly-labs/pragma-miden) if this feed stops resolving. + // Pass a compatible oracle account ID and its `get_median` procedure root as CLI + // arguments (or through the matching environment variables). This tutorial remains skipped + // by the runner until Pragma publishes a deployment for the current protocol release. let oracle_bech32 = std::env::args() .nth(1) - .unwrap_or_else(|| "mtst1apadf2szkxqkcyt7x2znuggv9qkhccam".to_string()); - let (_, oracle_account_id) = AccountId::from_bech32(&oracle_bech32).unwrap(); + .or_else(|| std::env::var("MIDEN_ORACLE_ACCOUNT_ID").ok()) + .ok_or_else(|| ClientError::Observer(Box::new(std::io::Error::other( + "Oracle deployment is required: set MIDEN_ORACLE_ACCOUNT_ID and MIDEN_ORACLE_GET_MEDIAN_ROOT for the selected network. Use a compatible v0.16 deployment on the selected network.", + ))))?; + let get_median_proc_root = std::env::args() + .nth(2) + .or_else(|| std::env::var("MIDEN_ORACLE_GET_MEDIAN_ROOT").ok()) + .ok_or_else(|| { + ClientError::Observer(Box::new(std::io::Error::other( + "Set MIDEN_ORACLE_GET_MEDIAN_ROOT to the deployed oracle's get_median procedure root", + ))) + })?; + let (account_network, oracle_account_id) = AccountId::from_bech32(&oracle_bech32).unwrap(); + assert_eq!( + account_network, + network.network_id(), + "oracle account must match the selected tutorial network" + ); - // BTC/USD is identified by the faucet ID pair `1:0` (prefix 1, suffix 0). + // BTC/USD was identified by the faucet ID pair `1:0` in the previous deployment. Override + // either value with the optional third and fourth CLI arguments for the selected deployment. // The faucet ID word is laid out as [0, 0, suffix, prefix]. - let pair_prefix: u64 = 1; - let pair_suffix: u64 = 0; - let btc_usd_pair: Word = - [ZERO, ZERO, Felt::new_unchecked(pair_suffix), Felt::new_unchecked(pair_prefix)].into(); + let pair_prefix: u64 = std::env::args() + .nth(3) + .map_or(1, |value| value.parse().expect("pair prefix must be a u64")); + let pair_suffix: u64 = std::env::args() + .nth(4) + .map_or(0, |value| value.parse().expect("pair suffix must be a u64")); + let btc_usd_pair: Word = [ + ZERO, + ZERO, + Felt::new_unchecked(pair_suffix), + Felt::new_unchecked(pair_prefix), + ] + .into(); let foreign_accounts: Vec = get_oracle_foreign_accounts(&mut client, oracle_account_id, btc_usd_pair).await?; @@ -164,8 +174,18 @@ async fn main() -> Result<(), ClientError> { // ------------------------------------------------------------------------- // Create Oracle Reader contract // ------------------------------------------------------------------------- - let contract_code = - fs::read_to_string(Path::new("../masm/accounts/oracle_reader.masm")).unwrap(); + let contract_code = include_str!("../../../masm/accounts/oracle_reader.masm") + .replace("{get_median_proc_root}", &get_median_proc_root) + .replace( + "{oracle_id_prefix}", + &oracle_account_id.prefix().to_string(), + ) + .replace( + "{oracle_id_suffix}", + &oracle_account_id.suffix().to_string(), + ) + .replace("{pair_prefix}", &pair_prefix.to_string()) + .replace("{pair_suffix}", &pair_suffix.to_string()); let contract_slot_name = StorageSlotName::new("miden::tutorials::oracle_reader").expect("valid slot name"); @@ -188,7 +208,8 @@ async fn main() -> Result<(), ClientError> { let oracle_reader_contract = AccountBuilder::new(seed) .account_type(AccountType::Public) .with_component(contract_component.clone()) - .with_auth_component(NoAuth) + .with_component(BasicWallet) + .with_component(NoAuth) .build() .unwrap(); @@ -196,22 +217,18 @@ async fn main() -> Result<(), ClientError> { .add_account(&oracle_reader_contract, false) .await .unwrap(); + fund_account_for_fees(&mut client, oracle_reader_contract.id(), &fee_config).await?; // ------------------------------------------------------------------------- // Build the script that calls our `get_price` procedure // ------------------------------------------------------------------------- - let script_path = Path::new("../masm/scripts/oracle_reader_script.masm"); - let script_code = fs::read_to_string(script_path).unwrap(); - - let library_path = "external_contract::oracle_reader"; - let account_component_lib = - create_library(library_path, &contract_code).unwrap(); + let script_code = include_str!("../../../masm/scripts/oracle_reader_script.masm"); let tx_script = client .code_builder() - .with_dynamically_linked_library(&account_component_lib) + .with_linked_module("external_contract::oracle_reader", &contract_code) .unwrap() - .compile_tx_script(&script_code) + .compile_tx_script(script_code) .unwrap(); let tx_increment_request = TransactionRequestBuilder::new() @@ -221,12 +238,13 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let tx_id = client - .submit_new_transaction(oracle_reader_contract.id(), tx_increment_request) + .submit_tutorial_transaction(oracle_reader_contract.id(), tx_increment_request) .await .unwrap(); println!( - "View transaction on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "View transaction on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); diff --git a/rust-client/src/bin/unauthenticated_note_transfer.rs b/rust-client/src/bin/unauthenticated_note_transfer.rs index b64f4a20..aaed1470 100644 --- a/rust-client/src/bin/unauthenticated_note_transfer.rs +++ b/rust-client/src/bin/unauthenticated_note_transfer.rs @@ -1,67 +1,46 @@ -use rand::RngCore; +use rand::Rng; +use rust_client::TutorialClientExt; use std::{path::PathBuf, sync::Arc}; -use tokio::time::{sleep, Duration, Instant}; +use tokio::time::{Duration, Instant}; use miden_client::{ account::{ component::{ - BasicWallet, BurnPolicyConfig, FungibleFaucet, MintPolicyConfig, PolicyRegistration, - TokenName, TokenPolicyManager, + create_singlesig_user_fungible_faucet, BasicWallet, BurnPolicy, FungibleFaucet, + MintPolicy, TokenName, TokenPolicyManager, }, AccountBuilder, AccountType, }, - address::NetworkId, - asset::{AssetAmount, AssetCallbackFlag, AssetVaultKey, FungibleAsset, TokenSymbol}, - auth::{AuthSchemeId, AuthSecretKey, AuthSingleSig}, + asset::{AssetAmount, AssetId, FungibleAsset, TokenSymbol}, + auth::{AuthSecretKey, AuthSingleSig}, builder::ClientBuilder, keystore::{FilesystemKeyStore, Keystore}, - note::{Note, NoteAttachments, NoteType, P2idNote}, - rpc::{Endpoint, GrpcClient}, - store::TransactionFilter, - transaction::{TransactionId, TransactionRequestBuilder, TransactionStatus}, + note::{Note, NoteType, P2idNote}, + rpc::{GrpcClient, VerifyingRpcClient}, + transaction::{TransactionId, TransactionRequestBuilder}, utils::{Deserializable, Serializable}, Client, ClientError, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use rust_client::{fund_account_for_fees, FeeConfig, TutorialNetwork}; /// Waits for a specific transaction to be committed. async fn wait_for_tx( client: &mut Client, tx_id: TransactionId, ) -> Result<(), ClientError> { - loop { - client.sync_state().await?; - - // Check transaction status - let txs = client - .get_transactions(TransactionFilter::Ids(vec![tx_id])) - .await?; - let tx_committed = if !txs.is_empty() { - matches!(txs[0].status, TransactionStatus::Committed { .. }) - } else { - false - }; - - if tx_committed { - println!("✅ transaction {} committed", tx_id.to_hex()); - break; - } - - println!( - "Transaction {} not yet committed. Waiting...", - tx_id.to_hex() - ); - sleep(Duration::from_secs(2)).await; - } - Ok(()) + rust_client::wait_for_transaction(client, tx_id).await } #[tokio::main] async fn main() -> Result<(), ClientError> { // Initialize client - let endpoint = Endpoint::testnet(); + let network = TutorialNetwork::from_env()?; + let endpoint = network.endpoint(); let timeout_ms = 10_000; - let rpc_client = Arc::new(GrpcClient::new(&endpoint, timeout_ms)); + let rpc_client = Arc::new(VerifyingRpcClient::new(GrpcClient::new( + &endpoint, timeout_ms, + ))); // Initialize keystore let keystore_path = PathBuf::from("./keystore"); @@ -73,12 +52,12 @@ async fn main() -> Result<(), ClientError> { .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await?; let sync_summary = client.sync_state().await.unwrap(); println!("Latest block: {}", sync_summary.block_num); + let fee_config = FeeConfig::from_client(&client, network).await?; //------------------------------------------------------------ // STEP 1: Deploy a fungible faucet @@ -98,38 +77,40 @@ async fn main() -> Result<(), ClientError> { let max_supply = AssetAmount::new(1_000_000).unwrap(); // Build the account - let faucet_account = AccountBuilder::new(init_seed) - .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) - .with_component( - FungibleFaucet::builder() - .name(TokenName::new("MID").unwrap()) - .symbol(symbol) - .decimals(decimals) - .max_supply(max_supply) - .build() - .unwrap(), - ) - .with_components( - TokenPolicyManager::new() - .with_mint_policy(MintPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap() - .with_burn_policy(BurnPolicyConfig::AllowAll, PolicyRegistration::Active) - .unwrap(), - ) + let faucet = FungibleFaucet::builder() + .name(TokenName::new("MID").unwrap()) + .symbol(symbol) + .decimals(decimals) + .max_supply(max_supply) .build() .unwrap(); + let policies = TokenPolicyManager::builder() + .active_mint_policy(MintPolicy::allow_all()) + .active_burn_policy(BurnPolicy::allow_all()) + .build(); + let faucet_account = create_singlesig_user_fungible_faucet( + init_seed, + faucet, + AuthSingleSig::from_public_key(key_pair.public_key()), + policies, + AccountType::Public, + ) + .unwrap(); // Add the faucet to the client client.add_account(&faucet_account, false).await?; println!( "Faucet account ID: {}", - faucet_account.id().to_bech32(NetworkId::Testnet) + faucet_account.id().to_bech32(network.network_id()) ); // Add the key pair to the keystore - keystore.add_key(&key_pair, faucet_account.id()).await.unwrap(); + keystore + .add_key(&key_pair, faucet_account.id()) + .await + .unwrap(); + fund_account_for_fees(&mut client, faucet_account.id(), &fee_config).await?; // Resync to show newly deployed faucet tokio::time::sleep(Duration::from_secs(2)).await; @@ -151,7 +132,7 @@ async fn main() -> Result<(), ClientError> { let account = AccountBuilder::new(init_seed) .account_type(AccountType::Public) - .with_auth_component(AuthSingleSig::new(key_pair.public_key().to_commitment(), AuthSchemeId::Falcon512Poseidon2)) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet) .build() .unwrap(); @@ -160,12 +141,13 @@ async fn main() -> Result<(), ClientError> { println!( "account id {:?}: {}", i, - account.id().to_bech32(NetworkId::Testnet) + account.id().to_bech32(network.network_id()) ); client.add_account(&account, true).await?; // Add the key pair to the keystore keystore.add_key(&key_pair, account.id()).await.unwrap(); + fund_account_for_fees(&mut client, account.id(), &fee_config).await?; } // For demo purposes, Alice is the first account. @@ -188,7 +170,7 @@ async fn main() -> Result<(), ClientError> { .unwrap(); let tx_id = client - .submit_new_transaction(faucet_account.id(), transaction_request) + .submit_tutorial_transaction(faucet_account.id(), transaction_request) .await?; println!("Minted tokens. TX: {:?}", tx_id); @@ -196,7 +178,9 @@ async fn main() -> Result<(), ClientError> { wait_for_tx(&mut client, tx_id).await?; // Get the minted note and consume it - let consumable_notes = client.get_consumable_notes(Some(alice.id())).await?; + let consumable_notes = client + .get_consumable_tutorial_notes(Some(alice.id())) + .await?; if let Some((note_record, _)) = consumable_notes.first() { let note: Note = note_record.clone().try_into()?; @@ -204,7 +188,7 @@ async fn main() -> Result<(), ClientError> { TransactionRequestBuilder::new().build_consume_notes(vec![note])?; let consume_tx_id = client - .submit_new_transaction(alice.id(), transaction_request) + .submit_tutorial_transaction(alice.id(), transaction_request) .await?; println!("Consumed minted note. TX: {:?}", consume_tx_id); @@ -221,10 +205,13 @@ async fn main() -> Result<(), ClientError> { for i in 0..number_of_accounts - 1 { let loop_start = Instant::now(); println!("\nunauthenticated tx {:?}", i + 1); - println!("sender: {}", accounts[i].id().to_bech32(NetworkId::Testnet)); + println!( + "sender: {}", + accounts[i].id().to_bech32(network.network_id()) + ); println!( "target: {}", - accounts[i + 1].id().to_bech32(NetworkId::Testnet) + accounts[i + 1].id().to_bech32(network.network_id()) ); // Time the creation of the p2id note @@ -239,15 +226,15 @@ async fn main() -> Result<(), ClientError> { NoteType::Public }; - let p2id_note = P2idNote::create( - accounts[i].id(), - accounts[i + 1].id(), - vec![fungible_asset_send_amount.into()], - note_type, - NoteAttachments::empty(), - client.rng(), - ) - .unwrap(); + let p2id_note: Note = P2idNote::builder() + .sender(accounts[i].id()) + .target(accounts[i + 1].id()) + .asset(fungible_asset_send_amount) + .note_type(note_type) + .generate_serial_number(client.rng()) + .build() + .unwrap() + .into(); let output_note = p2id_note.clone(); @@ -257,10 +244,12 @@ async fn main() -> Result<(), ClientError> { .build() .unwrap(); - let tx_id = client + // Do not wait for inclusion: the receiver is given the complete note below. + client.sync_state().await?; + let send_tx_id = client .submit_new_transaction(accounts[i].id(), transaction_request) .await?; - println!("Created note. TX: {:?}", tx_id); + println!("Created note. TX: {:?}", send_tx_id); // Note serialization/deserialization // This demonstrates how you could send the serialized note to another client instance @@ -268,17 +257,17 @@ async fn main() -> Result<(), ClientError> { let deserialized_p2id_note = Note::read_from_bytes(&serialized).unwrap(); // Time consume note request building - let consume_note_request = TransactionRequestBuilder::new() - .input_notes([(deserialized_p2id_note, None)]) - .build() - .unwrap(); + let consume_note_request = + TransactionRequestBuilder::new().build_consume_notes(vec![deserialized_p2id_note])?; let tx_id = client - .submit_new_transaction(accounts[i + 1].id(), consume_note_request) + .submit_tutorial_transaction(accounts[i + 1].id(), consume_note_request) .await?; + rust_client::wait_for_transaction(&mut client, send_tx_id).await?; println!( - "Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/{:?}", + "Consumed Note Tx on MidenScan: {}/tx/{:?}", + network.explorer_url(), tx_id ); println!( @@ -296,20 +285,29 @@ async fn main() -> Result<(), ClientError> { // Final resync and display account balances tokio::time::sleep(Duration::from_secs(3)).await; client.sync_state().await?; - for account in accounts.clone() { + for (index, account) in accounts.iter().enumerate() { let new_account = client.get_account(account.id()).await.unwrap().unwrap(); let balance = new_account .vault() - .get_balance(AssetVaultKey::new_fungible( - faucet_account.id(), - AssetCallbackFlag::Disabled, - )) + .get_balance(AssetId::new_fungible(faucet_account.id())) .unwrap(); println!( "Account: {} balance: {}", - account.id().to_bech32(NetworkId::Testnet), + account.id().to_bech32(network.network_id()), balance ); + let expected = if index == 0 { + 80 + } else if index == accounts.len() - 1 { + 20 + } else { + 0 + }; + assert_eq!( + balance.as_u64(), + expected, + "unexpected transfer-chain balance" + ); } Ok(()) diff --git a/rust-client/src/lib.rs b/rust-client/src/lib.rs new file mode 100644 index 00000000..531ea4df --- /dev/null +++ b/rust-client/src/lib.rs @@ -0,0 +1,547 @@ +//! Shared network and transaction-fee setup used by the executable tutorials. + +use std::{env, fmt::Display, time::Duration}; + +use miden_client::{ + account::{AccountId, Address}, + address::{AddressId, NetworkId}, + note::{Note, NoteConsumability, NoteId, TxFeeNote}, + rpc::Endpoint, + store::{InputNoteRecord, TransactionFilter}, + transaction::{ + TransactionAuthenticator, TransactionId, TransactionRequest, TransactionRequestBuilder, + TransactionStatus, + }, + Client, ClientError, +}; +use serde::Deserialize; +use sha2::{Digest, Sha256}; + +// Allow for asynchronous network-note execution, but never poll indefinitely. +const DEFAULT_SYNC_RETRIES: u32 = 24; +const SYNC_RETRY_DELAY: Duration = Duration::from_secs(5); +const REQUEST_TIMEOUT: Duration = Duration::from_secs(30); + +/// Fee-aware execution safeguards shared by the runnable examples. +#[allow(async_fn_in_trait)] +pub trait TutorialClientExt { + /// Refreshes the reference block, submits the transaction and verifies commitment. + async fn submit_tutorial_transaction( + &mut self, + account_id: AccountId, + request: TransactionRequest, + ) -> Result; + /// Excludes TX_FEE notes, which are consumable but are not tutorial transfers. + async fn get_consumable_tutorial_notes( + &self, + account_id: Option, + ) -> Result)>, ClientError>; +} + +impl TutorialClientExt for Client { + async fn submit_tutorial_transaction( + &mut self, + account_id: AccountId, + request: TransactionRequest, + ) -> Result { + self.sync_state().await?; + let tx_id = self.submit_new_transaction(account_id, request).await?; + wait_for_transaction(self, tx_id).await?; + Ok(tx_id) + } + + async fn get_consumable_tutorial_notes( + &self, + account_id: Option, + ) -> Result)>, ClientError> { + let mut notes = self.get_consumable_notes(account_id).await?; + notes.retain(|(note, _)| is_tutorial_note_script(note.details().script().root())); + Ok(notes) + } +} + +fn is_tutorial_note_script(root: miden_client::note::NoteScriptRoot) -> bool { + root != TxFeeNote::script_root() +} + +/// Waits for actual on-chain commitment, failing with the transaction ID on timeout. +pub async fn wait_for_transaction( + client: &mut Client, + tx_id: TransactionId, +) -> Result<(), ClientError> { + let retries = env_u32("MIDEN_TX_SYNC_RETRIES", DEFAULT_SYNC_RETRIES)?; + for attempt in 0..retries { + client.sync_state().await?; + let records = client + .get_transactions(TransactionFilter::Ids(vec![tx_id])) + .await?; + if let Some(record) = records.first() { + if matches!(record.status, TransactionStatus::Committed { .. }) { + println!("Transaction committed: {tx_id}"); + return Ok(()); + } + if let TransactionStatus::Discarded(cause) = &record.status { + return Err(tutorial_error(format!( + "transaction {tx_id} was discarded: {cause}" + ))); + } + } + if attempt + 1 < retries { + tokio::time::sleep(SYNC_RETRY_DELAY).await; + } + } + Err(tutorial_error(format!( + "transaction {tx_id} was not committed after {retries} sync attempts" + ))) +} + +/// Fetches exactly the notes created by the example, not unrelated or TX_FEE notes. +pub async fn wait_for_notes_by_id( + client: &mut Client, + ids: &[NoteId], +) -> Result, ClientError> { + for attempt in 0..DEFAULT_SYNC_RETRIES { + client.sync_state().await?; + let mut notes = Vec::new(); + for id in ids { + if let Some(record) = client.get_input_note(*id).await? { + if record.is_committed() { + notes.push(record.try_into()?); + } + } + } + if notes.len() == ids.len() { + return Ok(notes); + } + if attempt + 1 < DEFAULT_SYNC_RETRIES { + tokio::time::sleep(SYNC_RETRY_DELAY).await; + } + } + Err(tutorial_error(format!( + "expected notes were not committed within the timeout: {ids:?}" + ))) +} + +/// Network selected for a tutorial run. +/// +/// `TUTORIAL_NETWORK` takes precedence over `MIDEN_NETWORK`; both accept `testnet` or `devnet`. +/// When neither is set, tutorials use testnet. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum TutorialNetwork { + Testnet, + Devnet, +} + +impl TutorialNetwork { + pub fn from_env() -> Result { + let value = env::var("TUTORIAL_NETWORK") + .or_else(|_| env::var("MIDEN_NETWORK")) + .unwrap_or_else(|_| "testnet".to_owned()); + + match value.to_ascii_lowercase().as_str() { + "testnet" => Ok(Self::Testnet), + "devnet" => Ok(Self::Devnet), + other => Err(tutorial_error(format!( + "unsupported tutorial network `{other}`; use `testnet` or `devnet`" + ))), + } + } + + pub fn endpoint(self) -> Endpoint { + match self { + Self::Testnet => Endpoint::testnet(), + Self::Devnet => Endpoint::devnet(), + } + } + + pub fn network_id(self) -> NetworkId { + match self { + Self::Testnet => NetworkId::Testnet, + Self::Devnet => NetworkId::Devnet, + } + } + + pub fn explorer_url(self) -> &'static str { + match self { + Self::Testnet => "https://testnet.midenscan.com", + Self::Devnet => "https://devnet.midenscan.com", + } + } + + pub fn remote_prover_url(self) -> &'static str { + match self { + Self::Testnet => "https://tx-prover.testnet.miden.io", + Self::Devnet => "https://tx-prover.devnet.miden.io", + } + } + + fn faucet_url(self) -> &'static str { + match self { + Self::Testnet => "https://faucet-api.testnet.miden.io", + Self::Devnet => "https://faucet-api.devnet.miden.io", + } + } +} + +/// Fee parameters read from the client's current reference block. +#[derive(Debug, Clone, Copy)] +pub struct FeeConfig { + network: TutorialNetwork, + fee_faucet_id: AccountId, + verification_base_fee: u32, +} + +impl FeeConfig { + pub async fn from_client( + client: &Client, + network: TutorialNetwork, + ) -> Result { + let header = client.get_latest_block_header().await?; + let parameters = header.fee_parameters(); + + Ok(Self { + network, + fee_faucet_id: parameters.fee_faucet_id(), + verification_base_fee: parameters.verification_base_fee(), + }) + } + + pub fn fees_are_active(&self) -> bool { + self.verification_base_fee != 0 + } + + pub fn native_fee_faucet_id(&self) -> AccountId { + self.fee_faucet_id + } +} + +/// Funds a newly-created account with the native fee asset when the selected network charges fees. +/// +/// The faucet creates a public P2ID note. This function waits until the note is committed, then +/// consumes it as the account's first transaction. Accounts using this helper must expose +/// `BasicWallet`, since P2ID moves its assets through `BasicWallet::receive_asset`. +/// +/// Environment overrides: +/// - `MIDEN_FAUCET_URL`: faucet REST API base URL. +/// - `MIDEN_FAUCET_API_KEY`: optional faucet API key. +/// - `MIDEN_FEE_AMOUNT`: native base units requested per account (defaults to the faucet's +/// advertised base amount). +/// - `MIDEN_FEE_SYNC_RETRIES`: number of five-second sync attempts (default 24). +pub async fn fund_account_for_fees( + client: &mut Client, + account_id: AccountId, + fee_config: &FeeConfig, +) -> Result<(), ClientError> +where + AUTH: TransactionAuthenticator + Sync + 'static, +{ + if !fee_config.fees_are_active() { + return Ok(()); + } + + let requested_amount = env::var("MIDEN_FEE_AMOUNT") + .ok() + .map(|value| { + value.parse::().map_err(|error| { + tutorial_error(format!("invalid MIDEN_FEE_AMOUNT value `{value}`: {error}")) + }) + }) + .transpose()?; + + let api_url = + env::var("MIDEN_FAUCET_URL").unwrap_or_else(|_| fee_config.network.faucet_url().to_owned()); + let api_key = env::var("MIDEN_FAUCET_API_KEY").ok(); + + println!( + "Requesting native fee funding for {} from {api_url}", + account_id.to_hex() + ); + + let (note_id, faucet_transaction_id, amount) = request_fee_note( + &api_url, + api_key.as_deref(), + account_id, + requested_amount, + fee_config.fee_faucet_id, + fee_config.network.network_id(), + ) + .await?; + println!( + "Faucet transaction {faucet_transaction_id} accepted; waiting for public note {} with {amount} native fee units", + note_id.to_hex() + ); + let retries = env_u32("MIDEN_FEE_SYNC_RETRIES", DEFAULT_SYNC_RETRIES)?; + let note_id_hex = note_id.to_hex(); + + let mut note_record = None; + for attempt in 1..=retries { + client.sync_state().await?; + if let Some(record) = client.get_input_note(note_id).await? { + if record.is_committed() { + note_record = Some(record); + break; + } + } + + if attempt < retries { + tokio::time::sleep(SYNC_RETRY_DELAY).await; + } + } + + let note_record = note_record.ok_or_else(|| { + tutorial_error(format!( + "native fee note {note_id_hex} from faucet transaction {faucet_transaction_id} was not committed after {retries} sync attempts" + )) + })?; + let input_note = note_record.try_into()?; + + let request = TransactionRequestBuilder::new().build_consume_notes(vec![input_note])?; + client.sync_state().await?; + let transaction_id = client.submit_new_transaction(account_id, request).await?; + println!("Native fee funding transaction submitted: {transaction_id:?}"); + + for attempt in 1..=retries { + client.sync_state().await?; + let transactions = client + .get_transactions(TransactionFilter::Ids(vec![transaction_id])) + .await?; + if let Some(transaction) = transactions.first() { + match &transaction.status { + TransactionStatus::Committed { .. } => { + println!("Native fee funding transaction committed: {transaction_id:?}"); + return Ok(()); + } + TransactionStatus::Discarded(cause) => { + return Err(tutorial_error(format!( + "native fee funding transaction {transaction_id:?} was discarded: {cause}" + ))); + } + TransactionStatus::Pending => {} + } + } + + if attempt < retries { + tokio::time::sleep(SYNC_RETRY_DELAY).await; + } + } + + return Err(tutorial_error(format!( + "native fee funding transaction {transaction_id:?} was not committed after {retries} sync attempts" + ))); +} + +#[derive(Debug, Deserialize)] +struct PowResponse { + challenge: String, + target: u64, +} + +#[derive(Debug, Deserialize)] +struct MintResponse { + note_id: String, + tx_id: String, +} + +#[derive(Debug, Deserialize)] +struct MetadataResponse { + id: String, + base_amount: u64, +} + +async fn request_fee_note( + api_url: &str, + api_key: Option<&str>, + account_id: AccountId, + requested_amount: Option, + expected_faucet_id: AccountId, + expected_network_id: NetworkId, +) -> Result<(NoteId, String, u64), ClientError> { + let http = reqwest::Client::builder() + .timeout(REQUEST_TIMEOUT) + .build() + .map_err(|error| tutorial_error(format!("failed to build faucet HTTP client: {error}")))?; + let base_url = reqwest::Url::parse(api_url) + .map_err(|error| tutorial_error(format!("invalid MIDEN_FAUCET_URL: {error}")))?; + + let metadata_url = base_url + .join("get_metadata") + .map_err(|error| tutorial_error(format!("invalid faucet metadata URL: {error}")))?; + let response = http + .get(metadata_url) + .send() + .await + .map_err(|error| tutorial_error(format!("faucet metadata request failed: {error}")))?; + let response = checked_response(response, "metadata", api_url).await?; + let metadata: MetadataResponse = response.json().await.map_err(|error| { + tutorial_error(format!( + "failed to decode faucet metadata response: {error}" + )) + })?; + let (actual_network_id, address) = Address::decode(&metadata.id).map_err(|error| { + tutorial_error(format!( + "faucet metadata returned an invalid address `{}`: {error}", + metadata.id + )) + })?; + if actual_network_id != expected_network_id { + return Err(tutorial_error(format!( + "faucet {api_url} is for {actual_network_id:?}, but the tutorial is using {expected_network_id:?}" + ))); + } + let actual_faucet_id = match address.id() { + AddressId::AccountId(account_id) => account_id, + _ => { + return Err(tutorial_error(format!( + "faucet metadata address `{}` is not account-based", + metadata.id + ))); + } + }; + if actual_faucet_id != expected_faucet_id { + return Err(tutorial_error(format!( + "faucet {api_url} issues asset {}, but the selected chain requires native fee asset {}", + actual_faucet_id.to_hex(), + expected_faucet_id.to_hex() + ))); + } + let amount = requested_amount.unwrap_or(metadata.base_amount); + if amount == 0 { + return Err(tutorial_error( + "MIDEN_FEE_AMOUNT or the faucet's advertised base amount must be greater than zero", + )); + } + + let mut pow_params = vec![ + ("account_id", account_id.to_hex()), + ("amount", amount.to_string()), + ]; + if let Some(api_key) = api_key { + pow_params.push(("api_key", api_key.to_owned())); + } + + let pow_url = base_url + .join("pow") + .map_err(|error| tutorial_error(format!("invalid faucet PoW URL: {error}")))?; + let response = http + .get(pow_url) + .query(&pow_params) + .send() + .await + .map_err(|error| tutorial_error(format!("faucet PoW request failed: {error}")))?; + let response = checked_response(response, "PoW", api_url).await?; + let pow: PowResponse = response.json().await.map_err(|error| { + tutorial_error(format!("failed to decode faucet PoW response: {error}")) + })?; + let nonce = solve_pow(pow.challenge.clone(), pow.target).await?; + + let mut mint_params = vec![ + ("account_id", account_id.to_hex()), + ("is_private_note", "false".to_owned()), + ("asset_amount", amount.to_string()), + ("challenge", pow.challenge), + ("nonce", nonce.to_string()), + ]; + if let Some(api_key) = api_key { + mint_params.push(("api_key", api_key.to_owned())); + } + + let mint_url = base_url + .join("get_tokens") + .map_err(|error| tutorial_error(format!("invalid faucet mint URL: {error}")))?; + let response = http + .get(mint_url) + .query(&mint_params) + .send() + .await + .map_err(|error| tutorial_error(format!("faucet mint request failed: {error}")))?; + let response = checked_response(response, "mint", api_url).await?; + let mint: MintResponse = response.json().await.map_err(|error| { + tutorial_error(format!("failed to decode faucet mint response: {error}")) + })?; + + let note_id = NoteId::try_from_hex(&mint.note_id) + .map_err(|error| tutorial_error(format!("faucet returned an invalid note ID: {error}")))?; + Ok((note_id, mint.tx_id, amount)) +} + +async fn checked_response( + response: reqwest::Response, + operation: &str, + api_url: &str, +) -> Result { + if response.status().is_success() { + return Ok(response); + } + + let status = response.status(); + let body = response.text().await.unwrap_or_default(); + Err(tutorial_error(format!( + "faucet {operation} request to {api_url} failed with {status}: {body}. Set \ + MIDEN_FAUCET_URL to a fee-faucet API compatible with the selected network" + ))) +} + +async fn solve_pow(challenge_hex: String, target: u64) -> Result { + if target == 0 { + return Err(tutorial_error("faucet returned a zero PoW target")); + } + let challenge = hex::decode(&challenge_hex).map_err(|error| { + tutorial_error(format!("faucet returned invalid challenge hex: {error}")) + })?; + + tokio::task::spawn_blocking(move || { + for nonce in 0..=u64::MAX { + let mut hasher = Sha256::new(); + hasher.update(&challenge); + hasher.update(nonce.to_be_bytes()); + let digest = hasher.finalize(); + let prefix = u64::from_be_bytes(digest[..8].try_into().expect("SHA-256 prefix")); + if prefix < target { + return nonce; + } + } + unreachable!("a valid u64 PoW nonce should exist") + }) + .await + .map_err(|error| tutorial_error(format!("faucet PoW task failed: {error}"))) +} + +fn env_u32(name: &str, default: u32) -> Result { + env::var(name).map_or(Ok(default), |value| { + value + .parse() + .map_err(|error| tutorial_error(format!("invalid {name} value `{value}`: {error}"))) + }) +} + +fn tutorial_error(message: impl Display) -> ClientError { + ClientError::Observer(Box::new(std::io::Error::other(message.to_string()))) +} + +#[cfg(test)] +mod tests { + use super::*; + use miden_client::note::P2idNote; + + #[test] + fn fee_notes_do_not_count_as_tutorial_transfers() { + assert!(!is_tutorial_note_script(TxFeeNote::script_root())); + assert!(is_tutorial_note_script(P2idNote::script_root())); + } + + #[tokio::test] + async fn invalid_pow_challenges_fail_instead_of_looping() { + assert!(solve_pow("00".into(), 0).await.is_err()); + assert!(solve_pow("not hex".into(), u64::MAX).await.is_err()); + } + + #[tokio::test] + async fn pow_nonce_satisfies_faucet_target() { + let nonce = solve_pow("abcd".into(), u64::MAX).await.unwrap(); + let mut hasher = Sha256::new(); + hasher.update([0xab, 0xcd]); + hasher.update(nonce.to_be_bytes()); + let digest = hasher.finalize(); + assert!(u64::from_be_bytes(digest[..8].try_into().unwrap()) < u64::MAX); + } +} diff --git a/rust-client/tests/masm_compilation.rs b/rust-client/tests/masm_compilation.rs new file mode 100644 index 00000000..1d24f398 --- /dev/null +++ b/rust-client/tests/masm_compilation.rs @@ -0,0 +1,36 @@ +//! Compile the standalone MASM artifacts that do not have a self-contained network run. + +use miden_client::assembly::CodeBuilder; + +#[test] +fn standalone_fee_auth_component_compiles() { + CodeBuilder::new() + .compile_component_code( + "tutorials::auth", + include_str!("../../masm/accounts/auth/no_auth.masm"), + ) + .expect("the standalone no-auth component must support the v0.16 fee API"); +} + +#[test] +fn oracle_component_and_transaction_script_compile_without_a_deployment() { + // These are assembly operands, not an oracle deployment or runtime price proof. + let component_code = include_str!("../../masm/accounts/oracle_reader.masm") + .replace("{pair_suffix}", "0") + .replace("{pair_prefix}", "1") + .replace( + "{get_median_proc_root}", + "0x0000000000000000000000000000000000000000000000000000000000000000", + ) + .replace("{oracle_id_prefix}", "1") + .replace("{oracle_id_suffix}", "0"); + + CodeBuilder::new() + .compile_component_code("external_contract::oracle_reader", &component_code) + .expect("the oracle reader component must assemble before a deployment is configured"); + CodeBuilder::new() + .with_linked_module("external_contract::oracle_reader", &component_code) + .unwrap() + .compile_tx_script(include_str!("../../masm/scripts/oracle_reader_script.masm")) + .expect("the oracle transaction must link its account procedure"); +} diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 00000000..c3f67b67 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "1.98.1" +profile = "minimal" +components = ["rustfmt", "clippy"] diff --git a/scripts/run_tutorials.sh b/scripts/run_tutorials.sh index 318776a6..29d5291f 100644 --- a/scripts/run_tutorials.sh +++ b/scripts/run_tutorials.sh @@ -12,6 +12,9 @@ WEB_EXAMPLES=( incrementCounterContract unauthenticatedNoteTransfer foreignProcedureInvocation + react:createMintConsume + react:multiSendWithDelegatedProver + react:unauthenticatedNoteTransfer ) WEB_SKIPPED=() @@ -31,11 +34,7 @@ RUST_EXAMPLES=( unauthenticated_note_transfer ) -RUST_SKIPPED=( - counter_contract_fpi - counter_contract_increment - oracle_data_query -) +RUST_SKIPPED=(oracle_data_query) usage() { cat <<'EOF' @@ -49,6 +48,10 @@ Examples: yarn tutorials --rust yarn tutorials --web=createMintConsume yarn tutorials --rust=counter_contract_deploy + +The default network is testnet. Set TUTORIAL_NETWORK=devnet for devnet tests. +Counter FPI/increment use a counter deployed by this run unless +MIDEN_COUNTER_ACCOUNT_ID is set. EOF } @@ -92,6 +95,12 @@ saw_selector=0 web_names=() rust_names=() failures=() +tutorial_network="${TUTORIAL_NETWORK:-testnet}" + +if [[ "$tutorial_network" != "testnet" && "$tutorial_network" != "devnet" ]]; then + echo "TUTORIAL_NETWORK must be either testnet or devnet, got: $tutorial_network" >&2 + exit 1 +fi while [[ $# -gt 0 ]]; do case "$1" in @@ -187,8 +196,11 @@ if [[ "$run_web" -eq 1 ]]; then done web_pattern="$(IFS='|'; echo "${web_names[*]}")" - echo "Running web tutorials: ${web_names[*]}" - if ! yarn --cwd "$WEB_DIR" playwright test --grep "$web_pattern"; then + echo "Running web tutorials on $tutorial_network: ${web_names[*]}" + if ! NEXT_PUBLIC_MIDEN_NETWORK="$tutorial_network" \ + NEXT_PUBLIC_MIDEN_FAUCET_URL="${MIDEN_FAUCET_URL:-}" \ + NEXT_PUBLIC_MIDEN_FEE_AMOUNT="${MIDEN_FEE_AMOUNT:-}" \ + yarn --cwd "$WEB_DIR" playwright test --grep "(^| )($web_pattern)$"; then failures+=("web") fi fi @@ -214,7 +226,18 @@ if [[ "$run_rust" -eq 1 ]]; then fi done - echo "Cleaning rust build artifacts before running tutorials..." + # Dependent tutorials must never reuse an account from an older network genesis. + if contains counter_contract_fpi "${rust_names[@]}" || contains counter_contract_increment "${rust_names[@]}"; then + if [[ -z "${MIDEN_COUNTER_ACCOUNT_ID:-}" ]]; then + ordered_names=(counter_contract_deploy) + for name in "${rust_names[@]}"; do + [[ "$name" == counter_contract_deploy ]] || ordered_names+=("$name") + done + rust_names=("${ordered_names[@]}") + fi + fi + + echo "Cleaning rust build artifacts before running tutorials on $tutorial_network..." cargo clean --manifest-path "$RUST_DIR/Cargo.toml" mkdir -p "$RUNS_DIR" @@ -239,13 +262,18 @@ if [[ "$run_rust" -eq 1 ]]; then set +e ( cd "$run_dir" - RUST_BACKTRACE=1 cargo run --manifest-path "$RUST_DIR/Cargo.toml" --bin "$name" + MIDEN_NETWORK="$tutorial_network" RUST_BACKTRACE=1 \ + cargo run --locked --manifest-path "$RUST_DIR/Cargo.toml" --bin "$name" ) 2>&1 | tee "$run_dir/output.log" status=${PIPESTATUS[0]} set -e echo "Output log: $run_dir/output.log" if [[ "$status" -eq 0 ]]; then + if [[ "$name" == counter_contract_deploy ]]; then + MIDEN_COUNTER_ACCOUNT_ID="$(sed -n 's/^Counter contract id: "\([^"]*\)"$/\1/p' "$run_dir/output.log" | tail -n 1)" + export MIDEN_COUNTER_ACCOUNT_ID + fi break fi diff --git a/web-client/README.md b/web-client/README.md index e215bc4c..553b9fca 100644 --- a/web-client/README.md +++ b/web-client/README.md @@ -16,6 +16,9 @@ bun dev Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. +The tutorials use v0.16 on testnet. Run `yarn playwright test` to execute them. +See the [setup guide](../docs/src/web-client/setup_guide.md) for fee funding. + You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel. diff --git a/web-client/app/react-tutorials/page.tsx b/web-client/app/react-tutorials/page.tsx new file mode 100644 index 00000000..01c8194e --- /dev/null +++ b/web-client/app/react-tutorials/page.tsx @@ -0,0 +1,44 @@ +'use client'; + +import dynamic from 'next/dynamic'; +import { useEffect, useState } from 'react'; + +const tutorials = { + createMintConsume: dynamic( + () => import('../../lib/react/createMintConsume'), + { ssr: false }, + ), + multiSendWithDelegatedProver: dynamic( + () => import('../../lib/react/multiSendWithDelegatedProver'), + { ssr: false }, + ), + unauthenticatedNoteTransfer: dynamic( + () => import('../../lib/react/unauthenticatedNoteTransfer'), + { ssr: false }, + ), +}; + +export default function ReactTutorials() { + const [selected, setSelected] = useState(null); + useEffect(() => { + const requested = new URLSearchParams(window.location.search).get( + 'tutorial', + ); + if (requested && requested in tutorials) + setSelected(requested as keyof typeof tutorials); + }, []); + const Tutorial = selected ? tutorials[selected] : null; + return ( +
+

React SDK tutorials

+ + {Tutorial && } +
+ ); +} diff --git a/web-client/lib/createMintConsume.ts b/web-client/lib/createMintConsume.ts index 9fcae5d5..aa361a73 100644 --- a/web-client/lib/createMintConsume.ts +++ b/web-client/lib/createMintConsume.ts @@ -1,5 +1,10 @@ // lib/createMintConsume.ts -import { MidenClient, NoteVisibility, StorageMode } from '@miden-sdk/miden-sdk/lazy'; +import { NoteVisibility, StorageMode } from '@miden-sdk/miden-sdk/lazy'; +import { + consumeAllFeeAware, + createTutorialClient, + fundAccountForFees, +} from './feeSupport'; export async function createMintConsume(): Promise { if (typeof window === 'undefined') { @@ -7,10 +12,8 @@ export async function createMintConsume(): Promise { return; } - await MidenClient.ready(); - - const client = await MidenClient.create({ - rpcUrl: 'https://rpc.testnet.miden.io', + const client = await createTutorialClient({ + proverUrl: 'local', }); // 1. Sync with the latest blockchain state @@ -24,7 +27,8 @@ export async function createMintConsume(): Promise { }); console.log('Alice ID:', alice.id().toString()); - // 3. Deploy a fungible faucet + // 3. Create our own fungible faucet. SDK v0.16 includes BasicWallet, + // allowing both accounts to consume native fee funding before minting MID. console.log('Creating faucet…'); const faucet = await client.accounts.create({ type: 0, // 0 = FungibleFaucet @@ -34,36 +38,46 @@ export async function createMintConsume(): Promise { storage: StorageMode.Public, }); console.log('Faucet ID:', faucet.id().toString()); + await fundAccountForFees(client, alice); + await fundAccountForFees(client, faucet); - // 4. Mint tokens to Alice + // 4. Mint tokens to Alice. console.log('Minting tokens to Alice...'); + await client.sync(); const { txId: mintTxId } = await client.transactions.mint({ account: faucet, to: alice, amount: BigInt(1000), type: NoteVisibility.Public, }); - console.log('Waiting for transaction confirmation...'); - await client.transactions.waitFor(mintTxId); + await client.transactions.waitFor(mintTxId, { timeout: 120_000 }); - // 5-6. Consume all available notes for Alice + // 5-6. Consume all available notes for Alice. console.log('Consuming minted notes...'); - await client.transactions.consumeAll({ - account: alice, - }); + await consumeAllFeeAware(client, alice); console.log('Notes consumed.'); // 7. Send tokens to Bob - const bobAddress = 'mtst1arpsz3jlmjxl7u2jjzfsc0wyqyaas6a9'; + const bob = await client.accounts.create({ + storage: StorageMode.Public, + }); console.log("Sending tokens to Bob's account..."); - await client.transactions.send({ + await client.sync(); + const { txId: sendTxId } = await client.transactions.send({ account: alice, - to: bobAddress, + to: bob, token: faucet, amount: BigInt(100), type: NoteVisibility.Public, + waitForConfirmation: true, + timeout: 120_000, }); + console.log(`Transaction committed: ${sendTxId.toHex()}`); + const updatedAlice = await client.accounts.get(alice); + const balance = updatedAlice?.vault().getBalance(faucet.id()); + if (balance !== BigInt(900)) + throw new Error(`Expected Alice to retain 900 MID, got ${balance}`); console.log('Tokens sent successfully!'); } diff --git a/web-client/lib/feeSupport.ts b/web-client/lib/feeSupport.ts new file mode 100644 index 00000000..abae17a8 --- /dev/null +++ b/web-client/lib/feeSupport.ts @@ -0,0 +1,288 @@ +import { + Account, + AccountBuilder, + AccountComponent, + AccountId, + AccountStorageMode, + AuthSecretKey, + Endpoint, + MidenClient, + RpcClient, + type ClientOptions, + type InputNoteRecord, +} from '@miden-sdk/miden-sdk/lazy'; + +type TutorialNetwork = 'testnet' | 'devnet'; +type ExecutingAccount = Account | AccountId; + +type FaucetPowResponse = { + challenge: string; + target: string | number; +}; + +type FaucetMintResponse = { + note_id: string; + tx_id: string; +}; + +type FaucetMetadata = { + base_amount: number; + id: string; +}; + +const DEFAULT_DEVNET_FAUCET_URL = 'https://faucet-api.devnet.miden.io'; +const DEFAULT_TESTNET_FAUCET_URL = 'https://faucet-api.testnet.miden.io'; +// Network notes settle asynchronously; keep a bounded two-minute polling window. +const FUNDING_NOTE_POLL_ATTEMPTS = 24; +const FUNDING_NOTE_POLL_INTERVAL_MS = 5_000; + +export function tutorialNetwork(): TutorialNetwork { + const configured = process.env.NEXT_PUBLIC_MIDEN_NETWORK?.toLowerCase(); + + if (!configured || configured === 'testnet') return 'testnet'; + if (configured === 'devnet') return 'devnet'; + + throw new Error( + `Unsupported NEXT_PUBLIC_MIDEN_NETWORK=${configured}; expected testnet or devnet`, + ); +} + +export function tutorialExplorerUrl(): string { + return tutorialNetwork() === 'devnet' + ? 'https://devnet.midenscan.com' + : 'https://testnet.midenscan.com'; +} + +export async function createTutorialClient( + options: ClientOptions = {}, +): Promise { + await MidenClient.ready(); + return tutorialNetwork() === 'devnet' + ? MidenClient.createDevnet(options) + : MidenClient.createTestnet(options); +} + +/** + * The high-level contract helper installs auth plus the custom component. A + * fee-enabled contract also needs BasicWallet so its bootstrap P2ID note can + * deposit the native fee asset into the vault. + */ +export async function createFundableContractAccount( + client: MidenClient, + seed: Uint8Array, + auth: AuthSecretKey, + components: AccountComponent[], +): Promise { + let builder = new AccountBuilder(seed) + .storageMode(AccountStorageMode.public()) + .withAuthComponent(AccountComponent.createAuthComponentFromSecretKey(auth)) + .withBasicWalletComponent(); + + for (const component of components) { + builder = builder.withComponent(component); + } + + const account = builder.build().account; + await client.accounts.insert({ account }); + await client.keystore.insert(account.id(), auth); + return account; +} + +function accountId(account: ExecutingAccount): AccountId { + return account instanceof Account ? account.id() : account; +} + +/** Read the native fee asset and activation from the selected chain. */ +export async function tutorialFeeConfig() { + const endpoint = + tutorialNetwork() === 'devnet' ? Endpoint.devnet() : Endpoint.testnet(); + const header = await new RpcClient(endpoint).getBlockHeaderByNumber(); + return { + faucetId: header.feeFaucetId(), + baseFee: header.verificationBaseFee(), + }; +} + +export async function consumeAllFeeAware( + client: MidenClient, + account: ExecutingAccount, +) { + await client.sync(); + const available = await client.notes.listAvailable({ + account: accountId(account), + }); + // TX_FEE notes (tag 0xFEE) are consumable by any account; they are not P2ID transfers. + const notes = available.filter( + (note) => note.metadata()?.tag().asU32() !== 0xfee, + ); + if (notes.length === 0) { + throw new Error(`No consumable notes found for ${accountId(account)}`); + } + return client.transactions.consume({ + account, + notes, + waitForConfirmation: true, + timeout: 120_000, + }); +} + +function faucetUrl(): string { + const configured = process.env.NEXT_PUBLIC_MIDEN_FAUCET_URL?.trim(); + if (configured) return configured.replace(/\/$/, ''); + + return tutorialNetwork() === 'devnet' + ? DEFAULT_DEVNET_FAUCET_URL + : DEFAULT_TESTNET_FAUCET_URL; +} + +function hexBytes(value: string): Uint8Array { + const hex = value.replace(/^0x/, ''); + if (hex.length % 2 !== 0 || !/^[0-9a-f]+$/i.test(hex)) { + throw new Error('The faucet returned an invalid PoW challenge'); + } + + return Uint8Array.from(hex.match(/.{2}/g)!, (byte) => + Number.parseInt(byte, 16), + ); +} + +async function solvePow(challenge: string, target: bigint): Promise { + const challengeBytes = hexBytes(challenge); + const nonceBytes = new Uint8Array(8); + const nonceView = new DataView(nonceBytes.buffer); + const input = new Uint8Array(challengeBytes.length + nonceBytes.length); + input.set(challengeBytes); + + for (let attempt = 0; ; attempt += 1) { + const high = BigInt(crypto.getRandomValues(new Uint32Array(1))[0]); + const low = BigInt(crypto.getRandomValues(new Uint32Array(1))[0]); + const nonce = (high << BigInt(32)) | low; + nonceView.setBigUint64(0, nonce, false); + input.set(nonceBytes, challengeBytes.length); + + const hash = await crypto.subtle.digest('SHA-256', input); + const digest = new DataView(hash).getBigUint64(0, false); + if (digest < target) return nonce; + + if (attempt % 1_000 === 0) { + await new Promise((resolve) => setTimeout(resolve, 0)); + } + } +} + +async function fetchJson(url: URL | string, operation: string): Promise { + const response = await fetch(url, { signal: AbortSignal.timeout(30_000) }); + if (!response.ok) { + const body = await response.text(); + throw new Error( + `${operation} failed (${response.status}): ${body.trim()}`, + ); + } + return response.json() as Promise; +} + +export async function requestFundingNote( + recipient: AccountId, + expectedFaucet: AccountId, + requestedAmount?: number, +): Promise { + const baseUrl = faucetUrl(); + const metadata = await fetchJson( + `${baseUrl}/get_metadata`, + 'Reading faucet metadata', + ); + const actualFaucet = metadata.id.startsWith('0x') + ? AccountId.fromHex(metadata.id) + : AccountId.fromBech32(metadata.id); + if (actualFaucet.toString() !== expectedFaucet.toString()) { + throw new Error( + `Configured faucet ${actualFaucet} does not issue ${tutorialNetwork()}'s native fee asset ${expectedFaucet}`, + ); + } + + const configuredAmount = process.env.NEXT_PUBLIC_MIDEN_FEE_AMOUNT?.trim(); + const amount = + requestedAmount ?? + (configuredAmount ? Number(configuredAmount) : metadata.base_amount); + if (!Number.isSafeInteger(amount) || amount <= 0) { + throw new Error( + `Invalid fee-funding amount ${String(amount)}; expected a positive safe integer`, + ); + } + + const powUrl = new URL(`${baseUrl}/pow`); + powUrl.searchParams.set('account_id', recipient.toString()); + powUrl.searchParams.set('amount', amount.toString()); + const pow = await fetchJson( + powUrl, + 'Requesting faucet PoW', + ); + const nonce = await solvePow(pow.challenge, BigInt(pow.target)); + + const mintUrl = new URL(`${baseUrl}/get_tokens`); + mintUrl.searchParams.set('account_id', recipient.toString()); + mintUrl.searchParams.set('is_private_note', 'false'); + mintUrl.searchParams.set('asset_amount', amount.toString()); + mintUrl.searchParams.set('challenge', pow.challenge); + mintUrl.searchParams.set('nonce', nonce.toString()); + return fetchJson(mintUrl, 'Requesting fee tokens'); +} + +async function waitForFundingNote( + client: MidenClient, + noteId: string, + faucetTxId: string, +): Promise { + for (let attempt = 0; attempt < FUNDING_NOTE_POLL_ATTEMPTS; attempt += 1) { + await client.sync(); + const note = await client.notes.get(noteId); + if (note?.inclusionProof()) return note; + if (attempt < FUNDING_NOTE_POLL_ATTEMPTS - 1) { + await new Promise((resolve) => + setTimeout(resolve, FUNDING_NOTE_POLL_INTERVAL_MS), + ); + } + } + + throw new Error( + `Fee-funding note ${noteId} from faucet transaction ${faucetTxId} was not found after ${FUNDING_NOTE_POLL_ATTEMPTS} sync attempts`, + ); +} + +/** + * Funds a newly-created account with the chain's native fee asset. The first + * consume transaction can pay from the asset added by the input P2ID note, so + * this also bootstraps accounts whose vault starts empty. + */ +export async function fundAccountForFees( + client: MidenClient, + account: ExecutingAccount, + amount?: number, +): Promise { + const { faucetId: feeFaucet, baseFee } = await tutorialFeeConfig(); + if (baseFee === 0) return; + + const id = accountId(account); + await client.sync(); + // Read the native fee balance from the synchronized account vault. + const updated = await client.accounts.get(id); + if (!updated) throw new Error(`Account ${id} is not in the local store`); + const balance = updated.vault().getBalance(feeFaucet); + if (balance > BigInt(0)) return; + + console.log(`Funding ${id} with ${tutorialNetwork()} fee tokens…`); + const mint = await requestFundingNote(id, feeFaucet, amount); + console.log( + `Faucet transaction ${mint.tx_id} accepted; waiting for note ${mint.note_id}…`, + ); + const note = await waitForFundingNote(client, mint.note_id, mint.tx_id); + await client.sync(); + const { txId } = await client.transactions.consume({ + account, + notes: [note], + waitForConfirmation: true, + timeout: 120_000, + }); + await client.sync(); + console.log(`Fee funding submitted: ${txId.toHex()}`); +} diff --git a/web-client/lib/foreignProcedureInvocation.ts b/web-client/lib/foreignProcedureInvocation.ts index 47f86240..1ebe6893 100644 --- a/web-client/lib/foreignProcedureInvocation.ts +++ b/web-client/lib/foreignProcedureInvocation.ts @@ -1,7 +1,16 @@ // lib/foreignProcedureInvocation.ts import counterContractCode from './masm/counter_contract.masm'; import countReaderCode from './masm/count_reader.masm'; -import { AuthSecretKey, StorageMode, StorageSlot, StorageResult, MidenClient } from '@miden-sdk/miden-sdk/lazy'; +import { + AuthSecretKey, + StorageSlot, + StorageResult, +} from '@miden-sdk/miden-sdk/lazy'; +import { + createFundableContractAccount, + createTutorialClient, + fundAccountForFees, +} from './feeSupport'; export async function foreignProcedureInvocation(): Promise { if (typeof window === 'undefined') { @@ -9,10 +18,7 @@ export async function foreignProcedureInvocation(): Promise { return; } - await MidenClient.ready(); - - const nodeEndpoint = 'https://rpc.testnet.miden.io'; - const client = await MidenClient.create({ rpcUrl: nodeEndpoint }); + const client = await createTutorialClient({ proverUrl: 'local' }); console.log('Current block number: ', (await client.sync()).blockNum()); const counterSlotName = 'miden::tutorials::counter'; @@ -32,30 +38,54 @@ export async function foreignProcedureInvocation(): Promise { crypto.getRandomValues(counterSeed); const counterAuth = AuthSecretKey.rpoFalconWithRNG(counterSeed); - const counterAccount = await client.accounts.create({ - storage: StorageMode.Public, - seed: counterSeed, - auth: counterAuth, - components: [counterComponent], - }); + const counterAccount = await createFundableContractAccount( + client, + counterSeed, + counterAuth, + [counterComponent], + ); + + await fundAccountForFees(client, counterAccount); // Deploy the counter to the node by executing a transaction on it const deployScript = await client.compile.txScript({ code: ` - use external_contract::counter_contract - begin - call.counter_contract::increment_count - end - `, - libraries: [{ namespace: 'external_contract::counter_contract', code: counterContractCode }], +use external_contract::counter_contract + +#! Increments the counter. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) + dropw + # => [pad(16)] + + call.counter_contract::increment_count + # => [pad(16)] +end +`, + libraries: [ + { + namespace: 'external_contract::counter_contract', + code: counterContractCode, + }, + ], }); // Wait for the deploy transaction to be committed to a block // before using it as a foreign account in FPI + await client.sync(); await client.transactions.execute({ account: counterAccount, script: deployScript, waitForConfirmation: true, + timeout: 120_000, }); console.log('Counter contract ID:', counterAccount.id().toString()); @@ -73,12 +103,14 @@ export async function foreignProcedureInvocation(): Promise { crypto.getRandomValues(readerSeed); const readerAuth = AuthSecretKey.rpoFalconWithRNG(readerSeed); - let countReaderAccount = await client.accounts.create({ - storage: StorageMode.Public, - seed: readerSeed, - auth: readerAuth, - components: [countReaderComponent], - }); + const countReaderAccount = await createFundableContractAccount( + client, + readerSeed, + readerAuth, + [countReaderComponent], + ); + + await fundAccountForFees(client, countReaderAccount); console.log('Count reader contract ID:', countReaderAccount.id().toString()); @@ -92,11 +124,21 @@ export async function foreignProcedureInvocation(): Promise { const getCountProcHash = counterComponent.getProcedureHash('get_count'); const fpiScriptCode = ` - use external_contract::count_reader_contract - use miden::core::sys - - begin - padw padw padw padw +use external_contract::count_reader_contract +use miden::core::sys + +#! Copies a public counter through the reader account. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) + dropw # => [pad(16)] push.${getCountProcHash} @@ -109,24 +151,32 @@ export async function foreignProcedureInvocation(): Promise { # => [account_id_suffix, account_id_prefix, GET_COUNT_HASH, pad(16)] call.count_reader_contract::copy_count - # => [] + # => [pad(16)] exec.sys::truncate_stack - # => [] - - end + # => [pad(16)] +end `; const script = await client.compile.txScript({ code: fpiScriptCode, - libraries: [{ namespace: 'external_contract::count_reader_contract', code: countReaderCode }], + libraries: [ + { + namespace: 'external_contract::count_reader_contract', + code: countReaderCode, + }, + ], }); - await client.transactions.execute({ + await client.sync(); + const { txId } = await client.transactions.execute({ account: countReaderAccount, script, foreignAccounts: [counterAccount], + waitForConfirmation: true, + timeout: 120_000, }); + console.log(`Transaction committed: ${txId.toHex()}`); const updatedCountReader = await client.accounts.get(countReaderAccount); // `getItem()` is typed to return a low-level `Word`, but at runtime the SDK @@ -138,7 +188,11 @@ export async function foreignProcedureInvocation(): Promise { if (countReaderStorage) { const countValue = Number(countReaderStorage.toBigInt()); + if (countValue !== 1) + throw new Error(`Expected copied counter 1, got ${countValue}`); console.log('Count copied via Foreign Procedure Invocation:', countValue); + } else { + throw new Error('Count reader storage was not available after commitment'); } console.log('\nForeign Procedure Invocation Transaction completed!'); diff --git a/web-client/lib/incrementCounterContract.ts b/web-client/lib/incrementCounterContract.ts index f5fd41d3..ae617730 100644 --- a/web-client/lib/incrementCounterContract.ts +++ b/web-client/lib/incrementCounterContract.ts @@ -1,6 +1,15 @@ // lib/incrementCounterContract.ts import counterContractCode from './masm/counter_contract.masm'; -import { AuthSecretKey, StorageMode, StorageSlot, StorageResult, MidenClient } from '@miden-sdk/miden-sdk/lazy'; +import { + AuthSecretKey, + StorageSlot, + StorageResult, +} from '@miden-sdk/miden-sdk/lazy'; +import { + createFundableContractAccount, + createTutorialClient, + fundAccountForFees, +} from './feeSupport'; export async function incrementCounterContract(): Promise { if (typeof window === 'undefined') { @@ -8,10 +17,7 @@ export async function incrementCounterContract(): Promise { return; } - await MidenClient.ready(); - - const nodeEndpoint = 'https://rpc.testnet.miden.io'; - const client = await MidenClient.create({ rpcUrl: nodeEndpoint }); + const client = await createTutorialClient({ proverUrl: 'local' }); console.log('Current block number: ', (await client.sync()).blockNum()); const counterSlotName = 'miden::tutorials::counter'; @@ -25,29 +31,55 @@ export async function incrementCounterContract(): Promise { crypto.getRandomValues(walletSeed); const auth = AuthSecretKey.rpoFalconWithRNG(walletSeed); - const account = await client.accounts.create({ - storage: StorageMode.Public, - seed: walletSeed, + const account = await createFundableContractAccount( + client, + walletSeed, auth, - components: [counterAccountComponent], - }); + [counterAccountComponent], + ); + + await fundAccountForFees(client, account); const txScriptCode = ` - use external_contract::counter_contract - begin +use external_contract::counter_contract + +#! Increments the counter. +#! +#! Inputs: [ARGS, pad(12)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - ARGS contains unused transaction script arguments. +#! +#! Invocation: dyncall +@transaction_script +pub proc main(args: word) + dropw + # => [pad(16)] + call.counter_contract::increment_count - end + # => [pad(16)] +end `; const script = await client.compile.txScript({ code: txScriptCode, - libraries: [{ namespace: 'external_contract::counter_contract', code: counterContractCode }], + libraries: [ + { + namespace: 'external_contract::counter_contract', + code: counterContractCode, + }, + ], }); - await client.transactions.execute({ + await client.sync(); + const { txId } = await client.transactions.execute({ account, script, + waitForConfirmation: true, + timeout: 120_000, }); + console.log(`Transaction committed: ${txId.toHex()}`); console.log('Counter contract ID:', account.id().toString()); @@ -56,8 +88,9 @@ export async function incrementCounterContract(): Promise { // wraps the slot in a `StorageResult` whose `toBigInt()` reads the first // felt — the count. The cast reflects that runtime type. const count = counter?.storage().getItem(counterSlotName) as unknown as - | StorageResult - | undefined; + StorageResult | undefined; const counterValue = Number(count!.toBigInt()); + if (counterValue !== 1) + throw new Error(`Expected counter 1, got ${counterValue}`); console.log('Count: ', counterValue); } diff --git a/web-client/lib/masm/count_reader.masm b/web-client/lib/masm/count_reader.masm index 5d92db91..7eed5e0a 100644 --- a/web-client/lib/masm/count_reader.masm +++ b/web-client/lib/masm/count_reader.masm @@ -1,26 +1,51 @@ -use miden::protocol::active_account use miden::protocol::native_account use miden::protocol::tx -use miden::core::word use miden::core::sys +use {AccountId, AccountProcedureRoot} from miden::protocol::types + +# CONSTANTS +# ================================================================================================= -# The storage slot where the copied count is stored. const COUNT_READER_SLOT = word("miden::tutorials::count_reader") -# => [account_id_suffix, account_id_prefix, PROC_HASH(4), foreign_procedure_inputs(16)] -pub proc copy_count +# PUBLIC INTERFACE +# ================================================================================================= + +#! Copies the count returned by the foreign counter into this account's storage. +#! +#! Inputs: [foreign_account_id_{suffix,prefix}, FOREIGN_PROC_ROOT, pad(10)] +#! Outputs: [pad(16)] +#! +#! Where: +#! - foreign_account_id_{suffix,prefix} identifies the public counter account. +#! - FOREIGN_PROC_ROOT is the root of its get_count procedure. +#! +#! Invocation: call +@account_procedure +@locals(6) +pub proc copy_count(foreign_account_id: AccountId, foreign_proc_root: AccountProcedureRoot) + # save the foreign target while preparing its sixteen zero inputs + loc_store.4 loc_store.5 loc_storew_le.0 dropw + # => [pad(16)] + + padw padw padw padw + # => [foreign_procedure_inputs(16), pad(16)] + + padw loc_loadw_le.0 loc_load.5 loc_load.4 + # => [foreign_account_id_suffix, foreign_account_id_prefix, FOREIGN_PROC_ROOT, foreign_procedure_inputs(16), pad(16)] + exec.tx::execute_foreign_procedure - # => [count, pad(12)] + # => [[count, 0, 0, 0], pad(28)] push.COUNT_READER_SLOT[0..2] - # [slot_id_prefix, slot_id_suffix, count, pad(12)] + # => [slot_id_suffix, slot_id_prefix, [count, 0, 0, 0], pad(28)] exec.native_account::set_item - # => [OLD_VALUE, pad(12)] + # => [OLD_VALUE, pad(28)] - dropw dropw dropw dropw - # => [] + dropw + # => [pad(28)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end diff --git a/web-client/lib/masm/counter_contract.masm b/web-client/lib/masm/counter_contract.masm index 8ac3bbc5..d14dd300 100644 --- a/web-client/lib/masm/counter_contract.masm +++ b/web-client/lib/masm/counter_contract.masm @@ -1,32 +1,50 @@ use miden::protocol::active_account use miden::protocol::native_account -use miden::core::word use miden::core::sys +# CONSTANTS +# ================================================================================================= + const COUNTER_SLOT = word("miden::tutorials::counter") -#! Inputs: [] -#! Outputs: [count] -pub proc get_count +# PUBLIC INTERFACE +# ================================================================================================= + +#! Returns the current count. +#! +#! Inputs: [pad(16)] +#! Outputs: [count, pad(15)] +#! +#! Invocation: call +@account_procedure +pub proc get_count() -> felt push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] exec.sys::truncate_stack - # => [count] + # => [count, pad(15)] end -#! Inputs: [] -#! Outputs: [] -pub proc increment_count +#! Increments the current count by one. +#! +#! Inputs: [pad(16)] +#! Outputs: [pad(16)] +#! +#! Invocation: call +@account_procedure +pub proc increment_count() push.COUNTER_SLOT[0..2] exec.active_account::get_item - # => [count] + # => [[count, 0, 0, 0], pad(16)] add.1 - # => [count+1] + # => [[count + 1, 0, 0, 0], pad(16)] push.COUNTER_SLOT[0..2] exec.native_account::set_item - # => [] + # => [OLD_VALUE, pad(16)] + + dropw + # => [pad(16)] exec.sys::truncate_stack - # => [] + # => [pad(16)] end diff --git a/web-client/lib/mintTestnetToAddress.ts b/web-client/lib/mintTestnetToAddress.ts index f3df7531..f3352e18 100644 --- a/web-client/lib/mintTestnetToAddress.ts +++ b/web-client/lib/mintTestnetToAddress.ts @@ -1,7 +1,12 @@ /** - * Mint 100 MIDEN tokens on testnet to a fixed recipient. + * Mint 100 MID base units on the configured network to a newly created recipient. + * Uses testnet unless another network is configured explicitly. */ -import { MidenClient, NoteVisibility, StorageMode } from '@miden-sdk/miden-sdk/lazy'; +import { NoteVisibility, StorageMode } from '@miden-sdk/miden-sdk/lazy'; +import { + createTutorialClient, + fundAccountForFees, +} from './feeSupport'; export async function mintTestnetToAddress(): Promise { if (typeof window === 'undefined') { @@ -9,10 +14,8 @@ export async function mintTestnetToAddress(): Promise { return; } - await MidenClient.ready(); - - const client = await MidenClient.create({ - rpcUrl: 'https://rpc.testnet.miden.io', + const client = await createTutorialClient({ + proverUrl: 'local', }); console.log('Latest block:', (await client.sync()).blockNum()); @@ -27,22 +30,25 @@ export async function mintTestnetToAddress(): Promise { storage: StorageMode.Public, }); console.log('Faucet ID:', faucet.id().toString()); + await fundAccountForFees(client, faucet); // ── Mint to recipient ─────────────────────────────────────────────────────── - const recipientAddress = 'mtst1arpsz3jlmjxl7u2jjzfsc0wyqyaas6a9'; + const recipient = await client.accounts.create({ + storage: StorageMode.Public, + }); + const recipientAddress = recipient.id().toString(); console.log('Recipient address:', recipientAddress); - console.log('Minting 100 MIDEN tokens...'); + console.log('Minting 100 MID base units...'); + await client.sync(); const { txId: mintTxId } = await client.transactions.mint({ account: faucet, - to: recipientAddress, + to: recipient, amount: BigInt(100), type: NoteVisibility.Public, }); - console.log('Waiting for settlement...'); - await client.transactions.waitFor(mintTxId); - + await client.transactions.waitFor(mintTxId, { timeout: 120_000 }); console.log('Mint tx id:', mintTxId.toHex()); console.log('Mint complete.'); } diff --git a/web-client/lib/multiSendWithDelegatedProver.ts b/web-client/lib/multiSendWithDelegatedProver.ts index e4565fbd..39128b3d 100644 --- a/web-client/lib/multiSendWithDelegatedProver.ts +++ b/web-client/lib/multiSendWithDelegatedProver.ts @@ -5,23 +5,22 @@ * @throws {Error} If the function cannot be executed in a browser environment */ import { - MidenClient, + NoteArray, NoteVisibility, StorageMode, createP2IDNote, - NoteArray, - TransactionRequestBuilder, } from '@miden-sdk/miden-sdk/lazy'; +import { + consumeAllFeeAware, + createTutorialClient, + fundAccountForFees, +} from './feeSupport'; export async function multiSendWithDelegatedProver(): Promise { // Ensure this runs only in a browser context if (typeof window === 'undefined') return console.warn('Run in browser'); - await MidenClient.ready(); - - const client = await MidenClient.create({ - rpcUrl: 'https://rpc.testnet.miden.io', - }); + const client = await createTutorialClient(); console.log('Latest block:', (await client.sync()).blockNum()); @@ -32,7 +31,7 @@ export async function multiSendWithDelegatedProver(): Promise { }); console.log('Alice account ID:', alice.id().toString()); - // ── Creating new faucet ────────────────────────────────────────────────────── + // ── Creating new faucet ──────────────────────────────────────────────────── const faucet = await client.accounts.create({ type: 0, // 0 = FungibleFaucet symbol: 'MID', @@ -41,29 +40,30 @@ export async function multiSendWithDelegatedProver(): Promise { storage: StorageMode.Public, }); console.log('Faucet ID:', faucet.id().toString()); + await fundAccountForFees(client, alice); + await fundAccountForFees(client, faucet); - // ── mint 10 000 MID to Alice ────────────────────────────────────────────────────── + // ── mint 10 000 MID to Alice ─────────────────────────────────────────────── + await client.sync(); const { txId: mintTxId } = await client.transactions.mint({ account: faucet, to: alice, amount: BigInt(10_000), type: NoteVisibility.Public, }); - console.log('waiting for settlement'); - await client.transactions.waitFor(mintTxId); - - // ── consume the freshly minted notes ────────────────────────────────────────────── - await client.transactions.consumeAll({ - account: alice, - }); + await client.transactions.waitFor(mintTxId, { timeout: 120_000 }); + await consumeAllFeeAware(client, alice); // ── build 3 P2ID notes (100 MID each) ───────────────────────────────────────────── - const recipientAddresses = [ - 'mtst1arqeemdpnzu4k52wlpd3xekl5uklfjl5', - 'mtst1arqk5qt3kms0cut9rdtqdaz8y5xmj245', - 'mtst1aq6kyfrh23n9gvt6jkg0z7fyts99hdqr', - ]; + const recipients = await Promise.all( + Array.from({ length: 3 }, () => + client.accounts.create({ storage: StorageMode.Public }), + ), + ); + const recipientAddresses = recipients.map((account) => + account.id().toString(), + ); const p2idNotes = recipientAddresses.map((addr) => createP2IDNote({ @@ -75,9 +75,18 @@ export async function multiSendWithDelegatedProver(): Promise { ); // ── create all P2ID notes ─────────────────────────────────────────────────────────────── - const builder = new TransactionRequestBuilder(); - const txRequest = builder.withOwnOutputNotes(new NoteArray(p2idNotes)).build(); - await client.transactions.submit(alice, txRequest); + await client.sync(); + const builder = await client.feeAwareTransactionRequestBuilder(alice); + const outputs = new NoteArray(); + for (const note of p2idNotes) outputs.push(note); + const request = builder.withOwnOutputNotes(outputs).build(); + const { txId } = await client.transactions.submit(alice, request); + await client.transactions.waitFor(txId, { timeout: 120_000 }); + console.log(`Transaction committed: ${txId.toHex()}`); + const updatedAlice = await client.accounts.get(alice); + const balance = updatedAlice?.vault().getBalance(faucet.id()); + if (balance !== BigInt(9_700)) + throw new Error(`Expected Alice to retain 9700 MID, got ${balance}`); console.log('All notes created ✅'); } diff --git a/web-client/lib/react/createMintConsume.tsx b/web-client/lib/react/createMintConsume.tsx index a8b11507..8b026db9 100644 --- a/web-client/lib/react/createMintConsume.tsx +++ b/web-client/lib/react/createMintConsume.tsx @@ -1,85 +1,111 @@ -// Documentation-only example for the "Mint, Consume, and Create Notes" tutorial. -// This component is embedded in docs via CodeSdkTabs and is not wired into the -// test harness (app/page.tsx). The TypeScript equivalent in lib/createMintConsume.ts -// is used for Playwright tests instead. 'use client'; -import { MidenProvider, useMiden, useCreateWallet, useCreateFaucet, useMint, useConsume, useSend, useWaitForCommit, useWaitForNotes } from '@miden-sdk/react/lazy'; +import { + MidenProvider, + useMiden, + useCreateWallet, + useCreateFaucet, + useMint, + useConsume, + useSend, +} from '@miden-sdk/react/lazy'; import { NoteVisibility, StorageMode } from '@miden-sdk/miden-sdk/lazy'; +import { tutorialNetwork } from '../feeSupport'; +import { + TutorialButton, + tutorialAuthScheme, + useTutorialSupport, +} from './tutorialSupport'; function CreateMintConsumeInner() { - const { isReady } = useMiden(); + const { sync } = useMiden(); const { createWallet } = useCreateWallet(); const { createFaucet } = useCreateFaucet(); const { mint } = useMint(); const { consume } = useConsume(); const { send } = useSend(); - const { waitForCommit } = useWaitForCommit(); - const { waitForConsumableNotes } = useWaitForNotes(); + const { + fundAccount, + committed, + waitForTokenNotes, + waitForNote, + assertBalance, + } = useTutorialSupport(); const run = async () => { - // 1. Create Alice's wallet (public, mutable) - console.log('Creating account for Alice…'); - const alice = await createWallet({ storageMode: StorageMode.Public }); + console.log('Synchronizing before creating accounts…'); + await sync(); + console.log('Creating Alice with useCreateWallet…'); + const authScheme = await tutorialAuthScheme(); + // Native fee tokens and the tutorial's MID token are separate assets. + const alice = await createWallet({ + storageMode: StorageMode.Public, + authScheme, + }); console.log('Alice ID:', alice.id().toString()); + await fundAccount(alice); - // 2. Deploy a fungible faucet - console.log('Creating faucet…'); + // v0.16 faucets include BasicWallet, so they can receive fee funding. const faucet = await createFaucet({ tokenSymbol: 'MID', decimals: 8, maxSupply: BigInt(1_000_000), storageMode: StorageMode.Public, + authScheme, }); console.log('Faucet ID:', faucet.id().toString()); + await fundAccount(faucet); - // 3. Mint 1000 tokens to Alice - console.log('Minting tokens to Alice...'); - const mintResult = await mint({ + await sync(); + const minted = await mint({ faucetId: faucet, targetAccountId: alice, amount: BigInt(1000), noteType: NoteVisibility.Public, }); - console.log('Mint tx:', mintResult.transactionId); - - // 4. Wait for the mint transaction to be committed - await waitForCommit(mintResult.transactionId); - - // 5. Wait for consumable notes to appear - const notes = await waitForConsumableNotes({ accountId: alice }); - console.log('Consumable notes:', notes.length); + await committed(minted.transactionId); + const notes = await waitForTokenNotes(alice, faucet); + const consumed = await consume({ accountId: alice.id().toString(), notes }); + await committed(consumed.transactionId); + await assertBalance(alice, faucet, BigInt(1000)); - // 6. Consume minted notes - console.log('Consuming minted notes...'); - await consume({ accountId: alice.id().toString(), notes }); - console.log('Notes consumed.'); - - // 7. Send 100 tokens to Bob - const bobAddress = 'mtst1arpsz3jlmjxl7u2jjzfsc0wyqyaas6a9'; - console.log("Sending tokens to Bob's account..."); - await send({ + const bob = await createWallet({ + storageMode: StorageMode.Public, + authScheme, + }); + const sent = await send({ from: alice, - to: bobAddress, + to: bob, assetId: faucet, amount: BigInt(100), noteType: NoteVisibility.Public, + returnNote: true, }); + await committed(sent.txId); + if (!sent.note) throw new Error('Send did not return its output note'); + await waitForNote(sent.note.id().toString()); + await assertBalance(alice, faucet, BigInt(900)); console.log('Tokens sent successfully!'); }; return ( -
- -
+ ); } export default function CreateMintConsume() { return ( - + ); diff --git a/web-client/lib/react/multiSendWithDelegatedProver.tsx b/web-client/lib/react/multiSendWithDelegatedProver.tsx index ed76d5fd..3e7b7798 100644 --- a/web-client/lib/react/multiSendWithDelegatedProver.tsx +++ b/web-client/lib/react/multiSendWithDelegatedProver.tsx @@ -1,79 +1,111 @@ -// Documentation-only example for the "Creating Multiple Notes" tutorial. -// This component is embedded in docs via CodeSdkTabs and is not wired into the -// test harness (app/page.tsx). The TypeScript equivalent in -// lib/multiSendWithDelegatedProver.ts is used for Playwright tests instead. 'use client'; -import { MidenProvider, useMiden, useCreateWallet, useCreateFaucet, useMint, useConsume, useMultiSend, useWaitForCommit, useWaitForNotes } from '@miden-sdk/react/lazy'; +import { + MidenProvider, + useMiden, + useCreateWallet, + useCreateFaucet, + useMint, + useConsume, + useMultiSend, +} from '@miden-sdk/react/lazy'; import { NoteVisibility, StorageMode } from '@miden-sdk/miden-sdk/lazy'; +import { tutorialNetwork } from '../feeSupport'; +import { + TutorialButton, + tutorialAuthScheme, + useTutorialSupport, +} from './tutorialSupport'; function MultiSendInner() { - const { isReady } = useMiden(); + const { sync } = useMiden(); const { createWallet } = useCreateWallet(); const { createFaucet } = useCreateFaucet(); const { mint } = useMint(); const { consume } = useConsume(); const { sendMany } = useMultiSend(); - const { waitForCommit } = useWaitForCommit(); - const { waitForConsumableNotes } = useWaitForNotes(); + const { fundAccount, committed, waitForTokenNotes, assertBalance } = + useTutorialSupport(); const run = async () => { - // 1. Create Alice's wallet - console.log('Creating account for Alice…'); - const alice = await createWallet({ storageMode: StorageMode.Public }); - console.log('Alice account ID:', alice.id().toString()); - - // 2. Deploy a fungible faucet + await sync(); + const authScheme = await tutorialAuthScheme(); + const alice = await createWallet({ + storageMode: StorageMode.Public, + authScheme, + }); + console.log('Alice ID:', alice.id().toString()); + await fundAccount(alice); const faucet = await createFaucet({ tokenSymbol: 'MID', decimals: 8, maxSupply: BigInt(1_000_000), storageMode: StorageMode.Public, + authScheme, }); console.log('Faucet ID:', faucet.id().toString()); + await fundAccount(faucet); - // 3. Mint 10,000 MID to Alice - const mintResult = await mint({ + await sync(); + const minted = await mint({ faucetId: faucet, targetAccountId: alice, amount: BigInt(10_000), noteType: NoteVisibility.Public, }); + await committed(minted.transactionId); + const notes = await waitForTokenNotes(alice, faucet); + const consumed = await consume({ accountId: alice.id().toString(), notes }); + await committed(consumed.transactionId); - console.log('Waiting for settlement…'); - await waitForCommit(mintResult.transactionId); - - // 4. Consume the freshly minted notes - const notes = await waitForConsumableNotes({ accountId: alice }); - await consume({ accountId: alice.id().toString(), notes }); - - // 5. Send 100 MID to three recipients in a single transaction - await sendMany({ + const recipients = []; + for (let index = 0; index < 3; index += 1) { + recipients.push( + await createWallet({ storageMode: StorageMode.Public, authScheme }), + ); + } + const sent = await sendMany({ from: alice, assetId: faucet, - recipients: [ - { to: 'mtst1arqeemdpnzu4k52wlpd3xekl5uklfjl5', amount: BigInt(100) }, - { to: 'mtst1arqk5qt3kms0cut9rdtqdaz8y5xmj245', amount: BigInt(100) }, - { to: 'mtst1aq6kyfrh23n9gvt6jkg0z7fyts99hdqr', amount: BigInt(100) }, - ], + recipients: recipients.map((account) => ({ + to: account, + amount: BigInt(100), + })), noteType: NoteVisibility.Public, }); - + await committed(sent.transactionId); + for (const recipient of recipients) { + const outputs = await waitForTokenNotes(recipient, faucet); + if ( + outputs.length !== 1 || + outputs[0].details().assets().fungibleAssets()[0]?.amount() !== + BigInt(100) + ) { + throw new Error(`Expected one 100 MID note for ${recipient.id()}`); + } + } + await assertBalance(alice, faucet, BigInt(9700)); console.log('All notes created ✅'); }; return ( -
- -
+ ); } export default function MultiSendWithDelegatedProver() { return ( - + ); diff --git a/web-client/lib/react/tutorialSupport.tsx b/web-client/lib/react/tutorialSupport.tsx new file mode 100644 index 00000000..cc438ce6 --- /dev/null +++ b/web-client/lib/react/tutorialSupport.tsx @@ -0,0 +1,175 @@ +'use client'; + +import { useState } from 'react'; +import { useConsume, useMiden, useWaitForCommit } from '@miden-sdk/react/lazy'; +import { + Account, + AccountId, + getWasmOrThrow, + type InputNoteRecord, +} from '@miden-sdk/miden-sdk/lazy'; +import { + requestFundingNote, + tutorialFeeConfig, + tutorialNetwork, +} from '../feeSupport'; + +const SETTLEMENT_TIMEOUT_MS = 120_000; +const POLL_INTERVAL_MS = 5_000; + +/** React wallet hooks expect the low-level numeric authentication enum. */ +export async function tutorialAuthScheme() { + const wasm = await getWasmOrThrow(); + return wasm.AuthScheme.AuthRpoFalcon512; +} + +/** Uses the provider's actual client and hooks, not a second client. */ +export function useTutorialSupport() { + const { client, sync, runExclusive } = useMiden(); + const { consume } = useConsume(); + const { waitForCommit } = useWaitForCommit(); + + const committed = async (transactionId: string) => { + await waitForCommit(transactionId, { + timeoutMs: SETTLEMENT_TIMEOUT_MS, + intervalMs: POLL_INTERVAL_MS, + }); + console.log(`Transaction committed: ${transactionId}`); + }; + + const waitForNote = async (noteId: string): Promise => { + if (!client) throw new Error('Miden client is not ready'); + const deadline = Date.now() + SETTLEMENT_TIMEOUT_MS; + while (Date.now() < deadline) { + await sync(); + const note = await runExclusive(() => client.getInputNote(noteId)); + if (note?.inclusionProof()) return note; + await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS)); + } + throw new Error(`Timed out waiting for committed note ${noteId}`); + }; + + const fundAccount = async (account: Account) => { + if (!client) throw new Error('Miden client is not ready'); + const { faucetId, baseFee } = await tutorialFeeConfig(); + if (baseFee === 0) return; + await sync(); + const updated = await runExclusive(() => client.getAccount(account.id())); + if (!updated) throw new Error(`Account ${account.id()} is not in the local store`); + if (updated.vault().getBalance(faucetId) > BigInt(0)) return; + console.log(`Funding ${account.id()} with native ${tutorialNetwork()} fee tokens`); + const minted = await requestFundingNote(account.id(), faucetId); + console.log( + `Funding note ${minted.note_id}; faucet transaction ${minted.tx_id}`, + ); + const note = await waitForNote(minted.note_id); + // The first transaction pays its fee from the native asset in the input note. + await sync(); + const result = await consume({ + accountId: account.id().toString(), + notes: [note], + }); + await committed(result.transactionId); + }; + + const waitForTokenNotes = async ( + account: Account, + faucet: Account, + ): Promise => { + if (!client) throw new Error('Miden client is not ready'); + const deadline = Date.now() + SETTLEMENT_TIMEOUT_MS; + while (Date.now() < deadline) { + await sync(); + const records = await runExclusive(() => + client.getConsumableNotes(account.id()), + ); + const notes = records + .map((record) => record.inputNoteRecord()) + .filter( + (record) => + // Globally consumable TX_FEE notes are not tutorial transfers. + record.metadata()?.tag().asU32() !== 0xfee && + record.inclusionProof() && + record + .details() + .assets() + .fungibleAssets() + .some( + (asset) => + asset.faucetId().toString() === faucet.id().toString(), + ), + ); + if (notes.length > 0) return notes; + await new Promise((resolve) => setTimeout(resolve, POLL_INTERVAL_MS)); + } + throw new Error( + `No committed ${faucet.id()} token notes for ${account.id()}`, + ); + }; + + const assertBalance = async ( + account: Account, + token: Account | AccountId, + expected: bigint, + ) => { + if (!client) throw new Error('Miden client is not ready'); + await sync(); + const updated = await runExclusive(() => client.getAccount(account.id())); + const actual = updated + ?.vault() + .getBalance(token instanceof Account ? token.id() : token); + if (actual !== expected) + throw new Error( + `Balance mismatch for ${account.id()}: expected ${expected}, got ${actual}`, + ); + console.log(`Verified balance ${account.id()}: ${actual}`); + }; + + return { + committed, + fundAccount, + waitForNote, + waitForTokenNotes, + assertBalance, + }; +} + +/** Surfaces actual hook errors to readers and to the browser test harness. */ +export function TutorialButton({ + name, + label, + run, +}: { + name: string; + label: string; + run: () => Promise; +}) { + const { isReady, error: initializationError } = useMiden(); + const [state, setState] = useState('idle'); + const [error, setError] = useState(null); + const execute = async () => { + setState('running'); + setError(null); + try { + await run(); + setState('passed'); + console.log(`React tutorial passed: ${name}`); + } catch (cause) { + const message = cause instanceof Error ? cause.message : String(cause); + setError(message); + setState('failed'); + console.error(message); + } + }; + return ( +
+ +

{initializationError?.message ?? error ?? state}

+
+ ); +} diff --git a/web-client/lib/react/unauthenticatedNoteTransfer.tsx b/web-client/lib/react/unauthenticatedNoteTransfer.tsx index cdf9fac7..082bc2b9 100644 --- a/web-client/lib/react/unauthenticatedNoteTransfer.tsx +++ b/web-client/lib/react/unauthenticatedNoteTransfer.tsx @@ -1,66 +1,79 @@ -// Documentation-only example for the "Unauthenticated Note Transfer" tutorial. -// This component is embedded in docs via CodeSdkTabs and is not wired into the -// test harness (app/page.tsx). The TypeScript equivalent in -// lib/unauthenticatedNoteTransfer.ts is used for Playwright tests instead. 'use client'; -import { MidenProvider, useMiden, useCreateWallet, useCreateFaucet, useMint, useConsume, useSend, useWaitForCommit, useWaitForNotes, type Account } from '@miden-sdk/react/lazy'; +import { + MidenProvider, + useMiden, + useCreateWallet, + useCreateFaucet, + useMint, + useConsume, + useSend, + type Account, +} from '@miden-sdk/react/lazy'; import { NoteVisibility, StorageMode } from '@miden-sdk/miden-sdk/lazy'; +import { tutorialExplorerUrl, tutorialNetwork } from '../feeSupport'; +import { + TutorialButton, + tutorialAuthScheme, + useTutorialSupport, +} from './tutorialSupport'; function UnauthenticatedNoteTransferInner() { - const { isReady } = useMiden(); + const { sync } = useMiden(); const { createWallet } = useCreateWallet(); const { createFaucet } = useCreateFaucet(); const { mint } = useMint(); const { consume } = useConsume(); const { send } = useSend(); - const { waitForCommit } = useWaitForCommit(); - const { waitForConsumableNotes } = useWaitForNotes(); + const { fundAccount, committed, waitForTokenNotes, assertBalance } = + useTutorialSupport(); const run = async () => { - // 1. Create Alice and 5 wallets for the transfer chain - console.log('Creating accounts…'); - const alice = await createWallet({ storageMode: StorageMode.Public }); - console.log('Alice account ID:', alice.id().toString()); - + await sync(); + const authScheme = await tutorialAuthScheme(); + const alice = await createWallet({ + storageMode: StorageMode.Public, + authScheme, + }); + console.log('Alice ID:', alice.id().toString()); + await fundAccount(alice); const wallets: Account[] = []; - for (let i = 0; i < 5; i++) { - const wallet = await createWallet({ storageMode: StorageMode.Public }); + for (let index = 0; index < 5; index += 1) { + const wallet = await createWallet({ + storageMode: StorageMode.Public, + authScheme, + }); + console.log(`Wallet ${index}:`, wallet.id().toString()); + // Every recipient pays fees when consuming and forwarding the note. + await fundAccount(wallet); wallets.push(wallet); - console.log(`Wallet ${i}:`, wallet.id().toString()); } - - // 2. Deploy a fungible faucet const faucet = await createFaucet({ tokenSymbol: 'MID', decimals: 8, maxSupply: BigInt(1_000_000), storageMode: StorageMode.Public, + authScheme, }); console.log('Faucet ID:', faucet.id().toString()); - - // 3. Mint 10,000 MID to Alice - const mintResult = await mint({ + await fundAccount(faucet); + await sync(); + const minted = await mint({ faucetId: faucet, targetAccountId: alice, amount: BigInt(10_000), noteType: NoteVisibility.Public, }); + await committed(minted.transactionId); + const notes = await waitForTokenNotes(alice, faucet); + const consumed = await consume({ accountId: alice.id().toString(), notes }); + await committed(consumed.transactionId); - console.log('Waiting for settlement…'); - await waitForCommit(mintResult.transactionId); - - // 4. Consume the freshly minted notes - const notes = await waitForConsumableNotes({ accountId: alice }); - await consume({ accountId: alice.id().toString(), notes }); - - // 5. Create the unauthenticated note transfer chain: - // Alice → Wallet 0 → Wallet 1 → Wallet 2 → Wallet 3 → Wallet 4 - console.log('Starting unauthenticated transfer chain…'); - let currentSender: Account = alice; - for (let i = 0; i < wallets.length; i++) { - const wallet = wallets[i]; - const { note } = await send({ + // Pass full Note objects directly, without fetching an inclusion proof. + let currentSender = alice; + for (let index = 0; index < wallets.length; index += 1) { + const wallet = wallets[index]; + const sent = await send({ from: currentSender, to: wallet, assetId: faucet, @@ -68,30 +81,43 @@ function UnauthenticatedNoteTransferInner() { noteType: NoteVisibility.Public, returnNote: true, }); - - const result = await consume({ accountId: wallet.id().toString(), notes: [note!] }); + if (!sent.note) throw new Error('Send did not return its output note'); + const received = await consume({ + accountId: wallet.id().toString(), + notes: [sent.note], + }); + await committed(sent.txId); + await committed(received.transactionId); + await assertBalance(wallet, faucet, BigInt(50)); console.log( - `Transfer ${i + 1}: https://testnet.midenscan.com/tx/${result.transactionId}`, + `Transfer ${index + 1}: ${tutorialExplorerUrl()}/tx/${received.transactionId}`, ); - currentSender = wallet; } - + await assertBalance(alice, faucet, BigInt(9950)); + for (const wallet of wallets.slice(0, -1)) + await assertBalance(wallet, faucet, BigInt(0)); console.log('Asset transfer chain completed ✅'); }; return ( -
- -
+ ); } export default function UnauthenticatedNoteTransfer() { return ( - + ); diff --git a/web-client/lib/unauthenticatedNoteTransfer.ts b/web-client/lib/unauthenticatedNoteTransfer.ts index b8d898ca..5c739434 100644 --- a/web-client/lib/unauthenticatedNoteTransfer.ts +++ b/web-client/lib/unauthenticatedNoteTransfer.ts @@ -1,19 +1,23 @@ /** - * Demonstrates unauthenticated note transfer chain against Miden testnet + * Demonstrates unauthenticated note transfer chain against the configured Miden network * Creates a chain of P2ID (Pay to ID) notes: Alice → wallet 1 → wallet 2 → wallet 3 → wallet 4 * * @throws {Error} If the function cannot be executed in a browser environment */ -import { MidenClient, NoteVisibility, StorageMode } from '@miden-sdk/miden-sdk/lazy'; +import { NoteVisibility, StorageMode } from '@miden-sdk/miden-sdk/lazy'; +import { + consumeAllFeeAware, + createTutorialClient, + fundAccountForFees, + tutorialExplorerUrl, +} from './feeSupport'; export async function unauthenticatedNoteTransfer(): Promise { // Ensure this runs only in a browser context if (typeof window === 'undefined') return console.warn('Run in browser'); - await MidenClient.ready(); - - const client = await MidenClient.create({ - rpcUrl: 'https://rpc.testnet.miden.io', + const client = await createTutorialClient({ + proverUrl: 'local', }); console.log('Latest block:', (await client.sync()).blockNum()); @@ -36,7 +40,6 @@ export async function unauthenticatedNoteTransfer(): Promise { console.log('wallet ', i.toString(), wallet.id().toString()); } - // ── Creating new faucet ────────────────────────────────────────────────────── const faucet = await client.accounts.create({ type: 0, // 0 = FungibleFaucet symbol: 'MID', @@ -45,22 +48,23 @@ export async function unauthenticatedNoteTransfer(): Promise { storage: StorageMode.Public, }); console.log('Faucet ID:', faucet.id().toString()); + await fundAccountForFees(client, alice); + await fundAccountForFees(client, faucet); - // ── mint 10 000 MID to Alice ────────────────────────────────────────────────────── + await client.sync(); const { txId: mintTxId } = await client.transactions.mint({ account: faucet, to: alice, amount: BigInt(10_000), type: NoteVisibility.Public, }); - console.log('Waiting for settlement'); - await client.transactions.waitFor(mintTxId); + await client.transactions.waitFor(mintTxId, { timeout: 120_000 }); + await consumeAllFeeAware(client, alice); - // ── Consume the freshly minted note ────────────────────────────────────────────── - await client.transactions.consumeAll({ - account: alice, - }); + for (const wallet of wallets) { + await fundAccountForFees(client, wallet); + } // ── Create unauthenticated note transfer chain ───────────────────────────────────────────── // Alice → wallet 1 → wallet 2 → wallet 3 → wallet 4 @@ -73,24 +77,36 @@ export async function unauthenticatedNoteTransfer(): Promise { console.log('Sender:', sender.id().toString()); console.log('Receiver:', receiver.id().toString()); - const { note } = await client.transactions.send({ + await client.sync(); + const { note, txId: sendTxId } = await client.transactions.send({ account: sender, to: receiver, token: faucet, amount: BigInt(50), type: NoteVisibility.Public, returnNote: true, + waitForConfirmation: false, }); + // Pass the full note before waiting for the sender's transaction. + await client.sync(); const { txId: consumeTxId } = await client.transactions.consume({ account: receiver, notes: [note], + waitForConfirmation: true, + timeout: 120_000, }); + await client.transactions.waitFor(sendTxId, { timeout: 120_000 }); + console.log(`Transaction committed: ${consumeTxId.toHex()}`); console.log( - `Consumed Note Tx on MidenScan: https://testnet.midenscan.com/tx/${consumeTxId.toHex()}`, + `Consumed Note Tx on MidenScan: ${tutorialExplorerUrl()}/tx/${consumeTxId.toHex()}`, ); } + const lastWallet = await client.accounts.get(wallets[wallets.length - 1]); + const balance = lastWallet?.vault().getBalance(faucet.id()); + if (balance !== BigInt(50)) + throw new Error(`Expected last wallet to hold 50 MID, got ${balance}`); console.log('Asset transfer chain completed ✅'); } diff --git a/web-client/package.json b/web-client/package.json index 6f117cee..4b5ab26d 100644 --- a/web-client/package.json +++ b/web-client/package.json @@ -9,8 +9,8 @@ "lint": "next lint" }, "dependencies": { - "@miden-sdk/miden-sdk": "0.15.2", - "@miden-sdk/react": "0.15.2", + "@miden-sdk/miden-sdk": "0.16.0", + "@miden-sdk/react": "0.16.0", "next": "15.3.2", "react": "^19.0.0", "react-dom": "^19.0.0" diff --git a/web-client/playwright.config.ts b/web-client/playwright.config.ts index 0d5850a7..584ea60f 100644 --- a/web-client/playwright.config.ts +++ b/web-client/playwright.config.ts @@ -1,6 +1,6 @@ import { defineConfig } from "@playwright/test"; -const tutorialTimeoutMs = 10 * 60 * 1000; +const tutorialTimeoutMs = 30 * 60 * 1000; export default defineConfig({ testDir: "./tests", @@ -12,14 +12,11 @@ export default defineConfig({ use: { baseURL: "http://localhost:3000", headless: true, - launchOptions: { - args: ["--disable-web-security"], - }, }, webServer: { command: "yarn dev", url: "http://localhost:3000", - reuseExistingServer: !process.env.CI, + reuseExistingServer: false, timeout: 120 * 1000, }, }); diff --git a/web-client/tests/react-tutorials.spec.ts b/web-client/tests/react-tutorials.spec.ts new file mode 100644 index 00000000..41d2d4ca --- /dev/null +++ b/web-client/tests/react-tutorials.spec.ts @@ -0,0 +1,47 @@ +import { expect, test } from '@playwright/test'; + +const tutorialTimeoutMs = 30 * 60 * 1000; + +const names = [ + 'createMintConsume', + 'multiSendWithDelegatedProver', + 'unauthenticatedNoteTransfer', +] as const; + +for (const name of names) { + test(`react:${name}`, async ({ page }) => { + test.setTimeout(tutorialTimeoutMs); + const logs: string[] = []; + const errors: string[] = []; + page.on('console', (message) => { + logs.push(`[${message.type()}] ${message.text()}`); + if (message.type() === 'error') errors.push(message.text()); + }); + page.on('pageerror', (error) => { + errors.push(error.message); + }); + await page.goto(`/react-tutorials?tutorial=${name}`); + const tutorial = page.getByTestId(`react-${name}`); + await expect(tutorial).toBeVisible({ timeout: 120_000 }); + await expect + .poll( + async () => { + const state = await tutorial.getAttribute('data-state'); + if (state === 'failed') throw new Error(await tutorial.innerText()); + return tutorial.getByRole('button').isEnabled(); + }, + { timeout: 120_000 }, + ) + .toBe(true); + await tutorial.getByRole('button').click(); + await expect(tutorial).toHaveAttribute('data-state', /passed|failed/, { + timeout: tutorialTimeoutMs, + }); + expect(await tutorial.getByRole('status').innerText()).toBe('passed'); + expect(errors).toEqual([]); + expect(logs.some((line) => line.includes('Transaction committed:'))).toBe( + true, + ); + expect(logs.some((line) => line.includes('Verified balance'))).toBe(true); + }); +} diff --git a/web-client/tests/tutorials.spec.ts b/web-client/tests/tutorials.spec.ts index 4ba0cd8d..b08ab026 100644 --- a/web-client/tests/tutorials.spec.ts +++ b/web-client/tests/tutorials.spec.ts @@ -1,7 +1,7 @@ import { expect, test } from "@playwright/test"; import type { Page } from "@playwright/test"; -const tutorialTimeoutMs = 10 * 60 * 1000; +const tutorialTimeoutMs = 30 * 60 * 1000; type RequiredLog = string | RegExp; @@ -97,6 +97,7 @@ const runTutorial = async ( ); } expect(status?.state).toBe("passed"); + expect(consoleLogs.some((line) => line.includes("Transaction committed:"))).toBe(true); for (const required of requiredLogs) { const matched = consoleLogs.some((line) => diff --git a/web-client/yarn.lock b/web-client/yarn.lock index 5b428f3f..3baa4d1c 100644 --- a/web-client/yarn.lock +++ b/web-client/yarn.lock @@ -215,37 +215,37 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" -"@miden-sdk/miden-sdk@0.15.2": - version "0.15.2" - resolved "https://registry.yarnpkg.com/@miden-sdk/miden-sdk/-/miden-sdk-0.15.2.tgz#c143231769513cc4493711aaa23ff48a7e8c56b9" - integrity sha512-0ww0aKrTZlLOpn9TbPnYg5erqE+j5QOqqGBn1ki/ku6iJRvkHyZquQPIz2CWi76AOAnUt+OZLKoMNEZ0X2RFww== +"@miden-sdk/miden-sdk@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@miden-sdk/miden-sdk/-/miden-sdk-0.16.0.tgz#a54e095b3fc2aa36ebf249b24eeb9f280b4fbc75" + integrity sha512-APdct6zmuoGRPQaZ3kf2ovpUQ1a9C8VxV2MrJcGS3DelupiV34WBNNvIXhGE+I6DnSV9t2NzAHvokPVYhUq+kQ== dependencies: dexie "^4.0.1" glob "^11.0.0" optionalDependencies: - "@miden-sdk/node-darwin-arm64" "0.15.2" - "@miden-sdk/node-darwin-x64" "0.15.2" - "@miden-sdk/node-linux-x64-gnu" "0.15.2" - -"@miden-sdk/node-darwin-arm64@0.15.2": - version "0.15.2" - resolved "https://registry.yarnpkg.com/@miden-sdk/node-darwin-arm64/-/node-darwin-arm64-0.15.2.tgz#c1724dbb204db0e638ff0d74d9f7ccfa9b71bdb8" - integrity sha512-Y4cZjjSImHC1AwAlk+xWp661+3LIIzlHB/1saDCSr4pAvufoMCou2vRRP+l4vwAT+9iDvLwi1iSw2qfybCORiA== - -"@miden-sdk/node-darwin-x64@0.15.2": - version "0.15.2" - resolved "https://registry.yarnpkg.com/@miden-sdk/node-darwin-x64/-/node-darwin-x64-0.15.2.tgz#176d6a47b854d227a5e4212b47d0f172e533ecca" - integrity sha512-pxUZpHWCNjClEcEVPDLF4HsFqAQMzoA2PjSjVHSUK8xdcD3F/fiRNIuW+3pYD9gDkvNPGRsJtPLO21R2Rmvskg== - -"@miden-sdk/node-linux-x64-gnu@0.15.2": - version "0.15.2" - resolved "https://registry.yarnpkg.com/@miden-sdk/node-linux-x64-gnu/-/node-linux-x64-gnu-0.15.2.tgz#b5a0e9ea7750e9aed42913430e23e8eaf4509eec" - integrity sha512-7ndNrEg+xSmcGb8lDcD/MAYKwXAzjlB6tfL/8fsUvZVgJ5h6ijDIhNCt4JMA40SS736mU7JHlzbTy8uPBwxqFA== - -"@miden-sdk/react@0.15.2": - version "0.15.2" - resolved "https://registry.yarnpkg.com/@miden-sdk/react/-/react-0.15.2.tgz#c5aa6caeb0fb2bd0cd343de26cc10d2305f01332" - integrity sha512-L3vxV2QRE+qQ9YPo4VIsCfQ7u12oN0fGp8oRnUGAgSwT1oztHx/rOku02ggAdy1SWQnpe8AiUGiFfC9lNoXkqg== + "@miden-sdk/node-darwin-arm64" "0.16.0" + "@miden-sdk/node-darwin-x64" "0.16.0" + "@miden-sdk/node-linux-x64-gnu" "0.16.0" + +"@miden-sdk/node-darwin-arm64@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@miden-sdk/node-darwin-arm64/-/node-darwin-arm64-0.16.0.tgz#0ce84fa029899820674557b8b92690d25fb21b0c" + integrity sha512-uxwzouQkVG91/pU9o0wajLqzq2yqdZSttzzHmQtpl2hlpyFZJ8lucMwMFKOLCzU04+87PutBiUQ18Xfir2et6w== + +"@miden-sdk/node-darwin-x64@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@miden-sdk/node-darwin-x64/-/node-darwin-x64-0.16.0.tgz#1f2aa253398984cda42a1bfd6888a7ba512c1b11" + integrity sha512-vqKtB5xw8iE5OkmEE31KMVuTWxJ006EwrFFSBFEsZNuGGWHyZXlpSqCA3y3azstu2RX3FEYoViBFPwu0fLJVzg== + +"@miden-sdk/node-linux-x64-gnu@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@miden-sdk/node-linux-x64-gnu/-/node-linux-x64-gnu-0.16.0.tgz#2618859bfc526a0ec67e79eaaa4d9290ad675aff" + integrity sha512-+gFdLiRcAcv77QX3n4/0BoAecho9lbMxQR87sKH8oIIwP70+1ux0DFCE2Uf1nR8RK/rsbSSk/57R+0QBRY1kgw== + +"@miden-sdk/react@0.16.0": + version "0.16.0" + resolved "https://registry.yarnpkg.com/@miden-sdk/react/-/react-0.16.0.tgz#c2ecc5d68425acbb17d03c13b6f1e193a8470f57" + integrity sha512-p4Blni66CPcZnyt1GNGh2I+OfbmIBQPSOqahsEzjfaZcP6P6k3XhhNt/sqxsoTr08QvVoxpwhXyosKyJNLQBvA== dependencies: zustand "^5.0.0" From 280c0489c742bea6121f7ef7df490d8233ab3444 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Vigara=20Fern=C3=A1ndez?= <312482795+0xrouss-miden@users.noreply.github.com> Date: Sun, 13 Sep 2026 19:22:28 +0200 Subject: [PATCH 2/3] fix: align tutorials and bank examples with Miden v0.16 --- docs/src/miden-bank/00-project-setup.md | 91 +- docs/src/miden-bank/01-account-components.md | 45 +- .../miden-bank/02-constants-constraints.md | 55 +- docs/src/miden-bank/03-asset-management.md | 97 +- docs/src/miden-bank/04-note-scripts.md | 242 +- .../miden-bank/05-cross-component-calls.md | 142 +- docs/src/miden-bank/06-transaction-scripts.md | 181 +- docs/src/miden-bank/07-output-notes.md | 232 +- docs/src/miden-bank/08-complete-flows.md | 298 +- docs/src/miden-bank/index.md | 51 +- docs/src/rust-client/index.md | 4 +- .../unauthenticated_note_how_to.md | 13 +- .../bridging_with_epoch_tutorial.md | 10 +- .../web-client/counter_contract_tutorial.md | 41 +- docs/src/web-client/create_deploy_tutorial.md | 126 +- .../creating_multiple_notes_tutorial.md | 80 +- .../foreign_procedure_invocation_tutorial.md | 41 +- .../mint_consume_create_tutorial.md | 47 +- docs/src/web-client/react_wallet_tutorial.md | 287 +- docs/src/web-client/setup_guide.md | 25 +- .../web-client/unauthenticated_note_how_to.md | 55 +- examples/miden-bank/Cargo.lock | 3779 ++++++++--------- examples/miden-bank/Cargo.toml | 4 + examples/miden-bank/README.md | 17 +- .../contracts/bank-account/Cargo.lock | 1357 +++--- .../contracts/bank-account/Cargo.toml | 2 +- .../contracts/bank-account/miden-project.toml | 4 +- .../contracts/bank-account/src/lib.rs | 21 +- .../contracts/deposit-note/Cargo.lock | 1357 +++--- .../contracts/deposit-note/Cargo.toml | 2 +- .../contracts/deposit-note/miden-project.toml | 5 +- .../contracts/deposit-note/src/lib.rs | 2 +- .../contracts/init-tx-script/Cargo.lock | 1357 +++--- .../contracts/init-tx-script/Cargo.toml | 2 +- .../init-tx-script/miden-project.toml | 4 +- .../contracts/init-tx-script/src/lib.rs | 2 +- .../withdraw-request-note/Cargo.lock | 1357 +++--- .../withdraw-request-note/Cargo.toml | 2 +- .../withdraw-request-note/miden-project.toml | 5 +- .../withdraw-request-note/src/lib.rs | 10 +- examples/miden-bank/integration/Cargo.toml | 13 +- .../miden-bank/integration/src/bin/deposit.rs | 77 +- .../integration/src/bin/initialize.rs | 53 +- .../miden-bank/integration/src/helpers.rs | 265 +- .../integration/tests/deposit_test.rs | 133 +- .../miden-bank/integration/tests/init_test.rs | 31 +- .../integration/tests/withdraw_test.rs | 124 +- examples/miden-bank/miden-toolchain.toml | 4 + examples/miden-bank/rust-toolchain.toml | 2 +- .../src/bin/unauthenticated_note_transfer.rs | 7 +- 50 files changed, 6232 insertions(+), 5929 deletions(-) create mode 100644 examples/miden-bank/miden-toolchain.toml diff --git a/docs/src/miden-bank/00-project-setup.md b/docs/src/miden-bank/00-project-setup.md index 3a713726..58ffe4b6 100644 --- a/docs/src/miden-bank/00-project-setup.md +++ b/docs/src/miden-bank/00-project-setup.md @@ -37,11 +37,11 @@ miden --version The Miden toolchain porcelain: Environment: -- cargo version: cargo 1.93.0 (083ac5135 2025-12-15). +- cargo version: cargo 1.98.1 (797e8a9bc 2026-08-05). Midenup: -- midenup + miden version: 0.1.0. -- active toolchain version: 0.20.3. +- midenup + miden version: 1.0.0. +- active toolchain version: 0.16.0. - ... ``` @@ -70,6 +70,7 @@ miden-bank/ │ │ └── helpers.rs # Helper functions for tests │ └── tests/ # Test files ├── Cargo.toml # Workspace root +├── miden-toolchain.toml # Miden toolchain specification └── rust-toolchain.toml # Rust toolchain specification ``` @@ -88,7 +89,7 @@ mv contracts/counter-account contracts/bank-account A contract is configured by three files: a minimal Cargo manifest, a Miden project manifest, and a Cargo build config. -First, update the `Cargo.toml` inside `contracts/bank-account/`. It only needs the `miden` guest dependency and the `cdylib` crate type: +First, update the `Cargo.toml` inside `contracts/bank-account/`. Keep the generated `build.rs` and its build dependency; they prepare the package cache for Cargo and IDE builds: ```toml title="contracts/bank-account/Cargo.toml" [package] @@ -100,7 +101,10 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -miden = "0.13" +miden = "0.14" + +[build-dependencies] +miden-sdk-build-script-support = "0.14" ``` Next, create `contracts/bank-account/miden-project.toml`. This is the Miden-specific project manifest that tells the compiler what kind of artifact to build and which package namespace to export: @@ -112,14 +116,12 @@ version = "0.1.0" [lib] kind = "account-component" +path = "src/lib.rs" namespace = "miden:bank-account/bank@0.1.0" [dependencies] miden-core = "*" miden-protocol = "*" - -[package.metadata.miden] -supported-types = ["RegularAccountImmutableCode"] ``` Finally, create `contracts/bank-account/.cargo/config.toml` so the contract always builds for the WebAssembly target with the `miden` cfg enabled (this also makes editor/LSP workflows resolve the right code): @@ -140,17 +142,8 @@ rustflags = ["--cfg", "miden"] | `crate-type = ["cdylib"]` | `Cargo.toml` | Required for WebAssembly compilation | | `kind = "account-component"` | `miden-project.toml` | Tells the compiler this is an account component | | `namespace = "miden:bank-account/bank@..."` | `miden-project.toml` | The package namespace used for cross-component calls | -| `supported-types` | `miden-project.toml` | Account types this component supports | | `target = "wasm32-wasip2"` | `.cargo/config.toml` | Compile target for the Miden VM | -:::info Supported Account Types -`RegularAccountImmutableCode` means the account code cannot be changed after deployment. This is appropriate for our bank since we want the logic to be fixed. -::: - -:::note Toolchain -This tutorial targets protocol v0.15. The contracts depend on the published `miden = "0.13"` SDK (the cross-component / sibling-call line of the v0.15 compiler), and the integration harness builds them with the published `cargo-miden = "0.9"` release. The pinned `rust-toolchain.toml` is `nightly-2026-04-30` with the `wasm32-wasip2` target. -::: - ## Step 3: Create a Minimal Bank Component Replace the contents of `contracts/bank-account/src/lib.rs` with a minimal bank structure: @@ -189,9 +182,11 @@ struct BankStorage { #[component] trait Bank { /// Initialize the bank account, enabling deposits. + #[account_procedure] fn initialize(&mut self); /// Get the bank-tracked balance for a depositor and specific asset type. + #[account_procedure] fn get_depositor_balance(&self, depositor: AccountId, asset: Asset) -> Felt; } @@ -229,10 +224,12 @@ This is our starting point with two storage slots: :::note Component Structure The `#[component_storage]` struct declares the storage layout, the `#[component] trait` declares the exported API, and `#[component] impl Bank for BankStorage` implements it. Any private helper methods you add later live in a separate plain `impl BankStorage` block — the `#[component]` macro only exports trait methods. + +Mark each method that notes, transaction scripts, or other account components can call with `#[account_procedure]` on the trait declaration. Unmarked methods are exported but are not part of the account procedure table. ::: :::note get_depositor_balance, not get_balance -The balance accessor is named `get_depositor_balance` rather than `get_balance` so it does not collide with the built-in `ActiveAccount::get_balance` vault method that the account wrapper generates. It also exercises the WIT binding types (`AccountId`, `Asset`), which the compiler needs in at least one exported method. +The balance accessor is named `get_depositor_balance` rather than `get_balance` so it does not collide with the built-in `ActiveAccount::get_balance` vault method that the account wrapper generates. ::: :::info Contracts Are Excluded @@ -262,44 +259,38 @@ miden build --release The compiled output is stored in `target/miden/release/bank-account.masp`. -:::note Cosmetic MAST ERROR lines -Every contract build prints one or more non-fatal `MAST`-serialization lines starting with `ERROR`. These are cosmetic — the build still succeeds and produces the `.masp` package. You can ignore them. -::: - :::tip What's a .masp File? A `.masp` file is a Miden Assembly Package. It contains the compiled MASM (Miden Assembly) code and metadata needed to deploy and interact with your contract. ::: -:::info Build Order Matters -The bank account is the base contract. The deposit/withdraw notes and the init transaction script call into it, and their build relies on the bank account's already-compiled package (the FPI `#[account(...)]` macro reads the bank's procedure roots from its `.masp` at compile time). So always build `bank-account` first, then the notes and transaction script. The integration test harness handles this ordering for you. +:::info Contract dependencies +The notes and transaction script call the bank account through generated bindings. Their `miden-project.toml` files declare the bank as an automatic path dependency, so `miden build` compiles it before the dependent contract and provides its interface and procedure roots to `#[account(...)]`. ::: ## Optional: Verify Your Setup :::note -This is an optional self-check. If you create this test file, you can run it to verify your code compiles and loads correctly. The main runnable tests begin in Part 4. +This is an optional self-check. It loads the package compiled in Step 4 and creates a test account locally. ::: Create a new test file: ```rust title="integration/tests/part0_setup_test.rs" -use integration::helpers::{ - build_project_in_dir, create_testing_account_from_package, AccountCreationConfig, -}; use miden_client::account::{ - component::{InitStorageData, StorageValueName}, - StorageSlotName, + component::{BasicWallet, InitStorageData, StorageValueName}, + AccountBuilder, AccountComponent, AccountType, StorageSlotName, }; -use miden_client::Word; -use std::{path::Path, sync::Arc}; - -#[tokio::test] -async fn test_bank_account_builds_and_loads() -> anyhow::Result<()> { - // Build the bank account contract - let bank_package = Arc::new(build_project_in_dir( - Path::new("../contracts/bank-account"), - true, - )?); +use miden_client::{utils::Deserializable, Word}; +use miden_mast_package::Package; +use miden_standards::account::auth::NoAuth; +use std::path::Path; + +#[test] +fn test_bank_account_loads() -> anyhow::Result<()> { + // Load the bank account package compiled in Step 4. + let package_path = Path::new(env!("CARGO_MANIFEST_DIR")) + .join("../contracts/bank-account/target/miden/release/bank-account.masp"); + let bank_package = Package::read_from_bytes(&std::fs::read(package_path)?)?; // The `initialized` value slot has no schema default, so it must be seeded // (with a zero Word = uninitialized) or `AccountComponent::from_package` @@ -313,16 +304,18 @@ async fn test_bank_account_builds_and_loads() -> anyhow::Result<()> { StorageValueName::from_slot_name(&initialized_slot), Word::default(), )?; - let bank_cfg = AccountCreationConfig { - init_storage_data, - ..Default::default() - }; + let bank_component = AccountComponent::from_package(&bank_package, &init_storage_data)?; + assert_eq!(bank_component.procedures().count(), 2); - let bank_account = - create_testing_account_from_package(bank_package.clone(), bank_cfg)?; + let bank_account = AccountBuilder::new([3u8; 32]) + .account_type(AccountType::Public) + .with_component(bank_component) + .with_component(BasicWallet) + .with_component(NoAuth) + .build_existing()?; // Verify the account was created - println!("Bank account created with ID: {:?}", bank_account.id()); + println!("Bank account created with ID: {}", bank_account.id().to_hex()); println!("Part 0 setup verified!"); Ok(()) @@ -332,7 +325,7 @@ async fn test_bank_account_builds_and_loads() -> anyhow::Result<()> { Run the test from the project root: ```bash title=">_ Terminal" -cargo test --package integration test_bank_account_builds_and_loads -- --nocapture +cargo test --package integration test_bank_account_loads -- --nocapture ```
@@ -346,7 +339,7 @@ cargo test --package integration test_bank_account_builds_and_loads -- --nocaptu running 1 test Bank account created with ID: 0x... Part 0 setup verified! -test test_bank_account_builds_and_loads ... ok +test test_bank_account_loads ... ok test result: ok. 1 passed; 0 failed; 0 ignored ``` diff --git a/docs/src/miden-bank/01-account-components.md b/docs/src/miden-bank/01-account-components.md index a4000cf8..7ac9a605 100644 --- a/docs/src/miden-bank/01-account-components.md +++ b/docs/src/miden-bank/01-account-components.md @@ -6,7 +6,7 @@ description: "Learn how to define account components with the #[component] attri # Part 1: Account Components and Storage -In this section, you'll learn the fundamentals of building Miden account components. We'll explore the storage types introduced in Part 0 — `Value` and `StorageMap` — and add component methods. +In this section, you'll learn the fundamentals of building Miden account components. We'll explore the storage types introduced in Part 0 — `StorageValue` and `StorageMap` — and add component methods. ## What You'll Build in This Part @@ -82,11 +82,11 @@ struct BankStorage { } ``` -The `balances` field is a `StorageMap` that tracks each depositor's balance. The compiler derives slot IDs by hashing slot names (not by field declaration order). Slot names follow the pattern `{package_name}::{component_struct}::{field_name}` — here `bank_account::bank::initialized` and `bank_account::bank::balances`. +The `balances` field is a `StorageMap` that tracks each depositor's balance. The compiler derives slot IDs by hashing slot names (not by field declaration order). Slot names follow the pattern `{package_name}::{component_interface}::{field_name}` — here `bank_account::bank::initialized` and `bank_account::bank::balances`. ## Storage Types Explained -Miden accounts have storage slots that persist state on-chain. Each slot holds one `Word` (4 Felts = 32 bytes). The Miden Rust compiler provides two abstractions: +Miden accounts have persistent storage slots. Public account storage is published on-chain; private accounts publish its commitment. A value slot holds one `Word` (4 Felts = 32 bytes), while a map slot holds the root of its key-value map. The Miden Rust compiler provides two abstractions: ### StorageValue Storage @@ -116,7 +116,7 @@ self.initialized.set(new_value); ``` :::tip Type Annotations -The `.get()` method requires a type annotation: `let current: Word = self.initialized.get();` +`StorageValue::get()` returns a `Word`. The annotation in `let current: Word = self.initialized.get();` makes that type explicit but is not required. ::: ### StorageMap @@ -143,17 +143,16 @@ let key = Word::from([ asset.key[2], ]); -// Get returns a generic type V where V: From. -// Here we annotate the result as Felt, which works because Felt implements From. +// This field is StorageMap, so get returns Felt. let balance: Felt = self.balances.get(key); -// Set stores a value at the key (any type that implements Into) +// Set stores a Felt at this Word key. let new_balance = Felt::new(balance.as_canonical_u64() + deposit_amount.as_canonical_u64()).unwrap(); self.balances.set(key, new_balance); ``` :::info StorageMap Has a Generic API -`StorageMap::get()` returns a generic type `V` (constrained by `V: From`), not specifically `Felt`. The type is inferred from the variable annotation. In this tutorial we use `Felt` because we store single balance values, but you could also use `Word` or any custom type that implements the trait. +`StorageMap::get()` returns the map's declared value type `V`, which must implement `WordValue`. Our `StorageMap` therefore returns `Felt`; the variable annotation does not change the map's value type. A map declared with `Word` values would return `Word`. ::: ### Storage Layout @@ -165,7 +164,7 @@ Plan your storage layout carefully: | `initialized` | `StorageValue` | Initialization flag | | `balances` | `StorageMap` | Depositor balances | -The `description` attribute generates named slot identifiers (e.g., `bank_account::bank::initialized`) used in tests to reference specific slots. The naming convention is `{package_name}::{component_struct}::{field_name}`. The compiler derives slot IDs by hashing these names, so field declaration order does not affect slot assignment. +The `description` attribute adds human-readable metadata. The package namespace, component interface, and field name determine slot names such as `bank_account::bank::initialized`, which tests use to identify slots. The naming convention is `{package_name}::{component_interface}::{field_name}`. The compiler derives slot IDs by hashing these names, so field declaration order does not affect slot assignment. ## Step 2: Implement Component Methods @@ -176,9 +175,11 @@ Now let's add methods to our Bank. The exported API is declared as a `#[componen #[component] trait Bank { /// Initialize the bank account, enabling deposits. + #[account_procedure] fn initialize(&mut self); /// Get the bank-tracked balance for a depositor and specific asset type. + #[account_procedure] fn get_depositor_balance(&self, depositor: AccountId, asset: Asset) -> Felt; } @@ -232,8 +233,8 @@ impl BankStorage { } ``` -:::info v0.15 fungible-asset key layout -A fungible asset's vault key Word is `[asset_id_suffix, asset_id_prefix, faucet_suffix | metadata_byte, faucet_prefix]`. So `asset.key[3]` is the faucet id prefix and `asset.key[2]` is the faucet id suffix folded together with a metadata byte (composition + callback flag) in its low 8 bits — `key[2]` is **not** the raw faucet suffix. For the callbacks-disabled fungible assets this bank accepts the metadata byte is constant, so `(key[3], key[2])` is a stable per-faucet identifier. The host-side mirror is `FungibleAsset::to_key_word()` indices `[3]`/`[2]`. +:::info v0.16 fungible-asset ID layout +A fungible asset's ID Word is `[asset_class_suffix, asset_class_prefix, faucet_suffix | metadata_byte, faucet_prefix]`. For fungible assets, the asset class is empty. `asset.key[3]` is the faucet ID prefix and `asset.key[2]` is the faucet ID suffix with the composition bits in its low byte, so `key[2]` is **not** the raw faucet suffix. The callback flag is now encoded in the faucet account ID, not in the asset metadata byte. The host-side mirror is `FungibleAsset::to_id_word()` indices `[3]`/`[2]`. ::: The bank requires initialization before accepting deposits: `require_initialized()` is called at the top of `deposit()` and `withdraw()` (covered in later parts). @@ -262,12 +263,9 @@ miden build This compiles the Rust code to Miden Assembly and generates: -- `target/miden/release/bank-account.masp` - The compiled package -- `target/generated-wit/` - WIT interface files for other contracts to use +- `target/miden/dev/bank-account.masp` - The compiled package +- The package embeds the WIT interface used by dependent contracts -:::note Cosmetic build errors -The build prints non-fatal `MAST`-serialization `ERROR` lines on every run. These are cosmetic — the build still succeeds and produces the `.masp` package. -::: ## Optional: Verify Your Code @@ -287,7 +285,7 @@ Create a new test file: use integration::helpers::{ build_project_in_dir, create_testing_account_from_package, AccountCreationConfig, }; -use miden_client::account::{StorageMap, StorageSlot, StorageSlotName}; +use miden_client::account::{component::{InitStorageData, StorageValueName}, StorageSlotName}; use miden_client::{Felt, Word}; use std::{path::Path, sync::Arc}; @@ -304,7 +302,7 @@ async fn test_bank_account_storage() -> anyhow::Result<()> { )?); // Create named storage slots matching the contract's storage layout - // The naming convention is: {package_name}::{component_struct}::{field_name} + // The naming convention is: {package_name}::{component_interface}::{field_name} let initialized_slot = StorageSlotName::new("bank_account::bank::initialized") .expect("Valid slot name"); @@ -349,8 +347,11 @@ async fn test_bank_account_storage() -> anyhow::Result<()> { // ========================================================================= // Check that we can query the balances map (should return 0 for any key) - let test_key = Word::from([Felt::new(1), Felt::new(2), Felt::new(0), Felt::new(0)]); - let balance = bank_account.storage().get_map_item(&balances_slot, test_key)?; + let test_key = Word::from([Felt::from(1u32), Felt::from(2u32), Felt::from(0u32), Felt::from(0u32)]); + let balance = bank_account.storage().get_map_item( + &balances_slot, + miden_client::account::StorageMapKey::new(test_key), + )?; // Balance for non-existent depositor should be all zeros assert_eq!( @@ -436,9 +437,11 @@ struct BankStorage { #[component] trait Bank { /// Initialize the bank account, enabling deposits. + #[account_procedure] fn initialize(&mut self); /// Get the bank-tracked balance for a depositor and specific asset type. + #[account_procedure] fn get_depositor_balance(&self, depositor: AccountId, asset: Asset) -> Felt; } @@ -493,7 +496,7 @@ impl BankStorage { ## Key Takeaways -1. **`#[component]`** marks structs and impl blocks as Miden account components +1. **`#[component]`** marks the exported component trait and its implementation; `#[component_storage]` marks the storage struct 2. **`StorageValue`** stores a single Word, read with `.get()`, write with `.set()` 3. **`StorageMap`** stores key-value pairs, access with `.get()` and `.set()` 4. **Storage slots** are identified by name (IDs derived from hashed slot names), each holds 4 Felts (32 bytes) diff --git a/docs/src/miden-bank/02-constants-constraints.md b/docs/src/miden-bank/02-constants-constraints.md index 2eb444f2..36edd6a5 100644 --- a/docs/src/miden-bank/02-constants-constraints.md +++ b/docs/src/miden-bank/02-constants-constraints.md @@ -14,9 +14,9 @@ By the end of this section, you will have: - Defined constants for business rules (`MAX_DEPOSIT_AMOUNT`, `MAX_BALANCE`) - Used `assert!()` for transaction validation -- Learned safe Felt comparison with `.as_canonical_u64()` +- Compared token amounts with `u64` business limits using `.as_canonical_u64()` - Added a deposit method skeleton with validation -- **Verified constraints work** by testing that invalid operations fail +- **Verified the component builds and loads** with its initial storage; later parts exercise the transaction guards ## Building on Part 1 @@ -93,40 +93,55 @@ When an assertion fails: This is the primary mechanism for enforcing business rules in Miden contracts. -## Safe Felt Comparisons +## Comparing Felt Amounts with Business Limits -:::warning Pitfall: Felt Comparison Operators -Never use `<`, `>`, `<=`, or `>=` operators directly on `Felt` values. They produce incorrect results due to field element ordering. +:::note Comparison and Arithmetic +The current SDK's `<`, `>`, `<=`, and `>=` operators compare the canonical integer values of `Felt`s. Direct comparisons are supported. Arithmetic on `Felt` is modular, however, so validate amounts before addition or subtraction can wrap around the field modulus. ::: -**Wrong approach:** +**Comparing two field elements:** ```rust -// DON'T DO THIS - produces incorrect results +// Direct Felt comparison uses canonical integer ordering. if deposit_amount > felt!(1_000_000) { - // This comparison is unreliable! + // The amount exceeds the limit. } ``` -**Correct approach:** +**Comparing with our `u64` constant:** ```rust -// CORRECT - convert to u64 first +// Convert the amount to compare it with the u64 business limit. if deposit_amount.as_canonical_u64() > MAX_DEPOSIT_AMOUNT { - // This works correctly + // The amount exceeds the limit. } ``` -The `.as_canonical_u64()` method extracts the underlying 64-bit integer from a Felt, allowing standard Rust comparisons. +Both comparisons have the same result. This tutorial uses `.as_canonical_u64()` to express quantity checks against `u64` limits explicitly. Converting a value after field arithmetic has wrapped does not recover its original quantity. ## Step 1: Add the Constant and Deposit Method -Update your `contracts/bank-account/src/lib.rs` to add the constant and a deposit method skeleton. The component's public API lives in `#[component] impl Bank for BankStorage`, while private helpers like `require_initialized` and `balance_key` live in a separate plain `impl BankStorage` block (the `#[component]` macro only exports trait methods): +Update your `contracts/bank-account/src/lib.rs` to add the constants and a deposit method skeleton. Keep the storage struct from Part 1 and replace the `Bank` trait and implementation blocks with the code below. Declare `deposit` in the trait with `#[account_procedure]` before implementing it in `#[component] impl Bank for BankStorage`. Private helpers like `require_initialized` and `balance_key` remain in a separate plain `impl BankStorage` block: ```rust title="contracts/bank-account/src/lib.rs" const MAX_DEPOSIT_AMOUNT: u64 = 1_000_000; const MAX_BALANCE: u64 = 9_223_372_034_707_292_160; // 2^63 - 2^31 +#[component] +trait Bank { + /// Initialize the bank account, enabling deposits. + #[account_procedure] + fn initialize(&mut self); + + /// Get the bank-tracked balance for a depositor and specific asset type. + #[account_procedure] + fn get_depositor_balance(&self, depositor: AccountId, asset: Asset) -> Felt; + + /// Deposit an asset into the bank for a specific depositor. + #[account_procedure] + fn deposit(&mut self, depositor: AccountId, deposit_asset: Asset); +} + #[component] impl Bank for BankStorage { fn initialize(&mut self) { @@ -191,8 +206,8 @@ impl BankStorage { } ``` -:::warning v0.15 asset-key layout -In v0.15 the fungible-asset vault key Word is `[asset_id_suffix, asset_id_prefix, faucet_suffix | metadata_byte, faucet_prefix]`. So `asset.key[2]` is the faucet suffix combined with a metadata byte (asset composition + a callback flag in the low 8 bits), **not** the raw faucet suffix. For the callbacks-disabled fungible assets this bank accepts the metadata byte is constant, so `(key[3], key[2])` remains a stable per-faucet identifier. The host/test side derives the same key from `FungibleAsset::new(faucet.id(), amt)?.to_key_word()` indices `[3]`/`[2]` (not `faucet.id().prefix()/suffix()`). +:::warning v0.16 asset-ID layout +In v0.16 the fungible-asset ID Word is `[asset_class_suffix, asset_class_prefix, faucet_suffix | metadata_byte, faucet_prefix]`. The fungible asset class is empty, and the metadata byte contains the composition bits; the callback flag is part of the faucet account ID. Thus `asset.key[2]` is **not** the raw faucet suffix. The host/test side derives the same ID from `FungibleAsset::new(faucet.id(), amt)?.to_id_word()` indices `[3]`/`[2]` (not `faucet.id().prefix()/suffix()`). ::: ### The require_initialized() Guard @@ -256,9 +271,6 @@ cd contracts/bank-account miden build ``` -:::note Cosmetic build output -The Miden compiler prints non-fatal `MAST`-serialization `ERROR` lines on every build. These are cosmetic — the build still succeeds and emits the `.masp` package. -::: ## Optional: Verify Constraints Work @@ -378,6 +390,8 @@ This pattern is **mandatory** for any operation that subtracts from a balance. M ### State Checks +This optional extension assumes a `paused: StorageValue` slot has been added to the component and initialized to a zero Word. The Bank component in this tutorial does not include that slot. + ```rust fn require_not_paused(&self) { let paused: Word = self.paused.get(); @@ -426,12 +440,15 @@ struct BankStorage { #[component] trait Bank { /// Initialize the bank account, enabling deposits. + #[account_procedure] fn initialize(&mut self); /// Get the bank-tracked balance for a depositor and specific asset type. + #[account_procedure] fn get_depositor_balance(&self, depositor: AccountId, asset: Asset) -> Felt; /// Deposit an asset into the bank for a specific depositor. + #[account_procedure] fn deposit(&mut self, depositor: AccountId, deposit_asset: Asset); } @@ -501,7 +518,7 @@ impl BankStorage { 1. **Constants** define immutable business rules at compile time 2. **`assert!()`** enforces constraints - failures reject the transaction -3. **Always use `.as_canonical_u64()`** for Felt comparisons, never direct operators +3. **Use `.as_canonical_u64()`** to compare amounts with `u64` business limits; validate quantities before field arithmetic can wrap 4. **Helper methods** like `require_initialized()` centralize validation logic 5. **Failed assertions** mean no valid proof can be generated diff --git a/docs/src/miden-bank/03-asset-management.md b/docs/src/miden-bank/03-asset-management.md index df3e2c07..f45c156c 100644 --- a/docs/src/miden-bank/03-asset-management.md +++ b/docs/src/miden-bank/03-asset-management.md @@ -37,12 +37,12 @@ Part 2: Part 3: ## The Asset Type Miden splits a fungible `Asset` into a `value` word and a `key` word. The `value` -holds the amount; the `key` is the vault key word. In protocol v0.15 the fungible +holds the amount; the `key` is the vault key word. In protocol v0.16 the fungible vault key word has this layout: ```text Asset value: [amount, 0, 0, 0] -Asset key: [asset_id_suffix, asset_id_prefix, faucet_suffix | metadata, faucet_prefix] +Asset key: [asset_class_suffix, asset_class_prefix, faucet_suffix | metadata, faucet_prefix] ━━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━ key index 2 key index 3 ``` @@ -62,12 +62,11 @@ let faucet_suffix = deposit_asset.key[2]; // Faucet ID suffix (+ metadata b let faucet_prefix = deposit_asset.key[3]; // Faucet ID prefix ``` -:::note v0.15 vault-key layout -`asset.key[2]` is **not** the raw faucet suffix — the asset's metadata byte -(composition + a callback flag) is folded into its low 8 bits. For the -callbacks-disabled fungible assets this bank accepts that byte is constant, so -`(asset.key[3], asset.key[2])` is still a stable per-faucet identifier. The -host-side mirror is `FungibleAsset::to_key_word()` indices `[3]` / `[2]`. +:::note v0.16 asset-ID layout +`asset.key[2]` is **not** the raw faucet suffix — the composition metadata is +folded into its low byte. The callback flag is encoded in the faucet account ID +in v0.16. Thus `(asset.key[3], asset.key[2])` is a stable per-faucet identifier. +The host-side mirror is `FungibleAsset::to_id_word()` indices `[3]` / `[2]`. ::: ## Receiving Assets with add_asset() @@ -98,10 +97,10 @@ fn deposit(&mut self, depositor: AccountId, deposit_asset: Asset) { // NOTE: Initialization guard — enabled in Part 6 (Transaction Scripts) // self.require_initialized(); - // Verify this is a fungible asset. - // For fungible assets, value = [amount, 0, 0, 0]; value[1] is always 0. + // Verify the asset composition identifies a fungible asset. + // Zero padding in the value word alone cannot distinguish NFTs. assert!( - deposit_asset.value[1].as_canonical_u64() == 0, + deposit_asset.is_fungible(), "Only fungible assets are supported" ); @@ -166,9 +165,9 @@ This design allows: - **Per-asset tracking**: Different token types are tracked separately - **Unique keys**: The combination ensures no collisions -Because `asset.key[2]` carries the v0.15 metadata byte in its low bits (not the raw -faucet suffix), the host side must derive the _same_ key from -`FungibleAsset::to_key_word()` rather than from `faucet.id().suffix()` directly — the +Because `asset.key[2]` carries the v0.16 composition metadata in its low byte (not the +raw faucet suffix), the host side must derive the _same_ ID from +`FungibleAsset::to_id_word()` rather than from `faucet.id().suffix()` directly — the test below shows this. The remaining internal helpers live in a separate, plain `impl BankStorage` block (not @@ -203,7 +202,15 @@ let new_balance = current_balance - withdraw_amount; This is not optional - it's a **security requirement** for any financial operation. ::: -Add this method to your Bank impl block: +Add this declaration inside your existing `Bank` trait: + +```rust title="contracts/bank-account/src/lib.rs" +/// Withdraw assets back to the depositor. +#[account_procedure] +fn withdraw(&mut self, withdraw_asset: Asset, serial_num: Word, tag: Felt, note_type: Felt); +``` + +Then add this method inside your existing `impl Bank for BankStorage` block: ```rust title="contracts/bank-account/src/lib.rs" fn withdraw( @@ -222,7 +229,7 @@ fn withdraw( // Verify this is a fungible asset — see `deposit()` for the rationale. assert!( - withdraw_asset.value[1].as_canonical_u64() == 0, + withdraw_asset.is_fungible(), "Only fungible assets are supported" ); @@ -275,7 +282,7 @@ fn create_p2id_note( _note_type: Felt, ) { // Placeholder - implemented in Part 7: Output Notes - // For now, this will cause a compile error if actually called + // Calling this placeholder aborts execution todo!("P2ID note creation - see Part 7") } ``` @@ -289,11 +296,6 @@ cd contracts/bank-account miden build ``` -:::note Cosmetic build output -The Miden compiler prints non-fatal `MAST`-serialization `ERROR` lines on every -build. They are cosmetic — the build still succeeds and produces the `.masp`. -::: - ## Try It: Verify Deposits Work First, verify your bank-account contract compiles: @@ -322,7 +324,7 @@ use integration::helpers::{ use miden_client::{ account::{component::{InitStorageData, StorageValueName}, StorageSlotName}, - auth::AuthSchemeId, + auth::AuthScheme, note::NoteAssets, transaction::RawOutputNote, Felt, Word, @@ -354,7 +356,7 @@ async fn deposit_test() -> anyhow::Result<()> { // Create a faucet to mint test assets let faucet = builder.add_existing_basic_faucet( Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, + auth_scheme: AuthScheme::Falcon512Poseidon2, }, "TEST", 1000, @@ -364,7 +366,7 @@ async fn deposit_test() -> anyhow::Result<()> { // Create note sender account (the depositor) let sender = builder.add_existing_wallet_with_assets( Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, + auth_scheme: AuthScheme::Falcon512Poseidon2, }, [FungibleAsset::new(faucet.id(), 100)?.into()], )?; @@ -434,14 +436,14 @@ async fn deposit_test() -> anyhow::Result<()> { let init_tx_script = build_tx_script_from_package(init_tx_script_package.as_ref())?; let init_tx_context = mock_chain - .build_tx_context(bank_account.id(), &[], &[])? + .build_transaction(bank_account.id()) .tx_script(init_tx_script) .build()?; let executed_init = init_tx_context.execute().await?; - bank_account.apply_delta(&executed_init.account_delta())?; mock_chain.add_pending_executed_transaction(&executed_init)?; mock_chain.prove_next_block()?; + bank_account = mock_chain.committed_account(bank_account.id())?.clone(); println!("Bank initialized successfully"); @@ -451,27 +453,26 @@ async fn deposit_test() -> anyhow::Result<()> { // Build the transaction context where bank consumes the deposit note let tx_context = mock_chain - .build_tx_context(bank_account.id(), &[deposit_note.id()], &[])? + .build_transaction(bank_account.id()) + .authenticated_input_note(deposit_note.id()) .build()?; // Execute the transaction let executed_transaction = tx_context.execute().await?; - // Apply the account delta to the bank account - bank_account.apply_delta(&executed_transaction.account_delta())?; - // Add the executed transaction to the mockchain and prove mock_chain.add_pending_executed_transaction(&executed_transaction)?; mock_chain.prove_next_block()?; + bank_account = mock_chain.committed_account(bank_account.id())?.clone(); // Create the key for the depositor (sender) in the storage map. // Key format: [depositor_prefix, depositor_suffix, asset.key[3], asset.key[2]]. - // In v0.15 the fungible-asset vault key is - // [asset_id_suffix, asset_id_prefix, faucet_suffix | metadata_byte, faucet_prefix], - // so `key[2]` is the faucet suffix combined with a metadata byte (composition + - // callback flag) — not the raw faucet suffix. Derive the read key from the asset's + // In v0.16 the fungible-asset vault key is + // [asset_class_suffix, asset_class_prefix, faucet_suffix | metadata_byte, faucet_prefix], + // so `key[2]` is the faucet suffix combined with composition metadata, + // not the raw faucet suffix. Derive the read key from the asset's // actual key word so it matches the key the contract writes. - let asset_key_word = FungibleAsset::new(faucet.id(), deposit_amount)?.to_key_word(); + let asset_key_word = FungibleAsset::new(faucet.id(), deposit_amount)?.to_id_word(); let depositor_key = Word::from([ sender.id().prefix().as_felt(), sender.id().suffix(), @@ -480,7 +481,7 @@ async fn deposit_test() -> anyhow::Result<()> { ]); // Get the depositor's balance from the bank's storage using named slot - let balance = bank_account.storage().get_map_item(&balances_slot, depositor_key)?; + let balance = bank_account.storage().get_map_item(&balances_slot, miden_client::account::StorageMapKey::new(depositor_key))?; // The contract stores `balance` as a `Felt`; reading the map returns the // single-Felt value widened into a Word at position [0] ([amount, 0, 0, 0]). @@ -515,21 +516,13 @@ cargo test --package integration --test deposit_test -- --nocapture Finished `test` profile [unoptimized + debuginfo] target(s) Running tests/deposit_test.rs -running 3 tests -Bank initialized successfully +running 1 test Deposit test passed! Deposited 1000 tokens test deposit_test ... ok -test deposit_exceeds_max_should_fail ... ok -test deposit_without_init_should_fail ... ok -test result: ok. 3 passed; 0 failed; 0 ignored +test result: ok. 1 passed; 0 failed; 0 ignored ``` -:::note Cosmetic build output -Each contract build during the test prints non-fatal `MAST`-serialization `ERROR` -lines from the Miden compiler. They are cosmetic and do not affect the result. -::: -
@@ -591,6 +584,7 @@ struct BankStorage { #[component] trait Bank { /// Initialize the bank account, enabling deposits. + #[account_procedure] fn initialize(&mut self); /// Get the bank-tracked balance for a depositor and specific asset type. @@ -598,12 +592,15 @@ trait Bank { /// Named `get_depositor_balance` (not `get_balance`) to avoid colliding with /// the built-in `ActiveAccount::get_balance` vault method that the account /// wrapper generates. + #[account_procedure] fn get_depositor_balance(&self, depositor: AccountId, asset: Asset) -> Felt; /// Deposit an asset into the bank for a specific depositor. + #[account_procedure] fn deposit(&mut self, depositor: AccountId, deposit_asset: Asset); /// Withdraw assets back to the depositor. + #[account_procedure] fn withdraw(&mut self, withdraw_asset: Asset, serial_num: Word, tag: Felt, note_type: Felt); } @@ -636,7 +633,7 @@ impl Bank for BankStorage { // self.require_initialized(); assert!( - deposit_asset.value[1].as_canonical_u64() == 0, + deposit_asset.is_fungible(), "Only fungible assets are supported" ); @@ -684,7 +681,7 @@ impl Bank for BankStorage { let depositor = active_note::get_sender(); assert!( - withdraw_asset.value[1].as_canonical_u64() == 0, + withdraw_asset.is_fungible(), "Only fungible assets are supported" ); @@ -744,7 +741,7 @@ impl BankStorage { ## Key Takeaways -1. **Asset layout**: `value[0]` = amount; `key[2]` = faucet_suffix + metadata byte (v0.15); `key[3]` = faucet_prefix. Mirror it host-side with `FungibleAsset::to_key_word()` indices `[3]`/`[2]` +1. **Asset layout**: `value[0]` = amount; `key[2]` = faucet suffix plus composition metadata; `key[3]` = faucet prefix. Mirror it host-side with `FungibleAsset::to_id_word()` indices `[3]`/`[2]` 2. **`native_account::add_asset()`** adds assets to the vault 3. **`native_account::remove_asset()`** removes assets from the vault (Part 7) 4. **Balance tracking** is application-level logic using `StorageMap` diff --git a/docs/src/miden-bank/04-note-scripts.md b/docs/src/miden-bank/04-note-scripts.md index 14a2d63c..4dd48f64 100644 --- a/docs/src/miden-bank/04-note-scripts.md +++ b/docs/src/miden-bank/04-note-scripts.md @@ -80,7 +80,7 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -miden = "0.13" +miden = "=0.14.0" ``` Create the `miden-project.toml`. This is where the note declares its kind and its dependency on the bank account it calls into: @@ -92,6 +92,7 @@ version = "0.1.0" [lib] kind = "note" +path = "src/lib.rs" namespace = "miden:deposit-note/miden-deposit-note@0.1.0" [dependencies] @@ -99,9 +100,6 @@ miden-core = "*" miden-protocol = "*" bank-account = { path = "../bank-account" } -# WIT for the account component this note calls, produced by building bank-account. -[package.metadata.miden.dependencies] -bank-account = { wit = "../bank-account/target/generated-wit/" } ``` Finally, the `.cargo/config.toml` pins the WebAssembly target and the `miden` cfg: @@ -117,7 +115,7 @@ rustflags = ["--cfg", "miden"] Key configuration: - `kind = "note"` - Marks this as a note script -- `bank-account = { path = "../bank-account" }` and the `[package.metadata.miden.dependencies]` `wit` entry declare the account component this note calls; the `wit` path points at the WIT files produced when `bank-account` is built +- `bank-account = { path = "../bank-account" }` declares the component this note calls. Compiler 0.10 builds the dependency and reads its interface from the compiled package ## Step 3: Implement the Deposit Note @@ -150,7 +148,7 @@ impl DepositNote { let depositor = active_note::get_sender(); // Get all assets attached to this note - let assets = active_note::get_assets(); + let assets = active_note::get_initial_assets(); // Deposit each asset into the bank for asset in assets { @@ -161,7 +159,7 @@ impl DepositNote { ``` :::info Cross-Component Calls -The `#[account(bank_account::Bank)] pub struct Wallet;` declaration and the `account.deposit(...)` call use Miden's cross-component binding system. The `#[account(...)]` macro wraps the consuming account so the note can call the bank's `Bank` methods directly. We'll explain exactly how this works in [Part 5: Cross-Component Calls](./cross-component-calls). For now, just know that building `bank-account` first generates the WIT files that `deposit-note` binds against. +The `#[account(bank_account::Bank)] pub struct Wallet;` declaration and the `account.deposit(...)` call use Miden's cross-component binding system. The `#[account(...)]` macro wraps the consuming account so the note can call the bank's `Bank` methods directly. We'll explain exactly how this works in [Part 5: Cross-Component Calls](./cross-component-calls). When you build `deposit-note`, Compiler 0.10 builds the `bank-account` dependency declared in `miden-project.toml` and reads its interface from the compiled package. ::: ### The #[note] and #[note_script] Attributes @@ -189,16 +187,16 @@ Returns the `AccountId` of the account that created/sent the note. In our bank: - The sender is the depositor - Their ID is used to credit their balance -### get_assets() - Attached Assets +### get_initial_assets() - Attached Assets ```rust -let assets = active_note::get_assets(); +let assets = active_note::get_initial_assets(); for asset in assets { // Process each asset } ``` -Returns an iterator over all assets attached to the note. +Returns a `Vec` containing all assets initially attached to the note. The `for` loop consumes that vector. ### get_storage() - Note Parameters @@ -207,22 +205,20 @@ let storage = active_note::get_storage(); let first_item = storage[0]; ``` -Returns a slice of `Felt` values passed when the note was created. We'll use storage items in the withdraw request note (Part 7). +Returns a `Vec` containing the storage items passed when the note was created. The indexing example requires at least one item. We'll use storage items in the withdraw request note (Part 7). ## Step 4: Build the Note Script -:::info Build Order Matters -Build account components **first** before building note scripts that depend on them. The note script needs the generated WIT files from the account, and the FPI `#[account(...)]` macro reads the bank account's procedure roots from its compiled `.masp` at compile time. +:::info Dependencies Build Automatically +Compiler 0.10 resolves and builds the `bank-account` dependency before compiling the note. The `#[account(...)]` macro uses the bank's compiled interface and procedure roots to bind calls to its methods. You can build the note directly using the dependency declaration in `miden-project.toml`. ::: -```bash title=">_ Terminal" -# First, ensure bank-account is built (generates WIT + the .masp the note binds against) -cd contracts/bank-account -cargo miden build --release +From the project root: -# Now build the deposit note -cd ../deposit-note -cargo miden build --release +```bash title=">_ Terminal" +cd contracts/deposit-note +miden build --release +cd ../.. ```
@@ -235,9 +231,6 @@ cargo miden build --release
-:::note Cosmetic MAST-serialization errors -The Miden compiler prints non-fatal `ERROR` lines about `MAST` serialization on every build. They are cosmetic — the build still succeeds and produces the `.masp` package. -::: ## Execution Flow Diagram @@ -257,31 +250,22 @@ The Miden compiler prints non-fatal `ERROR` lines about `MAST` serialization on 3. Note script runs depositor = get_sender() → User's AccountId - assets = get_assets() → [100 tokens] + assets = get_initial_assets() → [100 tokens] account.deposit(depositor, 100 tokens) 4. Bank's deposit() method executes - - Validates initialization and amount + - Validates asset type and amount + - Checks initialization once the guard is enabled in Part 6 - Updates balance: balances[User] += 100 - Adds asset to vault ``` ## Try It: Verify Deposits Work -First, verify your deposit-note builds successfully: - -```bash title=">_ Terminal" -# Ensure bank-account is built first -cd contracts/bank-account && cargo miden build --release - -# Then build deposit-note -cd ../deposit-note && cargo miden build --release -``` +This test verifies the deposit flow end-to-end — building the contracts, initializing the bank, creating a deposit, and checking the balance. -This is the first runnable test in the tutorial. It verifies the deposit flow end-to-end — building the bank and deposit-note contracts, creating a deposit, and checking the balance. - -:::note Initialization happens before deposits -The bank's `require_initialized()` guard is active, so a deposit only succeeds once the bank has been initialized. The shipped `deposit_test.rs` initializes the bank first via the init transaction script (which we build in Part 6). The illustrative excerpt below omits that step to keep the focus on the deposit and note-script mechanics; see the shipped test for the complete init-then-deposit flow. +:::note Preview of the Part 6 Initialization Flow +The bank inherited from Part 3 still has `require_initialized()` commented out, so deposits currently work without initialization. In [Part 6](./06-transaction-scripts.md), we'll create the initialization transaction script and enable the guard, making initialization mandatory. The test below previews that flow: it initializes the bank, consumes a deposit note, and checks the depositor's balance. Run it after completing Part 6, or use the complete example projects from the repository. ::: Create the test file: @@ -290,76 +274,101 @@ Create the test file: The snippet below illustrates the deposit happy-path. The shipped repository's `examples/miden-bank/integration/tests/deposit_test.rs` is the source of truth and additionally exercises failure paths (`deposit_exceeds_max_should_fail`, `deposit_without_init_should_fail`). ::: -```rust title="integration/tests/deposit_test.rs (illustrative — see shipped file for the full version)" +```rust title="integration/tests/deposit_test.rs" use integration::helpers::{ - build_project_in_dir, create_testing_account_from_package, + build_project_in_dir, build_tx_script_from_package, create_testing_account_from_package, create_testing_note_from_package, AccountCreationConfig, NoteCreationConfig, }; -use miden_client::account::{component::{InitStorageData, StorageValueName}, StorageSlotName}; + +use miden_client::{ + account::{component::{InitStorageData, StorageValueName}, StorageSlotName}, + auth::AuthScheme, + note::NoteAssets, + transaction::RawOutputNote, + Felt, Word, +}; use miden_client::asset::{Asset, FungibleAsset}; -use miden_client::auth::AuthSchemeId; -use miden_client::note::NoteAssets; -use miden_client::transaction::RawOutputNote; -use miden_client::{Felt, Word}; use miden_testing::{Auth, MockChain}; use std::{path::Path, sync::Arc}; +/// Storage slot names for the bank account component. +/// +/// The `initialized` value slot has no schema default, so `AccountComponent::from_package` +/// requires it to be seeded via `InitStorageData` (otherwise it errors with +/// `InitValueNotProvided`). The `balances` map slot defaults to empty and needs no entry. +fn bank_storage_slots() -> (StorageSlotName, StorageSlotName) { + let initialized_slot = + StorageSlotName::new("bank_account::bank::initialized") + .expect("Valid slot name"); + let balances_slot = + StorageSlotName::new("bank_account::bank::balances") + .expect("Valid slot name"); + (initialized_slot, balances_slot) +} + #[tokio::test] async fn deposit_test() -> anyhow::Result<()> { - // ========================================================================= - // SETUP: Build contracts and create mock chain - // ========================================================================= + // Test that after executing the deposit note, the depositor's balance is updated let mut builder = MockChain::builder(); - // Create a faucet for test tokens - let faucet = builder.add_existing_basic_faucet(Auth::BasicAuth { auth_scheme: AuthSchemeId::Falcon512Poseidon2 }, "TEST", 1000, Some(10))?; + // Create a faucet to mint test assets + let faucet = builder.add_existing_basic_faucet( + Auth::BasicAuth { + auth_scheme: AuthScheme::Falcon512Poseidon2, + }, + "TEST", + 1000, + Some(10), + )?; - // Create sender (depositor) wallet - let sender = builder.add_existing_wallet_with_assets(Auth::BasicAuth { auth_scheme: AuthSchemeId::Falcon512Poseidon2 }, [FungibleAsset::new(faucet.id(), 100)?.into()])?; + // Create note sender account (the depositor) + let sender = builder.add_existing_wallet_with_assets( + Auth::BasicAuth { + auth_scheme: AuthScheme::Falcon512Poseidon2, + }, + [FungibleAsset::new(faucet.id(), 100)?.into()], + )?; - // Build bank-account and deposit-note (the shipped test also builds init-tx-script; omitted here for brevity) + // Build contracts let bank_package = Arc::new(build_project_in_dir( Path::new("../contracts/bank-account"), true, )?); - let deposit_note_package = Arc::new(build_project_in_dir( Path::new("../contracts/deposit-note"), true, )?); + let init_tx_script_package = Arc::new(build_project_in_dir( + Path::new("../contracts/init-tx-script"), + true, + )?); - // Create the bank account with storage slots. - // - // The shipped deposit_test.rs initializes the bank first (via the init - // transaction script built in Part 6) because `require_initialized()` is - // active; this excerpt omits that step and focuses on the deposit flow. - let initialized_slot = - StorageSlotName::new("bank_account::bank::initialized") - .expect("Valid slot name"); - let balances_slot = - StorageSlotName::new("bank_account::bank::balances") - .expect("Valid slot name"); - - let mut init_storage_data = InitStorageData::default(); - init_storage_data.insert_value( - StorageValueName::from_slot_name(&initialized_slot), - Word::default(), - )?; - + // Create the bank account. The `initialized` value slot has no schema default, so it must + // be seeded (here with a zero Word = uninitialized) or `from_package` errors with + // `InitValueNotProvided`; the `balances` map defaults to empty. + let (initialized_slot, balances_slot) = bank_storage_slots(); let bank_cfg = AccountCreationConfig { - init_storage_data, + init_storage_data: { + let mut data = InitStorageData::default(); + data.insert_value( + StorageValueName::from_slot_name(&initialized_slot), + Word::default(), + )?; + data + }, ..Default::default() }; let mut bank_account = create_testing_account_from_package(bank_package.clone(), bank_cfg)?; - builder.add_account(bank_account.clone())?; - // Create the deposit note + // Create a fungible asset to deposit let deposit_amount: u64 = 1000; let fungible_asset = FungibleAsset::new(faucet.id(), deposit_amount)?; let note_assets = NoteAssets::new(vec![Asset::Fungible(fungible_asset)])?; + // Create the deposit note with assets attached + // The sender becomes the depositor let deposit_note = create_testing_note_from_package( deposit_note_package.clone(), sender.id(), @@ -369,33 +378,59 @@ async fn deposit_test() -> anyhow::Result<()> { }, )?; + // Add bank account and deposit note to mockchain + builder.add_account(bank_account.clone())?; builder.add_output_note(RawOutputNote::Full(deposit_note.clone())); + + // Build the mock chain let mut mock_chain = builder.build()?; - // ========================================================================= - // EXECUTE DEPOSIT (the shipped test initializes the bank first; this excerpt omits that step) - // ========================================================================= + // ********************************************************************************* + // STEP 1: INITIALIZE THE BANK VIA TX SCRIPT + // ********************************************************************************* + // Preview the Part 6 flow, where require_initialized() is enabled. + // Initialize via a transaction script that calls bank.initialize(). + + let init_tx_script = build_tx_script_from_package(init_tx_script_package.as_ref())?; + + let init_tx_context = mock_chain + .build_transaction(bank_account.id()) + .tx_script(init_tx_script) + .build()?; + + let executed_init = init_tx_context.execute().await?; + mock_chain.add_pending_executed_transaction(&executed_init)?; + mock_chain.prove_next_block()?; + bank_account = mock_chain.committed_account(bank_account.id())?.clone(); + + println!("Bank initialized successfully"); + + // ********************************************************************************* + // STEP 2: DEPOSIT + // ********************************************************************************* + + // Build the transaction context where bank consumes the deposit note let tx_context = mock_chain - .build_tx_context(bank_account.id(), &[deposit_note.id()], &[])? + .build_transaction(bank_account.id()) + .authenticated_input_note(deposit_note.id()) .build()?; + // Execute the transaction let executed_transaction = tx_context.execute().await?; - bank_account.apply_delta(&executed_transaction.account_delta())?; + + // Add the executed transaction to the mockchain and prove mock_chain.add_pending_executed_transaction(&executed_transaction)?; mock_chain.prove_next_block()?; + bank_account = mock_chain.committed_account(bank_account.id())?.clone(); - println!("Deposit transaction executed!"); - - // ========================================================================= - // VERIFY: Check balance was updated - // ========================================================================= + // Create the key for the depositor (sender) in the storage map. // Key format: [depositor_prefix, depositor_suffix, asset.key[3], asset.key[2]]. - // In v0.15 the fungible-asset vault key is - // [asset_id_suffix, asset_id_prefix, faucet_suffix | metadata_byte, faucet_prefix], - // so `key[2]` is the faucet suffix combined with a metadata byte (composition + - // callback flag) — not the raw faucet suffix. Derive the read key from the asset's + // In v0.16 the fungible-asset vault key is + // [asset_class_suffix, asset_class_prefix, faucet_suffix | metadata_byte, faucet_prefix], + // so `key[2]` is the faucet suffix combined with composition metadata, + // not the raw faucet suffix. Derive the read key from the asset's // actual key word so it matches the key the contract writes. - let asset_key_word = FungibleAsset::new(faucet.id(), deposit_amount)?.to_key_word(); + let asset_key_word = FungibleAsset::new(faucet.id(), deposit_amount)?.to_id_word(); let depositor_key = Word::from([ sender.id().prefix().as_felt(), sender.id().suffix(), @@ -403,7 +438,8 @@ async fn deposit_test() -> anyhow::Result<()> { asset_key_word[2], ]); - let balance = bank_account.storage().get_map_item(&balances_slot, depositor_key)?; + // Get the depositor's balance from the bank's storage using named slot + let balance = bank_account.storage().get_map_item(&balances_slot, miden_client::account::StorageMapKey::new(depositor_key))?; // The contract stores `balance` as a `Felt`; reading the map returns the // single-Felt value widened into a Word at position [0] ([amount, 0, 0, 0]). @@ -416,10 +452,10 @@ async fn deposit_test() -> anyhow::Result<()> { assert_eq!( balance, expected_balance, - "Balance should equal deposited amount" + "Depositor balance should equal the deposited amount" ); - println!("\nPart 4 deposit test passed!"); + println!("Deposit test passed! Deposited {} tokens", deposit_amount); Ok(()) } ``` @@ -438,12 +474,12 @@ cargo test --package integration --test deposit_test -- --nocapture Finished `test` profile [unoptimized + debuginfo] target(s) Running tests/deposit_test.rs -running 3 tests +running 1 test +Bank initialized successfully +Deposit test passed! Deposited 1000 tokens test deposit_test ... ok -test deposit_exceeds_max_should_fail ... ok -test deposit_without_init_should_fail ... ok -test result: ok. 3 passed; 0 failed; 0 ignored +test result: ok. 1 passed; 0 failed; 0 ignored ``` @@ -463,10 +499,10 @@ pub struct Wallet; /// # Note Storage (14 Felts) /// [0-3]: withdraw asset, encoded as [amount, 0, faucet_suffix(+metadata), faucet_prefix]. /// `storage[2]` carries the faucet suffix with the asset's metadata byte in its -/// low 8 bits (host side: `FungibleAsset::to_key_word()[2]`), not the raw suffix. +/// low 8 bits (host side: `FungibleAsset::to_id_word()[2]`), not the raw suffix. /// [4-7]: serial_num (random/unique per note) /// [8]: tag (P2ID note tag for routing) -/// [9]: note_type (1 = Public, 2 = Private) +/// [9]: note_type (1 = Public, 0 = Private) /// [10-13]: P2ID script_root (MAST root of the P2ID note script, Poseidon2-hashed) #[note] struct WithdrawRequestNote; @@ -482,7 +518,7 @@ impl WithdrawRequestNote { "Withdraw request requires exactly 14 storage items" ); - // Asset: reconstruct the v0.15 fungible-asset key/value from the note storage. + // Asset: reconstruct the v0.16 fungible-asset ID/value from the note storage. // key = [0, 0, storage[2], storage[3]] where storage[2] = faucet suffix + metadata // byte (low 8 bits) and storage[3] = faucet prefix. // value = [amount, 0, 0, 0] @@ -542,7 +578,7 @@ impl DepositNote { let depositor = active_note::get_sender(); // Get all assets attached to this note - let assets = active_note::get_assets(); + let assets = active_note::get_initial_assets(); // Deposit each asset into the bank for asset in assets { @@ -559,10 +595,10 @@ impl DepositNote { 1. **`#[note]`** marks the struct and impl block, with **`#[note_script]`** on the entry point method `fn run(self, _arg: Word, account: &mut Wallet)` 2. **`#[account(bank_account::Bank)] pub struct Wallet;`** wraps the consuming account so the note can call the bank's methods via `account.deposit(...)` 3. **`active_note::get_sender()`** returns who created the note -4. **`active_note::get_assets()`** returns assets attached to the note +4. **`active_note::get_initial_assets()`** returns the assets attached to the note at creation time 5. **`active_note::get_storage()`** returns parameterized data 6. **Note scripts execute once** when consumed - no persistent state -7. **Build order matters** - account components first, then note scripts +7. **Dependencies build automatically** - declare the account component in `miden-project.toml`, then build the note with `miden build` :::tip View Complete Source See the complete note script implementations: diff --git a/docs/src/miden-bank/05-cross-component-calls.md b/docs/src/miden-bank/05-cross-component-calls.md index d8a6e396..d09850cf 100644 --- a/docs/src/miden-bank/05-cross-component-calls.md +++ b/docs/src/miden-bank/05-cross-component-calls.md @@ -14,7 +14,7 @@ By the end of this section, you will have: - Understood how bindings are generated and imported - Learned the dependency configuration in `miden-project.toml` -- Explored the WIT interface files +- Explored the embedded WIT interface - **Verified cross-component calls work** via the deposit flow ## Building on Part 4 @@ -22,24 +22,32 @@ By the end of this section, you will have: In Part 4, you wrote `account.deposit(depositor, asset)` in the deposit note. But how does that call actually work? This part explains the binding system: ```text -┌────────────────────────────────────────────────────────────┐ -│ How Bindings Work │ -├────────────────────────────────────────────────────────────┤ -│ │ -│ bank-account/ │ -│ └── src/lib.rs miden build │ -│ fn deposit() ─────────────▶ generated-wit/ │ -│ fn withdraw() miden-bank-account.wit -│ │ -│ ┌───────────────────────────┐ │ -│ ▼ │ │ -│ deposit-note/ │ │ -│ └── src/lib.rs │ │ -│ #[account(bank_account::Bank)] │ │ -│ pub struct Wallet; │ │ -│ account.deposit(...) ────────────▶ calls via binding│ -│ │ -└────────────────────────────────────────────────────────────┘ +┌────────────────────────────────────────────────────────────────────────┐ +│ How Bindings Work │ +├────────────────────────────────────────────────────────────────────────┤ +│ │ +│ bank-account/ │ +│ └── src/lib.rs │ +│ #[component] trait Bank │ +│ ├── deposit(...) │ +│ └── withdraw(...) │ +│ │ │ +│ │ miden build │ +│ ▼ │ +│ ┌────────────────────────────────────────────────┐ │ +│ │ bank-account.masp │ │ +│ │ Compiled code + embedded WIT + procedure roots │ │ +│ └────────────────────────────────────────────────┘ │ +│ │ │ +│ │ Read the embedded interface during the note build │ +│ ▼ │ +│ deposit-note/ │ +│ └── src/lib.rs │ +│ #[account(bank_account::Bank)] │ +│ pub struct Wallet; │ +│ account.deposit(...) ──▶ generated binding ──▶ Bank::deposit │ +│ │ +└────────────────────────────────────────────────────────────────────────┘ ``` ## The Bindings System @@ -47,23 +55,26 @@ In Part 4, you wrote `account.deposit(depositor, asset)` in the deposit note. Bu When you build an account component with `miden build`, it generates: 1. **MASM code** - The compiled contract logic -2. **WIT files** - WebAssembly Interface Type definitions +2. **Embedded WIT** - WebAssembly Interface Type definitions stored in the package -Other contracts (note scripts, transaction scripts) import these WIT files to call the account's methods. +Other contracts (note scripts, transaction scripts) read the package's embedded interface to call the account's methods. ```text Build Flow: -┌──────────────────┐ miden build ┌─────────────────────────────────┐ -│ bank-account/ │ ─────────────────▶│ target/generated-wit/ │ -│ src/lib.rs │ │ miden-bank-account.wit │ -│ │ │ (includes world definition) │ -└──────────────────┘ └─────────────────────────────────┘ - │ - ▼ - ┌─────────────────────────────────┐ - │ deposit-note/ │ - │ imports generated bindings │ - └─────────────────────────────────┘ + +┌────────────────────┐ ┌───────────────────────────────────┐ +│ bank-account/ │ miden build │ bank-account.masp │ +│ src/lib.rs │ ──────────────▶ │ Code + embedded WIT │ +│ Bank component │ │ Account procedure roots │ +└────────────────────┘ └───────────────────────────────────┘ + │ + ▼ + ┌───────────────────────────────────┐ + │ deposit-note/ │ + │ #[account(bank_account::Bank)] │ + │ Generated Wallet bindings │ + │ account.deposit(...) │ + └───────────────────────────────────┘ ``` ## Declaring the Account Wrapper @@ -108,7 +119,7 @@ impl DepositNote { let depositor = active_note::get_sender(); // Get all assets attached to this note - let assets = active_note::get_assets(); + let assets = active_note::get_initial_assets(); // Deposit each asset into the bank for asset in assets { @@ -126,7 +137,7 @@ The binding automatically handles: ## Configuring Dependencies -Cross-component calls are configured in the note's `miden-project.toml`, which needs **two** dependency entries: +Cross-component calls are configured in the note's `miden-project.toml`, which declares the bank as a path dependency: ```toml title="contracts/deposit-note/miden-project.toml" [dependencies] @@ -134,9 +145,6 @@ miden-core = "*" miden-protocol = "*" bank-account = { path = "../bank-account" } -# WIT for the account component this note calls, produced by building bank-account. -[package.metadata.miden.dependencies] -bank-account = { wit = "../bank-account/target/generated-wit/" } ``` ### `[dependencies]` path @@ -151,22 +159,13 @@ This tells `cargo-miden` where to find the source package. Used during the build - Verify interface compatibility - Link the compiled MASM code -### `[package.metadata.miden.dependencies]` WIT - -```toml -[package.metadata.miden.dependencies] -bank-account = { wit = "../bank-account/target/generated-wit/" } -``` - -This points at the WIT interface files for the account component this note calls. The path is the `generated-wit/` directory created when you built the account component. +### Embedded Interface -:::warning Both Entries Required -If either entry is missing, your build will fail with linking or interface errors. -::: +Compiler 0.10 embeds the WIT interface in the compiled bank package. The path dependency provides both the interface and the procedure roots. Remove the legacy `[package.metadata.miden.dependencies]` `wit` override: supplying it alongside an embedded interface causes the compiler to reject the build. ## Build Order -Components must be built in dependency order: +From the project root, build the account first to inspect its output, then build the note: ```bash title=">_ Terminal" # 1. Build the account component first @@ -176,9 +175,12 @@ miden build # 2. Then build note scripts that depend on it cd ../deposit-note miden build + +# 3. Return to the project root +cd ../.. ``` -If you build out of order, you'll see errors about missing WIT files. +If you build a dependent contract directly, compiler 0.10 also builds its path dependencies. ## What Methods Are Available? @@ -189,9 +191,13 @@ Only the methods declared on the `#[component] trait Bank` are exported through #[component] trait Bank { // EXPORTED: Available through bindings + #[account_procedure] fn initialize(&mut self); + #[account_procedure] fn get_depositor_balance(&self, depositor: AccountId, asset: Asset) -> Felt; + #[account_procedure] fn deposit(&mut self, depositor: AccountId, deposit_asset: Asset); + #[account_procedure] fn withdraw(&mut self, withdraw_asset: Asset, serial_num: Word, tag: Felt, note_type: Felt); } ``` @@ -213,17 +219,25 @@ The balance getter is named `get_depositor_balance` to avoid colliding with the ## Understanding the Generated WIT -The WIT files describe the interface. Here's a simplified example: +The compiler embeds this WIT in the bank package. Its imported core types come from the SDK: + +```wit title="Embedded bank interface" +package miden:bank-account@0.1.0; + +use miden:base/core-types@1.0.0; -```wit title="target/generated-wit/miden-bank-account.wit" -interface bank-account { - use miden:types/types.{account-id, asset, felt, word}; +interface bank { + use core-types.{account-id, asset, felt, word}; initialize: func(); get-depositor-balance: func(depositor: account-id, asset: asset) -> felt; deposit: func(depositor: account-id, deposit-asset: asset); withdraw: func(withdraw-asset: asset, serial-num: word, tag: felt, note-type: felt); } + +world bank-world { + export bank; +} ``` This WIT is what the `#[account(bank_account::Bank)]` macro reads to generate the `Wallet` wrapper's methods. @@ -249,23 +263,23 @@ The `Wallet` wrapper gives direct method access through the `account` parameter, ## Try It: Verify Bindings Work -If you completed Part 4 and built both contracts, the bindings are already working! Let's verify: +After running the builds above, check the bank package from the project root: ```bash title=">_ Terminal" -# Check that the WIT files were generated -ls contracts/bank-account/target/generated-wit/ +# Check the compiled package (its interface is embedded) +ls contracts/bank-account/target/miden/dev/bank-account.masp ```
Expected output ```text -miden-bank-account.wit +contracts/bank-account/target/miden/dev/bank-account.masp ```
-These files enable the deposit note's `#[account(bank_account::Bank)]` wrapper to call `account.deposit()`. +The embedded interface enables the deposit note's `#[account(bank_account::Bank)]` wrapper to call `account.deposit()`. ## Common Issues @@ -275,12 +289,12 @@ These files enable the deposit note's `#[account(bank_account::Bank)]` wrapper t error: cannot find module `bindings` ``` -**Cause**: The account component wasn't built, or the WIT path is wrong. +**Cause**: The account path dependency is missing or points to the wrong project. **Solution**: 1. Build the account: `cd contracts/bank-account && miden build` -2. Verify the WIT path in `miden-project.toml` points to `target/generated-wit/` +2. Verify the `bank-account` path dependency in `miden-project.toml` points to the account project; remove legacy `wit` overrides ### "Method not found" Error @@ -300,12 +314,12 @@ error: dependency 'bank-account' not found **Cause**: One of the dependency entries in `miden-project.toml` is missing or has the wrong path. -**Solution**: Ensure both `[dependencies]` (`bank-account = { path = "../bank-account" }`) and `[package.metadata.miden.dependencies]` (`bank-account = { wit = "../bank-account/target/generated-wit/" }`) are present with correct paths. +**Solution**: Add `bank-account = { path = "../bank-account" }` under `[dependencies]` and remove the legacy `wit` override. ## Key Takeaways -1. **Build accounts first** - They generate WIT files that note scripts need -2. **Two dependency entries** - Both `[dependencies]` (`path`) and `[package.metadata.miden.dependencies]` (`wit`) in `miden-project.toml` are required +1. **Declare the path dependency** - The compiler builds the account package and reads its embedded WIT +2. **Embedded interface** - Declare the path under `[dependencies]`; compiler 0.10 reads the interface from the compiled dependency. Do not add the legacy `wit` override. 3. **Account wrapper pattern** - `#[account(bank_account::Bank)] pub struct Wallet;` exposes the component's methods on the `account` parameter 4. **Only trait methods** - Methods on the private `impl BankStorage` helpers aren't exposed in bindings 5. **Note and tx scripts share the pattern** - Both receive the account wrapper as a parameter (Part 6) diff --git a/docs/src/miden-bank/06-transaction-scripts.md b/docs/src/miden-bank/06-transaction-scripts.md index 8f8cb6b8..fea8bdea 100644 --- a/docs/src/miden-bank/06-transaction-scripts.md +++ b/docs/src/miden-bank/06-transaction-scripts.md @@ -8,6 +8,8 @@ description: "Learn how to write transaction scripts for account initialization In this section, you'll learn how to write transaction scripts - code that the account owner explicitly executes. We'll implement an initialization script that enables the bank to accept deposits. +The companion testnet example uses `AuthSingleSig` with Falcon512Poseidon2 and saves the bank owner's key in its keystore. This authentication component enforces ownership. The `NoAuth` component in our MockChain test helper is only for isolated tests and must not be used to deploy the bank to a live network. + ## What You'll Build in This Part By the end of this section, you will have: @@ -22,30 +24,32 @@ By the end of this section, you will have: In Parts 4-5, you created note scripts that execute when notes are consumed. Now you'll create a transaction script - code the account owner explicitly runs: ```text -┌────────────────────────────────────────────────────────────────┐ -│ Script Types Comparison │ -├────────────────────────────────────────────────────────────────┤ -│ │ -│ Note Scripts (Parts 4-5) Transaction Scripts (Part 6)│ -│ ───────────────────────── ────────────────────────────│ -│ • Triggered by note consumption • Explicitly called by owner│ -│ • Import bindings via modules • Receive account parameter │ -│ • Process incoming assets • Setup, admin operations │ -│ │ -│ deposit-note/ init-tx-script/ │ -│ └── calls bank_account::deposit() └── calls account.initialize() -│ │ -└────────────────────────────────────────────────────────────────┘ +┌────────────────────────────────────────────────────────────────────────┐ +│ Script Types Comparison │ +├────────────────────────────────────────────────────────────────────────┤ +│ │ +│ Note Scripts (Parts 4-5) Transaction Scripts (Part 6) │ +│ ────────────────────────────── ────────────────────────────── │ +│ Triggered by note consumption Attached to a transaction │ +│ Receive account: &mut Wallet Receive account: &mut Wallet │ +│ Read active_note:: context Run setup / owner operations │ +│ Process incoming assets Authorized by account auth │ +│ │ +│ deposit-note/ init-tx-script/ │ +│ └── account.deposit(...) └── account.initialize() │ +│ │ +└────────────────────────────────────────────────────────────────────────┘ ``` ## Transaction Scripts vs Note Scripts -| Aspect | Transaction Script | Note Script | -| ---------- | ---------------------------------- | -------------------------------- | -| Initiation | Explicitly called by account owner | Triggered when note is consumed | -| Access | Direct account method access | Must call through bindings | -| Use case | Setup, owner operations | Receiving messages/assets | -| Parameter | `account: &mut Wallet` | Note context via `active_note::` | +| Aspect | Transaction Script | Note Script | +| ---------- | ---------------------------- | ---------------------------------- | +| Initiation | Selected for the transaction | Triggered when note is consumed | +| Access | Account wrapper bindings | Account wrapper bindings | +| Use case | Setup, owner operations | Receiving messages/assets | +| Parameter | `account: &mut Wallet` | `account: &mut Wallet` | +| Context | Active account | Active account and `active_note::` | **Use transaction scripts for:** @@ -83,7 +87,7 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -miden = "0.13" +miden = "=0.14.0" ``` Create the `miden-project.toml`: @@ -95,6 +99,7 @@ version = "0.1.0" [lib] kind = "tx-script" +path = "src/lib.rs" namespace = "miden:base/transaction-script@1.0.0" [dependencies] @@ -102,8 +107,6 @@ miden-core = "*" miden-protocol = "*" bank-account = { path = "../bank-account" } -[package.metadata.miden.dependencies] -bank-account = { wit = "../bank-account/target/generated-wit/" } ``` Create the `.cargo/config.toml`: @@ -120,7 +123,7 @@ Key configuration: - `kind = "tx-script"` - Marks this as a transaction script (not `account-component` or `note`) - `namespace = "miden:base/transaction-script@1.0.0"` - The standard transaction-script namespace -- The `bank-account` path dependency plus the `[package.metadata.miden.dependencies]` WIT entry let the script call into the account component (same pattern as the note scripts) +- The `bank-account` path dependency lets the script call the account component through the interface embedded in its compiled package ## Step 3: Implement the Transaction Script @@ -146,7 +149,7 @@ pub struct Wallet; /// 1. Transaction is created with this script attached /// 2. Script executes in the context of the bank account /// 3. Calls `account.initialize()` to enable deposits -/// 4. Bank account is now "deployed" and visible on chain +/// 4. Bank is ready to process deposits after the transaction commits /// /// # Arguments /// * `_arg` - Transaction script argument (unused in this script) @@ -191,14 +194,16 @@ The `Wallet` type is generated by the `#[account(...)]` attribute and provides a ## The Native Account Binding -Both note scripts and transaction scripts bind the native account with `#[account(bank_account::Bank)]` and call its methods directly on the `&mut Wallet` parameter. The difference is the trigger and the available context: +Both note scripts and transaction scripts bind the native account with `#[account(bank_account::Bank)]` and call its methods directly on the `&mut Wallet` parameter. The entrypoints below belong in separate note-script and transaction-script contracts; the note method goes inside an `impl` marked `#[note]`. The difference is the trigger and the available context: ```rust // Note script: triggered by note consumption, has access to note context. #[note_script] fn run(self, _arg: Word, account: &mut Wallet) { let depositor = active_note::get_sender(); // note context - account.deposit(depositor, asset); // native-account method + for asset in active_note::get_initial_assets() { + account.deposit(depositor, asset); // native-account method + } } // Transaction script: explicitly run by the owner, no note context. @@ -216,16 +221,14 @@ The `Wallet` wrapper provides: ## Step 4: Build the Transaction Script -Build in dependency order. The transaction script calls into the bank account via the FPI `#[account(...)]` macro, which reads the account's procedure roots from its compiled `.masp` at build time, so the `bank-account` component must be built first: +Compiler 0.10 resolves and builds the `bank-account` path dependency automatically. The `#[account(...)]` macro reads the interface and procedure roots from the compiled dependency to generate the script's account bindings. -```bash title=">_ Terminal" -# First, build the account component (generates WIT files and its .masp) -cd contracts/bank-account -cargo miden build --release +From the project root, build the transaction script directly: -# Then build the transaction script -cd ../init-tx-script -cargo miden build --release +```bash title=">_ Terminal" +cd contracts/init-tx-script +miden build --release +cd ../.. ```
@@ -238,48 +241,44 @@ cargo miden build --release
-:::note Cosmetic build errors -The Miden compiler prints non-fatal `MAST`-serialization `ERROR` lines on every build. They are cosmetic — the build still succeeds and produces the `.masp` package. -::: - ## Account Deployment Pattern -In Miden, accounts are only visible on-chain after their first state change. Transaction scripts are commonly used for this "deployment": +A public account becomes visible on-chain when its first transaction commits. The bank's `initialized` flag is separate from deployment: it controls whether the bank's deposit and withdrawal methods can run. + +The live example first consumes a funding note to obtain native tokens for fees. That transaction deploys the account while the bank is still uninitialized. The owner then submits the initialization script: ```text -Execution Flow: - -1. Account owner creates transaction with init-tx-script - ┌───────────────────────────────────────┐ - │ Transaction │ - │ Account: Bank's AccountId │ - │ Script: init-tx-script │ - └───────────────────────────────────────┘ - -2. Transaction executes - ┌───────────────────────────────────────┐ - │ run(_arg, account) │ - │ └─ account.initialize() │ - │ └─ Sets initialized flag to 1 │ - └───────────────────────────────────────┘ - -3. Account state updated - ┌───────────────────────────────────────┐ - │ Bank Account │ - │ Storage[0] = [1, 0, 0, 0] ← Initialized - │ Now visible on-chain │ - └───────────────────────────────────────┘ +┌────────────────────────────────────────────────────────────────────────┐ +│ Initialization Flow │ +├────────────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. OWNER SIGNS THE INITIALIZATION TRANSACTION │ +│ ┌────────────────────────────────────────────┐ │ +│ │ Account: Bank's AccountId │ │ +│ │ Script: init-tx-script │ │ +│ │ AuthSingleSig verifies the owner signature │ │ +│ └────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ 2. TRANSACTION SCRIPT EXECUTES │ +│ ┌────────────────────────────────────────┐ │ +│ │ run(_arg, account) │ │ +│ │ └── account.initialize() │ │ +│ │ └── Sets the initialized flag to 1 │ │ +│ └────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ 3. TRANSACTION COMMITS │ +│ ┌──────────────────────────────────────────────────────────┐ │ +│ │ bank_account::bank::initialized = [1, 0, 0, 0] │ │ +│ │ Bank can now process deposits and withdrawals │ │ +│ │ Funding already deployed the account in the live example │ │ +│ └──────────────────────────────────────────────────────────┘ │ +│ │ +└────────────────────────────────────────────────────────────────────────┘ ``` -Before initialization: - -- Account exists locally but isn't visible on the network -- Cannot receive notes or interact with other accounts - -After initialization: - -- Account is "deployed" and visible -- Can receive deposits and interact normally +Before initialization, other accounts can already create notes addressed to the bank, but its deposit and withdrawal methods reject them. After initialization, those methods can process the notes. A funding P2ID is handled by `BasicWallet` and does not credit any depositor's ledger balance. ## Using Script Arguments @@ -288,18 +287,17 @@ The `_arg` parameter can pass data to the script: ```rust title="Example: Parameterized script" #[tx_script] fn run(arg: Word, account: &mut Wallet) { - // Use arg as configuration - let config_value = arg[0]; - account.configure(config_value); + assert!(arg[0].as_canonical_u64() == 42, "Expected initialization argument"); + account.initialize(); } ``` -When creating the transaction, provide the argument: +When creating the transaction, pass the argument with `tx_script_args`: ```rust title="Integration code (not contract code)" -let tx_script_args = Word::from([felt!(42), felt!(0), felt!(0), felt!(0)]); +let tx_script_args = Word::from([42u32, 0, 0, 0]); let tx_context = mock_chain - .build_tx_context(bank_account.id(), &[], &[])? + .build_transaction(bank_account.id()) .tx_script(init_tx_script) .tx_script_args(tx_script_args) // Pass the argument .build()?; @@ -317,7 +315,7 @@ use integration::helpers::{ use miden_client::{ account::{component::{InitStorageData, StorageValueName}, StorageSlotName}, - auth::AuthSchemeId, + auth::AuthScheme, Word, }; use miden_testing::{Auth, MockChain}; @@ -372,7 +370,7 @@ async fn init_test() -> anyhow::Result<()> { let mut builder = MockChain::builder(); builder.add_existing_basic_faucet( Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, + auth_scheme: AuthScheme::Falcon512Poseidon2, }, "TEST", 10_000_000, @@ -385,14 +383,14 @@ async fn init_test() -> anyhow::Result<()> { let init_tx_script = build_tx_script_from_package(init_tx_script_package.as_ref())?; let init_tx_context = mock_chain - .build_tx_context(bank_account.id(), &[], &[])? + .build_transaction(bank_account.id()) .tx_script(init_tx_script) .build()?; let executed_init = init_tx_context.execute().await?; - bank_account.apply_delta(&executed_init.account_delta())?; mock_chain.add_pending_executed_transaction(&executed_init)?; mock_chain.prove_next_block()?; + bank_account = mock_chain.committed_account(bank_account.id())?.clone(); // Verify initialized flag flipped to 1 let after = bank_account.storage().get_item(&initialized_slot)?; @@ -412,7 +410,7 @@ A few things to note in this test: - The slot name is `bank_account::bank::initialized` (the namespace is `bank_account`, not `miden_bank_account`). - The `initialized` value slot has **no schema default**, so it must be seeded via `InitStorageData` or `AccountComponent::from_package` errors with `InitValueNotProvided`. Only the `balances` map slot defaults to empty. -- A `kind = "tx-script"` contract compiles to a `TransactionScript`-kind package, **not** an `Executable`. So `unwrap_program()` / `TransactionScript::from_package` do not apply — the `build_tx_script_from_package` helper locates the entry export and builds the script via `TransactionScript::from_parts`. +- A `kind = "tx-script"` contract exposes its entry procedure with `#[transaction_script]`. The `build_tx_script_from_package` helper loads it with `TransactionScript::from_package`. ## Enable the Initialization Guard @@ -435,7 +433,7 @@ With this change, deposits and withdrawals will fail unless the bank has been in ## Try It: Verify Initialization -Run the companion init test to verify the transaction script correctly flips the initialized flag: +From the project root, run the companion init test to verify the transaction script correctly flips the initialized flag: ```bash title=">_ Terminal" cargo test --package integration --test init_test -- --nocapture @@ -466,13 +464,13 @@ Your actual output may include additional trace lines from the Miden VM or MockC ::: :::tip Troubleshooting -**"Cannot find module bindings"**: The bank-account wasn't built. Run `cargo miden build --release` in `contracts/bank-account` first — the FPI `#[account(...)]` macro reads its procedure roots from the compiled `.masp`. +**Account binding errors**: Check that `#[account(bank_account::Bank)]` matches the dependency name and exported component trait. Declare the `bank-account` path under `[dependencies]` and remove legacy `wit` overrides. Rebuild the transaction script with `miden build --release`; the compiler builds its account dependency automatically. -**"Dependency not found"**: Check that the `bank-account` path dependency and the `[package.metadata.miden.dependencies]` WIT entry are both present in `miden-project.toml` with correct paths. +**"Dependency not found"**: Check that the `bank-account` path dependency in `miden-project.toml` points to the account project. ::: :::note Live network bin -The MockChain test above is the source of truth for verifying this flow. The live-network bin (`cargo run --bin initialize`) also runs against a testnet node. +The MockChain test above is the source of truth for verifying this flow. The live-network bin (`cargo run --bin initialize`) also runs against a testnet node. It prints the new bank ID and waits while you request native tokens from the testnet faucet, then consumes the funding note and submits the signed initialization transaction. ::: ## What We've Built So Far @@ -509,7 +507,7 @@ pub struct Wallet; /// 1. Transaction is created with this script attached /// 2. Script executes in the context of the bank account /// 3. Calls `account.initialize()` to enable deposits -/// 4. Bank account is now "deployed" and visible on chain +/// 4. Bank is ready to process deposits after the transaction commits /// /// # Arguments /// * `_arg` - Transaction script argument (unused in this script) @@ -530,7 +528,7 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -miden = "0.13" +miden = "=0.14.0" ``` ```toml title="contracts/init-tx-script/miden-project.toml" @@ -540,6 +538,7 @@ version = "0.1.0" [lib] kind = "tx-script" +path = "src/lib.rs" namespace = "miden:base/transaction-script@1.0.0" [dependencies] @@ -547,8 +546,6 @@ miden-core = "*" miden-protocol = "*" bank-account = { path = "../bank-account" } -[package.metadata.miden.dependencies] -bank-account = { wit = "../bank-account/target/generated-wit/" } ``` ```toml title="contracts/init-tx-script/.cargo/config.toml" @@ -566,9 +563,9 @@ rustflags = ["--cfg", "miden"] 1. **`#[tx_script]`** marks the entry point with signature `fn run(_arg: Word, account: &mut Wallet)` 2. **`#[account(...)]`** binds a `Wallet` wrapper to the native account's component, enabling direct method calls 3. **Direct account access** - Methods called on the `account` parameter, not via module imports -4. **Owner-initiated** - Only the account owner can execute transaction scripts +4. **Authorization** - The account's authentication component controls which transactions can update it; a transaction script alone does not enforce ownership 5. **Deployment pattern** - First state change makes account visible on-chain -6. **TransactionScript-kind package** - Unlike an executable, the compiled tx-script is extracted with `build_tx_script_from_package` +6. **Loading a transaction script** - `build_tx_script_from_package` uses `TransactionScript::from_package` to load the compiled entry procedure :::tip View Complete Source See the complete transaction script implementation in [contracts/init-tx-script/src/lib.rs](https://github.com/0xMiden/miden-tutorials/blob/main/examples/miden-bank/contracts/init-tx-script/src/lib.rs). diff --git a/docs/src/miden-bank/07-output-notes.md b/docs/src/miden-bank/07-output-notes.md index e911c68a..ff47ccb6 100644 --- a/docs/src/miden-bank/07-output-notes.md +++ b/docs/src/miden-bank/07-output-notes.md @@ -72,7 +72,7 @@ P2ID (Pay-to-ID) is a standard note pattern in Miden that sends assets to a spec In Part 3, we introduced `withdraw()` and `create_p2id_note()` as skeletons. Now we'll complete them with full implementations. -Update `contracts/bank-account/src/lib.rs`: +Replace the existing `withdraw()` method in `impl Bank for BankStorage` in `contracts/bank-account/src/lib.rs`. Keep the other methods: ```rust title="contracts/bank-account/src/lib.rs" #[component] @@ -95,7 +95,7 @@ impl Bank for BankStorage { // Verify this is a fungible asset — see `deposit()` for the rationale. assert!( - withdraw_asset.value[1].as_canonical_u64() == 0, + withdraw_asset.is_fungible(), "Only fungible assets are supported" ); @@ -131,7 +131,7 @@ impl Bank for BankStorage { } ``` -The withdraw method derives the balance-map key inline by packing `depositor.prefix`, `depositor.suffix`, `withdraw_asset.key[3]`, and `withdraw_asset.key[2]` into a `Word`. In the v0.15 fungible-asset vault-key layout, `asset.key[3]` is the faucet id prefix and `asset.key[2]` is the faucet id suffix with the asset's metadata byte folded into its low 8 bits — so `key[2]` is NOT the raw faucet suffix. `withdraw()` and `deposit()` derive the key the same way so a withdrawal reconstructs the exact key the deposit was recorded under. +The withdraw method derives the balance-map key inline by packing `depositor.prefix`, `depositor.suffix`, `withdraw_asset.key[3]`, and `withdraw_asset.key[2]` into a `Word`. In the v0.16 fungible-asset ID layout, `asset.key[3]` is the faucet ID prefix and `asset.key[2]` is the faucet ID suffix with the composition metadata folded into its low byte — so `key[2]` is NOT the raw faucet suffix. `withdraw()` and `deposit()` derive the key the same way so a withdrawal reconstructs the exact key the deposit was recorded under. :::danger Critical Security: Balance Validation Always validate `current_balance >= withdraw_amount` BEFORE subtraction. Miden uses modular field arithmetic - subtracting a larger value silently wraps to a massive positive number! @@ -146,11 +146,11 @@ let storage = active_note::get_storage(); let script_root = Word::from([storage[10], storage[11], storage[12], storage[13]]); ``` -This design keeps the bank contract version-agnostic: callers embed the P2ID script root they want to use into the note storage when they create the withdraw-request note. The test obtains the correct value at test time with `P2idNote::script_root()` from the `miden_client` crate. In v0.15 `script_root()` returns a `NoteScriptRoot`, so wrap it in `Word::from(...)` before indexing its felts (see the test below). +This design keeps the bank contract version-agnostic: callers embed the P2ID script root they want to use into the note storage when they create the withdraw-request note. The test obtains the correct value at test time with `P2idNote::script_root()` from the `miden_client` crate. In v0.16 `script_root()` returns a `NoteScriptRoot`, so wrap it in `Word::from(...)` before indexing its felts (see the test below). ## Step 3: Implement create_p2id_note -This replaces the `todo!()` placeholder from Part 3. The `#[component]` macro exports only the `Bank` trait methods, so `create_p2id_note` (along with the other private helper `require_initialized`) lives in a plain `impl BankStorage` block, NOT inside `impl Bank for BankStorage`. Add the full implementation: +This replaces the `todo!()` placeholder from Part 3. The `#[component]` macro exports only the `Bank` trait methods, so `create_p2id_note` (along with the other private helper `require_initialized`) lives in a plain `impl BankStorage` block, NOT inside `impl Bank for BankStorage`. Replace the existing helper with the implementation below, keeping `require_initialized()` in the same block: ```rust title="contracts/bank-account/src/lib.rs" /// Internal helpers that are not part of the component's exported WIT API. @@ -173,7 +173,7 @@ impl BankStorage { script_root: Word, ) { // Convert the passed tag Felt to a Tag and note_type Felt to a NoteType. - // note_type: 1 = Public (stored on-chain), 2 = Private (off-chain) + // note_type: 1 = Public (stored on-chain), 0 = Private (off-chain) let tag = Tag::from(tag); let note_type = NoteType::from(note_type); @@ -218,7 +218,7 @@ Note the order: `suffix` comes before `prefix`. This is the opposite of how `Acc | Parameter | Type | Description | | ----------- | ----------- | -------------------------------- | | `tag` | `Tag` | Routing information for the note | -| `note_type` | `NoteType` | Public (1) or Private (2) | +| `note_type` | `NoteType` | Public (1) or Private (0) | | `recipient` | `Recipient` | Who can consume the note | ## Step 4: Create the Withdraw Request Note Project @@ -243,7 +243,7 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -miden = "0.13" +miden = "=0.14.0" ``` ```toml title="contracts/withdraw-request-note/miden-project.toml" @@ -253,6 +253,7 @@ version = "0.1.0" [lib] kind = "note" +path = "src/lib.rs" namespace = "miden:withdraw-request-note/miden-withdraw-request-note@0.1.0" [dependencies] @@ -260,9 +261,6 @@ miden-core = "*" miden-protocol = "*" bank-account = { path = "../bank-account" } -# WIT for the account component this note calls, produced by building bank-account. -[package.metadata.miden.dependencies] -bank-account = { wit = "../bank-account/target/generated-wit/" } ``` ```toml title="contracts/withdraw-request-note/.cargo/config.toml" @@ -273,7 +271,7 @@ target = "wasm32-wasip2" rustflags = ["--cfg", "miden"] ``` -The note declares `bank-account` as both a path dependency (so its types are visible) and as a `[package.metadata.miden.dependencies]` WIT dependency pointing at bank-account's generated WIT. That WIT is produced by building bank-account first — see the build order below. +The note declares `bank-account` as a path dependency. Compiler 0.10 builds the account package and reads its embedded interface; do not add a separate `wit` override. ## Step 5: Implement the Withdraw Request Note Script @@ -304,13 +302,13 @@ pub struct Wallet; /// /// # Note Storage (14 Felts) /// [0-3]: withdraw asset, encoded as [amount, 0, faucet_suffix(+metadata), faucet_prefix]. -/// Reconstructed into the v0.15 vault key [0, 0, storage[2], storage[3]] and value +/// Reconstructed into the v0.16 asset ID [0, 0, storage[2], storage[3]] and value /// [amount, 0, 0, 0]. `storage[2]` carries the faucet suffix with the asset's metadata -/// byte in its low 8 bits (host side: `FungibleAsset::to_key_word()[2]`), not the raw +/// composition bits in its low byte (host side: `FungibleAsset::to_id_word()[2]`), not the raw /// suffix — so the bank reconstructs exactly the key the depositor's asset had. /// [4-7]: serial_num (random/unique per note) /// [8]: tag (P2ID note tag for routing) -/// [9]: note_type (1 = Public, 2 = Private) +/// [9]: note_type (1 = Public, 0 = Private) /// [10-13]: P2ID script_root (MAST root of the P2ID note script, Poseidon2-hashed). /// Consumed by the bank account directly from the active note's storage inside /// `Bank::withdraw`, so it never appears on the call — this keeps that @@ -329,7 +327,7 @@ impl WithdrawRequestNote { "Withdraw request requires exactly 14 storage items" ); - // Asset: reconstruct the v0.15 fungible-asset key/value from the note storage. + // Asset: reconstruct the v0.16 fungible-asset ID/value from the note storage. // key = [0, 0, storage[2], storage[3]] where storage[2] = faucet suffix + metadata // byte (low 8 bits) and storage[3] = faucet prefix. // value = [amount, 0, 0, 0] @@ -344,7 +342,7 @@ impl WithdrawRequestNote { // Tag: single Felt for P2ID note routing let tag = storage[8]; - // Note type: 1 = Public, 2 = Private + // Note type: 1 = Public, 0 = Private let note_type = storage[9]; // Note: P2ID script root (storage[10..13]) is read by the bank account directly @@ -358,7 +356,7 @@ impl WithdrawRequestNote { } ``` -The `#[account(bank_account::Bank)]` macro generates the `Wallet` wrapper from bank-account's WIT, giving the note script a typed `account.withdraw(...)` call. The macro reads bank-account's procedure roots from its compiled `.masp` at compile time, which is why bank-account must be built first. +The `#[account(bank_account::Bank)]` macro generates the `Wallet` wrapper from bank-account's WIT, giving the note script a typed `account.withdraw(...)` call. The automatic path dependency in `miden-project.toml` builds bank-account and supplies its compiled interface and procedure roots to the macro. ### Note Storage Layout @@ -366,44 +364,43 @@ The withdraw-request-note uses 14 Felt storage items: ```text Note Storage (14 Felts): -┌───────────────────────────────────────────────────────────────────────────┐ -│ Index │ Value │ Description │ -├───────┼─────────────────┼─────────────────────────────────────────────────┤ -│ 0 │ amount │ Token amount to withdraw │ -│ 1 │ 0 │ Reserved (always 0 for fungible) │ -│ 2 │ faucet_suffix* │ Faucet ID suffix + metadata byte (v0.15 key[2]) │ -│ 3 │ faucet_prefix │ Faucet ID prefix (identifies asset type) │ -│ 4-7 │ serial_num │ Unique ID for the output P2ID note (4 Felts) │ -│ 8 │ tag │ Note routing tag for P2ID note │ -│ 9 │ note_type │ 1 (Public) or 2 (Private) │ -│ 10-13 │ script_root │ P2ID script MAST root (Poseidon2-hashed, 4 Felts)│ -└───────────────────────────────────────────────────────────────────────────┘ +┌───────┬────────────────┬───────────────────────────────────────────────────┐ +│ Index │ Value │ Description │ +├───────┼────────────────┼───────────────────────────────────────────────────┤ +│ 0 │ amount │ Token amount to withdraw │ +├───────┼────────────────┼───────────────────────────────────────────────────┤ +│ 1 │ 0 │ Reserved (always 0 for fungible) │ +├───────┼────────────────┼───────────────────────────────────────────────────┤ +│ 2 │ faucet_suffix* │ Faucet ID suffix + metadata byte (v0.16 key[2]) │ +├───────┼────────────────┼───────────────────────────────────────────────────┤ +│ 3 │ faucet_prefix │ Faucet ID prefix (identifies asset type) │ +├───────┼────────────────┼───────────────────────────────────────────────────┤ +│ 4-7 │ serial_num │ Unique ID for the output P2ID note (4 Felts) │ +├───────┼────────────────┼───────────────────────────────────────────────────┤ +│ 8 │ tag │ Note routing tag for P2ID note │ +├───────┼────────────────┼───────────────────────────────────────────────────┤ +│ 9 │ note_type │ 1 (Public) or 0 (Private) │ +├───────┼────────────────┼───────────────────────────────────────────────────┤ +│ 10-13 │ script_root │ P2ID script MAST root (Poseidon2-hashed, 4 Felts) │ +└───────┴────────────────┴───────────────────────────────────────────────────┘ ``` -\*Index 2 is the v0.15 fungible-asset vault key's `key[2]`: the faucet ID suffix with the asset's metadata byte folded into its low 8 bits, not the raw suffix. The host side encodes it from `FungibleAsset::new(faucet.id(), amount)?.to_key_word()[2]`. +\*Index 2 is the v0.16 fungible-asset ID's `key[2]`: the faucet ID suffix with the composition metadata folded into its low byte, not the raw suffix. The host side encodes it from `FungibleAsset::new(faucet.id(), amount)?.to_id_word()[2]`. :::note Why the Asset is in Inputs -Unlike the deposit note which gets assets from `active_note::get_assets()`, the withdraw request note doesn't carry assets. Instead, the asset to withdraw is specified in the note inputs. The bank then withdraws from its own vault based on these inputs. +Unlike the deposit note which gets its creation-time assets from `active_note::get_initial_assets()`, the withdraw request note doesn't carry assets. Instead, the asset to withdraw is specified in the note inputs. The bank then withdraws from its own vault based on these inputs. ::: ## Step 6: Build All Components -Build in dependency order — bank-account first so its WIT and compiled `.masp` exist before the note that depends on them: +Build the withdrawal note from the workspace root. Its automatic path dependency also rebuilds the bank account: ```bash title=">_ Terminal" -# 1. Build the account component (generates WIT files and the .masp) -cd contracts/bank-account -cargo miden build --release - -# 2. Build the withdraw request note -cd ../withdraw-request-note -cargo miden build --release +cd contracts/withdraw-request-note +miden build --release +cd ../.. ``` -:::note Cosmetic build errors -The Miden compiler prints non-fatal `MAST`-serialization `ERROR` lines on every build. They are cosmetic — the build still succeeds and produces the package. You can ignore them. -::: - ## Try It: Verify Withdrawals Work Let's test the complete withdraw flow. This test: @@ -411,15 +408,18 @@ Let's test the complete withdraw flow. This test: 1. Creates a bank account and initializes it 2. Creates a deposit note and processes it 3. Creates a withdraw-request note with the 14-Felt storage layout -4. Processes the withdrawal and verifies a P2ID output note is created +4. Processes the withdrawal and verifies the expected P2ID output note +5. Rejects consumption by another account, then credits the depositor when they consume it -A few v0.15 host-side details to note: +The test exercises both public and private output notes. MockChain is supplied with the full expected note in either case; on a live network, private note details must reach the recipient separately. + +A few host-side details to note: - The bank account's slot names are `bank_account::bank::initialized` and `bank_account::bank::balances`. - The `initialized` value slot has no schema default, so it MUST be seeded via `InitStorageData` (with a zero `Word` = uninitialized) or `from_package` fails with `InitValueNotProvided`. Only the `balances` map defaults to empty. -- The init transaction script is extracted with the `build_tx_script_from_package` helper. A tx-script package is a `TargetType::TransactionScript`, so `unwrap_program()` / `TransactionScript::from_package` would panic. +- The `build_tx_script_from_package` helper calls `TransactionScript::from_package` to load the procedure marked `#[transaction_script]` from the compiled package. - Host-side felts use `Felt::new_unchecked`, and the expected output note uses `PartialNoteMetadata` (not `NoteMetadata`). -- The withdraw asset is encoded from `FungibleAsset::new(faucet.id(), withdraw_amount)?.to_key_word()` indices `[2]`/`[3]` so the bank reconstructs the exact vault key the deposit recorded — NOT from `faucet.id().suffix()/prefix()`. +- The withdraw asset is encoded from `FungibleAsset::new(faucet.id(), withdraw_amount)?.to_id_word()` indices `[2]`/`[3]` so the bank reconstructs the exact asset ID the deposit recorded — NOT from `faucet.id().suffix()/prefix()`. ```rust title="integration/tests/withdraw_test.rs" use integration::helpers::{ @@ -427,14 +427,17 @@ use integration::helpers::{ create_testing_note_from_package, AccountCreationConfig, NoteCreationConfig, }; +use miden_client::asset::{Asset, FungibleAsset}; use miden_client::{ - account::{component::{InitStorageData, StorageValueName}, StorageSlotName}, - auth::AuthSchemeId, + account::{ + component::{InitStorageData, StorageValueName}, + StorageSlotName, + }, + auth::AuthScheme, note::{Note, NoteAssets, NoteTag, NoteType, P2idNote, P2idNoteStorage, PartialNoteMetadata}, transaction::RawOutputNote, Felt, Word, }; -use miden_client::asset::{Asset, FungibleAsset}; use miden_testing::{Auth, MockChain}; use std::{path::Path, sync::Arc}; @@ -442,21 +445,26 @@ use std::{path::Path, sync::Arc}; /// seeded via `InitStorageData` (no schema default); the `balances` map defaults to empty. fn bank_storage_slots() -> (StorageSlotName, StorageSlotName) { let initialized_slot = - StorageSlotName::new("bank_account::bank::initialized") - .expect("Valid slot name"); + StorageSlotName::new("bank_account::bank::initialized").expect("Valid slot name"); let balances_slot = - StorageSlotName::new("bank_account::bank::balances") - .expect("Valid slot name"); + StorageSlotName::new("bank_account::bank::balances").expect("Valid slot name"); (initialized_slot, balances_slot) } #[tokio::test] async fn withdraw_test() -> anyhow::Result<()> { + for note_type in [NoteType::Public, NoteType::Private] { + withdraw_flow(note_type).await?; + } + Ok(()) +} + +async fn withdraw_flow(note_type: NoteType) -> anyhow::Result<()> { // ********************************************************************************* // SETUP // ********************************************************************************* - // Test that after executing the deposit note, the depositor's balance is updated + // Verify withdrawal through consumption of the resulting P2ID note. let mut builder = MockChain::builder(); // Define the deposit amount @@ -465,7 +473,7 @@ async fn withdraw_test() -> anyhow::Result<()> { // Create a faucet to mint test assets let faucet = builder.add_existing_basic_faucet( Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, + auth_scheme: AuthScheme::Falcon512Poseidon2, }, "TEST", deposit_amount, @@ -475,7 +483,7 @@ async fn withdraw_test() -> anyhow::Result<()> { // Create note sender account (the depositor) let sender = builder.add_existing_wallet_with_assets( Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, + auth_scheme: AuthScheme::Falcon512Poseidon2, }, [FungibleAsset::new(faucet.id(), deposit_amount)?.into()], )?; @@ -497,7 +505,7 @@ async fn withdraw_test() -> anyhow::Result<()> { // Create the bank account. The `initialized` value slot has no schema default, so it must // be seeded (here with a zero Word = uninitialized) or `from_package` errors with // `InitValueNotProvided`; the `balances` map defaults to empty. - let (initialized_slot, _balances_slot) = bank_storage_slots(); + let (initialized_slot, balances_slot) = bank_storage_slots(); let bank_cfg = AccountCreationConfig { init_storage_data: { let mut data = InitStorageData::default(); @@ -510,8 +518,7 @@ async fn withdraw_test() -> anyhow::Result<()> { ..Default::default() }; - let mut bank_account = - create_testing_account_from_package(bank_package.clone(), bank_cfg)?; + let mut bank_account = create_testing_account_from_package(bank_package.clone(), bank_cfg)?; // ********************************************************************************* // STEP 1: CRAFT DEPOSIT NOTE @@ -560,22 +567,22 @@ async fn withdraw_test() -> anyhow::Result<()> { println!("Serial num (random): {:?}", p2id_output_note_serial_num); // Note type for the P2ID output note - let note_type_felt = Felt::new_unchecked(1); // 1 = Public note (stored on-chain) + let note_type_felt = Felt::from(note_type); // Public = 1, Private = 0 // Get the P2ID script root (Poseidon2-hashed MAST root). `script_root()` returns - // a `NoteScriptRoot` in v0.15; convert to a `Word` so its felts can be indexed. + // a `NoteScriptRoot` in v0.16; convert to a `Word` so its felts can be indexed. let p2id_script_root = Word::from(P2idNote::script_root()); // Note storage layout (14 Felts): - // [0-3]: withdraw asset encoded as [amount, 0, faucet_suffix, faucet_prefix] + // [0-3]: withdraw asset encoded as [amount, 0, asset.key[2] (faucet suffix + metadata byte), asset.key[3] (faucet prefix)] // [4-7]: serial_num (random/unique per note) // [8]: tag (P2ID note tag for routing) - // [9]: note_type (1 = Public, 2 = Private) + // [9]: note_type (1 = Public, 0 = Private) // [10-13]: P2ID script_root (MAST root for recipient computation) - // In v0.15 the fungible-asset vault key encodes the faucet suffix together with a + // In v0.16 the fungible-asset vault key encodes the faucet suffix together with a // metadata byte at index [2] (and the faucet prefix at [3]). Encode the asset from the // asset's real key word so the bank reconstructs the same key it deposited under. - let withdraw_asset_key_word = FungibleAsset::new(faucet.id(), withdraw_amount)?.to_key_word(); + let withdraw_asset_key_word = FungibleAsset::new(faucet.id(), withdraw_amount)?.to_id_word(); let withdraw_request_note_storage = vec![ // WITHDRAW ASSET ENCODING Felt::new_unchecked(withdraw_amount), @@ -589,7 +596,7 @@ async fn withdraw_test() -> anyhow::Result<()> { p2id_output_note_serial_num[3], // TAG (directly passed, no advice provider needed) p2id_tag_felt, - // NOTE TYPE (1 = Public) + // NOTE TYPE (1 = Public, 0 = Private) note_type_felt, // P2ID SCRIPT ROOT (4 Felts) p2id_script_root[0], @@ -625,14 +632,14 @@ async fn withdraw_test() -> anyhow::Result<()> { let init_tx_script = build_tx_script_from_package(init_tx_script_package.as_ref())?; let init_tx_context = mock_chain - .build_tx_context(bank_account.id(), &[], &[])? + .build_transaction(bank_account.id()) .tx_script(init_tx_script) .build()?; let executed_init = init_tx_context.execute().await?; - bank_account.apply_delta(&executed_init.account_delta())?; mock_chain.add_pending_executed_transaction(&executed_init)?; mock_chain.prove_next_block()?; + bank_account = mock_chain.committed_account(bank_account.id())?.clone(); println!("Bank initialized successfully"); @@ -642,18 +649,17 @@ async fn withdraw_test() -> anyhow::Result<()> { // Build the transaction context where bank consumes the deposit note let deposit_tx_context = mock_chain - .build_tx_context(bank_account.id(), &[deposit_note.id()], &[])? + .build_transaction(bank_account.id()) + .authenticated_input_note(deposit_note.id()) .build()?; // Execute the transaction let executed_deposit_transaction = deposit_tx_context.execute().await?; - // Apply the account delta to the bank account - bank_account.apply_delta(&executed_deposit_transaction.account_delta())?; - // Add the executed transaction to the mockchain and prove mock_chain.add_pending_executed_transaction(&executed_deposit_transaction)?; mock_chain.prove_next_block()?; + bank_account = mock_chain.committed_account(bank_account.id())?.clone(); println!("Bank deposit successful"); @@ -665,8 +671,8 @@ async fn withdraw_test() -> anyhow::Result<()> { let recipient = P2idNoteStorage::new(sender.id()).into_recipient(p2id_output_note_serial_num); let p2id_output_note_asset = FungibleAsset::new(faucet.id(), withdraw_amount)?; let p2id_output_note_assets = NoteAssets::new(vec![p2id_output_note_asset.into()])?; - let p2id_output_note_metadata = PartialNoteMetadata::new(bank_account.id(), NoteType::Public) - .with_tag(p2id_tag); + let p2id_output_note_metadata = + PartialNoteMetadata::new(bank_account.id(), note_type).with_tag(p2id_tag); println!("Recipient digest: {:?}", recipient.digest().to_hex()); @@ -677,18 +683,72 @@ async fn withdraw_test() -> anyhow::Result<()> { ); let withdraw_request_tx_context = mock_chain - .build_tx_context(bank_account.id(), &[withdraw_request_note.id()], &[])? - .extend_expected_output_notes(vec![RawOutputNote::Full(p2id_output_note)]) + .build_transaction(bank_account.id()) + .authenticated_input_note(withdraw_request_note.id()) + .expected_output_notes(vec![RawOutputNote::Full(p2id_output_note.clone())]) .build()?; let executed_withdraw_request_transaction = withdraw_request_tx_context.execute().await?; - bank_account.apply_delta(&executed_withdraw_request_transaction.account_delta())?; - mock_chain.add_pending_executed_transaction(&executed_withdraw_request_transaction)?; mock_chain.prove_next_block()?; + bank_account = mock_chain.committed_account(bank_account.id())?.clone(); + + let remaining = deposit_amount - withdraw_amount; + let asset = FungibleAsset::new(faucet.id(), withdraw_amount)?; + let asset_key = asset.to_id_word(); + let depositor_key = miden_client::account::StorageMapKey::new(Word::from([ + sender.id().prefix().as_felt(), + sender.id().suffix(), + asset_key[3], + asset_key[2], + ])); + let balance = bank_account + .storage() + .get_map_item(&balances_slot, depositor_key)?; + assert_eq!(balance[0].as_canonical_u64(), remaining); + assert_eq!( + u64::from(bank_account.vault().get_balance(asset.id())?), + remaining + ); + assert_eq!( + executed_withdraw_request_transaction + .output_notes() + .num_notes(), + 1 + ); + // MockChain retains only headers for newly committed private notes. Supply their + // full details explicitly, as the recipient would receive them out of band. + let consume_p2id = |account_id| { + let tx = mock_chain.build_transaction(account_id); + if note_type == NoteType::Public { + tx.authenticated_input_note(p2id_output_note.id()) + } else { + tx.unauthenticated_input_note(p2id_output_note.clone()) + } + }; - println!("Withdraw test passed!"); + // P2ID must reject a consumer other than the depositor. + let error = consume_p2id(bank_account.id()) + .build()? + .execute() + .await + .expect_err("only the depositor may consume the withdrawal note"); + assert!( + format!("{error:?}").contains("FailedAssertion"), + "unexpected failure: {error:?}" + ); + + let sender_balance_before = u64::from(sender.vault().get_balance(asset.id())?); + let executed_receive = consume_p2id(sender.id()).build()?.execute().await?; + mock_chain.add_pending_executed_transaction(&executed_receive)?; + mock_chain.prove_next_block()?; + let sender_after = mock_chain.committed_account(sender.id())?; + assert_eq!( + u64::from(sender_after.vault().get_balance(asset.id())?), + sender_balance_before + withdraw_amount + ); + println!("{note_type:?} withdrawal consumed by depositor! Remaining bank balance: {remaining}"); Ok(()) } @@ -755,13 +815,13 @@ pub struct Wallet; /// /// # Note Storage (14 Felts) /// [0-3]: withdraw asset, encoded as [amount, 0, faucet_suffix(+metadata), faucet_prefix]. -/// Reconstructed into the v0.15 vault key [0, 0, storage[2], storage[3]] and value +/// Reconstructed into the v0.16 asset ID [0, 0, storage[2], storage[3]] and value /// [amount, 0, 0, 0]. `storage[2]` carries the faucet suffix with the asset's metadata -/// byte in its low 8 bits (host side: `FungibleAsset::to_key_word()[2]`), not the raw +/// composition bits in its low byte (host side: `FungibleAsset::to_id_word()[2]`), not the raw /// suffix — so the bank reconstructs exactly the key the depositor's asset had. /// [4-7]: serial_num (random/unique per note) /// [8]: tag (P2ID note tag for routing) -/// [9]: note_type (1 = Public, 2 = Private) +/// [9]: note_type (1 = Public, 0 = Private) /// [10-13]: P2ID script_root (MAST root of the P2ID note script, Poseidon2-hashed). /// Consumed by the bank account directly from the active note's storage inside /// `Bank::withdraw`, so it never appears on the call — this keeps that @@ -780,7 +840,7 @@ impl WithdrawRequestNote { "Withdraw request requires exactly 14 storage items" ); - // Asset: reconstruct the v0.15 fungible-asset key/value from the note storage. + // Asset: reconstruct the v0.16 fungible-asset ID/value from the note storage. // key = [0, 0, storage[2], storage[3]] where storage[2] = faucet suffix + metadata // byte (low 8 bits) and storage[3] = faucet prefix. // value = [amount, 0, 0, 0] @@ -795,7 +855,7 @@ impl WithdrawRequestNote { // Tag: single Felt for P2ID note routing let tag = storage[8]; - // Note type: 1 = Public, 2 = Private + // Note type: 1 = Public, 0 = Private let note_type = storage[9]; // Note: P2ID script root (storage[10..13]) is read by the bank account directly diff --git a/docs/src/miden-bank/08-complete-flows.md b/docs/src/miden-bank/08-complete-flows.md index fc931882..a28f4978 100644 --- a/docs/src/miden-bank/08-complete-flows.md +++ b/docs/src/miden-bank/08-complete-flows.md @@ -22,28 +22,29 @@ By the end of this section, you will have: You've built all the pieces. Now let's see them work together: ```text -┌────────────────────────────────────────────────────────────────┐ -│ COMPLETE BANK SYSTEM │ -├────────────────────────────────────────────────────────────────┤ -│ │ -│ Components Built: │ -│ ┌─────────────────────────────────────────────────────────┐ │ -│ │ bank-account │ Storage + deposit() + withdraw() │ │ -│ ├─────────────────┼───────────────────────────────────────┤ │ -│ │ deposit-note │ Note script → bank_account::deposit() │ │ -│ ├─────────────────┼───────────────────────────────────────┤ │ -│ │ withdraw-note │ Note script → bank_account::withdraw() │ │ -│ ├─────────────────┼───────────────────────────────────────┤ │ -│ │ init-tx-script │ Transaction script → initialize() │ │ -│ └─────────────────┴───────────────────────────────────────┘ │ -│ │ -│ Storage Layout: │ -│ ┌─────────────────────────────────────────────────────────┐ │ -│ │ initialized (Value) │ Word: [1, 0, 0, 0] when ready│ │ -│ │ balances (StorageMap) │ Map: user_key → [balance, 0, 0, 0]│ │ -│ └─────────────────────────────────────────────────────────┘ │ -│ │ -└────────────────────────────────────────────────────────────────┘ +┌────────────────────────────────────────────────────────────────────────┐ +│ COMPLETE BANK SYSTEM │ +├────────────────────────────────────────────────────────────────────────┤ +│ │ +│ Components Built: │ +│ ┌───────────────────────┬───────────────────────────────────┐ │ +│ │ bank-account │ Storage + deposit() + withdraw() │ │ +│ ├───────────────────────┼───────────────────────────────────┤ │ +│ │ deposit-note │ Note script → account.deposit() │ │ +│ ├───────────────────────┼───────────────────────────────────┤ │ +│ │ withdraw-request-note │ Note script → account.withdraw() │ │ +│ ├───────────────────────┼───────────────────────────────────┤ │ +│ │ init-tx-script │ Transaction script → initialize() │ │ +│ └───────────────────────┴───────────────────────────────────┘ │ +│ │ +│ Storage Layout: │ +│ ┌───────────────────────┬──────────────────────────────────┐ │ +│ │ initialized (Value) │ Word: [1, 0, 0, 0] when ready │ │ +│ ├───────────────────────┼──────────────────────────────────┤ │ +│ │ balances (StorageMap) │ Balance per user and asset class │ │ +│ └───────────────────────┴──────────────────────────────────┘ │ +│ │ +└────────────────────────────────────────────────────────────────────────┘ ``` ## The Complete Deposit Flow @@ -51,48 +52,53 @@ You've built all the pieces. Now let's see them work together: Let's trace through exactly what happens when a user deposits tokens: ```text -┌─────────────────────────────────────────────────────────────────────┐ -│ DEPOSIT FLOW │ -├─────────────────────────────────────────────────────────────────────┤ -│ │ -│ 1. USER CREATES DEPOSIT NOTE │ -│ ┌──────────────────────┐ │ -│ │ Deposit Note │ │ -│ │ sender: User │ │ -│ │ assets: [1000 tok] │ │ -│ │ script: deposit-note│ │ -│ │ target: Bank │ │ -│ └──────────────────────┘ │ -│ │ │ -│ ▼ │ -│ 2. BANK CONSUMES NOTE (Transaction begins) │ -│ ┌──────────────────────┐ │ -│ │ Bank Account │ │ -│ │ vault += 1000 tokens│ ◀── Protocol adds assets to vault │ -│ └──────────────────────┘ │ -│ │ │ -│ ▼ │ -│ 3. NOTE SCRIPT EXECUTES │ -│ depositor = active_note::get_sender() → User's AccountId │ -│ assets = active_note::get_assets() → [1000 tokens] │ -│ for asset in assets: │ -│ bank_account::deposit(depositor, asset) ◀── Cross-component│ -│ │ │ -│ ▼ │ -│ 4. DEPOSIT METHOD RUNS (in bank-account context) │ -│ ┌──────────────────────────────────────────┐ │ -│ │ require_initialized() ✓ Passes │ │ -│ │ amount <= MAX_DEPOSIT ✓ 1000 <= 100k │ │ -│ │ native_account::add_asset() ← Confirm │ │ -│ │ balances[User] += 1000 ← Update │ │ -│ └──────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ 5. TRANSACTION COMPLETES │ -│ Bank storage: balances[User] = 1000 │ -│ Bank vault: +1000 tokens │ -│ │ -└─────────────────────────────────────────────────────────────────────┘ +┌────────────────────────────────────────────────────────────────────────┐ +│ DEPOSIT FLOW │ +├────────────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. USER CREATES DEPOSIT NOTE │ +│ ┌─────────────────────────┐ │ +│ │ Deposit Note │ │ +│ │ sender: User │ │ +│ │ assets: [1000 tokens] │ │ +│ │ script: deposit-note │ │ +│ │ consumed by: Bank │ │ +│ └─────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ 2. BANK CONSUMES THE NOTE │ +│ ┌────────────────────────────────────────────────────┐ │ +│ │ Transaction begins; note script executes │ │ +│ │ Vault is credited when deposit() calls add_asset() │ │ +│ └────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ 3. NOTE SCRIPT CALLS THE BANK COMPONENT │ +│ ┌────────────────────────────────────────────────────────────┐ │ +│ │ depositor = active_note::get_sender() → User's AccountId │ │ +│ │ assets = active_note::get_initial_assets() → [1000 tokens] │ │ +│ │ for asset in assets: │ │ +│ │ account.deposit(depositor, asset) │ │ +│ └────────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ 4. DEPOSIT METHOD VALIDATES AND RECEIVES THE ASSET │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ require_initialized() ✓ │ │ +│ │ assert asset.is_fungible() ✓ │ │ +│ │ assert 0 < amount <= MAX_DEPOSIT (1,000,000) ✓ │ │ +│ │ native_account::add_asset(asset) → Credit vault │ │ +│ │ balances[User, asset class] += 1000 → Update ledger │ │ +│ └─────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ 5. TRANSACTION COMMITS │ +│ ┌──────────────────────────────────┐ │ +│ │ Depositor's ledger balance: 1000 │ │ +│ │ Bank vault: +1000 tokens │ │ +│ └──────────────────────────────────┘ │ +│ │ +└────────────────────────────────────────────────────────────────────────┘ ``` ## The Complete Withdraw Flow @@ -100,76 +106,79 @@ Let's trace through exactly what happens when a user deposits tokens: Now let's trace the withdrawal process: ```text -┌─────────────────────────────────────────────────────────────────────┐ -│ WITHDRAW FLOW │ -├─────────────────────────────────────────────────────────────────────┤ -│ │ -│ 1. USER CREATES WITHDRAW REQUEST NOTE │ -│ ┌──────────────────────────────┐ │ -│ │ Withdraw Request Note │ │ -│ │ sender: User │ │ -│ │ inputs: [serial, tag, │ │ -│ │ note_type] │ │ -│ │ assets: [withdraw amount] │ │ -│ │ target: Bank │ │ -│ └──────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ 2. BANK CONSUMES REQUEST (Transaction begins) │ -│ ┌──────────────────────────────┐ │ -│ │ Note script executes: │ │ -│ │ sender = get_sender() │ │ -│ │ storage = get_storage() │ │ -│ │ asset = Asset from inputs │ │ -│ │ bank_account::withdraw(...) │ │ -│ └──────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ 3. WITHDRAW METHOD RUNS │ -│ ┌──────────────────────────────────────────────────────┐ │ -│ │ require_initialized() ✓ Passes │ │ -│ │ current_balance = get_depositor_balance(User) → 1000 │ │ -│ │ VALIDATE: 1000 >= 400 ✓ Passes │ ◀ CRITICAL -│ │ balances[User] = 1000 - 400 → 600 │ │ -│ │ create_p2id_note(...) → Output note │ │ -│ └──────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ 4. P2ID NOTE CREATED (inside create_p2id_note) │ -│ ┌──────────────────────────────────────────────────────┐ │ -│ │ script_root = storage[10..13] → MAST digest │ │ -│ │ recipient = note::build_recipient( │ │ -│ │ serial_num, script_root, │ │ -│ │ [user.suffix, user.prefix] │ │ -│ │ ) │ │ -│ │ note_idx = output_note::create(tag, note_type, │ │ -│ │ recipient) │ │ -│ │ native_account::remove_asset(400 tokens) │ │ -│ │ output_note::add_asset(400 tokens, note_idx) │ │ -│ └──────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ 5. TRANSACTION COMPLETES │ -│ Bank storage: balances[User] = 600 │ -│ Bank vault: -400 tokens │ -│ Output: P2ID note with 400 tokens → User │ -│ │ │ -│ ▼ │ -│ 6. USER CONSUMES P2ID NOTE (separate transaction) │ -│ User's wallet receives 400 tokens │ -│ │ -└─────────────────────────────────────────────────────────────────────┘ +┌────────────────────────────────────────────────────────────────────────┐ +│ WITHDRAW FLOW │ +├────────────────────────────────────────────────────────────────────────┤ +│ │ +│ 1. USER CREATES WITHDRAWAL REQUEST NOTE │ +│ ┌───────────────────────────────────────────────────────┐ │ +│ │ Withdrawal Request Note │ │ +│ │ sender: User │ │ +│ │ assets: [] │ │ +│ │ storage (14 Felts): │ │ +│ │ asset (4), serial (4), tag, type, script root (4) │ │ +│ │ requested amount: 500 tokens │ │ +│ │ consumed by: Bank │ │ +│ └───────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ 2. BANK CONSUMES THE REQUEST │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ Note script reads active_note::get_storage() │ │ +│ │ Reconstructs the requested asset from storage[0..4] │ │ +│ │ Calls account.withdraw(asset, serial, tag, type) │ │ +│ └─────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ 3. WITHDRAW METHOD VALIDATES AND UPDATES THE LEDGER │ +│ ┌────────────────────────────────────────────────┐ │ +│ │ require_initialized() ✓ │ │ +│ │ assert asset.is_fungible() ✓ │ │ +│ │ User = active_note::get_sender() │ │ +│ │ current_balance = 1000 │ │ +│ │ assert current_balance >= 500 ✓ │ │ +│ │ balances[User, asset class] = 1000 - 500 = 500 │ │ +│ │ create_p2id_note(...) → Output note │ │ +│ └────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ 4. P2ID NOTE IS CREATED │ +│ ┌──────────────────────────────────────────────────────┐ │ +│ │ script_root = storage[10..14] │ │ +│ │ recipient = note::build_recipient( │ │ +│ │ serial, script_root, [user.suffix, user.prefix]) │ │ +│ │ note_idx = output_note::create(tag, type, recipient) │ │ +│ │ native_account::remove_asset(500 tokens) │ │ +│ │ output_note::add_asset(500 tokens, note_idx) │ │ +│ └──────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ 5. TRANSACTION COMMITS │ +│ ┌───────────────────────────────────────────────────────────┐ │ +│ │ Depositor's ledger balance: 500 │ │ +│ │ Bank vault: -500 tokens │ │ +│ │ Output: public or private P2ID carrying 500 tokens → User │ │ +│ └───────────────────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ 6. USER CONSUMES P2ID IN A SEPARATE TRANSACTION │ +│ ┌──────────────────────────────────────┐ │ +│ │ P2ID recipient check passes for User │ │ +│ │ User's wallet receives 500 tokens │ │ +│ └──────────────────────────────────────┘ │ +│ │ +└────────────────────────────────────────────────────────────────────────┘ ``` ## Try It: Complete End-to-End Test -The complete flow is exercised by the three integration tests built up over the previous chapters, which together cover the same `init → deposit → withdraw` story shown in the diagram above: +The complete flow is exercised by the three integration test files built up over the previous chapters, which together cover the same `init → deposit → withdraw` story shown in the diagram above: -- `examples/miden-bank/integration/tests/deposit_test.rs` — introduced in Part 4. Covers the deposit happy path (`deposit_test`) plus two failure paths: `deposit_exceeds_max_should_fail` and `deposit_without_init_should_fail`. +- `examples/miden-bank/integration/tests/deposit_test.rs` — introduced in Part 4. Covers the deposit happy path (`deposit_test`) plus rejection tests for excessive deposits, deposits before initialization, and NFTs with zero padding in their value word. - `examples/miden-bank/integration/tests/init_test.rs` — introduced in Part 6. Exercises the init transaction script (`init_test`) and verifies the `initialized` flag flips from `0` to `1`. -- `examples/miden-bank/integration/tests/withdraw_test.rs` — introduced in Part 7. Runs init + deposit + withdraw end-to-end (`withdraw_test`) and asserts the P2ID output note is created with the correct payload. +- `examples/miden-bank/integration/tests/withdraw_test.rs` — introduced in Part 7. Runs init + deposit + withdraw end-to-end (`withdraw_test`) for both public and private outputs, rejects consumption by another account, and verifies the depositor receives the withdrawn tokens. -Running all three together from the workspace root is the closest thing to a single end-to-end run: +Run the complete suite from the workspace root: ```bash title=">_ Terminal" cargo test --package integration --release -- --nocapture --test-threads=1 @@ -183,12 +192,13 @@ cargo test --package integration --release -- --nocapture --test-threads=1 Finished `release` profile [optimized] target(s) Running tests/deposit_test.rs -running 3 tests +running 4 tests test deposit_test ... ok test deposit_exceeds_max_should_fail ... ok test deposit_without_init_should_fail ... ok +test deposit_nft_with_zero_padding_should_fail ... ok -test result: ok. 3 passed; 0 failed; 0 ignored +test result: ok. 4 passed; 0 failed; 0 ignored Running tests/init_test.rs @@ -208,7 +218,7 @@ test result: ok. 1 passed; 0 failed; 0 ignored :::note Live network bins -The repository also ships `cargo run --bin initialize` and `cargo run --bin deposit` (under `examples/miden-bank/integration/src/bin/`) for exercising the same flow against a live testnet node. The MockChain integration tests above verify the deposit, init, and withdraw flows end-to-end. +The repository also ships `cargo run --bin initialize` and `cargo run --bin deposit` (under `examples/miden-bank/integration/src/bin/`) for exercising the same flow against a live testnet node. The deposit bin attaches 1,000 native base units, and both binaries wait for actual transaction commitment before reporting success. Testnet charges fees: each binary prints the new account ID and waits for a public native-token P2ID. Request funding for that ID from the testnet faucet while it waits; the helper consumes the funding note before proceeding. The MockChain tests above verify initialization, deposit, and withdrawal without external funding. ::: ## Summary: All Components @@ -227,15 +237,15 @@ Here's the complete picture of what you've built: | `initialized` | `StorageValue` | Initialization flag | | `balances` | `StorageMap` | Depositor balances | -| API | Purpose | -| -------------------------------- | --------------------- | -| `active_note::get_sender()` | Identify note creator | -| `active_note::get_assets()` | Get attached assets | -| `active_note::get_storage()` | Get note parameters | -| `native_account::add_asset()` | Receive into vault | -| `native_account::remove_asset()` | Send from vault | -| `output_note::create()` | Create output note | -| `output_note::add_asset()` | Attach assets to note | +| API | Purpose | +| ----------------------------------- | --------------------------------- | +| `active_note::get_sender()` | Identify note creator | +| `active_note::get_initial_assets()` | Get creation-time attached assets | +| `active_note::get_storage()` | Get note parameters | +| `native_account::add_asset()` | Receive into vault | +| `native_account::remove_asset()` | Send from vault | +| `output_note::create()` | Create output note | +| `output_note::add_asset()` | Attach assets to note | ## Key Security Patterns @@ -257,17 +267,19 @@ let new_balance = current_balance - withdraw_amount; ::: -:::warning Felt Comparison Operators -Never use `<`, `>` on Felt values directly. Always convert to u64 first: +:::note Felt Comparison Operators +Direct `Felt` comparisons use canonical integer ordering in the current SDK. Both forms below are valid; this tutorial uses the explicit `u64` form for quantity checks: ```rust -// ❌ BROKEN: Produces incorrect results +// Direct comparison of canonical Felt values. if current_balance < withdraw_amount { ... } -// ✅ CORRECT: Use as_canonical_u64() +// Equivalent comparison with explicit integer conversion. if current_balance.as_canonical_u64() < withdraw_amount.as_canonical_u64() { ... } ``` +Always perform this check before subtracting. Conversion after modular underflow cannot recover the intended balance. + ::: ## Congratulations! 🎉 diff --git a/docs/src/miden-bank/index.md b/docs/src/miden-bank/index.md index d5b5dead..bf80d823 100644 --- a/docs/src/miden-bank/index.md +++ b/docs/src/miden-bank/index.md @@ -15,12 +15,12 @@ You'll create a **banking system** consisting of: - **Bank Account Component**: A smart contract that manages depositor balances and vault operations - **Deposit Note**: A note script that processes deposits into the bank - **Withdraw Request Note**: A note script that requests withdrawals from the bank -- **Initialization Script**: A transaction script to deploy and initialize the bank +- **Initialization Script**: A transaction script to initialize the bank -The tutorial includes runnable tests where appropriate — some parts are setup-only or conceptual, with the first runnable test in Part 4. +The tutorial includes runnable tests where appropriate — some parts are setup-only or conceptual, with setup tests in Parts 0–2 and transaction tests once the required contracts are in place. -:::note Verification runs on MockChain -This tutorial targets protocol **v0.15** and the v0.15-aligned Rust compiler. The contracts depend on the published `miden = "0.13"` SDK, and the integration harness builds them with the published `cargo-miden = "0.9"` release. The flow is verified end-to-end by the MockChain integration tests (`tests/{init,deposit,withdraw}_test.rs`), which all pass. The live-network binaries (`cargo run --bin initialize` / `--bin deposit`) also run against testnet. +:::note Version and fee setup +The contracts use stable `miden = "=0.14.0"` and compiler 0.10.0; the native integration harness uses protocol/client 0.16. The companion MockChain tests cover initialization, deposit, deposit rejection, and withdrawal. Live testnet transactions also need native tokens for fees. The live binaries print each new account ID and wait for an externally requested public P2ID funding note, then consume it before proceeding. ::: ## Tutorial Structure @@ -49,23 +49,30 @@ This tutorial is designed for hands-on learning. Each part builds on the previou ## Tutorial Cards import DocCard from '@theme/DocCard'; +import {useDoc} from '@docusaurus/plugin-content-docs/client'; + +export const BankDocCard = ({item}) => { +const {metadata} = useDoc(); +const sectionPath = metadata.permalink.replace(/\/$/, ''); + return ; +};
-
-
-
-
-
-
-
-
- Result<(), ClientError> { let deserialized_p2id_note = Note::read_from_bytes(&serialized).unwrap(); // Time consume note request building - let consume_note_request = - TransactionRequestBuilder::new().build_consume_notes(vec![deserialized_p2id_note])?; + // Keep this input unauthenticated even if syncing has already fetched its proof. + let consume_note_request = TransactionRequestBuilder::new() + .explicit_input_notes([(InputNote::unauthenticated(deserialized_p2id_note), None)]) + .build()?; let tx_id = client .submit_tutorial_transaction(accounts[i + 1].id(), consume_note_request) @@ -468,7 +471,7 @@ Account: balance: 20 ## Conclusion -This example builds, serializes, and consumes complete notes through `build_consume_notes` without first waiting for their inclusion proofs. It confirms four transfers across five accounts and checks the tutorial-asset balances `[80, 0, 0, 0, 20]`; each account's native fee balance is separate. +This example builds and serializes complete notes, then consumes the four transfer notes through `explicit_input_notes` with an explicitly unauthenticated mode. The earlier mint consumption uses `build_consume_notes` and may be authenticated. It confirms four transfers across five accounts and checks the tutorial-asset balances `[80, 0, 0, 0, 20]`; each account's native fee balance is separate. Applications can use this pattern to submit dependent transactions before the notes are committed. The node must still accept the creation transaction for its dependent consumption to settle. diff --git a/docs/src/web-client/bridging_with_epoch_tutorial.md b/docs/src/web-client/bridging_with_epoch_tutorial.md index 12f469d3..7c43886b 100644 --- a/docs/src/web-client/bridging_with_epoch_tutorial.md +++ b/docs/src/web-client/bridging_with_epoch_tutorial.md @@ -31,7 +31,7 @@ You need three things to follow along. 2. Two wallets: an EVM wallet supported by [RainbowKit](https://www.rainbowkit.com/) (MetaMask, Rabby, Coinbase Wallet, …) and the [MidenFi browser extension](https://chromewebstore.google.com/detail/miden-wallet/ablmompanofnodfdkgchkpmphailefpb) for signing P2IDE notes on Miden. -3. A small Sepolia ETH balance for gas. The community [pk910 PoW faucet](https://sepolia-faucet.pk910.de/) pays 0.05–0.1 ETH per ~10-minute mining session; the [Google Cloud Sepolia faucet](https://cloud.google.com/application/web3/faucet/ethereum/sepolia) is the backup. Either covers the gas for `depositERC20AndRegister` plus a couple of allowance approvals. +3. A small Sepolia ETH balance for gas. The community [pk910 PoW faucet](https://sepolia-faucet.pk910.de/) and [Google Cloud Sepolia faucet](https://cloud.google.com/application/web3/faucet/ethereum/sepolia) are possible sources; check their current requirements and limits. Keep enough test ETH for token approvals and the Compact deposit. :::caution Do not set COOP/COEP headers `@miden-sdk/vite-plugin` defaults to `crossOriginIsolation: true`, which sets `Cross-Origin-Opener-Policy` and `Cross-Origin-Embedder-Policy` headers on the dev server and breaks gRPC-Web to `transport.miden.io`. The reference app passes `{ crossOriginIsolation: false }` to opt out — see the [Vite + WASM setup guide](./setup_guide.md) for the deployment-side counterpart. @@ -202,7 +202,7 @@ Success is signalled by the 5-second polling loop: `getIntentStatus` returns an The reverse direction lives in `buildEVMToMidenTaskDataParams` + `useWithdrawIntent`. The task envelope sets `destinationChainId` to the Miden virtual chain id (`999999999`) so the allocator's `getTokenDataFromMidenFaucetId` resolves the output side as Miden-native, and the note type flips to `P2ID` (not `P2IDE`) because the Miden recipient consumes the note directly rather than recalling it. The reverse-quote convention is the same as Step 2: pass `tokenInAmount: '0'` and a Miden-side `minTokenOut` in base units; the backend computes the required EVM input. :::caution Bridge with headroom before the reverse direction -The Step 3 reverse quote folds a route fee into the required deposit, so a Step 2 bridge of exactly 1 USDC won't cover a 1-USDC reverse — the quote asks for ~1.01 USDC and MetaMask flags `depositERC20AndRegister` as likely to fail (the `approve` lands first; rejecting the deposit is recoverable). Set Step 2's `min output` to about `2e18` for headroom, or run a second forward bridge before retrying. +The reverse quote includes route fees, so bridging out one token may not leave enough to request one token back. Compare the quoted input amount with your balance before approval and deposit. Use the selected token's decimals when converting amounts to base units; do not assume an 18-decimal asset. ::: **From `examples/bridging-app/src/services/epoch-bridge.ts` (lines 216–237):** @@ -234,7 +234,7 @@ The Step 3 reverse quote folds a route fee into the required deposit, so a Step return taskDataParams; ``` -`solveIntent({ ..., collateralType: CollateralType.EVM })` then walks the user's wallet through an ERC-20 `approve` (only on the first deposit of a given token) and `depositERC20AndRegister` / `depositNativeAndRegister` against Epoch's [Compact](https://docs.epochprotocol.xyz/epoch-miden-integration/integration-guide) contract on Sepolia. The intent nonce extracted from the solve result drives the same 5-second status poll as the forward direction. +`solveIntent({ ..., collateralType: CollateralType.EVM })` then walks the user's wallet through an ERC-20 `approve` (only on the first deposit of a given token) and `depositERC20AndRegister` / `depositNativeAndRegister` against Epoch's [Compact](https://docs.epochprotocol.xyz/integration-guides/sdk-integration-guide) contract on Sepolia. The intent nonce extracted from the solve result drives the same 5-second status poll as the forward direction. :::caution Forced-withdrawal preflight If the user cancelled a prior EVM → Miden intent on the same Compact deposit id, the next intent will revert. Call `sdk.disableForcedWithdrawal(depositId)` first; the SDK error message names the deposit id when this preflight is required. @@ -272,7 +272,7 @@ Recovery primitives (`retryIntentSolve`, `disableForcedWithdrawal`, `withdrawTok Check these integration details before a live round trip: -- **Don't follow the npm package README.** It documents an unrelated SDK; the [integration guide](https://docs.epochprotocol.xyz/epoch-miden-integration/integration-guide) and `dist/sdk/epoch-intent-sdk.d.ts` are the source of truth. +- **Don't follow the npm package README.** It documents an unrelated SDK; the [integration guide](https://docs.epochprotocol.xyz/integration-guides/sdk-integration-guide) and `dist/sdk/epoch-intent-sdk.d.ts` are the source of truth. - **Public notes only.** P2IDE notes for the allocator must be `'public'`; a `'private'` note is invisible to the solver. - **Await confirmation and match the note ID.** A fee-paying transaction also creates a `TX_FEE` output. Do not pass `outputNotes[0]` to Epoch; locate the exact collateral note ID after `waitForTransaction`. - **Honor Epoch’s callback window and binding.** `createMidenP2IDENote` supplies `recallBlocks` and `bindingAttachmentFelts`. Build a public P2IDE with `currentBlock + recallBlocks` after a fresh sync and include the attachment verbatim. A plain `SendTransaction` cannot represent this attachment. The quote’s preliminary reclaim-height field is not a substitute for the callback values. @@ -287,6 +287,6 @@ Check these integration details before a live round trip: ## Where to go next - The runnable [`examples/bridging-app/`](https://github.com/0xMiden/tutorials/tree/main/examples/bridging-app) is the canonical reference; every code block above is a paste-verified slice of it. -- The [Epoch protocol integration guide](https://docs.epochprotocol.xyz/epoch-miden-integration/integration-guide) covers the SDK surface in depth, including the parts this tutorial does not exercise (multi-hop intents, custom resource locks). +- The [Epoch protocol integration guide](https://docs.epochprotocol.xyz/integration-guides/sdk-integration-guide) covers the SDK surface in depth, including the parts this tutorial does not exercise (multi-hop intents, custom resource locks). - Upstream Epoch example: [`epochprotocol/miden-integration-example`](https://github.com/epochprotocol/miden-integration-example). The reference app forks this with the adaptations documented in its README. - The companion [React wallet tutorial](./react_wallet_tutorial.md) walks the `@miden-sdk/react` hook surface end-to-end if you want a deeper foundation before extending the bridging app. diff --git a/docs/src/web-client/counter_contract_tutorial.md b/docs/src/web-client/counter_contract_tutorial.md index 48c0cf24..53349cf6 100644 --- a/docs/src/web-client/counter_contract_tutorial.md +++ b/docs/src/web-client/counter_contract_tutorial.md @@ -52,15 +52,17 @@ This tutorial assumes you have a basic understanding of Miden assembly. To quick yarn add @miden-sdk/miden-sdk@0.16.0 ``` -**NOTE!**: Be sure to add the `--webpack` command to your `package.json` when running the `dev script`. The dev script should look like this: +The current Next.js template uses Turbopack by default. These examples use the webpack configuration from the setup guide, so update both scripts in `package.json`: `package.json` ```json +{ "scripts": { "dev": "next dev --webpack", - ... + "build": "next build --webpack" } +} ``` ## Step 2: Edit the `app/page.tsx` file: @@ -184,17 +186,11 @@ Add an `asset/source` webpack rule so `.masm` files are imported as plain text s Open `next.config.ts` and add the following rule inside the `webpack` callback: ```ts -webpack: (config, { isServer }) => { - // ... existing WASM config ... - - // Import .masm files as strings - config.module.rules.push({ - test: /\.masm$/, - type: "asset/source", - }); - - return config; -}, +// Import .masm files as strings. Keep the existing WASM configuration. +config.module.rules.push({ + test: /\.masm$/, + type: "asset/source", +}); ``` :::tip Other bundlers @@ -314,7 +310,7 @@ end To run the code above in our frontend, run the following command: -``` +```bash yarn dev ``` @@ -510,15 +506,18 @@ yarn dev ### Resetting the `MidenClientDB` -The Miden webclient stores account and note data in the browser. If you get errors such as "Failed to build MMR", then you should reset the Miden webclient store. When switching between Miden networks such as from localhost to testnet be sure to reset the browser store. To clear the account and node data in the browser, paste this code snippet into the browser console: +The Miden webclient stores account and note data in IndexedDB. Stop or terminate the tutorial client and close other tabs using its store before resetting it. This deletes local account data and keys, so use it only for disposable tutorial accounts. The following browser-console snippet deletes the default testnet `MidenClientDB_mtst` store after the deletion request completes; change `name` if you configured a different store. ```javascript (async () => { - const dbs = await indexedDB.databases(); - for (const db of dbs) { - await indexedDB.deleteDatabase(db.name); - console.log(`Deleted database: ${db.name}`); - } - console.log('All databases deleted.'); + const name = 'MidenClientDB_mtst'; + await new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase(name); + request.onsuccess = () => resolve(); + request.onerror = () => reject(request.error); + request.onblocked = () => + reject(new Error('Close clients and tabs using this store, then retry.')); + }); + console.log(`Deleted database: ${name}`); })(); ``` diff --git a/docs/src/web-client/create_deploy_tutorial.md b/docs/src/web-client/create_deploy_tutorial.md index a1f39cc3..15aa44b4 100644 --- a/docs/src/web-client/create_deploy_tutorial.md +++ b/docs/src/web-client/create_deploy_tutorial.md @@ -38,13 +38,13 @@ In this tutorial, we'll build a simple Next.js application that demonstrates the Before we dive into code, a quick refresher: - **Public accounts**: The account's data and code are stored on-chain and are openly visible, including its assets. -- **Private accounts**: The account's state and logic are off-chain, only known to its owner. +- **Private accounts**: The account's state and logic are kept off-chain. The owner retains them locally and can share them; the chain records the account commitment. - **Public notes**: The note's state is visible to anyone - perfect for scenarios where transparency is desired. - **Private notes**: The note's state is stored off-chain, you will need to share the note data with the relevant parties (via email or Telegram) for them to be able to consume the note. > **Important**: In Miden, "accounts" and "smart contracts" can be used interchangeably due to native account abstraction. Every account is programmable and can contain custom logic. -It is useful to think of notes on Miden as "cryptographic cashier's checks" that allow users to send tokens. If the note is private, the note transfer is only known to the sender and receiver. +It is useful to think of notes on Miden as "cryptographic cashier's checks" that allow users to send tokens. Private note details must be shared with the recipient. The chain still records public note metadata, the note commitment, and its eventual nullifier; privacy also depends on how the details and transaction witness are shared. ## Step 1: Initialize your Next.js project @@ -69,15 +69,17 @@ It is useful to think of notes on Miden as "cryptographic cashier's checks" that typescript: { code: `yarn add @miden-sdk/miden-sdk@0.16.0` }, }} reactFilename="" tsFilename="" /> -**NOTE!**: Be sure to add the `--webpack` command to your `package.json` when running the `dev script`. The dev script should look like this: +The current Next.js template uses Turbopack by default. These SDK examples use the webpack configuration from the setup guide, so update both scripts in `package.json`: `package.json` ```json +{ "scripts": { "dev": "next dev --webpack", - ... + "build": "next build --webpack" } +} ``` ## Step 2: Set up the Miden client @@ -89,7 +91,7 @@ The Miden client is your gateway to interact with the Miden blockchain. It handl First, we'll create a separate file for our blockchain logic. In the project root, create a folder `lib/` and inside it `lib/react/createMintConsume.tsx` (React) or `lib/createMintConsume.ts` (TypeScript): ```bash -mkdir -p lib +mkdir -p lib/react ``` { .console.log('Alice ID:', alice.id().toString()); };` }, typescript: { code: `// lib/createMintConsume.ts -import { MidenClient } from '@miden-sdk/miden-sdk/lazy'; +import { MidenClient, StorageMode } from '@miden-sdk/miden-sdk/lazy'; export async function createMintConsume(): Promise { .if (typeof window === 'undefined') { @@ -261,7 +263,7 @@ export async function createMintConsume(): Promise { A faucet in Miden is a special type of account that can mint new tokens. Think of it as your own token factory. Let's deploy one that will create our custom "MID" tokens. -Add this code after creating Alice's account: +Add this code after creating Alice’s account. Use `fundAccount` from `useTutorialSupport` in React, or import `fundAccountForFees` from `./feeSupport` in TypeScript, as shown in the complete example. Consuming native fee funding is the first transaction that deploys each account. @@ -320,11 +324,8 @@ import { .useMiden, .useCreateWallet, .useCreateFaucet, -.useMint, -.useConsume, -.useSend, } from '@miden-sdk/react/lazy'; -import { NoteVisibility, StorageMode } from '@miden-sdk/miden-sdk/lazy'; +import { StorageMode } from '@miden-sdk/miden-sdk/lazy'; import { tutorialNetwork } from '../feeSupport'; import { .TutorialButton, @@ -336,16 +337,7 @@ function CreateMintConsumeInner() { .const { sync } = useMiden(); .const { createWallet } = useCreateWallet(); .const { createFaucet } = useCreateFaucet(); -.const { mint } = useMint(); -.const { consume } = useConsume(); -.const { send } = useSend(); -.const { -..fundAccount, -..committed, -..waitForTokenNotes, -..waitForNote, -..assertBalance, -.} = useTutorialSupport(); +.const { fundAccount } = useTutorialSupport(); .const run = async () => { ..console.log('Synchronizing before creating accounts…'); @@ -371,42 +363,13 @@ function CreateMintConsumeInner() { ..console.log('Faucet ID:', faucet.id().toString()); ..await fundAccount(faucet); -..await sync(); -..const minted = await mint({ -...faucetId: faucet, -...targetAccountId: alice, -...amount: BigInt(1000), -...noteType: NoteVisibility.Public, -..}); -..await committed(minted.transactionId); -..const notes = await waitForTokenNotes(alice, faucet); -..const consumed = await consume({ accountId: alice.id().toString(), notes }); -..await committed(consumed.transactionId); -..await assertBalance(alice, faucet, BigInt(1000)); - -..const bob = await createWallet({ -...storageMode: StorageMode.Public, -...authScheme, -..}); -..const sent = await send({ -...from: alice, -...to: bob, -...assetId: faucet, -...amount: BigInt(100), -...noteType: NoteVisibility.Public, -...returnNote: true, -..}); -..await committed(sent.txId); -..if (!sent.note) throw new Error('Send did not return its output note'); -..await waitForNote(sent.note.id().toString()); -..await assertBalance(alice, faucet, BigInt(900)); -..console.log('Tokens sent successfully!'); +..console.log('Setup complete.'); .}; .return ( .. .); @@ -426,9 +389,8 @@ export default function CreateMintConsume() { .); }`}, typescript: { code: `// lib/createMintConsume.ts -import { NoteVisibility, StorageMode } from '@miden-sdk/miden-sdk/lazy'; +import { StorageMode } from '@miden-sdk/miden-sdk/lazy'; import { -.consumeAllFeeAware, .createTutorialClient, .fundAccountForFees, } from './feeSupport'; @@ -468,50 +430,14 @@ export async function createMintConsume(): Promise { .await fundAccountForFees(client, alice); .await fundAccountForFees(client, faucet); -.// 4. Mint tokens to Alice. -.console.log('Minting tokens to Alice...'); -.await client.sync(); -.const { txId: mintTxId } = await client.transactions.mint({ -..account: faucet, -..to: alice, -..amount: BigInt(1000), -..type: NoteVisibility.Public, -.}); -.console.log('Waiting for transaction confirmation...'); -.await client.transactions.waitFor(mintTxId, { timeout: 120_000 }); - -.// 5-6. Consume all available notes for Alice. -.console.log('Consuming minted notes...'); -.await consumeAllFeeAware(client, alice); - -.console.log('Notes consumed.'); - -.// 7. Send tokens to Bob -.const bob = await client.accounts.create({ -..storage: StorageMode.Public, -.}); -.console.log("Sending tokens to Bob's account..."); -.await client.sync(); -.const { txId: sendTxId } = await client.transactions.send({ -..account: alice, -..to: bob, -..token: faucet, -..amount: BigInt(100), -..type: NoteVisibility.Public, -..waitForConfirmation: true, -..timeout: 120_000, -.}); -.console.log(\`Transaction committed: \${sendTxId.toHex()}\`); -.const updatedAlice = await client.accounts.get(alice); -.const balance = updatedAlice?.vault().getBalance(faucet.id()); -.if (balance !== BigInt(900)) -..throw new Error(\`Expected Alice to retain 900 MID, got \${balance}\`); -.console.log('Tokens sent successfully!'); +.console.log('Setup complete.'); }` }, }} reactFilename="lib/react/createMintConsume.tsx" tsFilename="lib/createMintConsume.ts" /> ### Running the example +From the parent directory of `miden-web-app`: + ```bash cd miden-web-app yarn install @@ -521,11 +447,11 @@ yarn dev Open [http://localhost:3000](http://localhost:3000) in your browser, click **Tutorial #1: Create a wallet and deploy a faucet**, and check the browser console (F12 or right-click → Inspect → Console): ``` -Latest block: 2247 +Latest block number: Creating account for Alice… -Alice ID: 0xd70b2072c6495d100000869a8bacf2 +Alice ID: Creating faucet… -Faucet ID: 0x2d7e506fb88dde200000a1386efec8 +Faucet ID: Setup complete. ``` diff --git a/docs/src/web-client/creating_multiple_notes_tutorial.md b/docs/src/web-client/creating_multiple_notes_tutorial.md index 98073b7d..a4751a36 100644 --- a/docs/src/web-client/creating_multiple_notes_tutorial.md +++ b/docs/src/web-client/creating_multiple_notes_tutorial.md @@ -22,7 +22,7 @@ In the previous sections we learned how to create accounts, deploy faucets, and - **Mint** test tokens from a faucet to Alice - **Consume** the minted notes so the assets appear in Alice's wallet -- **Create three P2ID notes in a _single_ transaction** using a custom note‑script and delegated proving +- **Create three P2ID notes in a _single_ transaction** using standard P2ID notes and delegated proving The entire flow is wrapped in a helper called `multiSendWithDelegatedProver()` that you can call from any browser page. @@ -42,9 +42,9 @@ The entire flow is wrapped in a helper called `multiSendWithDelegatedProver()` t Before diving into our code example, let's clarify what in the world "delegated proving" actually is. -Delegated proving is the process of outsourcing a part of the ZK proof generation of your transaction to a third party. For certain computationally constrained devices such as mobile phones and web browser environments, generating ZK proofs might take too long to ensure an acceptable user experience. Devices that do not have the computational resources to generate Miden proofs in under 1-2 seconds can use delegated proving to provide a more responsive user experience. +Delegated proving moves transaction proof generation to a remote service. This can reduce the work required on a mobile device or in a browser. The time to submit a transaction still depends on execution, network latency, prover capacity, and node settlement. -_How does it work?_ When a user choses to use delegated proving, they send off a portion of the zk proof of their transaction to a dedicated server. This dedicated server generates the remainder of the ZK proof of the transaction and submits it to the network. Submitting a transaction with delegated proving is trustless, meaning if the delegated prover is malicious, the could not compromise the security of the account that is submitting a transaction to be processed by the delegated prover. The downside of using delegated proving is that it reduces the privacy of the account that uses delegated proving, because the delegated prover would have knowledge of the transaction that is being proven. Additionally, transactions that require sensitive data such as the knowledge of a hash preimage or a secret, should not use delegated proving as this data will be shared with the delegated prover for proof generation. +_How does it work?_ The client sends a transaction witness to the delegated prover, receives the generated proof, and submits the proven transaction to the node. The node verifies the proof. Delegation shares the witness with the prover, including private data needed for execution; use local proving when those inputs must remain on your device. Anyone can run their own delegated prover server. If you are building a product on Miden, it may make sense to run your own delegated prover server for your users. To run your own delegated proving server, follow the instructions here: https://crates.io/crates/miden-proving-service @@ -74,15 +74,17 @@ proving service. This means your browser never has to generate the full ZK proof typescript: { code: `yarn add @miden-sdk/miden-sdk@0.16.0` }, }} reactFilename="" tsFilename="" /> -**NOTE!**: Be sure to add the `--webpack` command to your `package.json` when running the `dev script`. The dev script should look like this: +The current Next.js template uses Turbopack by default. These SDK examples use the webpack configuration from the setup guide, so update both scripts in `package.json`: `package.json` ```json +{ "scripts": { "dev": "next dev --webpack", - ... + "build": "next build --webpack" } +} ``` ## Step 2: Edit the `app/page.tsx` file: @@ -146,27 +148,30 @@ export default function Home() { Create `lib/react/multiSendWithDelegatedProver.tsx` (React) or `lib/multiSendWithDelegatedProver.ts` (TypeScript) and add the following code. This snippet initializes the Miden client. -``` -mkdir -p lib +```bash +mkdir -p lib/react ``` { +..await sync(); +..const authScheme = await tutorialAuthScheme(); ..// We'll add our logic here .}; @@ -192,8 +197,8 @@ export default function MultiSendWithDelegatedProver() { .StorageMode, .createP2IDNote, .NoteArray, -.TransactionRequestBuilder, } from '@miden-sdk/miden-sdk/lazy'; +import { fundAccountForFees, consumeAllFeeAware } from './feeSupport'; export async function multiSendWithDelegatedProver(): Promise { .// Ensure this runs only in a browser context @@ -210,7 +215,7 @@ export async function multiSendWithDelegatedProver(): Promise { ## Step 4 — Create an account, deploy a faucet, mint and consume tokens -Add the code snippet below to the function. This code creates a wallet and faucet, mints tokens from the faucet for the wallet, and then consumes the minted tokens. +Add the code below to the function. The shared helpers imported in Step 3 fund Alice and the faucet with native fee tokens, wait for confirmation and select the tutorial notes before consuming them. The React helpers come from the same `tutorialSupport` file used by the complete example. ## Step 5 — Build and Create P2ID notes @@ -290,7 +299,7 @@ const recipients = await Promise.all( .), ); -await sendMany({ +const sent = await sendMany({ .from: alice, .assetId: faucet, .recipients: recipients.map((account) => ({ @@ -300,6 +309,8 @@ await sendMany({ .noteType: NoteVisibility.Public, }); +await committed(sent.transactionId); +await assertBalance(alice, faucet, BigInt(9700)); console.log('All notes created ✅');`}, typescript: { code:`// ── build 3 P2ID notes (100 MID each) ───────────────────────────────────────────── const recipients = await Promise.all( @@ -321,9 +332,13 @@ const p2idNotes = recipientAddresses.map((addr) => ); // ── create all P2ID notes ─────────────────────────────────────────────────────────────── -const builder = new TransactionRequestBuilder(); -const txRequest = builder.withOwnOutputNotes(new NoteArray(p2idNotes)).build(); -await client.transactions.submit(alice, txRequest); +await client.sync(); +const builder = await client.feeAwareTransactionRequestBuilder(alice); +const outputs = new NoteArray(); +for (const note of p2idNotes) outputs.push(note); +const txRequest = builder.withOwnOutputNotes(outputs).build(); +const { txId } = await client.transactions.submit(alice, txRequest); +await client.transactions.waitFor(txId, { timeout: 120_000 }); console.log('All notes created ✅');` }, }} reactFilename="lib/react/multiSendWithDelegatedProver.tsx" tsFilename="lib/multiSendWithDelegatedProver.ts" /> @@ -545,15 +560,18 @@ yarn dev ### Resetting the `MidenClientDB` -The Miden webclient stores account and note data in the browser. To clear the account and node data in the browser, paste this code snippet into the browser console: +The Miden webclient stores account and note data in IndexedDB. Stop or terminate the tutorial client and close other tabs using its store before resetting it. This deletes local account data and keys, so use it only for disposable tutorial accounts. The following browser-console snippet deletes the default testnet `MidenClientDB_mtst` store after the deletion request completes; change `name` if you configured a different store. ```javascript (async () => { - const dbs = await indexedDB.databases(); // Get all database names - for (const db of dbs) { - await indexedDB.deleteDatabase(db.name); - console.log(`Deleted database: ${db.name}`); - } - console.log('All databases deleted.'); + const name = 'MidenClientDB_mtst'; + await new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase(name); + request.onsuccess = () => resolve(); + request.onerror = () => reject(request.error); + request.onblocked = () => + reject(new Error('Close clients and tabs using this store, then retry.')); + }); + console.log(`Deleted database: ${name}`); })(); ``` diff --git a/docs/src/web-client/foreign_procedure_invocation_tutorial.md b/docs/src/web-client/foreign_procedure_invocation_tutorial.md index 1082de9d..e1bf1014 100644 --- a/docs/src/web-client/foreign_procedure_invocation_tutorial.md +++ b/docs/src/web-client/foreign_procedure_invocation_tutorial.md @@ -67,15 +67,17 @@ This tutorial assumes you have a basic understanding of Miden assembly and compl yarn add @miden-sdk/miden-sdk@0.16.0 ``` -**NOTE!**: Be sure to add the `--webpack` command to your `package.json` when running the `dev script`. The dev script should look like this: +The current Next.js template uses Turbopack by default. These examples use the webpack configuration from the setup guide, so update both scripts in `package.json`: `package.json` ```json +{ "scripts": { "dev": "next dev --webpack", - ... + "build": "next build --webpack" } +} ``` ## Step 2: Edit the `app/page.tsx` file @@ -261,17 +263,11 @@ We need to tell our bundler to treat `.masm` files as plain text strings. In Nex Open `next.config.ts` and add the highlighted rule inside the `webpack` callback: ```ts -webpack: (config, { isServer }) => { - // ... existing WASM config ... - - // Import .masm files as strings - config.module.rules.push({ - test: /\.masm$/, - type: "asset/source", - }); - - return config; -}, +// Import .masm files as strings. Keep the existing WASM configuration. +config.module.rules.push({ + test: /\.masm$/, + type: "asset/source", +}); ``` :::tip Other bundlers @@ -675,6 +671,8 @@ await client.transactions.execute({ account: countReaderAccount, script, foreignAccounts: [counterAccount], + waitForConfirmation: true, + timeout: 120_000, }); ``` @@ -704,16 +702,19 @@ yarn dev ### Resetting the `MidenClientDB` -The Miden webclient stores account and note data in the browser. If you get errors such as "Failed to build MMR", then you should reset the Miden webclient store. When switching between Miden networks such as from localhost to testnet be sure to reset the browser store. To clear the account and node data in the browser, paste this code snippet into the browser console: +The Miden webclient stores account and note data in IndexedDB. Stop or terminate the tutorial client and close other tabs using its store before resetting it. This deletes local account data and keys, so use it only for disposable tutorial accounts. The following browser-console snippet deletes the default testnet `MidenClientDB_mtst` store after the deletion request completes; change `name` if you configured a different store. ```javascript (async () => { - const dbs = await indexedDB.databases(); - for (const db of dbs) { - await indexedDB.deleteDatabase(db.name); - console.log(`Deleted database: ${db.name}`); - } - console.log('All databases deleted.'); + const name = 'MidenClientDB_mtst'; + await new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase(name); + request.onsuccess = () => resolve(); + request.onerror = () => reject(request.error); + request.onblocked = () => + reject(new Error('Close clients and tabs using this store, then retry.')); + }); + console.log(`Deleted database: ${name}`); })(); ``` diff --git a/docs/src/web-client/mint_consume_create_tutorial.md b/docs/src/web-client/mint_consume_create_tutorial.md index c3d19bbc..0d048e3b 100644 --- a/docs/src/web-client/mint_consume_create_tutorial.md +++ b/docs/src/web-client/mint_consume_create_tutorial.md @@ -45,21 +45,21 @@ Before we start coding, it's important to understand **notes**: Let's mint some tokens for Alice. When we mint from a faucet, it creates a note containing the specified amount of tokens targeted to Alice's account. -Add this to the end of your `createMintConsume` function: +Add the operations below after funding Alice and the faucet in `createMintConsume`. Import `NoteVisibility` and the shared support functions shown in the complete example. For React, also initialize `useMint`, `useConsume` and `useSend`, and obtain `committed`, `waitForTokenNotes` and `assertBalance` from `useTutorialSupport`. @@ -115,13 +115,15 @@ react: { code: `// 7. Create Bob and send him 100 tokens const bob = await createWallet({ storageMode: StorageMode.Public, authScheme }); const bobAddress = bob.id().toString(); console.log("Sending tokens to Bob's account..."); -await send({ +const sent = await send({ .from: alice, .to: bobAddress, .assetId: faucet, .amount: BigInt(100), .noteType: NoteVisibility.Public, }); +await committed(sent.txId); +await assertBalance(alice, faucet, BigInt(900)); console.log('Tokens sent successfully!');` }, typescript: { code: `// 7. Create Bob and send him tokens const bob = await client.accounts.create({ @@ -136,6 +138,8 @@ await client.transactions.send({ .token: faucet, // Asset ID (faucet that created the tokens) .amount: BigInt(100), // Amount to send .type: NoteVisibility.Public, // Note visibility +.waitForConfirmation: true, +.timeout: 120_000, }); console.log('Tokens sent successfully!');` }, @@ -372,16 +376,19 @@ Tokens sent successfully! ### Resetting the `MidenClientDB` -The Miden webclient stores account and note data in the browser. To clear the account and note data in the browser, paste this code snippet into the browser console: +The Miden webclient stores account and note data in IndexedDB. Stop or terminate the tutorial client and close other tabs using its store before resetting it. This deletes local account data and keys, so use it only for disposable tutorial accounts. The following browser-console snippet deletes the default testnet `MidenClientDB_mtst` store after the deletion request completes; change `name` if you configured a different store. ```javascript (async () => { - const dbs = await indexedDB.databases(); // Get all database names - for (const db of dbs) { - await indexedDB.deleteDatabase(db.name); - console.log(`Deleted database: ${db.name}`); - } - console.log('All databases deleted.'); + const name = 'MidenClientDB_mtst'; + await new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase(name); + request.onsuccess = () => resolve(); + request.onerror = () => reject(request.error); + request.onblocked = () => + reject(new Error('Close clients and tabs using this store, then retry.')); + }); + console.log(`Deleted database: ${name}`); })(); ``` diff --git a/docs/src/web-client/react_wallet_tutorial.md b/docs/src/web-client/react_wallet_tutorial.md index 636c0e73..f288edfa 100644 --- a/docs/src/web-client/react_wallet_tutorial.md +++ b/docs/src/web-client/react_wallet_tutorial.md @@ -64,13 +64,36 @@ First, create a new Vite + React project and install the Miden React SDK. yarn add @miden-sdk/miden-sdk@0.16.0 @miden-sdk/react@0.16.0 ``` -3. Configure the `MidenProvider` in your `main.tsx` file. The provider initializes the Miden client and makes it available to all child components: +3. Install the Vite integration and update `vite.config.ts`. The Miden plugin v0.16 supports Vite 5 and 6, so pin Vite 6 and its compatible React plugin even if the generator installed newer versions: + + ```bash + yarn add -D vite@^6 @vitejs/plugin-react@^4 @miden-sdk/vite-plugin@0.16.0 vite-plugin-wasm vite-plugin-top-level-await + ``` + + ```ts + import { defineConfig } from 'vite'; + import react from '@vitejs/plugin-react'; + import { midenVitePlugin } from '@miden-sdk/vite-plugin'; + import wasm from 'vite-plugin-wasm'; + import topLevelAwait from 'vite-plugin-top-level-await'; + + export default defineConfig({ + plugins: [react(), midenVitePlugin({ crossOriginIsolation: false }), wasm(), topLevelAwait()], + worker: { format: 'es', plugins: () => [wasm(), topLevelAwait()] }, + }); + ``` + + This Vite tutorial uses the main SDK entries throughout. Para and Turnkey import + `SignerContext` from `@miden-sdk/react`; mixing it with `/lazy` creates separate + contexts in v0.16. Keep providers and hooks on the same entry. + +4. Configure the `MidenProvider` in your `main.tsx` file. The provider initializes the Miden client and makes it available to all child components: ```tsx // main.tsx import React from 'react'; import ReactDOM from 'react-dom/client'; -import { MidenProvider } from '@miden-sdk/react/lazy'; +import { MidenProvider } from '@miden-sdk/react'; import App from './App'; ReactDOM.createRoot(document.getElementById('root')!).render( @@ -100,7 +123,7 @@ The `useMiden()` hook provides access to the client's initialization state. Use ```tsx // App.tsx -import { useMiden } from '@miden-sdk/react/lazy'; +import { useMiden } from '@miden-sdk/react'; export default function App() { const { isReady, error } = useMiden(); @@ -124,7 +147,7 @@ The `useMiden()` hook returns: The `useAccounts()` hook provides access to all accounts stored in the client. Use it to check if the user has any existing wallets. ```tsx -import { useMiden, useAccounts } from '@miden-sdk/react/lazy'; +import { useMiden, useAccounts } from '@miden-sdk/react'; export default function App() { const { isReady, error } = useMiden(); @@ -156,8 +179,8 @@ The `useAccounts()` hook returns: The `useCreateWallet()` hook provides a function to create new wallet accounts. ```tsx -import { useMiden, useAccounts, useCreateWallet } from '@miden-sdk/react/lazy'; -import { getWasmOrThrow } from '@miden-sdk/miden-sdk/lazy'; +import { useMiden, useAccounts, useCreateWallet } from '@miden-sdk/react'; +import { getWasmOrThrow } from '@miden-sdk/miden-sdk'; export default function App() { const { isReady, error } = useMiden(); @@ -209,7 +232,7 @@ The `useCreateWallet()` hook returns: The `useAccount(accountId)` hook provides detailed information about a specific account, including its assets and balances. ```tsx -import { useAccount, formatAssetAmount } from '@miden-sdk/react/lazy'; +import { useAccount, formatAssetAmount } from '@miden-sdk/react'; function Wallet({ accountId }: { accountId: string }) { const { account, assets } = useAccount(accountId); @@ -258,7 +281,7 @@ The `formatAssetAmount(amount, decimals)` utility formats a raw amount with the The `useNotes({ accountId })` hook provides access to notes that can be consumed by the account. ```tsx -import { useNotes, formatNoteSummary } from '@miden-sdk/react/lazy'; +import { useNotes, formatNoteSummary } from '@miden-sdk/react'; function UnclaimedNotes({ accountId }: { accountId: string }) { const { consumableNoteSummaries } = useNotes({ accountId }); @@ -294,14 +317,14 @@ The `formatNoteSummary(summary)` utility formats a note summary for display. The `useConsume()` hook provides a function to consume (claim) notes and add their assets to the account. ```tsx -import { useConsume, formatNoteSummary } from '@miden-sdk/react/lazy'; +import { useConsume, formatNoteSummary, type NoteSummary } from '@miden-sdk/react'; function UnclaimedNotes({ accountId, consumableNoteSummaries, }: { accountId: string; - consumableNoteSummaries: Array<{ id: string }>; + consumableNoteSummaries: NoteSummary[]; }) { const { consume, isLoading: isConsuming } = useConsume(); @@ -340,12 +363,12 @@ The `useConsume()` hook returns: ## Step 8: Sending Tokens with useSend -The `useSend()` hook provides a function to send tokens to other accounts. +The `useSend()` hook provides a function to send tokens to other accounts. Select the first asset when balances arrive asynchronously, as shown below, so a newly funded wallet can use the form. ```tsx -import { useState, type ChangeEvent } from 'react'; -import { useSend, parseAssetAmount } from '@miden-sdk/react/lazy'; -import { NoteVisibility } from '@miden-sdk/miden-sdk/lazy'; +import { useEffect, useState, type ChangeEvent } from 'react'; +import { useSend, parseAssetAmount } from '@miden-sdk/react'; +import { NoteVisibility } from '@miden-sdk/miden-sdk'; function SendForm({ accountId, @@ -356,7 +379,12 @@ function SendForm({ }) { const { send, isLoading: isSending } = useSend(); const [to, setTo] = useState(''); - const [assetId, setAssetId] = useState(assets[0]?.assetId ?? ''); + const [assetId, setAssetId] = useState(''); + const defaultAssetId = assets[0]?.assetId; + + useEffect(() => { + if (!assetId && defaultAssetId) setAssetId(defaultAssetId); + }, [assetId, defaultAssetId]); const [amount, setAmount] = useState(''); const [noteType, setNoteType] = useState( NoteVisibility.Private, @@ -451,7 +479,7 @@ Here is the complete wallet application combining all the features we've covered ```tsx import React from 'react'; import ReactDOM from 'react-dom/client'; -import { MidenProvider } from '@miden-sdk/react/lazy'; +import { MidenProvider } from '@miden-sdk/react'; import App from './App'; ReactDOM.createRoot(document.getElementById('root')!).render( @@ -476,7 +504,7 @@ import { formatAssetAmount, formatNoteSummary, parseAssetAmount, -} from '@miden-sdk/react/lazy'; +} from '@miden-sdk/react'; import { useMiden, useAccounts, @@ -485,8 +513,8 @@ import { useCreateWallet, useConsume, useSend, -} from '@miden-sdk/react/lazy'; -import { NoteVisibility, getWasmOrThrow } from '@miden-sdk/miden-sdk/lazy'; +} from '@miden-sdk/react'; +import { NoteVisibility, getWasmOrThrow } from '@miden-sdk/miden-sdk'; const Panel = ({ title, children }: { title: string; children: ReactNode }) => (
@@ -677,7 +705,7 @@ own accounts; the wallet UI above starts with an empty wallet that needs funding The Miden client stores account and note data in the browser's IndexedDB. Upgrading from v0.15 automatically recreates the Miden store; export private notes and any other local data you need before upgrading. To manually reset only -Miden databases on the current origin, close other tabs using the client and run: +Miden databases on the current origin, stop the current client, close other tabs using it, and run: ```javascript (async () => { @@ -706,7 +734,7 @@ By default, the Miden React SDK manages keys internally using the browser's Inde The `useSigner()` hook from `@miden-sdk/react` provides a unified interface for interacting with any signer provider. When you wrap your app with a signer provider (Para, Turnkey, MidenFi, etc.), the hook returns the signer context with connection state and methods. ```tsx -import { useSigner } from '@miden-sdk/react/lazy'; +import { useSigner } from '@miden-sdk/react'; function ConnectButton() { const signer = useSigner(); @@ -735,30 +763,68 @@ This unified interface means your wallet UI code works the same regardless of wh --- +### External signer sessions in v0.16 + +The Para and Turnkey examples below import an **existing public testnet account** +controlled by the selected signer. Pass its ID as `existingAccountId`. This uses +`importAccountId` to avoid the new-account authentication-enum mismatch in React +SDK v0.16.0. An API key or organization ID alone does not create that account. + +Use this shared wrapper in `SignerSession.tsx`. It mounts `MidenProvider` after +connection and unmounts it on disconnect, so reconnecting creates a fresh client +instead of calling v0.16.0's unavailable `setSignCb` method. Replace the original +provider wrapper in `main.tsx` with the selected signer example; do not nest two +`MidenProvider` instances. + +```tsx +import type { ReactNode } from 'react'; +import { MidenProvider, useSigner } from '@miden-sdk/react'; + +export function SignerSession({ children }: { children: ReactNode }) { + const signer = useSigner(); + if (!signer?.isConnected) { + return ; + } + return ( + + {children} + + ); +} +``` + ### Para: EVM Wallet Integration -[Para](https://para.space/) provides a modal-based authentication flow that allows users to sign in with their EVM wallets (MetaMask, WalletConnect, etc.). +[Para](https://docs.getpara.com/v2/introduction/welcome) provides a modal-based authentication flow that allows users to sign in with their EVM wallets (MetaMask, WalletConnect, etc.). -:::note Compatible Para release required +Use `@miden-sdk/para-react@0.16.0` with the 0.16 SDK packages. +Provide a Para API key for the selected environment. -`@miden-sdk/use-miden-para-react@0.15.1` requires v0.15 SDK packages. -The pattern below needs an adapter release with v0.16-compatible peer dependencies; -check the [package metadata](https://registry.npmjs.org/@miden-sdk/use-miden-para-react) before installing. +Install the adapter and its peer dependencies: -::: +```bash +yarn add @miden-sdk/para-react@0.16.0 @miden-sdk/para@0.16.0 @getpara/react-sdk-lite@^2.11.0 @getpara/web-sdk@^2.11.0 @tanstack/react-query@^5 +yarn add -D vite-plugin-node-polyfills@^0.22.0 +``` + +In `vite.config.ts`, import `paraVitePlugin` from `@miden-sdk/para-react/vite` +and add `paraVitePlugin()` to the existing `plugins` array. It supplies the +browser polyfills required by Para. Import `@getpara/react-sdk-lite/styles.css` +once in `src/main.tsx` for the connection modal. -**Integration pattern (requires a compatible adapter):** +**Integration:** ```tsx -import { ParaSignerProvider } from '@miden-sdk/use-miden-para-react'; -import { MidenProvider, useSigner } from '@miden-sdk/react/lazy'; +import { ParaSignerProvider } from '@miden-sdk/para-react'; +import { useSigner } from '@miden-sdk/react'; +import { SignerSession } from './SignerSession'; -function App() { +function App({ existingAccountId }: { existingAccountId: string }) { return ( - - + + - + ); } @@ -785,7 +851,7 @@ function Wallet() { | `apiKey` | `string` | Your Para API key | | `environment` | `"PRODUCTION" \| "DEVELOPMENT" \| "SANDBOX"` | Para environment | | `showSigningModal` | `boolean` | Whether to show signing confirmation modal | -| `customSignConfirmStep` | `ReactNode` | Custom signing confirmation UI | +| `customSignConfirmStep` | `CustomSignConfirmStep` | Custom signing confirmation UI | --- @@ -793,26 +859,28 @@ function Wallet() { [Turnkey](https://turnkey.com/) provides programmatic key management, giving your application full control over the authentication flow. -:::note Compatible Turnkey release required +Use `@miden-sdk/turnkey-react@0.16.0` with the 0.16 SDK packages. +Create a Turnkey organization and pass its ID in `config`. -`@miden-sdk/miden-turnkey-react@1.15.1` requires v0.15 SDK packages. -The pattern below needs an adapter release with v0.16-compatible peer dependencies; -check the [package metadata](https://registry.npmjs.org/@miden-sdk/miden-turnkey-react) before installing. +Install the adapter and its peer dependencies: -::: +```bash +yarn add @miden-sdk/turnkey-react@0.16.0 @miden-sdk/turnkey@0.16.0 @turnkey/core@^1.8.2 @turnkey/react-wallet-kit@^1.6.2 @turnkey/sdk-browser@^5.13.4 +``` -**Integration pattern (requires a compatible adapter):** +**Integration:** ```tsx -import { TurnkeySignerProvider } from '@miden-sdk/miden-turnkey-react'; -import { MidenProvider, useSigner } from '@miden-sdk/react/lazy'; +import { TurnkeySignerProvider } from '@miden-sdk/turnkey-react'; +import { useSigner } from '@miden-sdk/react'; +import { SignerSession } from './SignerSession'; -function App() { +function App({ existingAccountId }: { existingAccountId: string }) { return ( - - + + - + ); } @@ -832,13 +900,13 @@ function Wallet() { } ``` -Calling `connect()` handles the full Turnkey authentication flow: passkey login, wallet discovery, and account selection. No manual setup is needed. +After configuring the organization, `connect()` starts the Turnkey authentication flow: passkey login, wallet discovery, and account selection. **TurnkeySignerProvider Props:** -| Prop | Type | Description | -| -------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | -| `config` | `Partial` | Optional. Defaults to `apiBaseUrl: "https://api.turnkey.com"` and `defaultOrganizationId` from `VITE_TURNKEY_ORG_ID` env var. | +| Prop | Type | Description | +| -------- | -------------------------------------- | ------------------------------------------------------------------------------------------ | +| `config` | `TurnkeySignerProviderProps["config"]` | Required. Set `defaultOrganizationId`; `apiBaseUrl` defaults to `https://api.turnkey.com`. | The `useTurnkeySigner()` hook is available for advanced use cases where you need direct access to the Turnkey `client`, the selected `account`, or the `setAccount()` method to manually control account selection. @@ -846,7 +914,7 @@ The `useTurnkeySigner()` hook is available for advanced use cases where you need ### MidenFi: Wallet Adapter -[MidenFi](https://miden.fi/) provides a wallet adapter pattern similar to Solana's wallet-adapter, enabling integration with the MidenFi ecosystem. +[MidenFi](https://github.com/0xMiden/wallet) provides a wallet adapter pattern similar to Solana's wallet-adapter, enabling integration with the MidenFi ecosystem. **Installation:** @@ -859,14 +927,15 @@ yarn add @miden-sdk/miden-wallet-adapter-react@0.16.0 @miden-sdk/miden-wallet-ad ```tsx import { MidenFiSignerProvider } from '@miden-sdk/miden-wallet-adapter-react'; import { WalletAdapterNetwork } from '@miden-sdk/miden-wallet-adapter-base'; -import { MidenProvider, useSigner } from '@miden-sdk/react/lazy'; +import { useSigner } from '@miden-sdk/react'; +import { SignerSession } from './SignerSession'; function App() { return ( - + - + ); } @@ -903,59 +972,93 @@ network strings, booleans, or string arrays in place of these enum values. If you need to integrate with a different signing service, you can build your own signer provider by implementing the `SignerContextValue` interface and providing it via `SignerContext.Provider`. +Pass your service initializer as `initializeSigningService`. It must return the ID +of an existing public account on testnet, its serialized public key commitment, +and a callback that signs the SDK's serialized signing inputs. The callback must +verify the requested public key before signing. Account creation and deployment +belong to the signing service in this example: `importAccountId` imports that +account instead of rebuilding it with a new seed. This also avoids the new-account +auth-enum mismatch in the published React SDK v0.16.0. + +Keep a non-null context while disconnected so `useSigner()` can expose `connect` +and `MidenProvider` waits for the signer. In v0.16, `accountConfig` is only read +when connected, although its TypeScript type is non-nullable; the assertion below +reflects that runtime guard. Import WASM classes from the core SDK and await +`MidenClient.ready()` before constructing them. + +The keyed fragment remounts the child `MidenProvider` after each connection. +This avoids v0.16.0's reconnect path, which calls an unavailable `setSignCb` +method. The account-specific store name stays the same, preserving local data. + ```tsx -import { useState, useCallback, type ReactNode } from 'react'; +import { Fragment, useState, useRef, useCallback, useMemo, type ReactNode } from 'react'; import { SignerContext, type SignerContextValue, - AccountStorageMode, -} from '@miden-sdk/react/lazy'; + type SignerAccountConfig, + type SignCallback, +} from '@miden-sdk/react'; +import { AccountStorageMode, MidenClient } from '@miden-sdk/miden-sdk'; + +interface SigningService { + // An existing public account on the network configured in MidenProvider. + accountId: string; + publicKeyCommitment: Uint8Array; + signMessage: SignCallback; + disconnect?: () => Promise; +} interface CustomSignerProviderProps { children: ReactNode; - // Your provider-specific config + initializeSigningService: () => Promise; } -export function CustomSignerProvider({ children }: CustomSignerProviderProps) { - const [isConnected, setIsConnected] = useState(false); - const [signerContext, setSignerContext] = useState( - null, - ); +export function CustomSignerProvider({ + children, + initializeSigningService, +}: CustomSignerProviderProps) { + const service = useRef(null); + const [accountConfig, setAccountConfig] = useState(null); + const [connection, setConnection] = useState(0); const connect = useCallback(async () => { - // 1. Initialize your signing service and get credentials - const { publicKeyCommitment, signMessage } = - await initializeYourSigningService(); - - // 2. Build the signer context - const context: SignerContextValue = { - signCb: async (pubKey, signingInputs) => { - // Sign the message using your service - return signMessage(signingInputs); - }, - accountConfig: { - publicKeyCommitment, - storageMode: AccountStorageMode.public(), - }, - storeName: 'custom_signer', - name: 'CustomSigner', - isConnected: true, - connect, - disconnect, - }; - - setSignerContext(context); - setIsConnected(true); - }, []); + await MidenClient.ready(); + const connected = await initializeSigningService(); + service.current = connected; + setAccountConfig({ + publicKeyCommitment: connected.publicKeyCommitment, + storageMode: AccountStorageMode.public(), + importAccountId: connected.accountId, + }); + setConnection((previous) => previous + 1); + }, [initializeSigningService]); const disconnect = useCallback(async () => { - setSignerContext(null); - setIsConnected(false); + const connected = service.current; + service.current = null; + setAccountConfig(null); + await connected?.disconnect?.(); + }, []); + + const signCb = useCallback(async (pubKey, signingInputs) => { + if (!service.current) throw new Error('CustomSigner is not connected'); + return service.current.signMessage(pubKey, signingInputs); }, []); + const signerContext = useMemo(() => ({ + signCb, + // v0.16 only reads this field when isConnected is true. + accountConfig: accountConfig!, + storeName: accountConfig ? `custom_${accountConfig.importAccountId}` : 'custom', + name: 'CustomSigner', + isConnected: accountConfig !== null, + connect, + disconnect, + }), [accountConfig, signCb, connect, disconnect]); + return ( - {children} + {children} ); } @@ -981,4 +1084,4 @@ Now that you've built a React wallet, explore these related topics: - [Creating Multiple Notes in a Single Transaction](./creating_multiple_notes_tutorial.md) - Learn about batch operations - [Miden React SDK Reference](https://github.com/0xMiden/web-sdk/tree/v0.16.0/packages/react-sdk) - Full API documentation -- [Miden Documentation](https://docs.miden.io/) - Core Miden concepts +- [Miden Documentation](https://docs.miden.xyz/) - Core Miden concepts diff --git a/docs/src/web-client/setup_guide.md b/docs/src/web-client/setup_guide.md index 25e93f09..8823683a 100644 --- a/docs/src/web-client/setup_guide.md +++ b/docs/src/web-client/setup_guide.md @@ -9,7 +9,7 @@ This guide covers the configuration required to use the Miden web SDK (`@miden-s ## Prerequisites -- Node.js 20+ (Node 22+ requires an extra `localStorage` polyfill — see below) +- Node.js 20.9+ for the current Next.js template; see the `localStorage` compatibility workaround below if needed - Next.js 14+ with App Router - yarn or npm @@ -29,7 +29,7 @@ These tutorials use Next.js, so all code examples import from the SDK's `/lazy` ## Next.js Configuration -Create or update `next.config.ts` with these required settings: +Create or update `next.config.ts` with these required settings. With Next.js 16 or newer, use `next dev --webpack` and `next build --webpack` so this webpack callback runs. The repository’s Next.js 15 app uses webpack by default. ```ts import type { NextConfig } from 'next'; @@ -171,13 +171,13 @@ repository runner. `NEXT_PUBLIC_MIDEN_NETWORK` selects the network when running ## Node.js 22+ `localStorage` polyfill -If you run `next dev` under Node.js 22 or later, every page request will crash with: +Some Node.js and Next.js combinations fail in the development overlay with: ``` TypeError: localStorage.getItem is not a function ``` -This is a Node + Next.js interaction, not a Miden SDK issue. Node 22+ defines `globalThis.localStorage` as an object, but its methods (`getItem`, `setItem`, …) are undefined unless Node is launched with `--localstorage-file`. Next.js's dev overlay guards with `typeof localStorage !== 'undefined'`, which passes on Node 22+, and then calls the missing methods. +The workaround below handles a server-side `localStorage` object that lacks the methods the development overlay expects. Apply it if you encounter this error; it is not a requirement for every Node.js 22+ installation. Add this polyfill at the top of `next.config.ts`, before the config object: @@ -204,22 +204,23 @@ Add this polyfill at the top of `next.config.ts`, before the config object: } ``` -This only affects `next dev` (SSR); static exports via `next build` are unaffected. The polyfill is harmless on Node ≤21 — it installs an in-memory stub that the dev overlay uses just like Node 22+'s (broken) built-in. +This fallback supplies in-memory storage to server-side tooling. It does not persist application data and does not replace the browser's storage. ## SDK API Patterns ### Transaction return types -All transaction methods return an object, not a plain transaction ID: +Transaction calls return an object containing the ID and result. In these fragments, `mintOptions` and `sendOptions` are the parameter objects built with your funded accounts and token, as shown in the mint-and-transfer tutorial: ```ts // mint and consume return { txId, result } -const { txId } = await client.transactions.mint({ ... }); +const { txId: mintTxId, result: mintResult } = + await client.transactions.mint(mintOptions); // send returns { txId, note, result } // note is non-null when returnNote: true -const { txId, note } = await client.transactions.send({ - ..., +const { txId: sendTxId, note } = await client.transactions.send({ + ...sendOptions, returnNote: true, }); ``` @@ -231,12 +232,12 @@ You can wait for a transaction to be committed in two ways: ```ts // Option 1: Pass waitForConfirmation in the transaction call await client.transactions.mint({ - ..., + ...mintOptions, waitForConfirmation: true, }); // Option 2: Wait separately using waitFor -const { txId } = await client.transactions.mint({ ... }); +const { txId } = await client.transactions.mint(mintOptions); await client.transactions.waitFor(txId); // accepts TransactionId object or hex string ``` @@ -245,7 +246,7 @@ await client.transactions.waitFor(txId); // accepts TransactionId object or hex When displaying transaction IDs in explorer links, call `.toHex()`: ```ts -const { txId } = await client.transactions.mint({ ... }); +const { txId } = await client.transactions.mint(mintOptions); console.log(`https://testnet.midenscan.com/tx/${txId.toHex()}`); ``` diff --git a/docs/src/web-client/unauthenticated_note_how_to.md b/docs/src/web-client/unauthenticated_note_how_to.md index a9167eb5..82009467 100644 --- a/docs/src/web-client/unauthenticated_note_how_to.md +++ b/docs/src/web-client/unauthenticated_note_how_to.md @@ -18,13 +18,13 @@ as shown in the complete example. ## Overview -In this tutorial, we will explore how to leverage unauthenticated notes on Miden to settle transactions faster than the blocktime using the Miden client. Unauthenticated notes are essentially UTXOs that have not yet been fully committed into a block. This feature allows the notes to be created and consumed within the same batch during [batch production](https://0xmiden.github.io/miden-docs/imported/miden-base/src/blockchain.html#batch-production). +This tutorial passes newly created P2ID notes directly to the next consumer. An unauthenticated input contains the full note without an inclusion proof. The transaction kernel delegates verification of the note's existence to the protocol kernels, allowing the consumer transaction to execute before the producer transaction is confirmed. Final settlement still requires verification by the network. -When using unauthenticated notes, both the creation and consumption of notes can happen within the same batch, enabling faster-than-blocktime settlement. This is particularly powerful for applications requiring high-frequency transactions or optimistic settlement patterns. +The Web and React SDKs choose the input mode from the executing client's store: they use an authenticated input when an inclusion proof is available and an unauthenticated input otherwise. Passing a full `Note` supports unauthenticated consumption but does not force that mode; synchronization can make an inclusion proof available. -We construct a chain of transactions using the unauthenticated notes method on the transaction builder. Unauthenticated notes are also referred to as "erasable notes". We also demonstrate how a note can be created and consumed, highlighting the ability to transfer notes between client instances for asset transfers that can be settled between parties faster than the blocktime. +The example uses one client to manage Alice and five recipient wallets. At each hop, it submits the consumer transaction before waiting for the sender's confirmation, then waits for both transactions before advancing to the next wallet. It verifies the resulting balances; it does not measure transaction latency or guarantee that both transactions settle in the same batch. -For example, our demo creates a chain of unauthenticated note transactions: +The asset follows this chain: ```markdown Alice ➡ Wallet 1 ➡ Wallet 2 ➡ Wallet 3 ➡ Wallet 4 ➡ Wallet 5 @@ -35,11 +35,11 @@ Alice ➡ Wallet 1 ➡ Wallet 2 ➡ Wallet 3 ➡ Wallet 4 ➡ Wallet 5 - **Introduction to Unauthenticated Notes:** Understand what unauthenticated notes are and how they differ from standard notes. - **Miden Client Setup:** Configure the Miden client for browser-based transactions. - **P2ID Note Creation:** Learn how to create Pay-to-ID notes for targeted transfers. -- **Performance Insights:** Observe how unauthenticated notes can reduce transaction times dramatically. +- **Confirmation Boundaries:** Distinguish optimistic execution from confirmed settlement. ## Prerequisites -- Node `v20` or greater +- Node `v20.9.0` or greater (required by the current Next.js template) - Familiarity with TypeScript - `yarn` @@ -64,8 +64,8 @@ This tutorial assumes you have a basic understanding of Miden assembly. To quick 5. **Unauthenticated Note Transfer Chain:** - Create P2ID (Pay-to-ID) notes for each transfer in the chain. - - Use unauthenticated input notes to consume notes faster than blocktime. - - Measure and observe the performance benefits. + - Pass each full output note directly to the next consumer. + - Wait for both transactions to be confirmed and verify the balances. ## Step 1: Initialize your Next.js project @@ -90,15 +90,17 @@ This tutorial assumes you have a basic understanding of Miden assembly. To quick typescript: { code: `yarn add @miden-sdk/miden-sdk@0.16.0` }, }} reactFilename="" tsFilename="" /> -**NOTE!**: Be sure to add the `--webpack` command to your `package.json` when running the `dev script`. The dev script should look like this: +The current Next.js template uses Turbopack by default. Use the webpack configuration from the setup guide and update both scripts in `package.json`: `package.json` ```json +{ "scripts": { "dev": "next dev --webpack", - ... + "build": "next build --webpack" } +} ``` ## Step 2: Edit the `app/page.tsx` file @@ -163,7 +165,7 @@ export default function Home() { Create the library file and add the following code: ```bash -mkdir -p lib +mkdir -p lib/react ``` Copy and paste the following code into `lib/react/unauthenticatedNoteTransfer.tsx` (React) or `lib/unauthenticatedNoteTransfer.ts` (TypeScript): @@ -408,7 +410,7 @@ export async function unauthenticatedNoteTransfer(): Promise { Unauthenticated notes are a powerful feature that allows notes to be: - **Created and consumed in the same block** -- **Transferred faster than blocktime** +- **Passed to a consuming transaction before block confirmation** - **Used for optimistic transactions** ### Performance Benefits @@ -416,8 +418,8 @@ Unauthenticated notes are a powerful feature that allows notes to be: By using unauthenticated notes, we can: - Skip waiting for block confirmation between note creation and consumption -- Create transaction chains that execute within a single block -- Achieve sub-blocktime settlement for certain use cases +- Submit dependent transaction chains that may be included in a single block +- Begin dependent execution earlier; final settlement still requires network confirmation ### Use Cases @@ -426,7 +428,7 @@ Unauthenticated notes are ideal for: - **High-frequency trading applications** - **Payment channels** - **Micropayment systems** -- **Any scenario requiring fast settlement** +- **Applications that benefit from optimistic execution before confirmation** ## Running the Example @@ -471,27 +473,30 @@ Asset transfer chain completed ✅ ## Conclusion -Unauthenticated notes on Miden offer a powerful mechanism for achieving faster asset settlements by allowing notes to be both created and consumed within the same block. In this guide, we walked through: +Unauthenticated notes let applications submit dependent transactions without first waiting for the producer's confirmation. Creation and consumption may be included in the same block; this does not provide settlement before block production. In this guide, we walked through: - **Setting up the Miden client** against testnet - **Creating P2ID Notes** for targeted asset transfers between specific accounts -- **Building Transaction Chains** using unauthenticated input notes for sub-blocktime settlement -- **Performance Observations** demonstrating how unauthenticated notes enable faster-than-blocktime transfers +- **Building Transaction Chains** that submit consumption before waiting for the producer's confirmation +- **Confirmation and balance checks** for the complete transfer chain By following this guide, you should now have a clear understanding of how to build and deploy high-performance transactions using unauthenticated notes on Miden with the Miden client. Unauthenticated notes are the ideal approach for applications like central limit order books (CLOBs) or other DeFi platforms where transaction speed is critical. ### Resetting the `MidenClientDB` -The Miden webclient stores account and note data in the browser. If you get errors such as "Failed to build MMR", then you should reset the Miden webclient store. When switching between Miden networks such as from localhost to testnet be sure to reset the browser store. To clear the account and node data in the browser, paste this code snippet into the browser console: +Stop or terminate the tutorial client and close other tabs using its store before resetting it. This deletes local account data and keys, so use it only for disposable tutorial accounts. The snippet below waits for deletion of the default testnet store; change `name` if you configured a different store. ```javascript (async () => { - const dbs = await indexedDB.databases(); - for (const db of dbs) { - await indexedDB.deleteDatabase(db.name); - console.log(`Deleted database: ${db.name}`); - } - console.log('All databases deleted.'); + const name = 'MidenClientDB_mtst'; + await new Promise((resolve, reject) => { + const request = indexedDB.deleteDatabase(name); + request.onsuccess = () => resolve(); + request.onerror = () => reject(request.error); + request.onblocked = () => + reject(new Error('Close clients and tabs using this store, then retry.')); + }); + console.log(`Deleted database: ${name}`); })(); ``` diff --git a/examples/miden-bank/Cargo.lock b/examples/miden-bank/Cargo.lock index 7c61b49c..7e5da56e 100644 --- a/examples/miden-bank/Cargo.lock +++ b/examples/miden-bank/Cargo.lock @@ -2,39 +2,13 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "Inflector" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -dependencies = [ - "lazy_static", - "regex", -] - [[package]] name = "addr2line" version = "0.25.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b" dependencies = [ - "gimli 0.32.3", -] - -[[package]] -name = "addr2line" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59317f77929f0e679d39364702289274de2f0f0b22cbf50b2b8cff2169a0b27a" -dependencies = [ - "cpp_demangle", - "fallible-iterator", - "gimli 0.33.0", - "memmap2", - "object 0.39.1", - "rustc-demangle", - "smallvec", - "typed-arena", + "gimli", ] [[package]] @@ -45,40 +19,28 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "aead" -version = "0.5.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +checksum = "1973cfbc1a2daf9cf550e74e1f088c28e7f7d8c1e1418fb6c9dc5184b7e84c99" dependencies = [ - "crypto-common", - "generic-array", + "crypto-common 0.2.2", + "inout", ] [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[package]] -name = "allocator-api2" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c880a97d28a3681c0267bd29cff89621202715b065127cd445fa0f0fe0aa2880" - [[package]] name = "alloy-primitives" -version = "1.5.7" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3b431b4e72cd8bd0ec7a50b4be18e73dab74de0dba180eef171055e5d5926e" +checksum = "ce7b00f0cb42c66ec353076ded1dff1fbf818f6e0e26c40c8a8456c04483fca4" dependencies = [ "bytes", "cfg-if", @@ -87,47 +49,56 @@ dependencies = [ "itoa", "paste", "ruint", - "rustc-hash", - "sha3", + "sha3 0.11.0", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24671b1f62edcf0f9b62994c7bf72cd621a04a4b99f5020ece1a647b40e2f103" +dependencies = [ + "arrayvec", + "bytes", ] [[package]] name = "alloy-sol-macro" -version = "1.5.7" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab81bab693da9bb79f7a95b64b394718259fdd7e41dceeced4cad57cb71c4f6a" +checksum = "c64558980fb038cd34b4285ec2b36a2a8bd8d4ddd13b3f6e42d97cb5ee29938e" dependencies = [ "alloy-sol-macro-expander", "alloy-sol-macro-input", - "proc-macro-error2", + "proc-macro-error3", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "alloy-sol-macro-expander" -version = "1.5.7" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489f1620bb7e2483fb5819ed01ab6edc1d2f93939dce35a5695085a1afd1d699" +checksum = "1ffb0e793abdbaea9d01259493c8272c3af295d03389e70a2acdf53b57ad1edf" dependencies = [ "alloy-sol-macro-input", "const-hex", "heck", - "indexmap", - "proc-macro-error2", + "indexmap 2.14.2", + "proc-macro-error3", "proc-macro2", "quote", - "sha3", - "syn 2.0.117", + "sha3 0.11.0", + "syn 2.0.119", "syn-solidity", ] [[package]] name = "alloy-sol-macro-input" -version = "1.5.7" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56cef806ad22d4392c5fc83cf8f2089f988eb99c7067b4e0c6f1971fc1cca318" +checksum = "32c2c0ec8425d9663dac939ba75750f17d2933d2f020814b4f8fde4a60da6d26" dependencies = [ "const-hex", "dunce", @@ -135,15 +106,15 @@ dependencies = [ "macro-string", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", "syn-solidity", ] [[package]] name = "alloy-sol-types" -version = "1.5.7" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64612d29379782a5dde6f4b6570d9c756d734d760c0c94c254d361e678a6591f" +checksum = "1f40e33a0f588dde548c3b6767a71e61b593421a8c1b253b9cf1441dc7cf7ab5" dependencies = [ "alloy-primitives", "alloy-sol-macro", @@ -151,9 +122,9 @@ dependencies = [ [[package]] name = "android_system_properties" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" dependencies = [ "libc", ] @@ -210,46 +181,288 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] -name = "anymap2" -version = "0.13.0" +name = "ark-ff" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint 0.4.8", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] [[package]] -name = "arrayref" -version = "0.3.9" +name = "ark-ff" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint 0.4.8", + "num-traits", + "paste", + "rustc_version 0.4.1", + "zeroize", +] [[package]] -name = "arrayvec" -version = "0.7.6" +name = "ark-ff" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" +dependencies = [ + "ark-ff-asm 0.5.0", + "ark-ff-macros 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "educe", + "itertools 0.13.0", + "num-bigint 0.4.8", + "num-traits", + "paste", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7a806ac6c8307b929df4645776290a50ee2aac754ad09d8bdf73391309e43af" +dependencies = [ + "ark-ff-asm 0.6.0", + "ark-ff-macros 0.6.0", + "ark-serialize 0.6.0", + "ark-std 0.6.0", + "digest 0.10.7", + "educe", + "num-bigint 0.4.8", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-ff-asm" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1479009684adc073dff49a1025d3a7065b317a9ead25aaaca38cdc70058ba8a2" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint 0.4.8", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint 0.4.8", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" +dependencies = [ + "num-bigint 0.4.8", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-ff-macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0691ed21ef00ef89c1e9bda832eba493dda3ec2f8d892fb25b705f73f06bb8" +dependencies = [ + "num-bigint 0.4.8", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint 0.4.8", +] + +[[package]] +name = "ark-serialize" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" +dependencies = [ + "ark-std 0.5.0", + "arrayvec", + "digest 0.10.7", + "num-bigint 0.4.8", +] + +[[package]] +name = "ark-serialize" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "a74dd304fd536fb95d0a328e72be759209cc496a9da094c5bc56e5fea4f9e86b" +dependencies = [ + "ark-serialize-derive", + "ark-std 0.6.0", + "digest 0.10.7", + "num-bigint 0.4.8", + "serde_with", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f153690697a2b91e5e1251ff98411ee5371500a111a0fd317a70e588eb300f9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand 0.8.8", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.8", +] [[package]] -name = "ascii-canvas" -version = "4.0.0" +name = "ark-std" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" +dependencies = [ + "num-traits", + "rand 0.8.8", +] + +[[package]] +name = "ark-std" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" +checksum = "367c9c827ed431bff6868b7aa926e05b16eb46603cc8b6e768e4a5553fa1d155" dependencies = [ - "term", + "num-traits", + "rand 0.8.8", ] +[[package]] +name = "arrayvec" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" + [[package]] name = "async-trait" -version = "0.1.89" +version = "0.1.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +checksum = "82f6aeea286b8eb4dd3431a1be1b59d290ace00f5bfd8e2a159bc2a05e2c1667" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.5", ] [[package]] @@ -258,11 +471,22 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "auto_impl" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "backtrace" @@ -270,11 +494,11 @@ version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6" dependencies = [ - "addr2line 0.25.1", + "addr2line", "cfg-if", "libc", "miniz_oxide", - "object 0.37.3", + "object", "rustc-demangle", "windows-link", ] @@ -290,9 +514,9 @@ dependencies = [ [[package]] name = "base16ct" -version = "0.2.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" [[package]] name = "base64" @@ -300,6 +524,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac07cdecf99051d9a5238b80f35af32cdeba5b336e55d957b318b50137e18da5" + [[package]] name = "base64ct" version = "1.8.3" @@ -318,50 +548,23 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bit-set" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" - [[package]] name = "bitflags" -version = "2.11.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4512299f36f043ab09a583e57bceb5a5aab7a73db1805848e8fef3c9e8c78b3" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] -name = "bitmaps" -version = "2.1.0" +name = "bitflags" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" -dependencies = [ - "typenum", -] +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "bitvec" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" dependencies = [ "funty", "radium", @@ -371,84 +574,78 @@ dependencies = [ [[package]] name = "blake3" -version = "1.8.4" +version = "1.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d2d5991425dfd0785aed03aedcf0b321d61975c9b5b3689c774a2610ae0b51e" +checksum = "6d9e454fc11f76977dc803893aff6304ed33d6a26efae8696573bea74baa27ae" dependencies = [ - "arrayref", "arrayvec", "cc", "cfg-if", "constant_time_eq", - "cpufeatures 0.3.0", -] - -[[package]] -name = "blink-alloc" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce4c15bad517bc0fb4a44523adf470e2c3eb3a365769327acdba849948ea3705" -dependencies = [ - "allocator-api2 0.4.0", + "cpufeatures 0.3.1", ] [[package]] name = "block-buffer" -version = "0.10.4" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] name = "bon" -version = "3.9.3" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a602c73c7b0148ec6d12af6fd5cc7a46e2eacc8878271a999abac56eed12f561" +checksum = "60eafe0d77c3a2fc292c1d1346c3041b33c0a108085a2afabf672b70f69dbbc9" dependencies = [ "bon-macros", - "rustversion", ] [[package]] name = "bon-macros" -version = "3.9.3" +version = "3.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dee98b0db6a962de883bf5d20362dee4d7ca0d12fe39a7c6c73c844e1cd7c1f" +checksum = "bd0f9631d8aaaee112c41985d675ef269e02acbd4f33122836af4f0c5f699ff6" dependencies = [ "darling", "ident_case", - "prettyplease", + "prettyplease 0.3.0", "proc-macro2", "quote", - "rustversion", - "syn 2.0.117", + "syn 3.0.5", ] [[package]] -name = "bstr" -version = "1.12.1" +name = "bs58" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ - "memchr", + "tinyvec", ] [[package]] name = "build-rs" -version = "0.3.4" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe808acca98fccf920154ee7833e791bfb683299be4aae7ec222ddffad8cd4f8" +checksum = "87a490fb7ec2896b97a4c721c03a2b2dc5c2b9b75b2a57ca396db4470dea0381" dependencies = [ "unicode-ident", ] [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "byte-slice-cast" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" [[package]] name = "byteorder" @@ -458,80 +655,15 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" - -[[package]] -name = "camino" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" -dependencies = [ - "serde_core", -] - -[[package]] -name = "cargo-miden" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb9938417feb0793507c9c75bc375b12ce86416b8e3717eade17dafbcf1b3e91" -dependencies = [ - "anyhow", - "clap", - "heck", - "liquid", - "liquid-core", - "log", - "miden-mast-package", - "midenc-compile", - "midenc-hir", - "midenc-log", - "midenc-session", - "path-absolutize", - "tempfile", - "toml_edit", - "walkdir", -] - -[[package]] -name = "cargo-platform" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0061da739915fae12ea00e16397555ed4371a6bb285431aab930f61b0aa4ba" -dependencies = [ - "serde", - "serde_core", -] - -[[package]] -name = "cargo_metadata" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef987d17b0a113becdd19d3d0022d04d7ef41f9efe4f3fb63ac44ba61df3ade9" -dependencies = [ - "camino", - "cargo-platform", - "semver 1.0.28", - "serde", - "serde_json", - "thiserror", -] - -[[package]] -name = "castaway" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" -dependencies = [ - "rustversion", -] +checksum = "fc652a48c352aef3ea3aed32080501cf3ef6ed5da78602a020c991775b0aff04" [[package]] name = "cc" -version = "1.2.60" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20" +checksum = "005ec2760ca554fae18df7a11195552ec576cd665632a881bc011d5bb2fd4d80" dependencies = [ "find-msvc-tools", "jobserver", @@ -547,92 +679,58 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chacha20" -version = "0.9.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" dependencies = [ "cfg-if", "cipher", - "cpufeatures 0.2.17", + "cpufeatures 0.3.1", + "rand_core 0.10.1", ] [[package]] name = "chacha20poly1305" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +checksum = "9b89e1c441e926b9c82a8d023f6e1b7ae0adcfaa7d621814e4d60789bac751cb" dependencies = [ "aead", "chacha20", "cipher", "poly1305", - "zeroize", ] [[package]] name = "chrono" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" dependencies = [ "iana-time-zone", "js-sys", "num-traits", + "serde", "wasm-bindgen", "windows-link", ] [[package]] name = "cipher" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ - "crypto-common", + "block-buffer", + "crypto-common 0.2.2", "inout", - "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 = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", - "terminal_size", -] - -[[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" +name = "cmov" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" [[package]] name = "codegen" @@ -640,7 +738,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "573800db6c3319bc125ddbf9b9cb001ad1602957f53642ba8d09ff3ddd4da7f1" dependencies = [ - "indexmap", + "indexmap 2.14.2", ] [[package]] @@ -649,25 +747,11 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" -[[package]] -name = "compact_str" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb1325a1cece981e8a296ab8f0f9b63ae357bd0784a9faaf548cc7b480707a" -dependencies = [ - "castaway", - "cfg-if", - "itoa", - "rustversion", - "ryu", - "static_assertions", -] - [[package]] name = "const-hex" -version = "1.18.1" +version = "1.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531185e432bb31db1ecda541e9e7ab21468d4d844ad7505e0546a49b4945d49b" +checksum = "33e2a781ebdf4467d1428dc4593067825fb646f6871475098d8577421af73558" dependencies = [ "cfg-if", "cpufeatures 0.2.17", @@ -677,9 +761,30 @@ dependencies = [ [[package]] name = "const-oid" -version = "0.9.6" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + +[[package]] +name = "const_format" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4481a617ad9a412be3b97c5d403fef8ed023103368908b9c50af598ff467cc1e" +dependencies = [ + "const_format_proc_macros", + "konst", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] [[package]] name = "constant_time_eq" @@ -713,13 +818,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] -name = "cpp_demangle" -version = "0.5.1" +name = "cpubits" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0667304c32ea56cb4cd6d2d7c0cfe9a2f8041229db8c033af7f8d69492429def" -dependencies = [ - "cfg-if", -] +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" [[package]] name = "cpufeatures" @@ -732,41 +834,13 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" dependencies = [ "libc", ] -[[package]] -name = "cranelift-bitset" -version = "0.131.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3af4f7d421b2354deb01d714266022f38fcdbebc9f5f1ec6d310d3c27286d9e" -dependencies = [ - "wasmtime-internal-core", -] - -[[package]] -name = "cranelift-entity" -version = "0.131.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aa2846b239a046217ecf95cfed0e31be4e86843785d07438ad33f456871e888" -dependencies = [ - "cranelift-bitset", - "wasmtime-internal-core", -] - -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - [[package]] name = "critical-section" version = "1.2.0" @@ -775,9 +849,9 @@ checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-deque" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -785,18 +859,18 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" [[package]] name = "crunchy" @@ -806,12 +880,15 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" -version = "0.5.5" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +checksum = "1a52aa3fcda4e6302a9f48734f234d35d4721b96f8fe07d073f07ce9df4f0271" dependencies = [ - "generic-array", - "rand_core 0.6.4", + "cpubits", + "ctutils", + "hybrid-array", + "num-traits", + "rand_core 0.10.1", "subtle", "zeroize", ] @@ -823,20 +900,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", - "rand_core 0.6.4", "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", + "rand_core 0.10.1", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", + "subtle", +] + [[package]] name = "curve25519-dalek" -version = "4.1.3" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "b5eed333089e2e1c1ac8c6c0398e5e2497b4c9926ca6d0365ed1e099afa5bc23" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures 0.3.1", "curve25519-dalek-derive", - "digest", + "digest 0.11.3", "fiat-crypto", "rustc_version 0.4.1", "subtle", @@ -851,14 +947,14 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "darling" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +checksum = "ed17f5901b6630b993ca003def43f2f8ef4014fc13b047b57aad617ff32bc2ec" dependencies = [ "darling_core", "darling_macro", @@ -866,26 +962,26 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +checksum = "6837e2cf7485aaae18f86181d2f0e9a7ed297a025e220aeabf63fdebd3a2ddff" dependencies = [ "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.117", + "syn 3.0.5", ] [[package]] name = "darling_macro" -version = "0.23.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +checksum = "2ac7135c3ef02b2f7833bbeb1be5ba7f966dcde8a87c6b87f65a778d71a02785" dependencies = [ "darling_core", "quote", - "syn 2.0.117", + "syn 3.0.5", ] [[package]] @@ -918,11 +1014,42 @@ dependencies = [ "deadpool-runtime", ] +[[package]] +name = "defmt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" +dependencies = [ + "bitflags 1.3.2", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror", +] + [[package]] name = "der" -version = "0.7.10" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "a878c850e9e421b20262e9b41f9c860e4785fa07541c266b62ff9d1ef998a80a" dependencies = [ "const-oid", "zeroize", @@ -934,7 +1061,18 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ - "powerfmt", + "serde_core", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] @@ -956,20 +1094,38 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.117", + "syn 2.0.119", "unicode-xid", ] +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "crypto-common 0.1.7", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer", "const-oid", - "crypto-common", - "subtle", + "crypto-common 0.2.2", + "ctutils", ] [[package]] @@ -984,25 +1140,32 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + [[package]] name = "ecdsa" -version = "0.16.9" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +checksum = "c0681a4fc24c767085329728d8dfba959af91228aa4610cca4f8ce317ba46ae0" dependencies = [ "der", - "digest", + "digest 0.11.3", "elliptic-curve", "rfc6979", "signature", "spki", + "zeroize", ] [[package]] name = "ed25519" -version = "2.2.3" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +checksum = "29fcf32e6c73d1079f83ab4d782de2d81620346a5f38c6237a86a22f8368980a" dependencies = [ "pkcs8", "signature", @@ -1010,58 +1173,83 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +checksum = "6ebaa1a2bf1290ab3bfe5a7b771d050ebffab2711c19a81691c683a5144a25de" dependencies = [ "curve25519-dalek", "ed25519", "serde", "sha2", + "signature", "subtle", "zeroize", ] +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.119", +] + [[package]] name = "either" -version = "1.15.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "elliptic-curve" -version = "0.13.8" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "9d65aa39b3a5c1c9c1b745c9a019234bb7a21b77abcb4f4d266d706e2d577d65" dependencies = [ "base16ct", "crypto-bigint", - "digest", + "crypto-common 0.2.2", + "digest 0.11.3", "ff", - "generic-array", "group", "hkdf", + "hybrid-array", "pkcs8", - "rand_core 0.6.4", + "rand_core 0.10.1", "sec1", "subtle", "zeroize", ] [[package]] -name = "ena" -version = "0.14.4" +name = "enum-ordinalize" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" +checksum = "89dd01549b09589510cf0647475075d12071456586d70f5c75c98ae2a5537677" dependencies = [ - "log", + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65863d15a4ce2888bd2f0f543cc963d3879c3a022c8ee43f6141d479a3ac815" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.5", ] [[package]] name = "env_filter" -version = "1.0.1" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" +checksum = "900d271a03799a1ee8d1ca9b19893b48ca674a9284fefcfb85f05e74ed314217" dependencies = [ "log", "regex", @@ -1069,9 +1257,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.10" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" +checksum = "de671bd27a75a797dc9ae289ba1e77276e75e2026408aab65185384e2d5cd3f6" dependencies = [ "anstream", "anstyle", @@ -1121,31 +1309,53 @@ checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" [[package]] name = "fastrand" -version = "2.4.1" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da7c62ceae207dd37ea5b845da6a0696c799f85e97da1ab5b7910be3c1c80223" + +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "fastrlp" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" +checksum = "ce8dba4714ef14b8274c371879b175aa55b16b30f269663f19d576f380018dc4" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] [[package]] name = "ff" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +checksum = "a1f686ab92a9fb0eaf188f6c6c87b89490baa6fdb0db4544ba4dc47f7942489f" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" +checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d" [[package]] name = "fixed-hash" @@ -1153,6 +1363,9 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ + "byteorder", + "rand 0.8.8", + "rustc-hex", "static_assertions", ] @@ -1163,25 +1376,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] -name = "flate2" -version = "1.1.9" +name = "flume" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" dependencies = [ - "crc32fast", - "miniz_oxide", -] - -[[package]] -name = "flume" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" -dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "spin 0.9.8", + "spin 0.9.9", ] [[package]] @@ -1204,9 +1404,9 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "fs-err" -version = "3.3.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fde052dbfc920003cfd2c8e2c6e6d4cc7c1091538c3a24226cec0665ab08c0" +checksum = "b91aa448ca50d7e79433bdf3ee8d99215430d2ec02ade5aefab2a073a1822e8a" dependencies = [ "autocfg", ] @@ -1219,9 +1419,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" dependencies = [ "futures-channel", "futures-core", @@ -1234,9 +1434,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -1244,15 +1444,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-executor" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" +checksum = "031b47cf1a3c6cc8bc2fc76cd437f521619387907d469316e7c0bc278f1f5432" dependencies = [ "futures-core", "futures-task", @@ -1261,38 +1461,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-macro" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" +checksum = "9fb9654ba8355388abeb8dcb4fc62f511300867002afc858860463bdd9fe0c44" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.5", ] [[package]] name = "futures-sink" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-channel", "futures-core", @@ -1307,9 +1507,9 @@ dependencies = [ [[package]] name = "generator" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52f04ae4152da20c76fe800fa48659201d5cf627c5149ca0b707b69d7eef6cf9" +checksum = "b3b854b0e584ead1a33f18b2fcad7cf7be18b3875c78816b753639aa501513ae" dependencies = [ "cc", "cfg-if", @@ -1328,7 +1528,6 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", - "zeroize", ] [[package]] @@ -1338,10 +1537,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", - "js-sys", "libc", "wasi", - "wasm-bindgen", ] [[package]] @@ -1360,16 +1557,15 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "js-sys", "libc", "r-efi 6.0.0", - "wasip2", - "wasip3", + "rand_core 0.10.1", "wasm-bindgen", ] @@ -1379,20 +1575,11 @@ version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7" -[[package]] -name = "gimli" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf7f043f89559805f8c7cacc432749b2fa0d0a0a9ee46ce47164ed5ba7f126c" -dependencies = [ - "stable_deref_trait", -] - [[package]] name = "glob" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" [[package]] name = "gloo-timers" @@ -1408,20 +1595,20 @@ dependencies = [ [[package]] name = "group" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] [[package]] name = "h2" -version = "0.4.13" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54" +checksum = "ef8e5e5a340588f4452631496976cf8636d4a7ecf600239fdc27615d2530bc16" dependencies = [ "atomic-waker", "bytes", @@ -1429,7 +1616,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap", + "indexmap 2.14.2", "slab", "tokio", "tokio-util", @@ -1438,32 +1625,25 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.5" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "allocator-api2 0.2.21", - "equivalent", - "foldhash 0.1.5", -] +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "hashbrown" -version = "0.16.1" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "foldhash 0.2.0", + "foldhash 0.1.5", ] [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" dependencies = [ - "allocator-api2 0.2.21", - "equivalent", "foldhash 0.2.0", ] @@ -1484,9 +1664,9 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" +checksum = "e17592d60ebacc7d5e169f4663c5f84f9161cc90328abcfe8456f41e4dfcb284" [[package]] name = "hex" @@ -1496,27 +1676,27 @@ checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" [[package]] name = "hkdf" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" dependencies = [ "hmac", ] [[package]] name = "hmac" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "digest", + "digest 0.11.3", ] [[package]] name = "http" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "918d3568bebf352712bc2ef3d46a8bcf1a75b373be6539de198e9105cbbf9ce0" dependencies = [ "bytes", "itoa", @@ -1524,9 +1704,9 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" dependencies = [ "bytes", "http", @@ -1534,9 +1714,9 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.3" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +checksum = "23169fe34a5fbcdd3f3862e78fb9b6fccd5f02a6dc6f732547005d45631ce71c" dependencies = [ "bytes", "futures-core", @@ -1557,11 +1737,22 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hybrid-array" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17" +dependencies = [ + "subtle", + "typenum", + "zeroize", +] + [[package]] name = "hyper" -version = "1.9.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "27b501faa50e7a26c3d3560ca625132f4078a17771f4810baf70475ae48cbe43" dependencies = [ "atomic-waker", "bytes", @@ -1636,12 +1827,6 @@ dependencies = [ "cc", ] -[[package]] -name = "id-arena" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" - [[package]] name = "ident_case" version = "1.0.1" @@ -1649,17 +1834,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] -name = "im-rc" -version = "15.1.0" +name = "impl-codec" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1955a75fa080c677d3972822ec4bad316169ab1cfc6c257a942c2265dbe5fe" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" dependencies = [ - "bitmaps", - "rand_core 0.6.4", - "rand_xoshiro 0.6.0", - "sized-chunks", - "typenum", - "version_check", + "parity-scale-codec", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] @@ -1670,23 +1861,34 @@ checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" -version = "2.14.0" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.17.1", "serde", "serde_core", ] [[package]] name = "inout" -version = "0.1.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -1694,34 +1896,15 @@ name = "integration" version = "0.1.0" dependencies = [ "anyhow", - "cargo-miden", "miden-client", "miden-client-sqlite-store", - "miden-mast-package", + "miden-protocol", "miden-standards", "miden-testing", - "rand 0.9.4", + "rand 0.10.2", "tokio", ] -[[package]] -name = "intrusive-collections" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b719c59241cfaac1042a6d26787e28ed7ee4a4e21a5a907786f54222d1b0062" -dependencies = [ - "memoffset", -] - -[[package]] -name = "inventory" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4f0c30c76f2f4ccee3fe55a2435f691ca00c0e4bd87abe4f4a851b1d4dac39b" -dependencies = [ - "rustversion", -] - [[package]] name = "is_ci" version = "1.2.0" @@ -1734,6 +1917,24 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.14.0" @@ -1743,6 +1944,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.18" @@ -1751,113 +1961,116 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.23" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a3546dc96b6d42c5f24902af9e2538e82e39ad350b0c766eb3fbf2d8f3d8359" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" dependencies = [ + "defmt", + "jiff-core", "jiff-static", + "jiff-tzdb-platform", "log", "portable-atomic", "portable-atomic-util", "serde_core", + "windows-link", +] + +[[package]] +name = "jiff-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +dependencies = [ + "defmt", ] [[package]] name = "jiff-static" -version = "0.2.23" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a8c8b344124222efd714b73bb41f8b5120b27a7cc1c75593a6ff768d9d05aa4" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" dependencies = [ + "jiff-core", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", ] [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.95" +version = "0.3.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" +checksum = "ce57d20d1ea864ce2ac172ab472d409214f4fd359f0b2a2775abdf522e2af99e" dependencies = [ "cfg-if", "futures-util", - "once_cell", "wasm-bindgen", ] [[package]] name = "k256" -version = "0.13.4" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +checksum = "93f50113171a713f4a4231ef82eb26703607139b35dcb56241f0ceab2ae1f7d8" dependencies = [ - "cfg-if", + "cpubits", "ecdsa", "elliptic-curve", - "once_cell", + "primeorder", "sha2", - "signature", + "wnaf", ] [[package]] name = "keccak" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" -dependencies = [ - "cpufeatures 0.2.17", -] - -[[package]] -name = "kstring" -version = "2.0.2" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "558bf9508a558512042d3095138b1f7b8fe90c5467d94f9f1da28b3731c5dbd1" +checksum = "d8f198d1db720e4940b5a493201d199d9f24f568f8f746bd13706243a2f71598" dependencies = [ - "serde", - "static_assertions", + "cfg-if", + "cpufeatures 0.3.1", ] [[package]] -name = "lalrpop" -version = "0.22.2" +name = "konst" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" +checksum = "128133ed7824fcd73d6e7b17957c5eb7bacb885649bd8c69708b2331a10bcefb" dependencies = [ - "ascii-canvas", - "bit-set", - "ena", - "itertools", - "lalrpop-util", - "petgraph 0.7.1", - "regex", - "regex-syntax", - "sha3", - "string_cache", - "term", - "unicode-xid", - "walkdir", + "konst_macro_rules", ] [[package]] -name = "lalrpop-util" -version = "0.22.2" +name = "konst_macro_rules" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" -dependencies = [ - "regex-automata", - "rustversion", -] +checksum = "a4933f3f57a8e9d9da04db23fb153356ecaf00cbd14aee46279c33dc80925c37" [[package]] name = "lazy_static" @@ -1865,17 +2078,11 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "leb128fmt" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" - [[package]] name = "libc" -version = "0.2.185" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libm" @@ -1900,112 +2107,6 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" -[[package]] -name = "liquid" -version = "0.26.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a494c3f9dad3cb7ed16f1c51812cbe4b29493d6c2e5cd1e2b87477263d9534d" -dependencies = [ - "liquid-core", - "liquid-derive", - "liquid-lib", - "serde", -] - -[[package]] -name = "liquid-core" -version = "0.26.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc623edee8a618b4543e8e8505584f4847a4e51b805db1af6d9af0a3395d0d57" -dependencies = [ - "anymap2", - "itertools", - "kstring", - "liquid-derive", - "pest", - "pest_derive", - "regex", - "serde", - "time", -] - -[[package]] -name = "liquid-derive" -version = "0.26.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de66c928222984aea59fcaed8ba627f388aaac3c1f57dcb05cc25495ef8faefe" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - -[[package]] -name = "liquid-lib" -version = "0.26.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9befeedd61f5995bc128c571db65300aeb50d62e4f0542c88282dbcb5f72372a" -dependencies = [ - "itertools", - "liquid-core", - "percent-encoding", - "regex", - "time", - "unicode-segmentation", -] - -[[package]] -name = "litcheck-core" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00d04c87eac46e722dea009607dbf01109872ccabdaa9088399f2a21c6b2a71d" -dependencies = [ - "Inflector", - "clap", - "compact_str", - "either", - "glob", - "hashbrown 0.15.5", - "log", - "memchr", - "miette", - "parking_lot", - "paste", - "rustc-hash", - "serde", - "serde_spanned", - "smallvec", - "thiserror", - "toml 0.9.12+spec-1.1.0", - "walkdir", -] - -[[package]] -name = "litcheck-filecheck" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3068bd232903a957c3dd219019857542dcc8e57eee9db2cebd08c916d8d989c" -dependencies = [ - "aho-corasick", - "bitflags", - "bstr", - "clap", - "either", - "im-rc", - "itertools", - "lalrpop", - "lalrpop-util", - "litcheck-core", - "log", - "logos 0.16.1", - "memchr", - "regex", - "regex-automata", - "regex-syntax", - "smallvec", - "thiserror", -] - [[package]] name = "lock_api" version = "0.4.14" @@ -2017,9 +2118,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "logos" @@ -2052,7 +2153,7 @@ dependencies = [ "quote", "regex-syntax", "rustc_version 0.4.1", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2066,7 +2167,7 @@ dependencies = [ "quote", "regex-automata", "regex-syntax", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2102,13 +2203,13 @@ dependencies = [ [[package]] name = "macro-string" -version = "0.1.4" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" +checksum = "59a9dbbfc75d2688ed057456ce8a3ee3f48d12eec09229f560f3643b9f275653" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -2122,70 +2223,54 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] -name = "memmap2" -version = "0.9.10" +name = "miden-ace-codegen" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +checksum = "00ff2a44c7f7dc497ac56c74dca5b3465b4b46be066fa88c2c58a8eb1bcb2dc8" dependencies = [ - "libc", + "miden-constraint-compiler", + "miden-core", + "miden-crypto", + "thiserror", ] [[package]] -name = "memoffset" -version = "0.9.1" +name = "miden-agglayer" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" -dependencies = [ - "autocfg", -] - -[[package]] -name = "miden-ace-codegen" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd45076fe4fef71f0f8b30aa0f018eb39c3086eeb5f3cafc0e12d60cd28339e" -dependencies = [ - "miden-core", - "miden-crypto", - "thiserror", -] - -[[package]] -name = "miden-agglayer" -version = "0.15.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ead17cc16651de0fea5fc3ea67109ad449c7bb274ca8ff91c5b25e2be4a0c9f8" +checksum = "c9340d981c2aaefded2a28ca66f10169dd4170c912538d33fe8690ea549e468e" dependencies = [ "alloy-sol-types", "fs-err", "miden-assembly", "miden-core", + "miden-core-lib", "miden-crypto", + "miden-mast-package", + "miden-package-registry", "miden-protocol", + "miden-protocol-build-utils", "miden-standards", "miden-utils-sync", - "primitive-types", - "regex", "thiserror", - "walkdir", ] [[package]] name = "miden-air" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f1a80330b3e3d3f98e08817dc6a5e3d90d11ab5e88aa9c0dad5d3b4202598b" +checksum = "84b6d3f3336c8a2da5cd0924c42dd1f339e6c3d5adf3221bc1c005b444fd0bf0" dependencies = [ "miden-ace-codegen", "miden-core", "miden-crypto", - "miden-lifted-stark", "miden-utils-indexing", + "p3-field", "proptest", "thiserror", "tracing", @@ -2193,9 +2278,9 @@ dependencies = [ [[package]] name = "miden-assembly" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8582d184360be35eb2111a99245f556f43e1066ed09192fbcd0f218c466862a5" +checksum = "644b31bdda941328f9ff2088382b7de41569c1cc83d6090f63e43d261e9cd262" dependencies = [ "env_logger", "log", @@ -2211,15 +2296,13 @@ dependencies = [ [[package]] name = "miden-assembly-syntax" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffa307bc2cbd1f0cb74ed58981823f400a433900fb8f963762331fbb8389d5dc" +checksum = "cad0d5174833b17b498d541d1ef62d73929a143ea56ea5eba719339c15cd0968" dependencies = [ - "aho-corasick", "env_logger", - "lalrpop", - "lalrpop-util", "log", + "miden-assembly-syntax-cst", "miden-core", "miden-debug-types", "miden-utils-diagnostics", @@ -2234,11 +2317,23 @@ dependencies = [ "thiserror", ] +[[package]] +name = "miden-assembly-syntax-cst" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff301e56d9201821a4458564ed19ae9b95c7a219662a422e47bb61d17e0fa7b1" +dependencies = [ + "miden-debug-types", + "miden-rowan", + "miden-utils-diagnostics", + "thiserror", +] + [[package]] name = "miden-block-prover" -version = "0.15.3" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "292ded918a0ddd056dc34db471f0bef6ac7991467d513ba505a4fcc0b1ecfac4" +checksum = "3e34859c5f2005e95cfc5ba97ae0dffec15bb44460fc23262532e5e2aee49155" dependencies = [ "miden-protocol", "thiserror", @@ -2246,9 +2341,9 @@ dependencies = [ [[package]] name = "miden-client" -version = "0.15.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eb783623b8f55d013833c4eef35190f44da3629d0d13a13693285004f8d3fe2" +checksum = "c9862fde2ef60a6a1f1066834c9920f50973a2012465c451ec64381fea4654fc" dependencies = [ "anyhow", "async-trait", @@ -2258,17 +2353,18 @@ dependencies = [ "gloo-timers", "hex", "miden-agglayer", + "miden-assembly-syntax", "miden-node-proto-build", "miden-note-transport-proto-build", + "miden-processor", "miden-protocol", - "miden-remote-prover-client", "miden-standards", "miden-tx", - "miden-tx-batch-prover", + "miden-tx-batch", "miette", "prost", "prost-types", - "rand 0.9.4", + "rand 0.10.2", "serde", "serde_json", "tempfile", @@ -2284,9 +2380,9 @@ dependencies = [ [[package]] name = "miden-client-sqlite-store" -version = "0.15.2" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efb7f78f6ce83e114c49c601aa563df2863ebebea471023d70c3577177356b39" +checksum = "b1bdb490a10753418209cf9efcb8d923b3b0a39105b9cba987e9674dd1528b66" dependencies = [ "anyhow", "async-trait", @@ -2299,13 +2395,24 @@ dependencies = [ "rusqlite_migration", "thiserror", "tokio", + "tracing", +] + +[[package]] +name = "miden-constraint-compiler" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01ef51ec02f0899c5fc6aa4af11eb050094d98e5e6bf8767a4da555d210f2de6" +dependencies = [ + "miden-core", + "miden-crypto", ] [[package]] name = "miden-core" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80657c32850817f5f67dcf114866495a4b055531778b7c26d0602646ce777eb8" +checksum = "3b27f9f91988c5e74b50b543c4e6d37ec729eabcf70db63cf752dedd780f8a90" dependencies = [ "derive_more", "log", @@ -2315,36 +2422,47 @@ dependencies = [ "miden-utils-core-derive", "miden-utils-indexing", "miden-utils-sync", - "num-derive", - "num-traits", "proptest", - "proptest-derive", "serde", "thiserror", ] [[package]] name = "miden-core-lib" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16410655f32f98537afc9ddf57b71cb6d1ca9d980da5f4eea164cafcaf891b2e" +checksum = "14df9652fc4963f20d11df9ceb576ccb7831b5dc72fabec5c1b602f51e57909c" dependencies = [ "env_logger", "fs-err", "miden-assembly", + "miden-assembly-syntax", "miden-core", + "miden-core-lib-codegen", "miden-crypto", + "miden-mast-package", "miden-package-registry", + "miden-precompiles", "miden-processor", "miden-utils-sync", "thiserror", ] +[[package]] +name = "miden-core-lib-codegen" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aad0b8badcf1636150cac0d74aabadd395ba7d570227eb0923ff14f02a278fff" +dependencies = [ + "miden-core", + "miden-precompiles", +] + [[package]] name = "miden-crypto" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35198bebd353cddc25ad4aafb5f4ef9e71b283d71c787b8938c575c16974135d" +checksum = "7c917b0342d911ae4b7a549bb3ca791c093dac4770f88b02e23b43f3fa8179f5" dependencies = [ "blake3", "cc", @@ -2371,14 +2489,12 @@ dependencies = [ "p3-maybe-rayon", "p3-symmetric", "p3-util", - "rand 0.9.4", - "rand_chacha", - "rand_core 0.9.5", - "rand_hc", + "rand 0.10.2", + "rand_chacha 0.10.0", "rayon", "serde", "sha2", - "sha3", + "sha3 0.12.0", "subtle", "thiserror", "x25519-dalek", @@ -2386,19 +2502,19 @@ dependencies = [ [[package]] name = "miden-crypto-derive" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9068c6554db0e051f62913575de9949841a46b96ae92d4b7d28e1fed5d8f052b" +checksum = "a7c3165dfd7fd6f587ea5731efd1cc8083ca55c23d2d9b3000f83a3948486044" dependencies = [ "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "miden-debug-types" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956708ccb2f643db398b4b3d4f8d0baf199b1bfb5e34c8be1cd1bc811c005e8e" +checksum = "4c9f3f8e4a8f54a36fbf00330ac8bd1947627c1786cd49b94a08b741590ed173" dependencies = [ "memchr", "miden-crypto", @@ -2411,22 +2527,23 @@ dependencies = [ "serde", "serde_spanned", "thiserror", + "zerocopy", ] [[package]] name = "miden-field" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379a39db52cd932a95d4017a18b712ee53ed0f86cfedf8c63ed72d687a18a191" +checksum = "58cf9de55b88ec86ad272ff4224d76b3e0cbda49e242e78776b0037ba9b0e857" dependencies = [ "miden-serde-utils", - "num-bigint", + "num-bigint 0.5.1", "p3-challenger", "p3-field", "p3-goldilocks", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", "subtle", "thiserror", @@ -2443,11 +2560,12 @@ dependencies = [ [[package]] name = "miden-lifted-air" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789e0e469d1731012d8a018057317f31580611535c20d2a47c022213228cb733" +checksum = "f67e06d47e246db853a9f3e52ec87fa33a8ffc0fe5be0dd99288b2439312f206" dependencies = [ "p3-air", + "p3-challenger", "p3-field", "p3-matrix", "p3-util", @@ -2456,9 +2574,9 @@ dependencies = [ [[package]] name = "miden-lifted-stark" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f62cca91182917b22a47e150028b7c785df620a15b2974a39c64e2b1b7a889d3" +checksum = "a5ee320597c7712698d06811d9144b0e4f2275a21224ef0238652c947b01198b" dependencies = [ "miden-lifted-air", "miden-stark-transcript", @@ -2471,7 +2589,7 @@ dependencies = [ "p3-maybe-rayon", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", "serde", "thiserror", "tracing", @@ -2479,15 +2597,20 @@ dependencies = [ [[package]] name = "miden-mast-package" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f37c21836b40785ce297d363c57740d4e33edcc411f84185a524eddadd5f53c7" +checksum = "1355a2563a52af4399b4a93120a4398f81415b1fc4edb58310de5034cfa3781d" dependencies = [ + "hashbrown 0.17.1", + "log", "miden-assembly-syntax", "miden-core", "miden-debug-types", + "miden-utils-indexing", + "rustc-hash", "serde", "thiserror", + "zerocopy", ] [[package]] @@ -2506,9 +2629,9 @@ dependencies = [ "rustc_version 0.2.3", "rustversion", "serde_json", - "spin 0.9.8", + "spin 0.9.9", "strip-ansi-escapes", - "syn 2.0.117", + "syn 2.0.119", "textwrap", "thiserror", "trybuild", @@ -2523,14 +2646,14 @@ checksum = "86a905f3ea65634dd4d1041a4f0fd0a3e77aa4118341d265af1a94339182222f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "miden-node-proto-build" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef3b301741cedd6d0b532583690bc21dbf856d4e14218c591f3924bc905c660a" +checksum = "724a79e7663157e73de1fc19fcd6e30c7cee4e4c4189d44477922a3969797acb" dependencies = [ "build-rs", "codegen", @@ -2542,9 +2665,9 @@ dependencies = [ [[package]] name = "miden-note-transport-proto-build" -version = "0.4.1" +version = "0.5.0-rc.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7399c2999453c781601f16d82f328ecc695f9375e2415a05147449990f32f71f" +checksum = "5a9d736051a42941788c6534caf8cf779b388c0ae72c9d5f0d729d2a9872d833" dependencies = [ "fs-err", "miette", @@ -2554,9 +2677,9 @@ dependencies = [ [[package]] name = "miden-package-registry" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ece6064beb0582d1c64ba30d0c548c4b7a45f87abae6d69e22fd49c8b343258" +checksum = "a799e66245492c193b0444c3e0ff0fe42418009ec668a3e80c40d9f5b1454aac" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -2568,16 +2691,51 @@ dependencies = [ "thiserror", ] +[[package]] +name = "miden-precompiles" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "073ebeeb4413b9a03c60b0b066f94b8edaa6f50150017a92dc09d3ace92d6976" +dependencies = [ + "miden-core", + "miden-crypto", +] + +[[package]] +name = "miden-precompiles-prover" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76663c4d90cc073f9e2d2aa2349b9dcd25bf6c40db5020d27ce59990b6bd5af" +dependencies = [ + "miden-ace-codegen", + "miden-air", + "miden-core", + "miden-crypto", + "miden-lifted-air", + "miden-lifted-stark", + "miden-precompiles", + "miden-serde-utils", + "ruint", + "serde", + "serde-wincode", + "thiserror", + "tracing", + "wincode", +] + [[package]] name = "miden-processor" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea972ca9e45dbf26aa396367e8508db0f7292adea6f6ddf8d39d0e334285fe2b" +checksum = "2c7331ab96f00f922d29e2f59285f539299061a44ffdeea31b853d2c071f8056" dependencies = [ - "itertools", + "hashbrown 0.17.1", + "itertools 0.15.0", "miden-air", "miden-core", "miden-debug-types", + "miden-mast-package", + "miden-precompiles", "miden-utils-diagnostics", "miden-utils-indexing", "paste", @@ -2588,9 +2746,9 @@ dependencies = [ [[package]] name = "miden-project" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5320e7e5b562359bd6161ac752dfe43dd4f69bb06e87f94a21a27bb656e5a20d" +checksum = "6f8201d3a6d0c85c747092309c3c420de42e61e76f71df2189a46411100d120a" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -2600,18 +2758,18 @@ dependencies = [ "serde", "serde-untagged", "thiserror", - "toml 1.1.2+spec-1.1.0", + "toml", ] [[package]] name = "miden-protocol" -version = "0.15.3" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66340243e37da5936cb278a8dd11037813f1dc6731c2fc866703b76ed465ebc3" +checksum = "89ccf181d3a4e90b9e6ac107547ce1db30f085dfe5696a7735b1de03ac02f6ba" dependencies = [ "bech32", "fs-err", - "getrandom 0.3.4", + "getrandom 0.4.3", "miden-assembly", "miden-assembly-syntax", "miden-core", @@ -2619,506 +2777,230 @@ dependencies = [ "miden-crypto", "miden-crypto-derive", "miden-mast-package", + "miden-package-registry", "miden-processor", + "miden-protocol-build-utils", "miden-utils-sync", "miden-verifier", - "rand 0.9.4", - "rand_chacha", - "rand_xoshiro 0.7.0", + "rand 0.10.2", + "rand_chacha 0.10.0", + "rand_xoshiro", "regex", "semver 1.0.28", "serde", "thiserror", - "toml 1.1.2+spec-1.1.0", + "toml", +] + +[[package]] +name = "miden-protocol-build-utils" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d16cdd96c1d0b3b2d57342d37eaadd15cc7c633bda965fc8c3b23ca249965b4" +dependencies = [ + "fs-err", + "miden-assembly", + "miden-core", + "miden-mast-package", + "miden-package-registry", + "miden-project", + "regex", "walkdir", ] [[package]] name = "miden-prover" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a91bcc00840b01126cd54e3b68ce3235def2ed48803f2eeb36a035d6951fbc1" +checksum = "b20c4cabb7a032e7613adff4c637c267bbcaad0d0fa37f7c7addbe7d425bb5c4" dependencies = [ - "bincode", "miden-air", "miden-core", "miden-crypto", + "miden-precompiles-prover", "miden-processor", "serde", + "serde-wincode", "tracing", ] [[package]] -name = "miden-remote-prover-client" -version = "0.15.0" +name = "miden-rowan" +version = "0.16.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2acdb9494689feeec0f60e3b61901b5eb2362b49b993b4cbc3eb75ad83514dd" +checksum = "c13695bf99aabaa21d6572b807c66bb26251aa3d9b75e828b3c99b97a3b1ce7e" dependencies = [ - "build-rs", - "fs-err", - "getrandom 0.4.2", - "miden-node-proto-build", - "miden-protocol", - "miden-tx", - "miette", - "prost", - "thiserror", - "tokio", - "tonic", - "tonic-prost", - "tonic-prost-build", - "tonic-web-wasm-client", + "hashbrown 0.17.1", + "rustc-hash", ] [[package]] name = "miden-serde-utils" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78cd1d4fcad937312e544f7d53423485e453598aa4fb989d2b6374027a8c136" +checksum = "f5c21a2acdc1928f86803b3ff3c44564c3f614a7dc47dcd64969a5c856d27988" dependencies = [ "p3-field", "p3-goldilocks", + "wincode", ] [[package]] name = "miden-standards" -version = "0.15.3" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c7146b028e637f4079b5bdefeefc54d7d6e47a805451fa0a18859d19efa2ff" +checksum = "ee6fc2cdac6d1bb48ae4b0c2f0498e754490750283783b7a71b25c3017e68754" dependencies = [ "bon", - "fs-err", "miden-assembly", "miden-core-lib", + "miden-package-registry", "miden-protocol", - "rand 0.9.4", - "regex", - "thiserror", - "walkdir", -] - -[[package]] -name = "miden-stark-transcript" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05901db2e30d3954243960fe21cea7fbec39f97c27774b56fd5031c28c4881ba" -dependencies = [ - "p3-challenger", - "p3-field", - "serde", - "thiserror", -] - -[[package]] -name = "miden-stateful-hasher" -version = "0.25.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faeb47a90c55c5d45051d23cf691588804dd531995b4582c79108b64e445a905" -dependencies = [ - "p3-field", - "p3-symmetric", -] - -[[package]] -name = "miden-testing" -version = "0.15.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4096fc44a4c88f37405be284e25efdce194d6051e9472ae136ab9249659433c" -dependencies = [ - "anyhow", - "itertools", - "miden-block-prover", - "miden-core-lib", - "miden-crypto", - "miden-processor", - "miden-protocol", - "miden-standards", - "miden-tx", - "miden-tx-batch-prover", - "rand 0.9.4", - "rand_chacha", - "thiserror", -] - -[[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]] -name = "miden-tx" -version = "0.15.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94092b45bc0abc656af25473c9807d1e6cee8e682c58d3b1186f0bd0fb6471fb" -dependencies = [ - "miden-processor", - "miden-protocol", - "miden-prover", - "miden-standards", - "miden-verifier", - "thiserror", -] - -[[package]] -name = "miden-tx-batch-prover" -version = "0.15.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60add2b40559352661bc86970541f88ffcf98c528f301295f9dc3bf15481b46" -dependencies = [ - "miden-protocol", - "miden-tx", -] - -[[package]] -name = "miden-utils-core-derive" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0b1ee4662beb049a824e11bb21f95a79746c52874967983c9999f1b19a2f471" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "miden-utils-diagnostics" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fdc1cd4eda372e1c4b99b9c3677e9b1f87a4d2e362a9f4b8f904273d395efc9" -dependencies = [ - "miden-crypto", - "miden-debug-types", - "miden-miette", - "tracing", -] - -[[package]] -name = "miden-utils-indexing" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31444125649f4dad9cde647f614309b6be4f918fed276ada4eb99c01e8b9ca7" -dependencies = [ - "miden-crypto", - "proptest", - "serde", + "miden-protocol-build-utils", + "primitive-types 0.14.0", + "rand 0.10.2", "thiserror", ] [[package]] -name = "miden-utils-sync" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "807c8ae625b7652ae7246b225c907c05da72927c31a0fd71c835c4f80931e92e" -dependencies = [ - "lock_api", - "loom", - "once_cell", - "parking_lot", -] - -[[package]] -name = "miden-verifier" -version = "0.23.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec5556dac919a1c13edeb2bd7181fc6a4c2ce52764a3e518bcdcd9ed48e5b38e" -dependencies = [ - "bincode", - "miden-air", - "miden-core", - "miden-crypto", - "serde", - "thiserror", - "tracing", -] - -[[package]] -name = "midenc-codegen-masm" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc78e4f5d33ed343f6ee0022eac56e77e39f0269b81632aaf60746faa427ded" -dependencies = [ - "anyhow", - "inventory", - "log", - "miden-assembly", - "miden-assembly-syntax", - "miden-core", - "miden-mast-package", - "miden-processor", - "miden-protocol", - "miden-thiserror", - "midenc-dialect-arith", - "midenc-dialect-cf", - "midenc-dialect-hir", - "midenc-dialect-scf", - "midenc-dialect-ub", - "midenc-dialect-wasm", - "midenc-hir", - "midenc-hir-analysis", - "midenc-session", - "petgraph 0.8.3", - "serde", - "smallvec", -] - -[[package]] -name = "midenc-compile" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d679758b002854f16961ab124862aa00a965174da6dd4db106ff0baef42fba3" -dependencies = [ - "cargo_metadata", - "clap", - "log", - "miden-assembly", - "miden-mast-package", - "miden-package-registry", - "miden-thiserror", - "midenc-codegen-masm", - "midenc-dialect-hir", - "midenc-dialect-scf", - "midenc-frontend-masm", - "midenc-frontend-wasm", - "midenc-hir", - "midenc-hir-transform", - "midenc-session", - "tempfile", - "toml_edit", - "wat", -] - -[[package]] -name = "midenc-dialect-arith" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "215c60c892c7780db5ced04ec6f87d247bdcd2bf6dd576be41302129482f7a95" -dependencies = [ - "midenc-hir", - "paste", -] - -[[package]] -name = "midenc-dialect-cf" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13b76bab89e9f02a75e2809a6774ad6c6586b17c6c2524ffd6772523c40d6fb9" -dependencies = [ - "log", - "midenc-dialect-arith", - "midenc-hir", -] - -[[package]] -name = "midenc-dialect-hir" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fee0657b45332e80fa8f6e47ab7218995174dc1fc05b8d0be740819ef00c8cc" -dependencies = [ - "log", - "miden-thiserror", - "midenc-dialect-arith", - "midenc-dialect-cf", - "midenc-dialect-scf", - "midenc-hir", - "midenc-hir-analysis", - "midenc-hir-transform", -] - -[[package]] -name = "midenc-dialect-scf" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14d6e89cacc9d5e28f4c0f7c679fca5397ec995582baf20adea03676b3aac085" -dependencies = [ - "bitvec", - "log", - "midenc-dialect-arith", - "midenc-dialect-cf", - "midenc-dialect-ub", - "midenc-hir", - "midenc-hir-transform", -] - -[[package]] -name = "midenc-dialect-ub" -version = "0.9.0" +name = "miden-stark-transcript" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b26c4ffa3b405901b4397d951c1fc808226fac6d90f24e3ce496fc21ea81a7f" +checksum = "d503630c353389838fa5d668a0d4550130453c7b2a72b802d4adc1ea39ab5bee" dependencies = [ - "midenc-hir", + "p3-challenger", + "p3-field", + "serde", + "thiserror", ] [[package]] -name = "midenc-dialect-wasm" -version = "0.9.0" +name = "miden-stateful-hasher" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "118db44a3f84a16d221fb7ad8aa11a78e534a9b374a114289e3ca9159bd59ff4" +checksum = "e8c2008195bdb552eeb744074bfc8822049552ccdf7aef3321a32e1ab6be92e6" dependencies = [ - "midenc-dialect-arith", - "midenc-dialect-hir", - "midenc-hir", + "p3-field", + "p3-symmetric", ] [[package]] -name = "midenc-frontend-masm" -version = "0.9.0" +name = "miden-testing" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cfe26a87cccdf03970843141cfa9cc5f8f8722eab07351790ac28421a430eeb" +checksum = "697ea989c4553c1676dd740e41ad29d35fa6b1ac2ab20893c647fa4c7ec6d9dd" dependencies = [ - "miden-assembly", - "miden-assembly-syntax", - "miden-core", + "anyhow", + "itertools 0.15.0", + "miden-block-prover", "miden-core-lib", - "miden-mast-package", - "miden-project", - "midenc-dialect-arith", - "midenc-dialect-cf", - "midenc-dialect-hir", - "midenc-dialect-scf", - "midenc-hir", - "rustc-hash", + "miden-crypto", + "miden-processor", + "miden-protocol", + "miden-standards", + "miden-tx", + "miden-tx-batch", + "rand 0.10.2", + "rand_chacha 0.10.0", + "thiserror", ] [[package]] -name = "midenc-frontend-wasm" -version = "0.9.0" +name = "miden-tx" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df008b71ba2b638de9b57542ac5dfc84bbceb18945edb79fe033f3923c60c61b" +checksum = "6d5e8e69cf0db2d2f37f16909fc17d0b28730e1d21a587580ec90f27e19e309f" dependencies = [ - "addr2line 0.26.1", - "anyhow", - "cranelift-entity", - "gimli 0.33.0", - "indexmap", - "log", - "miden-core", - "miden-thiserror", - "midenc-dialect-arith", - "midenc-dialect-cf", - "midenc-dialect-hir", - "midenc-dialect-ub", - "midenc-dialect-wasm", - "midenc-frontend-wasm-metadata", - "midenc-hir", - "midenc-hir-symbol", - "midenc-session", - "wasmparser 0.248.0", - "wasmprinter", -] - -[[package]] -name = "midenc-frontend-wasm-metadata" -version = "0.13.0" + "bon", + "miden-agglayer", + "miden-processor", + "miden-protocol", + "miden-prover", + "miden-standards", + "thiserror", +] + +[[package]] +name = "miden-tx-batch" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3303cecb0858b92395b5c3710d52aae96d28e12f13966208731712e83803d" +checksum = "06419d4c747d8e79674d2be1436f0a46abe70aa2598f1789e71a07c14106cfa9" dependencies = [ - "serde", - "serde_json", + "miden-processor", + "miden-protocol", + "miden-prover", + "miden-verifier", + "thiserror", ] [[package]] -name = "midenc-hir" -version = "0.9.0" +name = "miden-utils-core-derive" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cf4e8a274761bfa396ec2695721bb3e1febf69bb48573b81651202ffc1c50b1" +checksum = "107d04fcd05b0308e6347113ee6dc13599755e5b4d05ecc08d8b5c05f36a5a39" dependencies = [ - "anyhow", - "base64", - "bitflags", - "bitvec", - "blink-alloc", - "compact_str", - "hashbrown 0.17.0", - "intrusive-collections", - "inventory", - "litcheck-filecheck", - "log", - "miden-core", - "miden-thiserror", - "midenc-hir-macros", - "midenc-hir-symbol", - "midenc-hir-type", - "midenc-session", - "paste", - "rustc-demangle", - "rustc-hash", - "semver 1.0.28", - "smallvec", + "proc-macro2", + "quote", + "syn 1.0.109", ] [[package]] -name = "midenc-hir-analysis" -version = "0.9.0" +name = "miden-utils-diagnostics" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf348db3c918a2370215a14b2c72a2fbd67150185ecf3a64a5e1859615257dd9" +checksum = "f3b444d204bf082cdab14015ff10d5b0b43a10fba662fef09e4753f6d07faf1f" dependencies = [ - "bitvec", - "blink-alloc", - "log", - "midenc-hir", + "miden-debug-types", + "miden-miette", + "tracing", ] [[package]] -name = "midenc-hir-macros" -version = "0.9.0" +name = "miden-utils-indexing" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abf4b1ebe109f9bab278db31773d947d341a8bf6831a816ffe0f06b3d0931242" +checksum = "f6ff225060e2a5cc4dd6c898eef1f04739461d3401b6de1692bf443cfdd302b0" dependencies = [ - "Inflector", - "darling", - "proc-macro2", - "quote", - "syn 2.0.117", + "miden-serde-utils", + "proptest", + "serde", + "thiserror", ] [[package]] -name = "midenc-hir-symbol" -version = "0.9.0" +name = "miden-utils-sync" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1866726ad1310cac43fa1818ba573466e1e482ee08836b838b52a10b9d897e" +checksum = "76b9cb00f01787f8687447cd8a45b3888b470eb35a132df1be9729779d311fd7" dependencies = [ - "Inflector", - "compact_str", - "hashbrown 0.17.0", "lock_api", - "miden-formatting", + "loom", + "once_cell", "parking_lot", - "rustc-hash", - "toml 1.1.2+spec-1.1.0", ] [[package]] -name = "midenc-hir-transform" -version = "0.9.0" +name = "miden-verifier" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3654f137f6ee811f32f71261eaf5f763a68937c6a5f8f538131cee12e368ef82" +checksum = "5e049df6008af1fea5a66df8ce98075cc9e00f16122fd5f4e7c4be9a263cae46" dependencies = [ - "log", - "midenc-hir", - "midenc-hir-analysis", - "midenc-session", + "miden-air", + "miden-core", + "miden-crypto", + "miden-precompiles", + "miden-precompiles-prover", + "miden-serde-utils", + "serde", + "serde-wincode", + "thiserror", ] [[package]] name = "midenc-hir-type" -version = "0.6.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff0511aa2201f7098995e38a3c97a319d379c3b2d26fb83677b21b71f61a7b4" +checksum = "dcdf2257de8f3486c8f3e93c45219b782bafad62a8694798c05d5b8f3f79c64e" dependencies = [ "miden-formatting", "miden-serde-utils", @@ -3128,48 +3010,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "midenc-log" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f70a0da3e6ac1434c65c24bd30dea9ae58b56db03d8b38c87596cec78799e03" -dependencies = [ - "anstream", - "anstyle", - "jiff", - "log", - "regex", -] - -[[package]] -name = "midenc-session" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35d790f66ac47df41fd3a355314562ba7b842474cb7727cb09e1f13a56e40202" -dependencies = [ - "anyhow", - "clap", - "hashbrown 0.17.0", - "heck", - "inventory", - "log", - "miden-assembly-syntax", - "miden-core", - "miden-core-lib", - "miden-debug-types", - "miden-mast-package", - "miden-package-registry", - "miden-project", - "miden-protocol", - "miden-thiserror", - "midenc-hir-macros", - "midenc-hir-symbol", - "parking_lot", - "rustc-hash", - "smallvec", - "termcolor", -] - [[package]] name = "miette" version = "7.6.0" @@ -3197,7 +3037,7 @@ checksum = "db5b29714e950dbb20d5e6f74f9dcec4edbcc1067bb7f8ed198c097b8c1a818b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -3207,14 +3047,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", - "simd-adler32", ] [[package]] name = "mio" -version = "1.2.0" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "4b18443e9c262bfe8fa82f51666e2642c53393f7e5c27b3e1aeab922cff5b9d8" dependencies = [ "libc", "wasi", @@ -3227,21 +3066,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom 0.2.17", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -3257,7 +3081,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "num-bigint", + "num-bigint 0.4.8", "num-complex", "num-integer", "num-iter", @@ -3267,9 +3091,19 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e7820bc0a80a0238e650327316f929ba18d5be054b647490a3a6a339f3e7c0" dependencies = [ "num-integer", "num-traits", @@ -3286,37 +3120,25 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" - -[[package]] -name = "num-derive" -version = "0.4.2" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-integer" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" dependencies = [ "num-traits", ] [[package]] name = "num-iter" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -3327,7 +3149,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "num-bigint", + "num-bigint 0.4.8", "num-integer", "num-traits", ] @@ -3361,17 +3183,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "object" -version = "0.39.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e5a6c098c7a3b6547378093f5cc30bc54fd361ce711e05293a5cc589562739b" -dependencies = [ - "flate2", - "memchr", - "ruzstd", -] - [[package]] name = "once_cell" version = "1.21.4" @@ -3388,12 +3199,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "openssl-probe" version = "0.2.1" @@ -3402,15 +3207,15 @@ checksum = "7c87def4c32ab89d880effc9e097653c8da5d6ef28e6b539d313baaacfbafcbe" [[package]] name = "owo-colors" -version = "4.3.0" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" +checksum = "13c45bb4a6ae1280ec0803b1ef9d3455eb50f01efbbe1447ab020f1d54fba9d8" [[package]] name = "p3-air" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c824e8d7c7ddf208b742eac8d48e0b2d52d22fa013578a7762bf6931dbab1f46" +checksum = "ddb1be05c0d6f691afe0c9f468018a9a37cfa904dee78a8081ec96eb3cdd88e8" dependencies = [ "p3-field", "p3-matrix", @@ -3419,9 +3224,9 @@ dependencies = [ [[package]] name = "p3-blake3" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2733229a713bd83ccf5eb749e8f8e7380c1052674394a25c0422a772204a20af" +checksum = "6f202f5fbcceb6f56f783d98efb5de27e5a171470e3364de97b0923b39c87ab5" dependencies = [ "blake3", "p3-symmetric", @@ -3430,9 +3235,9 @@ dependencies = [ [[package]] name = "p3-challenger" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8972ccd1d5dc90e46cdb1f2ab4ee2bae49b3917e5e98aa533f0c2b779c010445" +checksum = "84d5d5e1ecf2c80b09b48ce870e8abd08b643454101c5dc9d0fd71bfbd78224d" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -3444,42 +3249,42 @@ dependencies = [ [[package]] name = "p3-dft" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17771aca44632f9cc11f2718d7ea7ec06794946c4190ef3a985bfc893f14c18a" +checksum = "4321a952da2721ecd85ca593ea189798dfb4e439a2cc1378ce1442091880f173" dependencies = [ - "itertools", + "itertools 0.15.0", "p3-field", "p3-matrix", "p3-maybe-rayon", "p3-util", - "spin 0.10.0", + "spin 0.12.3", "tracing", ] [[package]] name = "p3-field" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3eb24d0591fd4d282d89cbe4e4efba5571c699375006f80b2cbf53ce83461c" +checksum = "53db75d38e04fc255826f388eca9d05976733dc9754aa3db411bc9ea1a37c1a0" dependencies = [ - "itertools", - "num-bigint", + "itertools 0.15.0", + "num-bigint 0.5.1", "p3-maybe-rayon", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", "tracing", ] [[package]] name = "p3-goldilocks" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5751c6591a0d2397d726620c2c29a7436ec6c5e19d2ed74ca5d078d4fbb18eb5" +checksum = "d03b3f31080df31be723b876709246f8f1e532e1c5b82efb5281d705c8304c63" dependencies = [ - "num-bigint", + "num-bigint 0.5.1", "p3-challenger", "p3-dft", "p3-field", @@ -3489,15 +3294,16 @@ dependencies = [ "p3-symmetric", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", + "spin 0.12.3", ] [[package]] name = "p3-keccak" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a7df174ff0c19a8742eb4698eaa1667c5f858d018e2faf09c55f1f24a6f9c3" +checksum = "ae50c8c37eb847c660298fb275e53c025c49b2623a8cfabf67f5322258b2b4db" dependencies = [ "p3-symmetric", "p3-util", @@ -3506,49 +3312,49 @@ dependencies = [ [[package]] name = "p3-matrix" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9c94c0714944e7b8a9a62e6340b1e3e1d3f8ecfd3e35c08798360200e73eff" +checksum = "473eb920c446a6f4536e0d3528fbdca2a23c0e24e1d0d7767452e6d385dd335c" dependencies = [ - "itertools", + "itertools 0.15.0", "p3-field", "p3-maybe-rayon", "p3-util", - "rand 0.10.1", + "rand 0.10.2", "serde", "tracing", ] [[package]] name = "p3-maybe-rayon" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebc233a34b1ab0273f35b4052fa2eeb3114b22ba4575bd7da00716e878ffb77" +checksum = "e6fddfd435f96394769414cf5590b77058aa506659bf20d6592e9d1989e04440" dependencies = [ "rayon", ] [[package]] name = "p3-mds" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b5441fa8116246ec9e6c835f15273cb27777ca572960ec87476b67fef13e01e" +checksum = "551ba0ab2cccd89f85a99450224898aff224e323bbf61f777ba6344f0896ef10" dependencies = [ "p3-dft", "p3-field", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-monty-31" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8724f330ea6d19dd4f2436aa0f88b5fcbf88f0f55ca7fccd3fea8b736dbcddad" +checksum = "871f635f7340cd0868b17e43e0c98fefdafdaed90469d0725caf6d8372a2a47c" dependencies = [ - "itertools", - "num-bigint", + "itertools 0.15.0", + "num-bigint 0.5.1", "p3-dft", "p3-field", "p3-matrix", @@ -3559,43 +3365,44 @@ dependencies = [ "p3-symmetric", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", - "spin 0.10.0", + "spin 0.12.3", "tracing", ] [[package]] name = "p3-poseidon1" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e2a562fea210baae390a32f9ecf0dd8724ae3f4352d1c8e413077b6f00a162" +checksum = "8d0d304e9a1f29c0d66534aa84e69528e2118351fdce08dcf5898af4e0fecc32" dependencies = [ "p3-field", + "p3-mds", "p3-symmetric", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-poseidon2" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06394851c161d17e4aa4ad2aad5557d32f14cadd1dc838f965d8e1821a63b8c5" +checksum = "43eb8a73a26d14becaed1c67c3e8a047e4311d7909b402383c82ca9643ba17c6" dependencies = [ "p3-field", "p3-mds", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-symmetric" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac1a276d421f8ef3361bb7d8c39a02c93c6b3f10eeaa559cc4c50222f9a5b82" +checksum = "2015ea80cad969b6aabf27a04884286fe1354393b166d968ee0d80a95126b2a4" dependencies = [ - "itertools", + "itertools 0.15.0", "p3-field", "p3-util", "serde", @@ -3603,13 +3410,40 @@ dependencies = [ [[package]] name = "p3-util" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d08a58162a4c264269ef454f0b28dcda89939490eecacb2b2cf5b00f719b80f6" +checksum = "6c5466fc40e6df89d3b291a2eff16b33e68e8571207790370137ec18090aadab" dependencies = [ "rayon", "serde", - "transpose", +] + +[[package]] +name = "parity-scale-codec" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "const_format", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "rustversion", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.119", ] [[package]] @@ -3639,83 +3473,28 @@ dependencies = [ name = "paste" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "path-absolutize" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4af381fe79fa195b4909485d99f73a80792331df0625188e707854f0b3383f5" -dependencies = [ - "path-dedot", -] - -[[package]] -name = "path-dedot" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07ba0ad7e047712414213ff67533e6dd477af0a4e1d14fb52343e53d30ea9397" -dependencies = [ - "once_cell", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "pest" -version = "2.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" -dependencies = [ - "memchr", - "ucd-trie", -] - -[[package]] -name = "pest_derive" -version = "2.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11f486f1ea21e6c10ed15d5a7c77165d0ee443402f0780849d1768e7d9d6fe77" -dependencies = [ - "pest", - "pest_generator", -] +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] -name = "pest_generator" -version = "2.8.6" +name = "pastey" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8040c4647b13b210a963c1ed407c1ff4fdfa01c31d6d2a098218702e6664f94f" -dependencies = [ - "pest", - "pest_meta", - "proc-macro2", - "quote", - "syn 2.0.117", -] +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" [[package]] -name = "pest_meta" -version = "2.8.6" +name = "percent-encoding" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89815c69d36021a140146f26659a81d6c2afa33d216d736dd4be5381a7362220" -dependencies = [ - "pest", - "sha2", -] +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] -name = "petgraph" -version = "0.7.1" +name = "pest" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" +checksum = "6d45aeb61b4bf818e12d4205f2466f8c4748f85f4fce0146d1c03d69d753f0ad" dependencies = [ - "fixedbitset", - "indexmap", + "memchr", + "ucd-trie", ] [[package]] @@ -3726,36 +3505,27 @@ checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" dependencies = [ "fixedbitset", "hashbrown 0.15.5", - "indexmap", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher", + "indexmap 2.14.2", ] [[package]] name = "pin-project" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.11" +version = "1.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -3766,9 +3536,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkcs8" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ "der", "spki", @@ -3776,32 +3546,31 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.33" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" +checksum = "f6b464fbc74e149a392436b17d523f769e057cb6877f6a5c4618bc6f11800548" [[package]] name = "poly1305" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +checksum = "6e2d0073b297041425c7c3df6eb4792d598a15323fe63346852b092eca02904c" dependencies = [ - "cpufeatures 0.2.17", - "opaque-debug", + "cpufeatures 0.3.1", "universal-hash", ] [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "portable-atomic-util" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" dependencies = [ "portable-atomic", ] @@ -3822,19 +3591,60 @@ dependencies = [ ] [[package]] -name = "precomputed-hash" -version = "0.1.1" +name = "prettyplease" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.119", +] [[package]] name = "prettyplease" -version = "0.2.37" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +checksum = "2bfe0f4c752e450fc2faf62654f1c134747922825d5b04ca717b8874f41a40c0" dependencies = [ "proc-macro2", - "syn 2.0.117", + "syn 3.0.5", +] + +[[package]] +name = "primefield" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c555a6e4eb7d4e158fcb028c835c3b8642206ddc279b5c6b202ef9a8bdb592f4" +dependencies = [ + "crypto-bigint", + "crypto-common 0.2.2", + "ff", + "rand_core 0.10.1", + "subtle", + "zeroize", +] + +[[package]] +name = "primeorder" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c9f42978c78a00e3d68f69fc03e57a234debae69da4020a4fb588fcdcd07b06" +dependencies = [ + "elliptic-curve", + "primefield", + "serdect", + "wnaf", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "uint 0.9.5", ] [[package]] @@ -3844,7 +3654,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "721a1da530b5a2633218dc9f75713394c983c352be88d2d7c9ee85e2c4c21794" dependencies = [ "fixed-hash", - "uint", + "uint 0.10.1", ] [[package]] @@ -3854,37 +3664,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" dependencies = [ "equivalent", - "indexmap", + "indexmap 2.14.2", "serde", ] [[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" +name = "proc-macro-crate" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error-attr3" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +checksum = "82366fd7d8b7a440d66d13418820c69df9b3908bcb1a0476d7f5ce5d12f5a04d" dependencies = [ "proc-macro2", "quote", ] [[package]] -name = "proc-macro-error2" -version = "2.0.1" +name = "proc-macro-error3" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +checksum = "b511283ea8a74b4b39447b128c5d00f03a356b7424554b13e298a5550100d9ac" dependencies = [ - "proc-macro-error-attr2", + "proc-macro-error-attr3", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -3895,10 +3714,10 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ - "bitflags", + "bitflags 2.13.1", "num-traits", - "rand 0.9.4", - "rand_chacha", + "rand 0.9.5", + "rand_chacha 0.9.0", "rand_xorshift", "regex-syntax", "unarray", @@ -3912,14 +3731,14 @@ checksum = "fb6dc647500e84a25a85b100e76c85b8ace114c209432dc174f20aac11d4ed6c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "prost" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +checksum = "528ac67416ff8646872a3c02cad9cc4ee5dc9f9540c9b10771855c95cb2e5ae1" dependencies = [ "bytes", "prost-derive", @@ -3927,45 +3746,45 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" +checksum = "03da047801ff44bb6a4d407d4860c05fd70bb81714e6b2f3812603d5b145b042" dependencies = [ "heck", - "itertools", + "itertools 0.14.0", "log", "multimap", - "petgraph 0.8.3", - "prettyplease", + "petgraph", + "prettyplease 0.2.37", "prost", "prost-types", "pulldown-cmark", "pulldown-cmark-to-cmark", "regex", - "syn 2.0.117", + "syn 2.0.119", "tempfile", ] [[package]] name = "prost-derive" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +checksum = "b570b25f7617e43d59005d0990ccb79e950a423952cea19671b7a876da390adf" dependencies = [ "anyhow", - "itertools", + "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "prost-reflect" -version = "0.16.3" +version = "0.16.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b89455ef41ed200cafc47c76c552ee7792370ac420497e551f16123a9135f76e" +checksum = "01b80ea363c31af2de2b92e3c07ed1156628f7838c4afb4df75ee78a37fedbd1" dependencies = [ - "logos 0.15.1", + "logos 0.16.1", "miette", "prost", "prost-types", @@ -3973,9 +3792,9 @@ dependencies = [ [[package]] name = "prost-types" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +checksum = "f94967dc7688f3054c7fac87473ffae4cc4c3904800e2d9f5b857246d8963b0a" dependencies = [ "prost", ] @@ -4013,7 +3832,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f5df7e552bc7edd075f5783a87fbfc21d6a546e32c16985679c488c18192d83" dependencies = [ - "indexmap", + "indexmap 2.14.2", "log", "priority-queue", "rustc-hash", @@ -4023,29 +3842,29 @@ dependencies = [ [[package]] name = "pulldown-cmark" -version = "0.13.3" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c3a14896dfa883796f1cb410461aef38810ea05f2b2c33c5aded3649095fdad" +checksum = "e9f068eba8e7071c5f9511831b44f32c740d5adf574e990f946ddb53db2f314e" dependencies = [ - "bitflags", + "bitflags 2.13.1", "memchr", "unicase", ] [[package]] name = "pulldown-cmark-to-cmark" -version = "22.0.0" +version = "22.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50793def1b900256624a709439404384204a5dc3a6ec580281bfaac35e882e90" +checksum = "ab1ad36992cead65f02aa399a373a42730922f1525d988172634fdefdecb8a60" dependencies = [ "pulldown-cmark", ] [[package]] name = "quote" -version = "1.0.45" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -4070,32 +3889,46 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" +checksum = "e058c7de0b26af77780c769414d6257830bb240f3c38477dbc2c16e5f54d6d4c" dependencies = [ + "libc", + "rand_chacha 0.3.1", "rand_core 0.6.4", ] [[package]] name = "rand" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ - "rand_chacha", + "rand_chacha 0.9.0", "rand_core 0.9.5", ] [[package]] name = "rand" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ + "chacha20", + "getrandom 0.4.3", "rand_core 0.10.1", ] +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + [[package]] name = "rand_chacha" version = "0.9.0" @@ -4106,6 +3939,16 @@ dependencies = [ "rand_core 0.9.5", ] +[[package]] +name = "rand_chacha" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e6af7f3e25ded52c41df4e0b1af2d047e45896c2f3281792ed68a1c243daedb" +dependencies = [ + "ppv-lite86", + "rand_core 0.10.1", +] + [[package]] name = "rand_core" version = "0.6.4" @@ -4130,15 +3973,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" -[[package]] -name = "rand_hc" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b363d4f6370f88d62bf586c80405657bde0f0e1b8945d47d2ad59b906cb4f54" -dependencies = [ - "rand_core 0.6.4", -] - [[package]] name = "rand_xorshift" version = "0.4.0" @@ -4150,20 +3984,11 @@ dependencies = [ [[package]] name = "rand_xoshiro" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" -dependencies = [ - "rand_core 0.6.4", -] - -[[package]] -name = "rand_xoshiro" -version = "0.7.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" +checksum = "662effc7698e08ea324d3acccf8d9d7f7bf79b9785e270a174ea36e56900c91d" dependencies = [ - "rand_core 0.9.5", + "rand_core 0.10.1", ] [[package]] @@ -4192,14 +4017,34 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags", + "bitflags 2.13.1", +] + +[[package]] +name = "ref-cast" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e440fb4e4b4147295338efb76001ab9e4efc0e5839df2c47fc5ac2381d365c3" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecd8964f8453721699a1ed72037b0db49ce2f5a5138486ee89bed6f67cdf3a" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.5", ] [[package]] name = "regex" -version = "1.12.3" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -4209,9 +4054,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -4220,18 +4065,18 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" +checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rfc6979" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +checksum = "b4a459cddafb3fe76b31fd8f1108007566c40301feb64dc7b54656eb7388172b" dependencies = [ + "crypto-bigint", "hmac", - "subtle", ] [[package]] @@ -4248,15 +4093,39 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + [[package]] name = "ruint" -version = "1.17.2" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c141e807189ad38a07276942c6623032d3753c8859c146104ac2e4d68865945a" +checksum = "f5e99bff0393163bb25029a6af25d3d8d202ba5b5438a74d1bd8789f5c822970" dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "ark-ff 0.5.0", + "ark-ff 0.6.0", + "bytes", + "fastrlp 0.3.1", + "fastrlp 0.4.0", + "num-bigint 0.4.8", + "num-integer", + "num-traits", + "parity-scale-codec", + "primitive-types 0.12.2", "proptest", - "rand 0.8.6", - "rand 0.9.4", + "rand 0.8.8", + "rand 0.9.5", + "rlp", "ruint-macro", "serde_core", "valuable", @@ -4275,7 +4144,7 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f" dependencies = [ - "bitflags", + "bitflags 2.13.1", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -4295,15 +4164,21 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" +checksum = "b74b56ffa8bb2830709a538c2cbcae9aa062db0d2a42563bfb09bdaae44020eb" [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" + +[[package]] +name = "rustc-hex" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" [[package]] name = "rustc_version" @@ -4314,6 +4189,15 @@ dependencies = [ "semver 0.9.0", ] +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + [[package]] name = "rustc_version" version = "0.4.1" @@ -4329,7 +4213,7 @@ version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags", + "bitflags 2.13.1", "errno", "libc", "linux-raw-sys", @@ -4338,9 +4222,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.38" +version = "0.23.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f9466fb2c14ea04357e91413efb882e2a6d4a406e625449bc0a5d360d53a21" +checksum = "6725596c3f2c3a0aef021139e145d4eafe314a6623e4680ca83852b2c67ab2ba" dependencies = [ "log", "once_cell", @@ -4353,9 +4237,9 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "612460d5f7bea540c490b2b6395d8e34a953e52b491accd6c86c8164c5932a63" +checksum = "dab5152771c58876a2146916e53e35057e1a4dfa2b9df0f0305b07f611fdea4d" dependencies = [ "openssl-probe", "rustls-pki-types", @@ -4365,18 +4249,18 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.14.0" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" +checksum = "2f4925028c7eb5d1fcdaf196971378ed9d2c1c4efc7dc5d011256f76c99c0a96" dependencies = [ "zeroize", ] [[package]] name = "rustls-webpki" -version = "0.103.12" +version = "0.103.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8279bb85272c9f10811ae6a6c547ff594d6a7f3c6c6b02ee9726d1d0dcfcdd06" +checksum = "f3c3cf1d8b1e7d4927e2d154c3fcb02979afb9939629c62cd9048d4f07b60ac2" dependencies = [ "ring", "rustls-pki-types", @@ -4385,24 +4269,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "ruzstd" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c1c839d570d835527c9a5e4db7cb2198683a988cb9d7293fc8674e6bd58fc8" -dependencies = [ - "twox-hash", -] - -[[package]] -name = "ryu" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "same-file" @@ -4422,6 +4291,30 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + [[package]] name = "scoped-tls" version = "1.0.1" @@ -4436,14 +4329,14 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sec1" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" dependencies = [ "base16ct", + "ctutils", "der", - "generic-array", - "pkcs8", + "hybrid-array", "subtle", "zeroize", ] @@ -4454,7 +4347,7 @@ version = "3.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7f4bc775c73d9a02cde8bf7b2ec4c9d12743edf609006c7facc23998404cd1d" dependencies = [ - "bitflags", + "bitflags 2.13.1", "core-foundation", "core-foundation-sys", "libc", @@ -4477,7 +4370,16 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" dependencies = [ - "semver-parser", + "semver-parser 0.7.0", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser 0.10.3", ] [[package]] @@ -4496,11 +4398,20 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" +[[package]] +name = "semver-parser" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" +dependencies = [ + "pest", +] + [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -4518,31 +4429,42 @@ dependencies = [ "typeid", ] +[[package]] +name = "serde-wincode" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa9d3a86c66cf10ce79df36f555a5a4c8d72a82515d9ea8ca420e02c925c30f" +dependencies = [ + "serde", + "thiserror", + "wincode", +] + [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.5", ] [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -4553,13 +4475,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.5", ] [[package]] @@ -4572,71 +4494,90 @@ dependencies = [ ] [[package]] -name = "sha2" -version = "0.10.9" +name = "serde_with" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "935177bb8c0cd8ca1a4e6d1a2ac8988bea69cab4f9d3a31311e012ad27868ea4" dependencies = [ - "cfg-if", - "cpufeatures 0.2.17", - "digest", + "base64 0.23.1", + "bs58", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.14.2", + "jiff", + "schemars 0.9.0", + "schemars 1.2.2", + "serde_core", + "serde_json", + "time", ] [[package]] -name = "sha3" -version = "0.10.9" +name = "serdect" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +checksum = "66cf8fedced2fcf12406bcb34223dffb92eaf34908ede12fed414c82b7f00b3e" dependencies = [ - "digest", - "keccak", + "base16ct", + "serde", ] [[package]] -name = "sharded-slab" -version = "0.1.7" +name = "sha2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ - "lazy_static", + "cfg-if", + "cpufeatures 0.3.1", + "digest 0.11.3", ] [[package]] -name = "shlex" -version = "1.3.0" +name = "sha3" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "be176f1a57ce4e3d31c1a166222d9768de5954f811601fb7ca06fc8203905ce1" +dependencies = [ + "digest 0.11.3", + "keccak", +] [[package]] -name = "signature" -version = "2.2.0" +name = "sha3" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "bc9bad02c26382724b2d2692c6f179285e4b54eeecd7968f52a50059c3c11759" dependencies = [ - "digest", - "rand_core 0.6.4", + "digest 0.11.3", + "keccak", + "sponge-cursor", ] [[package]] -name = "simd-adler32" -version = "0.3.9" +name = "sharded-slab" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] [[package]] -name = "siphasher" -version = "1.0.2" +name = "shlex" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2aa850e253778c88a04c3d7323b043aeda9d3e30d5971937c1855769763678e" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] -name = "sized-chunks" -version = "0.6.5" +name = "signature" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" dependencies = [ - "bitmaps", - "typenum", + "digest 0.11.3", + "rand_core 0.10.1", ] [[package]] @@ -4647,24 +4588,24 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.1" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +checksum = "b9be42f50aa861c555654aa3a37f52f4b1074bacf4e48fe0ef7fa584e80f1f0f" dependencies = [ "serde", ] [[package]] name = "smawk" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" +checksum = "e8e2fb0f499abb4d162f2bedad68f5ef91a1682b5a03596ddb67efd37768d100" [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4" dependencies = [ "libc", "windows-sys 0.61.2", @@ -4672,37 +4613,37 @@ dependencies = [ [[package]] name = "spin" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" dependencies = [ "lock_api", ] [[package]] name = "spin" -version = "0.10.0" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +checksum = "0134f9043ed38b087ac4f7d4af44c79e2c9e5094421fe3164f435ce585953b10" dependencies = [ "lock_api", ] [[package]] name = "spki" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" dependencies = [ "base64ct", "der", ] [[package]] -name = "stable_deref_trait" -version = "1.2.1" +name = "sponge-cursor" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" +checksum = "3a0219bd7d979d58245a4f41f695e1ac9f8befdffadd7f61f1bae9e39abc6620" [[package]] name = "static_assertions" @@ -4710,24 +4651,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "strength_reduce" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" - -[[package]] -name = "string_cache" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" -dependencies = [ - "new_debug_unreachable", - "parking_lot", - "phf_shared", - "precomputed-hash", -] - [[package]] name = "strip-ansi-escapes" version = "0.2.1" @@ -4783,9 +4706,20 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9" dependencies = [ "proc-macro2", "quote", @@ -4794,14 +4728,14 @@ dependencies = [ [[package]] name = "syn-solidity" -version = "1.5.7" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53f425ae0b12e2f5ae65542e00898d500d4d318b4baf09f40fd0d410454e9947" +checksum = "4c6415502cd1e9ed58b3ceb415164b812d5572757b1a6f0e280ae806723c1fab" dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -4817,10 +4751,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] -name = "target-triple" -version = "1.0.0" +name = "target-tuple" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" +checksum = "876fef147edbcbddc8ac5cbbba92c7b86519e314e86638596c09673b2ed01e7f" [[package]] name = "tempfile" @@ -4829,21 +4763,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.2", + "getrandom 0.4.3", "once_cell", "rustix", "windows-sys 0.61.2", ] -[[package]] -name = "term" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1" -dependencies = [ - "windows-sys 0.61.2", -] - [[package]] name = "termcolor" version = "1.4.1" @@ -4876,41 +4801,40 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.5", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] [[package]] name = "time" -version = "0.3.47" +version = "0.3.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" dependencies = [ "deranged", - "itoa", "num-conv", "powerfmt", "serde_core", @@ -4920,15 +4844,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" [[package]] name = "time-macros" -version = "0.2.27" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" dependencies = [ "num-conv", "time-core", @@ -4943,11 +4867,26 @@ dependencies = [ "crunchy", ] +[[package]] +name = "tinyvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cf0ded5c4e56918d8f8a339e1bb67d038d3bc6d144ac407904015ba2e4cde9b" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + [[package]] name = "tokio" -version = "1.52.1" +version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ "bytes", "libc", @@ -4960,20 +4899,20 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.7.0" +version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +checksum = "78773a2a397f451582ce068015985c33193cf6dea8b74d2a639fe457b2f07b0e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.5", ] [[package]] name = "tokio-rustls" -version = "0.26.4" +version = "0.26.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +checksum = "b0c85f2c3ef0b1cd58b36682f4b17aaa995f0e5db534d85692b4903abce21f67" dependencies = [ "rustls", "tokio", @@ -4981,9 +4920,9 @@ dependencies = [ [[package]] name = "tokio-stream" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32da49809aab5c3bc678af03902d4ccddea2a87d028d86392a4b1560c6906c70" +checksum = "a3d06f0b082ba57c26b79407372e57cf2a1e28124f78e9479fe80322cf53420b" dependencies = [ "futures-core", "pin-project-lite", @@ -4993,54 +4932,31 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.18" +version = "0.7.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +checksum = "494815d09bf52b5548659851081238f0ca39ff638363907596da739561c62c52" dependencies = [ "bytes", "futures-core", "futures-sink", + "libc", "pin-project-lite", "tokio", ] [[package]] name = "toml" -version = "0.9.12+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863" -dependencies = [ - "indexmap", - "serde_core", - "serde_spanned", - "toml_datetime 0.7.5+spec-1.1.0", - "toml_parser", - "toml_writer", - "winnow 0.7.15", -] - -[[package]] -name = "toml" -version = "1.1.2+spec-1.1.0" +version = "1.1.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +checksum = "12c0ba9680044b4ce98d391a62094047eada0d64860b80166c39f4a6b5640785" dependencies = [ - "indexmap", + "indexmap 2.14.2", "serde_core", "serde_spanned", - "toml_datetime 1.1.1+spec-1.1.0", + "toml_datetime", "toml_parser", "toml_writer", - "winnow 1.0.1", -] - -[[package]] -name = "toml_datetime" -version = "0.7.5+spec-1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" -dependencies = [ - "serde_core", + "winnow", ] [[package]] @@ -5054,42 +4970,39 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.12+spec-1.1.0" +version = "0.25.13+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" +checksum = "6975367e4d2ef766d86af01ffad14b622fecc8d4357a998fbc4deb6e9bacaf9b" dependencies = [ - "indexmap", - "serde_core", - "serde_spanned", - "toml_datetime 1.1.1+spec-1.1.0", + "indexmap 2.14.2", + "toml_datetime", "toml_parser", - "toml_writer", - "winnow 1.0.1", + "winnow", ] [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ - "winnow 1.0.1", + "winnow", ] [[package]] name = "toml_writer" -version = "1.1.1+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" [[package]] name = "tonic" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec7c61a0695dc1887c1b53952990f3ad2e3a31453e1f49f10e75424943a93ec" +checksum = "ac2a5518c70fa84342385732db33fb3f44bc4cc748936eb5833d2df34d6445ef" dependencies = [ "async-trait", - "base64", + "base64 0.22.1", "bytes", "h2", "http", @@ -5114,21 +5027,21 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1882ac3bf5ef12877d7ed57aad87e75154c11931c2ba7e6cde5e22d63522c734" +checksum = "c68f61875ac5293cf72e6c8cf0158086428c82c37229e98c840878f1706b0322" dependencies = [ - "prettyplease", + "prettyplease 0.2.37", "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "tonic-health" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4ff0636fef47afb3ec02818f5bceb4377b8abb9d6a386aeade18bd6212f8eb7" +checksum = "fcfab99db777fba2802f0dfa861d1628d1ae916fb199d29819941f139ae85082" dependencies = [ "prost", "tokio", @@ -5139,9 +5052,9 @@ dependencies = [ [[package]] name = "tonic-prost" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55376a0bbaa4975a3f10d009ad763d8f4108f067c7c2e74f3001fb49778d309" +checksum = "50849f68853be452acf590cde0b146665b8d507b3b8af17261df47e02c209ea0" dependencies = [ "bytes", "prost", @@ -5150,16 +5063,16 @@ dependencies = [ [[package]] name = "tonic-prost-build" -version = "0.14.5" +version = "0.14.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3144df636917574672e93d0f56d7edec49f90305749c668df5101751bb8f95a" +checksum = "654e5643eff75d7f8c99197ce1440ed19a3474eada74c12bbac488b2cafdae27" dependencies = [ - "prettyplease", + "prettyplease 0.2.37", "proc-macro2", "prost-build", "prost-types", "quote", - "syn 2.0.117", + "syn 2.0.119", "tempfile", "tonic-build", ] @@ -5170,7 +5083,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c0469c353de5f665c95f898074b5b004b500c6722214c3249f1dc79c0a2a3f6" dependencies = [ - "base64", + "base64 0.22.1", "byteorder", "bytes", "futures-util", @@ -5197,7 +5110,7 @@ checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", - "indexmap", + "indexmap 2.14.2", "pin-project-lite", "slab", "sync_wrapper", @@ -5239,7 +5152,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -5281,16 +5194,6 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "transpose" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" -dependencies = [ - "num-integer", - "strength_reduce", -] - [[package]] name = "try-lock" version = "0.2.5" @@ -5299,32 +5202,20 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" -version = "1.0.116" +version = "1.0.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c635f0191bd3a2941013e5062667100969f8c4e9cd787c14f977265d73616e" +checksum = "c0cabaa10be1917331a313866bd94526343e03c77bcf69144b62b072ad35d47c" dependencies = [ "dissimilar", "glob", "serde", "serde_derive", "serde_json", - "target-triple", + "target-tuple", "termcolor", - "toml 1.1.2+spec-1.1.0", + "toml", ] -[[package]] -name = "twox-hash" -version = "2.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" - -[[package]] -name = "typed-arena" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" - [[package]] name = "typeid" version = "1.0.3" @@ -5333,9 +5224,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "ucd-trie" @@ -5345,9 +5236,21 @@ checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" [[package]] name = "uint" -version = "0.10.0" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909988d098b2f738727b161a106cfc7cab00c539c2687a8836f8e565976fb53e" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "uint" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f9227a75a5a540a464c832ad4a4195dbdbecd8787610a56262721fde6f04f90" dependencies = [ "byteorder", "crunchy", @@ -5381,9 +5284,9 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-segmentation" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +checksum = "c6f5d3c3b1bf09027a88a6bc961fc00497d651009560b5463668dc81b0fa87a8" [[package]] name = "unicode-width" @@ -5405,12 +5308,12 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" dependencies = [ - "crypto-common", - "subtle", + "crypto-common 0.2.2", + "ctutils", ] [[package]] @@ -5488,27 +5391,18 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.3+wasi-0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" -dependencies = [ - "wit-bindgen 0.57.1", -] - -[[package]] -name = "wasip3" -version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +version = "1.0.4+wasi-0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +checksum = "b67efb37e106e55ce722a510d6b5f9c17f083e5fc79afc2badeb12cc313d9487" dependencies = [ - "wit-bindgen 0.51.0", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.118" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" +checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf" dependencies = [ "cfg-if", "once_cell", @@ -5519,9 +5413,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.68" +version = "0.4.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" +checksum = "6ef4c5d3d2cdf5c54f4231181768f5510842e350db025faf1f7163b1030ed928" dependencies = [ "js-sys", "wasm-bindgen", @@ -5529,9 +5423,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.118" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" +checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5539,58 +5433,26 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.118" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" +checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.117", + "syn 3.0.5", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.118" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" +checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e" dependencies = [ "unicode-ident", ] -[[package]] -name = "wasm-encoder" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" -dependencies = [ - "leb128fmt", - "wasmparser 0.244.0", -] - -[[package]] -name = "wasm-encoder" -version = "0.252.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8185ae345fa5687c054626ff9a50e7089797a343d9904d1dc9820eb4c4d3196f" -dependencies = [ - "leb128fmt", - "wasmparser 0.252.0", -] - -[[package]] -name = "wasm-metadata" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" -dependencies = [ - "anyhow", - "indexmap", - "wasm-encoder 0.244.0", - "wasmparser 0.244.0", -] - [[package]] name = "wasm-streams" version = "0.5.0" @@ -5604,88 +5466,11 @@ dependencies = [ "web-sys", ] -[[package]] -name = "wasmparser" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" -dependencies = [ - "bitflags", - "hashbrown 0.15.5", - "indexmap", - "semver 1.0.28", -] - -[[package]] -name = "wasmparser" -version = "0.248.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa4439c5eee9df71ee0c6efb37f63b1fcb1fec38f85f5142c54e7ed05d33091a" -dependencies = [ - "bitflags", - "indexmap", - "semver 1.0.28", -] - -[[package]] -name = "wasmparser" -version = "0.252.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3eb099dcadcde5be9eef55e3a337128efd4e44b4c93122487e4d2e4e1c6627c" -dependencies = [ - "bitflags", - "indexmap", - "semver 1.0.28", -] - -[[package]] -name = "wasmprinter" -version = "0.248.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b264a5410b008d4d199a92bf536eae703cbd614482fc1ec53831cf19e1c183" -dependencies = [ - "anyhow", - "termcolor", - "wasmparser 0.248.0", -] - -[[package]] -name = "wasmtime-internal-core" -version = "44.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedd3947487d0afdd37accb981466fcd60571e898004c8955111f88686581dfc" -dependencies = [ - "hashbrown 0.16.1", - "libm", -] - -[[package]] -name = "wast" -version = "252.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942a3449d6a593fccc111a6241c8df52bda168af30e40bf9580d4394d7374c65" -dependencies = [ - "bumpalo", - "leb128fmt", - "memchr", - "unicode-width 0.2.2", - "wasm-encoder 0.252.0", -] - -[[package]] -name = "wat" -version = "1.252.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c72a4ba7088f7bac94cf516e49882bdf97068904a563768cf249efc839ec42cb" -dependencies = [ - "wast", -] - [[package]] name = "web-sys" -version = "0.3.95" +version = "0.3.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" +checksum = "9fbddc4a036f00ec4f18c83445bd3115cb306a91da554919a099d9222fe4a7f8" dependencies = [ "js-sys", "wasm-bindgen", @@ -5700,6 +5485,18 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "wincode" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfc6339f1ba427bf7ad7c42403b28e524832ba2ddb5eef1bb2cc3b85db6b7b75" +dependencies = [ + "pastey", + "proc-macro2", + "quote", + "thiserror", +] + [[package]] name = "windows-core" version = "0.62.2" @@ -5721,7 +5518,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -5732,7 +5529,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] @@ -5843,28 +5640,13 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" - -[[package]] -name = "winnow" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" dependencies = [ "memchr", ] -[[package]] -name = "wit-bindgen" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" -dependencies = [ - "wit-bindgen-rust-macro", -] - [[package]] name = "wit-bindgen" version = "0.57.1" @@ -5872,82 +5654,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" [[package]] -name = "wit-bindgen-core" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" -dependencies = [ - "anyhow", - "heck", - "wit-parser", -] - -[[package]] -name = "wit-bindgen-rust" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" -dependencies = [ - "anyhow", - "heck", - "indexmap", - "prettyplease", - "syn 2.0.117", - "wasm-metadata", - "wit-bindgen-core", - "wit-component", -] - -[[package]] -name = "wit-bindgen-rust-macro" -version = "0.51.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" -dependencies = [ - "anyhow", - "prettyplease", - "proc-macro2", - "quote", - "syn 2.0.117", - "wit-bindgen-core", - "wit-bindgen-rust", -] - -[[package]] -name = "wit-component" -version = "0.244.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" -dependencies = [ - "anyhow", - "bitflags", - "indexmap", - "log", - "serde", - "serde_derive", - "serde_json", - "wasm-encoder 0.244.0", - "wasm-metadata", - "wasmparser 0.244.0", - "wit-parser", -] - -[[package]] -name = "wit-parser" -version = "0.244.0" +name = "wnaf" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +checksum = "795ca18b3fdb5e62bf982199278341ddcf7ebf7d32e25e212ad05d496e95f6fa" dependencies = [ - "anyhow", - "id-arena", - "indexmap", - "log", - "semver 1.0.28", - "serde", - "serde_derive", - "serde_json", - "unicode-xid", - "wasmparser 0.244.0", + "ff", + "group", + "hybrid-array", + "primefield", ] [[package]] @@ -5961,42 +5676,56 @@ dependencies = [ [[package]] name = "x25519-dalek" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +checksum = "e7e8131a03190127fb2263afc72b322ecadae46b6ff8c6f399ff5d02f5559af6" dependencies = [ "curve25519-dalek", - "rand_core 0.6.4", + "rand_core 0.10.1", ] [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "d35102a9f36d089ccae9e4c6802bc118be4487b80aaffc0ab4e0cf5ce92d2873" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "146c01f5ab44258da43cf276c74a2763db2ff3969c9c652c3f2de07041d0b2bc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.117", + "syn 2.0.119", ] [[package]] name = "zeroize" -version = "1.8.2" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/examples/miden-bank/Cargo.toml b/examples/miden-bank/Cargo.toml index 520e172e..2f551c3d 100644 --- a/examples/miden-bank/Cargo.toml +++ b/examples/miden-bank/Cargo.toml @@ -12,3 +12,7 @@ edition = "2021" [workspace.dependencies] + +# Keep local proving within the network reference-block window. +[profile.dev] +opt-level = 2 diff --git a/examples/miden-bank/README.md b/examples/miden-bank/README.md index fa2c5049..0846822b 100644 --- a/examples/miden-bank/README.md +++ b/examples/miden-bank/README.md @@ -9,10 +9,11 @@ Companion code for the **Building a Bank with Miden Rust** tutorial. Build all contracts: ```bash -cd contracts/bank-account && miden build -cd ../deposit-note && miden build -cd ../withdraw-request-note && miden build -cd ../init-tx-script && miden build +miden --version +(cd contracts/bank-account && miden build) +(cd contracts/deposit-note && miden build) +(cd contracts/withdraw-request-note && miden build) +(cd contracts/init-tx-script && miden build) ``` Run integration tests: @@ -25,3 +26,11 @@ cargo test -p integration - Rust (nightly, configured via `rust-toolchain.toml`) - [Miden CLI](https://docs.miden.xyz/builder/get-started/) (`midenup`) + +## Testnet and fees + +The `initialize` and `deposit` binaries target testnet. Each binary prints its new account ID and waits for a public P2ID containing native testnet tokens. Request the standard amount from the testnet faucet for that ID while the binary runs. The helper consumes the funding note, waits for commitment, and then continues. The bank includes `BasicWallet` so it can receive this note. No faucet request is made automatically. + +The deposit binary attaches 1,000 native base units to the deposit note. Both binaries wait for the transactions to be committed and verify the resulting storage before reporting success. The native development profile enables optimizations so local proving stays within the network reference-block window. + +The live bank uses `AuthSingleSig` with Falcon512Poseidon2. Its owner key is saved in `keystore/`, and the client signs bank transactions with that key. Keep this keystore when running the deposit binary against the bank. `NoAuth` is used only in the isolated MockChain tests; adding `BasicWallet` to a live bank without authentication would let anyone spend its vault assets. diff --git a/examples/miden-bank/contracts/bank-account/Cargo.lock b/examples/miden-bank/contracts/bank-account/Cargo.lock index cc5567e5..ed32a609 100644 --- a/examples/miden-bank/contracts/bank-account/Cargo.lock +++ b/examples/miden-bank/contracts/bank-account/Cargo.lock @@ -4,19 +4,19 @@ version = 4 [[package]] name = "aead" -version = "0.5.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +checksum = "1973cfbc1a2daf9cf550e74e1f088c28e7f7d8c1e1418fb6c9dc5184b7e84c99" dependencies = [ "crypto-common", - "generic-array", + "inout", ] [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] @@ -73,30 +73,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" - -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "arrayvec" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe" - -[[package]] -name = "ascii-canvas" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" -dependencies = [ - "term", -] +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] name = "autocfg" @@ -113,9 +98,9 @@ dependencies = [ [[package]] name = "base16ct" -version = "0.2.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" [[package]] name = "base64ct" @@ -129,30 +114,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bit-set" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" - [[package]] name = "bitflags" version = "1.3.2" @@ -161,31 +122,30 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.13.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "blake3" -version = "1.8.5" +version = "1.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce" +checksum = "6d9e454fc11f76977dc803893aff6304ed33d6a26efae8696573bea74baa27ae" dependencies = [ - "arrayref", "arrayvec", "cc", "cfg-if", "constant_time_eq", - "cpufeatures 0.3.0", + "cpufeatures", ] [[package]] name = "block-buffer" -version = "0.10.4" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -196,9 +156,9 @@ checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "cc" -version = "1.2.65" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" +checksum = "005ec2760ca554fae18df7a11195552ec576cd665632a881bc011d5bb2fd4d80" dependencies = [ "find-msvc-tools", "jobserver", @@ -214,39 +174,45 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chacha20" -version = "0.9.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" dependencies = [ "cfg-if", "cipher", - "cpufeatures 0.2.17", + "cpufeatures", + "rand_core 0.10.1", ] [[package]] name = "chacha20poly1305" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +checksum = "9b89e1c441e926b9c82a8d023f6e1b7ae0adcfaa7d621814e4d60789bac751cb" dependencies = [ "aead", "chacha20", "cipher", "poly1305", - "zeroize", ] [[package]] name = "cipher" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ + "block-buffer", "crypto-common", "inout", - "zeroize", ] +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "colorchoice" version = "1.0.5" @@ -255,9 +221,9 @@ checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "const-oid" -version = "0.9.6" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" [[package]] name = "constant_time_eq" @@ -266,19 +232,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" [[package]] -name = "cpufeatures" -version = "0.2.17" +name = "cpubits" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" [[package]] name = "cpufeatures" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" dependencies = [ "libc", ] @@ -291,9 +254,9 @@ checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-deque" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -301,18 +264,18 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" [[package]] name = "crunchy" @@ -322,35 +285,47 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" -version = "0.5.5" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +checksum = "1a52aa3fcda4e6302a9f48734f234d35d4721b96f8fe07d073f07ce9df4f0271" dependencies = [ - "generic-array", - "rand_core 0.6.4", + "cpubits", + "ctutils", + "hybrid-array", + "num-traits", + "rand_core 0.10.1", "subtle", "zeroize", ] [[package]] name = "crypto-common" -version = "0.1.7" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ - "generic-array", - "rand_core 0.6.4", - "typenum", + "hybrid-array", + "rand_core 0.10.1", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", + "subtle", ] [[package]] name = "curve25519-dalek" -version = "4.1.3" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "b5eed333089e2e1c1ac8c6c0398e5e2497b4c9926ca6d0365ed1e099afa5bc23" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures", "curve25519-dalek-derive", "digest", "fiat-crypto", @@ -367,14 +342,14 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "defmt" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6e524506490a1953d237cb87b1cfc1e46f88c18f10a22dfe0f507dc6bfc7f7f" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" dependencies = [ "bitflags 1.3.2", "defmt-macros", @@ -382,15 +357,14 @@ dependencies = [ [[package]] name = "defmt-macros" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a27770e9c8f719a79d8b638281f4d828f77d8fd61e0bd94451b9b85e576a0b" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" dependencies = [ "defmt-parser", - "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -404,9 +378,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.10" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "a878c850e9e421b20262e9b41f9c860e4785fa07541c266b62ff9d1ef998a80a" dependencies = [ "const-oid", "zeroize", @@ -430,19 +404,19 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "digest" -version = "0.10.7" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer", "const-oid", "crypto-common", - "subtle", + "ctutils", ] [[package]] @@ -453,9 +427,9 @@ checksum = "aeda16ab4059c5fd2a83f2b9c9e9c981327b18aa8e3b313f7e6563799d4f093e" [[package]] name = "ecdsa" -version = "0.16.9" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +checksum = "c0681a4fc24c767085329728d8dfba959af91228aa4610cca4f8ce317ba46ae0" dependencies = [ "der", "digest", @@ -463,13 +437,14 @@ dependencies = [ "rfc6979", "signature", "spki", + "zeroize", ] [[package]] name = "ed25519" -version = "2.2.3" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +checksum = "29fcf32e6c73d1079f83ab4d782de2d81620346a5f38c6237a86a22f8368980a" dependencies = [ "pkcs8", "signature", @@ -477,53 +452,46 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +checksum = "6ebaa1a2bf1290ab3bfe5a7b771d050ebffab2711c19a81691c683a5144a25de" dependencies = [ "curve25519-dalek", "ed25519", "serde", "sha2", + "signature", "subtle", "zeroize", ] [[package]] name = "either" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "elliptic-curve" -version = "0.13.8" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "9d65aa39b3a5c1c9c1b745c9a019234bb7a21b77abcb4f4d266d706e2d577d65" dependencies = [ "base16ct", "crypto-bigint", + "crypto-common", "digest", "ff", - "generic-array", "group", "hkdf", + "hybrid-array", "pkcs8", - "rand_core 0.6.4", + "rand_core 0.10.1", "sec1", "subtle", "zeroize", ] -[[package]] -name = "ena" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" -dependencies = [ - "log", -] - [[package]] name = "env_filter" version = "2.0.0" @@ -566,42 +534,33 @@ dependencies = [ [[package]] name = "ff" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +checksum = "a1f686ab92a9fb0eaf188f6c6c87b89490baa6fdb0db4544ba4dc47f7942489f" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "fixedbitset" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d" [[package]] name = "flume" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "spin 0.9.8", + "spin 0.9.9", ] [[package]] @@ -612,18 +571,18 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "fs-err" -version = "3.3.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fde052dbfc920003cfd2c8e2c6e6d4cc7c1091538c3a24226cec0665ab08c0" +checksum = "b91aa448ca50d7e79433bdf3ee8d99215430d2ec02ade5aefab2a073a1822e8a" dependencies = [ "autocfg", ] [[package]] name = "futures" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" dependencies = [ "futures-channel", "futures-core", @@ -635,9 +594,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -645,39 +604,38 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-io" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-sink" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-core", "futures-sink", "futures-task", "pin-project-lite", - "slab", ] [[package]] @@ -695,58 +653,46 @@ dependencies = [ "windows-result", ] -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - [[package]] name = "getrandom" -version = "0.2.17" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", - "js-sys", "libc", - "wasi", - "wasm-bindgen", + "r-efi 5.3.0", + "wasip2", ] [[package]] name = "getrandom" -version = "0.3.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", - "wasip2", + "r-efi 6.0.0", + "rand_core 0.10.1", "wasm-bindgen", ] [[package]] name = "glob" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" [[package]] name = "group" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] @@ -767,22 +713,33 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hkdf" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" dependencies = [ "hmac", ] [[package]] name = "hmac" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ "digest", ] +[[package]] +name = "hybrid-array" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17" +dependencies = [ + "subtle", + "typenum", + "zeroize", +] + [[package]] name = "id-arena" version = "2.3.0" @@ -797,9 +754,9 @@ checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" -version = "2.14.0" +version = "2.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" dependencies = [ "equivalent", "hashbrown", @@ -809,11 +766,11 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -824,9 +781,9 @@ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc" dependencies = [ "either", ] @@ -839,11 +796,12 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.29" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f877a98676d2fb664698d74cc6a51ce6c484ce8c770f05d0108ec9090aeb46" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" dependencies = [ "defmt", + "jiff-core", "jiff-static", "log", "portable-atomic", @@ -851,89 +809,69 @@ dependencies = [ "serde_core", ] +[[package]] +name = "jiff-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +dependencies = [ + "defmt", +] + [[package]] name = "jiff-static" -version = "0.2.29" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0666b5ab5ecaca213fc2a85b8c0083d9004e84ee2d5f9a7e0017aaf50986f25f" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" dependencies = [ + "jiff-core", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.103" +version = "0.3.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +checksum = "ce57d20d1ea864ce2ac172ab472d409214f4fd359f0b2a2775abdf522e2af99e" dependencies = [ "cfg-if", - "futures-util", "wasm-bindgen", ] [[package]] name = "k256" -version = "0.13.4" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +checksum = "93f50113171a713f4a4231ef82eb26703607139b35dcb56241f0ceab2ae1f7d8" dependencies = [ - "cfg-if", + "cpubits", "ecdsa", "elliptic-curve", - "once_cell", + "primeorder", "sha2", - "signature", + "wnaf", ] [[package]] name = "keccak" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" -dependencies = [ - "cpufeatures 0.2.17", -] - -[[package]] -name = "lalrpop" -version = "0.22.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" -dependencies = [ - "ascii-canvas", - "bit-set", - "ena", - "itertools", - "lalrpop-util", - "petgraph", - "regex", - "regex-syntax", - "sha3", - "string_cache", - "term", - "unicode-xid", - "walkdir", -] - -[[package]] -name = "lalrpop-util" -version = "0.22.2" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" +checksum = "d8f198d1db720e4940b5a493201d199d9f24f568f8f746bd13706243a2f71598" dependencies = [ - "rustversion", + "cfg-if", + "cpufeatures", ] [[package]] @@ -950,9 +888,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.186" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libm" @@ -971,9 +909,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "loom" @@ -999,15 +937,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.2" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "miden" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab74b8469fe68b32551bbd85943580800c1b5f2e4683c85ad3e88a628c4e28a7" +checksum = "d0cad08495d4826f7e40ee0cd69bc207f81cc5376844e1718ccb9a3e9e0ba0d6" dependencies = [ "miden-base", "miden-base-macros", @@ -1016,15 +954,17 @@ dependencies = [ "miden-field-repr", "miden-sdk-alloc", "miden-stdlib-sys", + "miden-tx-script-args", "wit-bindgen", ] [[package]] name = "miden-ace-codegen" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd45076fe4fef71f0f8b30aa0f018eb39c3086eeb5f3cafc0e12d60cd28339e" +checksum = "00ff2a44c7f7dc497ac56c74dca5b3465b4b46be066fa88c2c58a8eb1bcb2dc8" dependencies = [ + "miden-constraint-compiler", "miden-core", "miden-crypto", "thiserror", @@ -1032,24 +972,24 @@ dependencies = [ [[package]] name = "miden-air" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f1a80330b3e3d3f98e08817dc6a5e3d90d11ab5e88aa9c0dad5d3b4202598b" +checksum = "84b6d3f3336c8a2da5cd0924c42dd1f339e6c3d5adf3221bc1c005b444fd0bf0" dependencies = [ "miden-ace-codegen", "miden-core", "miden-crypto", - "miden-lifted-stark", "miden-utils-indexing", + "p3-field", "thiserror", "tracing", ] [[package]] name = "miden-assembly" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8582d184360be35eb2111a99245f556f43e1066ed09192fbcd0f218c466862a5" +checksum = "644b31bdda941328f9ff2088382b7de41569c1cc83d6090f63e43d261e9cd262" dependencies = [ "log", "miden-assembly-syntax", @@ -1064,14 +1004,12 @@ dependencies = [ [[package]] name = "miden-assembly-syntax" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffa307bc2cbd1f0cb74ed58981823f400a433900fb8f963762331fbb8389d5dc" +checksum = "cad0d5174833b17b498d541d1ef62d73929a143ea56ea5eba719339c15cd0968" dependencies = [ - "aho-corasick", - "lalrpop", - "lalrpop-util", "log", + "miden-assembly-syntax-cst", "miden-core", "miden-debug-types", "miden-utils-diagnostics", @@ -1085,11 +1023,23 @@ dependencies = [ "thiserror", ] +[[package]] +name = "miden-assembly-syntax-cst" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff301e56d9201821a4458564ed19ae9b95c7a219662a422e47bb61d17e0fa7b1" +dependencies = [ + "miden-debug-types", + "miden-rowan", + "miden-utils-diagnostics", + "thiserror", +] + [[package]] name = "miden-base" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2465a5ecd9546c354cbc6121ffe427cc5c7f98cbca08852049d11c675eb5a4b" +checksum = "5635698d03259fd13404b5376ae5f6c3b2d9e95918befd9ce0799de91e3b036a" dependencies = [ "miden-base-sys", "miden-stdlib-sys", @@ -1097,9 +1047,9 @@ dependencies = [ [[package]] name = "miden-base-macros" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a840ad62ba5264b33e460fbd530efacfc3dadca4d40534316ed50609e291e071" +checksum = "0d4e1fad0a94d307b223dd59e5a54c39615f4b48cd3b0e58670912fc404bd480" dependencies = [ "heck", "miden-assembly-syntax", @@ -1112,7 +1062,7 @@ dependencies = [ "proc-macro2", "quote", "semver 1.0.28", - "syn 2.0.118", + "syn 2.0.119", "toml", "wit-bindgen-core", "wit-bindgen-rust", @@ -1120,19 +1070,29 @@ dependencies = [ [[package]] name = "miden-base-sys" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "933380029fdc065398ae07af3ebdebd8fb425a74b4fe231d23774bbf00e11d67" +checksum = "8156d21c2e9f6755b82502045b775cb98c5d10f80ab957d9bcfde509aa32b8dc" dependencies = [ "miden-field-repr", "miden-stdlib-sys", ] +[[package]] +name = "miden-constraint-compiler" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01ef51ec02f0899c5fc6aa4af11eb050094d98e5e6bf8767a4da555d210f2de6" +dependencies = [ + "miden-core", + "miden-crypto", +] + [[package]] name = "miden-core" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80657c32850817f5f67dcf114866495a4b055531778b7c26d0602646ce777eb8" +checksum = "3b27f9f91988c5e74b50b543c4e6d37ec729eabcf70db63cf752dedd780f8a90" dependencies = [ "derive_more", "log", @@ -1142,34 +1102,46 @@ dependencies = [ "miden-utils-core-derive", "miden-utils-indexing", "miden-utils-sync", - "num-derive", - "num-traits", "serde", "thiserror", ] [[package]] name = "miden-core-lib" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16410655f32f98537afc9ddf57b71cb6d1ca9d980da5f4eea164cafcaf891b2e" +checksum = "14df9652fc4963f20d11df9ceb576ccb7831b5dc72fabec5c1b602f51e57909c" dependencies = [ "env_logger", "fs-err", "miden-assembly", + "miden-assembly-syntax", "miden-core", + "miden-core-lib-codegen", "miden-crypto", + "miden-mast-package", "miden-package-registry", + "miden-precompiles", "miden-processor", "miden-utils-sync", "thiserror", ] +[[package]] +name = "miden-core-lib-codegen" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aad0b8badcf1636150cac0d74aabadd395ba7d570227eb0923ff14f02a278fff" +dependencies = [ + "miden-core", + "miden-precompiles", +] + [[package]] name = "miden-crypto" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35198bebd353cddc25ad4aafb5f4ef9e71b283d71c787b8938c575c16974135d" +checksum = "7c917b0342d911ae4b7a549bb3ca791c093dac4770f88b02e23b43f3fa8179f5" dependencies = [ "blake3", "cc", @@ -1196,10 +1168,8 @@ dependencies = [ "p3-maybe-rayon", "p3-symmetric", "p3-util", - "rand 0.9.4", - "rand_chacha", - "rand_core 0.9.5", - "rand_hc", + "rand 0.10.2", + "rand_chacha 0.10.0", "serde", "sha2", "sha3", @@ -1210,19 +1180,19 @@ dependencies = [ [[package]] name = "miden-crypto-derive" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9068c6554db0e051f62913575de9949841a46b96ae92d4b7d28e1fed5d8f052b" +checksum = "a7c3165dfd7fd6f587ea5731efd1cc8083ca55c23d2d9b3000f83a3948486044" dependencies = [ "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "miden-debug-types" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956708ccb2f643db398b4b3d4f8d0baf199b1bfb5e34c8be1cd1bc811c005e8e" +checksum = "4c9f3f8e4a8f54a36fbf00330ac8bd1947627c1786cd49b94a08b741590ed173" dependencies = [ "memchr", "miden-crypto", @@ -1235,22 +1205,23 @@ dependencies = [ "serde", "serde_spanned", "thiserror", + "zerocopy", ] [[package]] name = "miden-field" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379a39db52cd932a95d4017a18b712ee53ed0f86cfedf8c63ed72d687a18a191" +checksum = "58cf9de55b88ec86ad272ff4224d76b3e0cbda49e242e78776b0037ba9b0e857" dependencies = [ "miden-serde-utils", - "num-bigint", + "num-bigint 0.5.1", "p3-challenger", "p3-field", "p3-goldilocks", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", "subtle", "thiserror", @@ -1258,9 +1229,9 @@ dependencies = [ [[package]] name = "miden-field-repr" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed71d35f511b703d1620094fcc748cb9383dbf2bd7b304d0b28c506a354acdf" +checksum = "93e13ffca1264db045cc344e573f9460bd0153aa89b755fac454b9070b953cdc" dependencies = [ "miden-field", "miden-field-repr-derive", @@ -1268,13 +1239,13 @@ dependencies = [ [[package]] name = "miden-field-repr-derive" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37e87fe1408b7ebc083614469b761a29c5749a34072b0e33dd4cbdd8d34766c" +checksum = "bf0e54de280a41e83a99caa16b3ffb8670c857c888d3e245920e8a96f42fad58" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1288,11 +1259,12 @@ dependencies = [ [[package]] name = "miden-lifted-air" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789e0e469d1731012d8a018057317f31580611535c20d2a47c022213228cb733" +checksum = "f67e06d47e246db853a9f3e52ec87fa33a8ffc0fe5be0dd99288b2439312f206" dependencies = [ "p3-air", + "p3-challenger", "p3-field", "p3-matrix", "p3-util", @@ -1301,9 +1273,9 @@ dependencies = [ [[package]] name = "miden-lifted-stark" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f62cca91182917b22a47e150028b7c785df620a15b2974a39c64e2b1b7a889d3" +checksum = "a5ee320597c7712698d06811d9144b0e4f2275a21224ef0238652c947b01198b" dependencies = [ "miden-lifted-air", "miden-stark-transcript", @@ -1316,7 +1288,7 @@ dependencies = [ "p3-maybe-rayon", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", "serde", "thiserror", "tracing", @@ -1324,15 +1296,20 @@ dependencies = [ [[package]] name = "miden-mast-package" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f37c21836b40785ce297d363c57740d4e33edcc411f84185a524eddadd5f53c7" +checksum = "1355a2563a52af4399b4a93120a4398f81415b1fc4edb58310de5034cfa3781d" dependencies = [ + "hashbrown", + "log", "miden-assembly-syntax", "miden-core", "miden-debug-types", + "miden-utils-indexing", + "rustc-hash", "serde", "thiserror", + "zerocopy", ] [[package]] @@ -1351,9 +1328,9 @@ dependencies = [ "rustc_version 0.2.3", "rustversion", "serde_json", - "spin 0.9.8", + "spin 0.9.9", "strip-ansi-escapes", - "syn 2.0.118", + "syn 2.0.119", "textwrap", "thiserror", "trybuild", @@ -1368,14 +1345,14 @@ checksum = "86a905f3ea65634dd4d1041a4f0fd0a3e77aa4118341d265af1a94339182222f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "miden-package-registry" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ece6064beb0582d1c64ba30d0c548c4b7a45f87abae6d69e22fd49c8b343258" +checksum = "a799e66245492c193b0444c3e0ff0fe42418009ec668a3e80c40d9f5b1454aac" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -1387,16 +1364,50 @@ dependencies = [ "thiserror", ] +[[package]] +name = "miden-precompiles" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "073ebeeb4413b9a03c60b0b066f94b8edaa6f50150017a92dc09d3ace92d6976" +dependencies = [ + "miden-core", + "miden-crypto", +] + +[[package]] +name = "miden-precompiles-prover" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76663c4d90cc073f9e2d2aa2349b9dcd25bf6c40db5020d27ce59990b6bd5af" +dependencies = [ + "miden-air", + "miden-core", + "miden-crypto", + "miden-lifted-air", + "miden-lifted-stark", + "miden-precompiles", + "miden-serde-utils", + "ruint", + "serde", + "serde-wincode", + "thiserror", + "tracing", + "wincode", +] + [[package]] name = "miden-processor" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea972ca9e45dbf26aa396367e8508db0f7292adea6f6ddf8d39d0e334285fe2b" +checksum = "2c7331ab96f00f922d29e2f59285f539299061a44ffdeea31b853d2c071f8056" dependencies = [ + "hashbrown", "itertools", "miden-air", "miden-core", "miden-debug-types", + "miden-mast-package", + "miden-precompiles", "miden-utils-diagnostics", "miden-utils-indexing", "paste", @@ -1407,9 +1418,9 @@ dependencies = [ [[package]] name = "miden-project" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5320e7e5b562359bd6161ac752dfe43dd4f69bb06e87f94a21a27bb656e5a20d" +checksum = "6f8201d3a6d0c85c747092309c3c420de42e61e76f71df2189a46411100d120a" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -1424,13 +1435,13 @@ dependencies = [ [[package]] name = "miden-protocol" -version = "0.15.3" +version = "0.16.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66340243e37da5936cb278a8dd11037813f1dc6731c2fc866703b76ed465ebc3" +checksum = "e275feebbe9c2458c5877c5f2a03b8e2152831ce956376f015fc4c50acfffb50" dependencies = [ "bech32", "fs-err", - "getrandom 0.3.4", + "getrandom 0.4.3", "miden-assembly", "miden-assembly-syntax", "miden-core", @@ -1438,37 +1449,65 @@ dependencies = [ "miden-crypto", "miden-crypto-derive", "miden-mast-package", + "miden-package-registry", "miden-processor", + "miden-protocol-build-utils", "miden-utils-sync", "miden-verifier", - "rand 0.9.4", + "rand 0.10.2", "regex", "semver 1.0.28", "thiserror", +] + +[[package]] +name = "miden-protocol-build-utils" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d16cdd96c1d0b3b2d57342d37eaadd15cc7c633bda965fc8c3b23ca249965b4" +dependencies = [ + "fs-err", + "miden-assembly", + "miden-core", + "miden-mast-package", + "miden-package-registry", + "miden-project", + "regex", "walkdir", ] +[[package]] +name = "miden-rowan" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13695bf99aabaa21d6572b807c66bb26251aa3d9b75e828b3c99b97a3b1ce7e" +dependencies = [ + "hashbrown", + "rustc-hash", +] + [[package]] name = "miden-sdk-alloc" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ee9eb34cde96e3158c19e22fedddb03b6e5eb363e272d11cbae9aa963cc315" +checksum = "15deb9ba073e632ca1151fcf7b718227294b750a7be9ac0c655d5ae7f2a6dc43" [[package]] name = "miden-serde-utils" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78cd1d4fcad937312e544f7d53423485e453598aa4fb989d2b6374027a8c136" +checksum = "f5c21a2acdc1928f86803b3ff3c44564c3f614a7dc47dcd64969a5c856d27988" dependencies = [ "p3-field", "p3-goldilocks", + "wincode", ] [[package]] name = "miden-stark-transcript" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05901db2e30d3954243960fe21cea7fbec39f97c27774b56fd5031c28c4881ba" +checksum = "d503630c353389838fa5d668a0d4550130453c7b2a72b802d4adc1ea39ab5bee" dependencies = [ "p3-challenger", "p3-field", @@ -1478,9 +1517,9 @@ dependencies = [ [[package]] name = "miden-stateful-hasher" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faeb47a90c55c5d45051d23cf691588804dd531995b4582c79108b64e445a905" +checksum = "e8c2008195bdb552eeb744074bfc8822049552ccdf7aef3321a32e1ab6be92e6" dependencies = [ "p3-field", "p3-symmetric", @@ -1488,18 +1527,29 @@ dependencies = [ [[package]] name = "miden-stdlib-sys" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "015cb758041aeaae5b2e5062af67459fb71cdacd199838a4a43795eb82f9a11d" +checksum = "152e858a662e3c4524e06becfb98d6727ec7cbc9d51cf9bb8b8bea9e17af5072" dependencies = [ "miden-field", ] +[[package]] +name = "miden-tx-script-args" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c32d126b51f111ff9e8aed25d1ccefc0e3e093b361b88b51e1ab2fd70f96a7" +dependencies = [ + "miden-field", + "miden-field-repr", + "miden-stdlib-sys", +] + [[package]] name = "miden-utils-core-derive" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0b1ee4662beb049a824e11bb21f95a79746c52874967983c9999f1b19a2f471" +checksum = "107d04fcd05b0308e6347113ee6dc13599755e5b4d05ecc08d8b5c05f36a5a39" dependencies = [ "proc-macro2", "quote", @@ -1508,11 +1558,10 @@ dependencies = [ [[package]] name = "miden-utils-diagnostics" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fdc1cd4eda372e1c4b99b9c3677e9b1f87a4d2e362a9f4b8f904273d395efc9" +checksum = "f3b444d204bf082cdab14015ff10d5b0b43a10fba662fef09e4753f6d07faf1f" dependencies = [ - "miden-crypto", "miden-debug-types", "miden-miette", "tracing", @@ -1520,11 +1569,11 @@ dependencies = [ [[package]] name = "miden-utils-indexing" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31444125649f4dad9cde647f614309b6be4f918fed276ada4eb99c01e8b9ca7" +checksum = "f6ff225060e2a5cc4dd6c898eef1f04739461d3401b6de1692bf443cfdd302b0" dependencies = [ - "miden-crypto", + "miden-serde-utils", "proptest", "serde", "thiserror", @@ -1532,9 +1581,9 @@ dependencies = [ [[package]] name = "miden-utils-sync" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "807c8ae625b7652ae7246b225c907c05da72927c31a0fd71c835c4f80931e92e" +checksum = "76b9cb00f01787f8687447cd8a45b3888b470eb35a132df1be9729779d311fd7" dependencies = [ "lock_api", "loom", @@ -1544,34 +1593,37 @@ dependencies = [ [[package]] name = "miden-verifier" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec5556dac919a1c13edeb2bd7181fc6a4c2ce52764a3e518bcdcd9ed48e5b38e" +checksum = "5e049df6008af1fea5a66df8ce98075cc9e00f16122fd5f4e7c4be9a263cae46" dependencies = [ - "bincode", "miden-air", "miden-core", "miden-crypto", + "miden-precompiles", + "miden-precompiles-prover", + "miden-serde-utils", "serde", + "serde-wincode", "thiserror", - "tracing", ] [[package]] name = "midenc-frontend-wasm-metadata" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3303cecb0858b92395b5c3710d52aae96d28e12f13966208731712e83803d" +checksum = "be2bc4e14ad915ca2b51b521bffbfc91bee1b94520277db144b27bd111cd60a7" dependencies = [ + "miden-mast-package", "serde", "serde_json", ] [[package]] name = "midenc-hir-type" -version = "0.6.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff0511aa2201f7098995e38a3c97a319d379c3b2d26fb83677b21b71f61a7b4" +checksum = "dcdf2257de8f3486c8f3e93c45219b782bafad62a8694798c05d5b8f3f79c64e" dependencies = [ "miden-formatting", "miden-serde-utils", @@ -1581,21 +1633,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom 0.2.17", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -1611,7 +1648,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "num-bigint", + "num-bigint 0.4.8", "num-complex", "num-integer", "num-iter", @@ -1621,50 +1658,48 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" dependencies = [ "num-integer", "num-traits", ] [[package]] -name = "num-complex" -version = "0.4.6" +name = "num-bigint" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +checksum = "93e7820bc0a80a0238e650327316f929ba18d5be054b647490a3a6a339f3e7c0" dependencies = [ + "num-integer", "num-traits", ] [[package]] -name = "num-derive" -version = "0.4.2" +name = "num-complex" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", + "num-traits", ] [[package]] name = "num-integer" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" dependencies = [ "num-traits", ] [[package]] name = "num-iter" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -1675,7 +1710,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "num-bigint", + "num-bigint 0.4.8", "num-integer", "num-traits", ] @@ -1706,23 +1741,17 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "owo-colors" -version = "4.3.0" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" +checksum = "13c45bb4a6ae1280ec0803b1ef9d3455eb50f01efbbe1447ab020f1d54fba9d8" [[package]] name = "p3-air" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c824e8d7c7ddf208b742eac8d48e0b2d52d22fa013578a7762bf6931dbab1f46" +checksum = "ddb1be05c0d6f691afe0c9f468018a9a37cfa904dee78a8081ec96eb3cdd88e8" dependencies = [ "p3-field", "p3-matrix", @@ -1731,9 +1760,9 @@ dependencies = [ [[package]] name = "p3-blake3" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2733229a713bd83ccf5eb749e8f8e7380c1052674394a25c0422a772204a20af" +checksum = "6f202f5fbcceb6f56f783d98efb5de27e5a171470e3364de97b0923b39c87ab5" dependencies = [ "blake3", "p3-symmetric", @@ -1742,9 +1771,9 @@ dependencies = [ [[package]] name = "p3-challenger" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8972ccd1d5dc90e46cdb1f2ab4ee2bae49b3917e5e98aa533f0c2b779c010445" +checksum = "84d5d5e1ecf2c80b09b48ce870e8abd08b643454101c5dc9d0fd71bfbd78224d" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -1756,42 +1785,42 @@ dependencies = [ [[package]] name = "p3-dft" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17771aca44632f9cc11f2718d7ea7ec06794946c4190ef3a985bfc893f14c18a" +checksum = "4321a952da2721ecd85ca593ea189798dfb4e439a2cc1378ce1442091880f173" dependencies = [ "itertools", "p3-field", "p3-matrix", "p3-maybe-rayon", "p3-util", - "spin 0.10.0", + "spin 0.12.3", "tracing", ] [[package]] name = "p3-field" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3eb24d0591fd4d282d89cbe4e4efba5571c699375006f80b2cbf53ce83461c" +checksum = "53db75d38e04fc255826f388eca9d05976733dc9754aa3db411bc9ea1a37c1a0" dependencies = [ "itertools", - "num-bigint", + "num-bigint 0.5.1", "p3-maybe-rayon", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", "tracing", ] [[package]] name = "p3-goldilocks" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5751c6591a0d2397d726620c2c29a7436ec6c5e19d2ed74ca5d078d4fbb18eb5" +checksum = "d03b3f31080df31be723b876709246f8f1e532e1c5b82efb5281d705c8304c63" dependencies = [ - "num-bigint", + "num-bigint 0.5.1", "p3-challenger", "p3-dft", "p3-field", @@ -1801,15 +1830,16 @@ dependencies = [ "p3-symmetric", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", + "spin 0.12.3", ] [[package]] name = "p3-keccak" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a7df174ff0c19a8742eb4698eaa1667c5f858d018e2faf09c55f1f24a6f9c3" +checksum = "ae50c8c37eb847c660298fb275e53c025c49b2623a8cfabf67f5322258b2b4db" dependencies = [ "p3-symmetric", "p3-util", @@ -1818,46 +1848,46 @@ dependencies = [ [[package]] name = "p3-matrix" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9c94c0714944e7b8a9a62e6340b1e3e1d3f8ecfd3e35c08798360200e73eff" +checksum = "473eb920c446a6f4536e0d3528fbdca2a23c0e24e1d0d7767452e6d385dd335c" dependencies = [ "itertools", "p3-field", "p3-maybe-rayon", "p3-util", - "rand 0.10.1", + "rand 0.10.2", "serde", "tracing", ] [[package]] name = "p3-maybe-rayon" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebc233a34b1ab0273f35b4052fa2eeb3114b22ba4575bd7da00716e878ffb77" +checksum = "e6fddfd435f96394769414cf5590b77058aa506659bf20d6592e9d1989e04440" [[package]] name = "p3-mds" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b5441fa8116246ec9e6c835f15273cb27777ca572960ec87476b67fef13e01e" +checksum = "551ba0ab2cccd89f85a99450224898aff224e323bbf61f777ba6344f0896ef10" dependencies = [ "p3-dft", "p3-field", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-monty-31" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8724f330ea6d19dd4f2436aa0f88b5fcbf88f0f55ca7fccd3fea8b736dbcddad" +checksum = "871f635f7340cd0868b17e43e0c98fefdafdaed90469d0725caf6d8372a2a47c" dependencies = [ "itertools", - "num-bigint", + "num-bigint 0.5.1", "p3-dft", "p3-field", "p3-matrix", @@ -1868,41 +1898,42 @@ dependencies = [ "p3-symmetric", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", - "spin 0.10.0", + "spin 0.12.3", "tracing", ] [[package]] name = "p3-poseidon1" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e2a562fea210baae390a32f9ecf0dd8724ae3f4352d1c8e413077b6f00a162" +checksum = "8d0d304e9a1f29c0d66534aa84e69528e2118351fdce08dcf5898af4e0fecc32" dependencies = [ "p3-field", + "p3-mds", "p3-symmetric", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-poseidon2" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06394851c161d17e4aa4ad2aad5557d32f14cadd1dc838f965d8e1821a63b8c5" +checksum = "43eb8a73a26d14becaed1c67c3e8a047e4311d7909b402383c82ca9643ba17c6" dependencies = [ "p3-field", "p3-mds", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-symmetric" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac1a276d421f8ef3361bb7d8c39a02c93c6b3f10eeaa559cc4c50222f9a5b82" +checksum = "2015ea80cad969b6aabf27a04884286fe1354393b166d968ee0d80a95126b2a4" dependencies = [ "itertools", "p3-field", @@ -1912,12 +1943,11 @@ dependencies = [ [[package]] name = "p3-util" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d08a58162a4c264269ef454f0b28dcda89939490eecacb2b2cf5b00f719b80f6" +checksum = "6c5466fc40e6df89d3b291a2eff16b33e68e8571207790370137ec18090aadab" dependencies = [ "serde", - "transpose", ] [[package]] @@ -1950,23 +1980,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] -name = "petgraph" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" -dependencies = [ - "fixedbitset", - "indexmap", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" +name = "pastey" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher", -] +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" [[package]] name = "pin-project-lite" @@ -1976,9 +1993,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkcs8" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ "der", "spki", @@ -1986,26 +2003,25 @@ dependencies = [ [[package]] name = "poly1305" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +checksum = "6e2d0073b297041425c7c3df6eb4792d598a15323fe63346852b092eca02904c" dependencies = [ - "cpufeatures 0.2.17", - "opaque-debug", + "cpufeatures", "universal-hash", ] [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "portable-atomic-util" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" dependencies = [ "portable-atomic", ] @@ -2019,12 +2035,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - [[package]] name = "prettyplease" version = "0.2.37" @@ -2032,47 +2042,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] -name = "priority-queue" -version = "2.7.0" +name = "primefield" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" +checksum = "c555a6e4eb7d4e158fcb028c835c3b8642206ddc279b5c6b202ef9a8bdb592f4" dependencies = [ - "equivalent", - "indexmap", - "serde", + "crypto-bigint", + "crypto-common", + "ff", + "rand_core 0.10.1", + "subtle", + "zeroize", ] [[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" +name = "primeorder" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +checksum = "5c9f42978c78a00e3d68f69fc03e57a234debae69da4020a4fb588fcdcd07b06" dependencies = [ - "proc-macro2", - "quote", + "elliptic-curve", + "primefield", + "serdect", + "wnaf", ] [[package]] -name = "proc-macro-error2" -version = "2.0.1" +name = "priority-queue" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" dependencies = [ - "proc-macro-error-attr2", - "proc-macro2", - "quote", - "syn 2.0.118", + "equivalent", + "indexmap", + "serde", ] [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -2083,10 +2097,10 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.1", "num-traits", - "rand 0.9.4", - "rand_chacha", + "rand 0.9.5", + "rand_chacha 0.9.0", "rand_xorshift", "regex-syntax", "unarray", @@ -2108,9 +2122,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.46" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -2121,22 +2135,30 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "rand" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ - "rand_chacha", + "rand_chacha 0.9.0", "rand_core 0.9.5", ] [[package]] name = "rand" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ + "chacha20", + "getrandom 0.4.3", "rand_core 0.10.1", ] @@ -2151,12 +2173,13 @@ dependencies = [ ] [[package]] -name = "rand_core" -version = "0.6.4" +name = "rand_chacha" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "3e6af7f3e25ded52c41df4e0b1af2d047e45896c2f3281792ed68a1c243daedb" dependencies = [ - "getrandom 0.2.17", + "ppv-lite86", + "rand_core 0.10.1", ] [[package]] @@ -2174,15 +2197,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" -[[package]] -name = "rand_hc" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b363d4f6370f88d62bf586c80405657bde0f0e1b8945d47d2ad59b906cb4f54" -dependencies = [ - "rand_core 0.6.4", -] - [[package]] name = "rand_xorshift" version = "0.4.0" @@ -2218,14 +2232,14 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.1", ] [[package]] name = "regex" -version = "1.12.4" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -2235,9 +2249,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -2252,19 +2266,34 @@ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rfc6979" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +checksum = "b4a459cddafb3fe76b31fd8f1108007566c40301feb64dc7b54656eb7388172b" dependencies = [ + "crypto-bigint", "hmac", - "subtle", ] +[[package]] +name = "ruint" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e99bff0393163bb25029a6af25d3d8d202ba5b5438a74d1bd8789f5c822970" +dependencies = [ + "ruint-macro", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustc_version" @@ -2286,9 +2315,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "same-file" @@ -2313,14 +2342,14 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sec1" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" dependencies = [ "base16ct", + "ctutils", "der", - "generic-array", - "pkcs8", + "hybrid-array", "subtle", "zeroize", ] @@ -2352,9 +2381,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -2372,31 +2401,42 @@ dependencies = [ "typeid", ] +[[package]] +name = "serde-wincode" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa9d3a86c66cf10ce79df36f555a5a4c8d72a82515d9ea8ca420e02c925c30f" +dependencies = [ + "serde", + "thiserror", + "wincode", +] + [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", ] [[package]] name = "serde_json" -version = "1.0.150" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -2407,13 +2447,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", ] [[package]] @@ -2425,25 +2465,36 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serdect" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66cf8fedced2fcf12406bcb34223dffb92eaf34908ede12fed414c82b7f00b3e" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "sha2" -version = "0.10.9" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures", "digest", ] [[package]] name = "sha3" -version = "0.10.9" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +checksum = "bc9bad02c26382724b2d2692c6f179285e4b54eeecd7968f52a50059c3c11759" dependencies = [ "digest", "keccak", + "sponge-cursor", ] [[package]] @@ -2463,31 +2514,19 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signature" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" dependencies = [ "digest", - "rand_core 0.6.4", + "rand_core 0.10.1", ] -[[package]] -name = "siphasher" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" - -[[package]] -name = "slab" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - [[package]] name = "smallvec" -version = "1.15.2" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +checksum = "b9be42f50aa861c555654aa3a37f52f4b1074bacf4e48fe0ef7fa584e80f1f0f" dependencies = [ "serde", ] @@ -2500,49 +2539,37 @@ checksum = "e8e2fb0f499abb4d162f2bedad68f5ef91a1682b5a03596ddb67efd37768d100" [[package]] name = "spin" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" dependencies = [ "lock_api", ] [[package]] name = "spin" -version = "0.10.0" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +checksum = "0134f9043ed38b087ac4f7d4af44c79e2c9e5094421fe3164f435ce585953b10" dependencies = [ "lock_api", ] [[package]] name = "spki" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" dependencies = [ "base64ct", "der", ] [[package]] -name = "strength_reduce" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" - -[[package]] -name = "string_cache" -version = "0.8.9" +name = "sponge-cursor" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" -dependencies = [ - "new_debug_unreachable", - "parking_lot", - "phf_shared", - "precomputed-hash", -] +checksum = "3a0219bd7d979d58245a4f41f695e1ac9f8befdffadd7f61f1bae9e39abc6620" [[package]] name = "strip-ansi-escapes" @@ -2572,9 +2599,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.118" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" dependencies = [ "proc-macro2", "quote", @@ -2582,19 +2609,21 @@ dependencies = [ ] [[package]] -name = "target-triple" -version = "1.0.0" +name = "syn" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" +checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] -name = "term" -version = "1.2.1" +name = "target-tuple" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1" -dependencies = [ - "windows-sys", -] +checksum = "876fef147edbcbddc8ac5cbbba92c7b86519e314e86638596c09673b2ed01e7f" [[package]] name = "termcolor" @@ -2618,29 +2647,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] @@ -2656,9 +2685,9 @@ dependencies = [ [[package]] name = "toml" -version = "1.1.2+spec-1.1.0" +version = "1.1.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +checksum = "12c0ba9680044b4ce98d391a62094047eada0d64860b80166c39f4a6b5640785" dependencies = [ "indexmap", "serde_core", @@ -2680,18 +2709,18 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ "winnow", ] [[package]] name = "toml_writer" -version = "1.1.1+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" [[package]] name = "tracing" @@ -2712,7 +2741,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -2754,28 +2783,18 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "transpose" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" -dependencies = [ - "num-integer", - "strength_reduce", -] - [[package]] name = "trybuild" -version = "1.0.117" +version = "1.0.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0710d4dfbeae4f9c390baa784c49858a7468fa433f3fe5d0ec5ebef651cf59f9" +checksum = "c0cabaa10be1917331a313866bd94526343e03c77bcf69144b62b072ad35d47c" dependencies = [ "dissimilar", "glob", "serde", "serde_derive", "serde_json", - "target-triple", + "target-tuple", "termcolor", "toml", ] @@ -2830,12 +2849,12 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" dependencies = [ "crypto-common", - "subtle", + "ctutils", ] [[package]] @@ -2859,12 +2878,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - [[package]] name = "vte" version = "0.14.1" @@ -2884,12 +2897,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - [[package]] name = "wasip2" version = "1.0.4+wasi-0.2.12" @@ -2901,9 +2908,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf" dependencies = [ "cfg-if", "once_cell", @@ -2914,9 +2921,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2924,22 +2931,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e" dependencies = [ "unicode-ident", ] @@ -2972,7 +2979,7 @@ version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e6fb4c2bee46c5ea4d40f8cdb5c131725cd976718ec56f1c8e82fbde5fa2a80" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.1", "hashbrown", "indexmap", "semver 1.0.28", @@ -2987,6 +2994,18 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "wincode" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfc6339f1ba427bf7ad7c42403b28e524832ba2ddb5eef1bb2cc3b85db6b7b75" +dependencies = [ + "pastey", + "proc-macro2", + "quote", + "thiserror", +] + [[package]] name = "windows-link" version = "0.2.1" @@ -3013,9 +3032,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" [[package]] name = "wit-bindgen" @@ -3047,7 +3066,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn 2.0.118", + "syn 2.0.119", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -3063,7 +3082,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -3075,7 +3094,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d567162a6b9843080e5e0053f696623ff694bae8ae017c9ec536d1873bbe3d8" dependencies = [ "anyhow", - "bitflags 2.13.0", + "bitflags 2.13.1", "indexmap", "log", "serde", @@ -3106,34 +3125,46 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "wnaf" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "795ca18b3fdb5e62bf982199278341ddcf7ebf7d32e25e212ad05d496e95f6fa" +dependencies = [ + "ff", + "group", + "hybrid-array", + "primefield", +] + [[package]] name = "x25519-dalek" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +checksum = "e7e8131a03190127fb2263afc72b322ecadae46b6ff8c6f399ff5d02f5559af6" dependencies = [ "curve25519-dalek", - "rand_core 0.6.4", + "rand_core 0.10.1", ] [[package]] name = "zerocopy" -version = "0.8.52" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" +checksum = "d35102a9f36d089ccae9e4c6802bc118be4487b80aaffc0ab4e0cf5ce92d2873" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.52" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" +checksum = "146c01f5ab44258da43cf276c74a2763db2ff3969c9c652c3f2de07041d0b2bc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -3144,6 +3175,6 @@ checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/examples/miden-bank/contracts/bank-account/Cargo.toml b/examples/miden-bank/contracts/bank-account/Cargo.toml index b7e5b67a..8e1cd247 100644 --- a/examples/miden-bank/contracts/bank-account/Cargo.toml +++ b/examples/miden-bank/contracts/bank-account/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -miden = "0.13" +miden = "=0.14.0" diff --git a/examples/miden-bank/contracts/bank-account/miden-project.toml b/examples/miden-bank/contracts/bank-account/miden-project.toml index c57ca053..17e9922b 100644 --- a/examples/miden-bank/contracts/bank-account/miden-project.toml +++ b/examples/miden-bank/contracts/bank-account/miden-project.toml @@ -3,12 +3,10 @@ name = "bank-account" version = "0.1.0" [lib] +path = "src/lib.rs" kind = "account-component" namespace = "miden:bank-account/bank@0.1.0" [dependencies] miden-core = "*" miden-protocol = "*" - -[package.metadata.miden] -supported-types = ["RegularAccountImmutableCode"] diff --git a/examples/miden-bank/contracts/bank-account/src/lib.rs b/examples/miden-bank/contracts/bank-account/src/lib.rs index 27151847..8e3ca711 100644 --- a/examples/miden-bank/contracts/bank-account/src/lib.rs +++ b/examples/miden-bank/contracts/bank-account/src/lib.rs @@ -53,7 +53,7 @@ struct BankStorage { /// Key is derived as: [depositor.prefix, depositor.suffix, faucet_prefix (asset.key[3]), faucet_suffix (asset.key[2])], /// which isolates balances per depositor per asset type. /// - /// Note (v0.15): the asset's metadata byte (composition + callback flag) is folded + /// Note (v0.16): the asset's metadata byte (composition; the callback flag is part of the faucet ID) is folded /// into the low 8 bits of the faucet-suffix limb (`asset.key[2]`), so that limb is /// NOT the raw faucet suffix. For the callbacks-disabled fungible assets this bank /// accepts the metadata byte is constant, so the derived key is still a stable @@ -73,6 +73,7 @@ trait Bank { /// /// # Panics /// Panics if the bank is already initialized. + #[account_procedure] fn initialize(&mut self); /// Get the bank-tracked balance for a depositor and specific asset type. @@ -87,6 +88,7 @@ trait Bank { /// /// # Returns /// The depositor's current balance as a Felt for the given asset type + #[account_procedure] fn get_depositor_balance(&self, depositor: AccountId, asset: Asset) -> Felt; /// Deposit an asset into the bank for a specific depositor. @@ -103,6 +105,7 @@ trait Bank { /// Panics if the deposit amount exceeds `MAX_DEPOSIT_AMOUNT`. /// Panics if the resulting balance would exceed `MAX_BALANCE` (u64 overflow). /// Panics if the bank has not been initialized. + #[account_procedure] fn deposit(&mut self, depositor: AccountId, deposit_asset: Asset); /// Withdraw assets back to the depositor. @@ -116,7 +119,7 @@ trait Bank { /// * `withdraw_asset` - The fungible asset to withdraw /// * `serial_num` - Unique serial number for the P2ID output note /// * `tag` - The note tag for the P2ID output note (allows caller to specify routing) - /// * `note_type` - Note type: 1 = Public (stored on-chain), 2 = Private (off-chain) + /// * `note_type` - Note type: 1 = Public (stored on-chain), 0 = Private (off-chain) /// /// The P2ID script root is read from the active note's storage (items 10-13). /// @@ -124,6 +127,7 @@ trait Bank { /// Panics if the asset is non-fungible. /// Panics if the withdrawal amount exceeds the depositor's current balance. /// Panics if the bank has not been initialized. + #[account_procedure] fn withdraw(&mut self, withdraw_asset: Asset, serial_num: Word, tag: Felt, note_type: Felt); } @@ -157,12 +161,9 @@ impl Bank for BankStorage { // Ensure the bank is initialized before accepting deposits self.require_initialized(); - // Verify this is a fungible asset. - // For fungible assets, value = [amount, 0, 0, 0]; value[1] is always 0. - // Non-fungible assets encode payload data into value[1..3], so any non-zero - // cell there means this branch can't safely treat the asset as a fungible amount. + // Check the asset composition; zero padding alone cannot distinguish NFTs. assert!( - deposit_asset.value[1].as_canonical_u64() == 0, + deposit_asset.is_fungible(), "Only fungible assets are supported" ); @@ -222,7 +223,7 @@ impl Bank for BankStorage { // Verify this is a fungible asset — see `deposit()` for the rationale. assert!( - withdraw_asset.value[1].as_canonical_u64() == 0, + withdraw_asset.is_fungible(), "Only fungible assets are supported" ); @@ -288,7 +289,7 @@ impl BankStorage { /// * `asset` - The asset to include in the note /// * `recipient_id` - The AccountId that can consume this note /// * `tag` - The note tag (passed by caller to allow proper P2ID routing) - /// * `note_type` - Note type as Felt: 1 = Public, 2 = Private + /// * `note_type` - Note type as Felt: 1 = Public, 0 = Private /// * `script_root` - The P2ID note script MAST root (Poseidon2-hashed) fn create_p2id_note( &mut self, @@ -305,7 +306,7 @@ impl BankStorage { let tag = Tag::from(tag); // Convert note_type Felt to NoteType - // 1 = Public (stored on-chain), 2 = Private (off-chain) + // 1 = Public (stored on-chain), 0 = Private (off-chain) let note_type = NoteType::from(note_type); // Compute the recipient hash from: diff --git a/examples/miden-bank/contracts/deposit-note/Cargo.lock b/examples/miden-bank/contracts/deposit-note/Cargo.lock index 7b7d6a3d..e8a96914 100644 --- a/examples/miden-bank/contracts/deposit-note/Cargo.lock +++ b/examples/miden-bank/contracts/deposit-note/Cargo.lock @@ -4,19 +4,19 @@ version = 4 [[package]] name = "aead" -version = "0.5.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +checksum = "1973cfbc1a2daf9cf550e74e1f088c28e7f7d8c1e1418fb6c9dc5184b7e84c99" dependencies = [ "crypto-common", - "generic-array", + "inout", ] [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] @@ -73,30 +73,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" - -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "arrayvec" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe" - -[[package]] -name = "ascii-canvas" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" -dependencies = [ - "term", -] +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] name = "autocfg" @@ -106,9 +91,9 @@ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "base16ct" -version = "0.2.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" [[package]] name = "base64ct" @@ -122,30 +107,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bit-set" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" - [[package]] name = "bitflags" version = "1.3.2" @@ -154,31 +115,30 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.13.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "blake3" -version = "1.8.5" +version = "1.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce" +checksum = "6d9e454fc11f76977dc803893aff6304ed33d6a26efae8696573bea74baa27ae" dependencies = [ - "arrayref", "arrayvec", "cc", "cfg-if", "constant_time_eq", - "cpufeatures 0.3.0", + "cpufeatures", ] [[package]] name = "block-buffer" -version = "0.10.4" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -189,9 +149,9 @@ checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "cc" -version = "1.2.65" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" +checksum = "005ec2760ca554fae18df7a11195552ec576cd665632a881bc011d5bb2fd4d80" dependencies = [ "find-msvc-tools", "jobserver", @@ -207,39 +167,45 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chacha20" -version = "0.9.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" dependencies = [ "cfg-if", "cipher", - "cpufeatures 0.2.17", + "cpufeatures", + "rand_core 0.10.1", ] [[package]] name = "chacha20poly1305" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +checksum = "9b89e1c441e926b9c82a8d023f6e1b7ae0adcfaa7d621814e4d60789bac751cb" dependencies = [ "aead", "chacha20", "cipher", "poly1305", - "zeroize", ] [[package]] name = "cipher" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ + "block-buffer", "crypto-common", "inout", - "zeroize", ] +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "colorchoice" version = "1.0.5" @@ -248,9 +214,9 @@ checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "const-oid" -version = "0.9.6" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" [[package]] name = "constant_time_eq" @@ -259,19 +225,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" [[package]] -name = "cpufeatures" -version = "0.2.17" +name = "cpubits" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" [[package]] name = "cpufeatures" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" dependencies = [ "libc", ] @@ -284,9 +247,9 @@ checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-deque" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -294,18 +257,18 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" [[package]] name = "crunchy" @@ -315,35 +278,47 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" -version = "0.5.5" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +checksum = "1a52aa3fcda4e6302a9f48734f234d35d4721b96f8fe07d073f07ce9df4f0271" dependencies = [ - "generic-array", - "rand_core 0.6.4", + "cpubits", + "ctutils", + "hybrid-array", + "num-traits", + "rand_core 0.10.1", "subtle", "zeroize", ] [[package]] name = "crypto-common" -version = "0.1.7" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ - "generic-array", - "rand_core 0.6.4", - "typenum", + "hybrid-array", + "rand_core 0.10.1", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", + "subtle", ] [[package]] name = "curve25519-dalek" -version = "4.1.3" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "b5eed333089e2e1c1ac8c6c0398e5e2497b4c9926ca6d0365ed1e099afa5bc23" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures", "curve25519-dalek-derive", "digest", "fiat-crypto", @@ -360,14 +335,14 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "defmt" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6e524506490a1953d237cb87b1cfc1e46f88c18f10a22dfe0f507dc6bfc7f7f" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" dependencies = [ "bitflags 1.3.2", "defmt-macros", @@ -375,15 +350,14 @@ dependencies = [ [[package]] name = "defmt-macros" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a27770e9c8f719a79d8b638281f4d828f77d8fd61e0bd94451b9b85e576a0b" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" dependencies = [ "defmt-parser", - "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -404,9 +378,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.10" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "a878c850e9e421b20262e9b41f9c860e4785fa07541c266b62ff9d1ef998a80a" dependencies = [ "const-oid", "zeroize", @@ -430,19 +404,19 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "digest" -version = "0.10.7" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer", "const-oid", "crypto-common", - "subtle", + "ctutils", ] [[package]] @@ -453,9 +427,9 @@ checksum = "aeda16ab4059c5fd2a83f2b9c9e9c981327b18aa8e3b313f7e6563799d4f093e" [[package]] name = "ecdsa" -version = "0.16.9" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +checksum = "c0681a4fc24c767085329728d8dfba959af91228aa4610cca4f8ce317ba46ae0" dependencies = [ "der", "digest", @@ -463,13 +437,14 @@ dependencies = [ "rfc6979", "signature", "spki", + "zeroize", ] [[package]] name = "ed25519" -version = "2.2.3" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +checksum = "29fcf32e6c73d1079f83ab4d782de2d81620346a5f38c6237a86a22f8368980a" dependencies = [ "pkcs8", "signature", @@ -477,53 +452,46 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +checksum = "6ebaa1a2bf1290ab3bfe5a7b771d050ebffab2711c19a81691c683a5144a25de" dependencies = [ "curve25519-dalek", "ed25519", "serde", "sha2", + "signature", "subtle", "zeroize", ] [[package]] name = "either" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "elliptic-curve" -version = "0.13.8" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "9d65aa39b3a5c1c9c1b745c9a019234bb7a21b77abcb4f4d266d706e2d577d65" dependencies = [ "base16ct", "crypto-bigint", + "crypto-common", "digest", "ff", - "generic-array", "group", "hkdf", + "hybrid-array", "pkcs8", - "rand_core 0.6.4", + "rand_core 0.10.1", "sec1", "subtle", "zeroize", ] -[[package]] -name = "ena" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" -dependencies = [ - "log", -] - [[package]] name = "env_filter" version = "2.0.0" @@ -566,42 +534,33 @@ dependencies = [ [[package]] name = "ff" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +checksum = "a1f686ab92a9fb0eaf188f6c6c87b89490baa6fdb0db4544ba4dc47f7942489f" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "fixedbitset" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d" [[package]] name = "flume" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "spin 0.9.8", + "spin 0.9.9", ] [[package]] @@ -612,18 +571,18 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "fs-err" -version = "3.3.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fde052dbfc920003cfd2c8e2c6e6d4cc7c1091538c3a24226cec0665ab08c0" +checksum = "b91aa448ca50d7e79433bdf3ee8d99215430d2ec02ade5aefab2a073a1822e8a" dependencies = [ "autocfg", ] [[package]] name = "futures" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" dependencies = [ "futures-channel", "futures-core", @@ -635,9 +594,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -645,39 +604,38 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-io" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-sink" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-core", "futures-sink", "futures-task", "pin-project-lite", - "slab", ] [[package]] @@ -695,58 +653,46 @@ dependencies = [ "windows-result", ] -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - [[package]] name = "getrandom" -version = "0.2.17" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", - "js-sys", "libc", - "wasi", - "wasm-bindgen", + "r-efi 5.3.0", + "wasip2", ] [[package]] name = "getrandom" -version = "0.3.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", - "wasip2", + "r-efi 6.0.0", + "rand_core 0.10.1", "wasm-bindgen", ] [[package]] name = "glob" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" [[package]] name = "group" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] @@ -767,22 +713,33 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hkdf" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" dependencies = [ "hmac", ] [[package]] name = "hmac" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ "digest", ] +[[package]] +name = "hybrid-array" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17" +dependencies = [ + "subtle", + "typenum", + "zeroize", +] + [[package]] name = "id-arena" version = "2.3.0" @@ -797,9 +754,9 @@ checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" -version = "2.14.0" +version = "2.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" dependencies = [ "equivalent", "hashbrown", @@ -809,11 +766,11 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -824,9 +781,9 @@ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc" dependencies = [ "either", ] @@ -839,11 +796,12 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.29" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f877a98676d2fb664698d74cc6a51ce6c484ce8c770f05d0108ec9090aeb46" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" dependencies = [ "defmt", + "jiff-core", "jiff-static", "log", "portable-atomic", @@ -851,89 +809,69 @@ dependencies = [ "serde_core", ] +[[package]] +name = "jiff-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +dependencies = [ + "defmt", +] + [[package]] name = "jiff-static" -version = "0.2.29" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0666b5ab5ecaca213fc2a85b8c0083d9004e84ee2d5f9a7e0017aaf50986f25f" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" dependencies = [ + "jiff-core", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.103" +version = "0.3.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +checksum = "ce57d20d1ea864ce2ac172ab472d409214f4fd359f0b2a2775abdf522e2af99e" dependencies = [ "cfg-if", - "futures-util", "wasm-bindgen", ] [[package]] name = "k256" -version = "0.13.4" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +checksum = "93f50113171a713f4a4231ef82eb26703607139b35dcb56241f0ceab2ae1f7d8" dependencies = [ - "cfg-if", + "cpubits", "ecdsa", "elliptic-curve", - "once_cell", + "primeorder", "sha2", - "signature", + "wnaf", ] [[package]] name = "keccak" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" -dependencies = [ - "cpufeatures 0.2.17", -] - -[[package]] -name = "lalrpop" -version = "0.22.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" -dependencies = [ - "ascii-canvas", - "bit-set", - "ena", - "itertools", - "lalrpop-util", - "petgraph", - "regex", - "regex-syntax", - "sha3", - "string_cache", - "term", - "unicode-xid", - "walkdir", -] - -[[package]] -name = "lalrpop-util" -version = "0.22.2" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" +checksum = "d8f198d1db720e4940b5a493201d199d9f24f568f8f746bd13706243a2f71598" dependencies = [ - "rustversion", + "cfg-if", + "cpufeatures", ] [[package]] @@ -950,9 +888,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.186" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libm" @@ -971,9 +909,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "loom" @@ -999,15 +937,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.2" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "miden" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab74b8469fe68b32551bbd85943580800c1b5f2e4683c85ad3e88a628c4e28a7" +checksum = "d0cad08495d4826f7e40ee0cd69bc207f81cc5376844e1718ccb9a3e9e0ba0d6" dependencies = [ "miden-base", "miden-base-macros", @@ -1016,15 +954,17 @@ dependencies = [ "miden-field-repr", "miden-sdk-alloc", "miden-stdlib-sys", + "miden-tx-script-args", "wit-bindgen", ] [[package]] name = "miden-ace-codegen" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd45076fe4fef71f0f8b30aa0f018eb39c3086eeb5f3cafc0e12d60cd28339e" +checksum = "00ff2a44c7f7dc497ac56c74dca5b3465b4b46be066fa88c2c58a8eb1bcb2dc8" dependencies = [ + "miden-constraint-compiler", "miden-core", "miden-crypto", "thiserror", @@ -1032,24 +972,24 @@ dependencies = [ [[package]] name = "miden-air" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f1a80330b3e3d3f98e08817dc6a5e3d90d11ab5e88aa9c0dad5d3b4202598b" +checksum = "84b6d3f3336c8a2da5cd0924c42dd1f339e6c3d5adf3221bc1c005b444fd0bf0" dependencies = [ "miden-ace-codegen", "miden-core", "miden-crypto", - "miden-lifted-stark", "miden-utils-indexing", + "p3-field", "thiserror", "tracing", ] [[package]] name = "miden-assembly" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8582d184360be35eb2111a99245f556f43e1066ed09192fbcd0f218c466862a5" +checksum = "644b31bdda941328f9ff2088382b7de41569c1cc83d6090f63e43d261e9cd262" dependencies = [ "log", "miden-assembly-syntax", @@ -1064,14 +1004,12 @@ dependencies = [ [[package]] name = "miden-assembly-syntax" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffa307bc2cbd1f0cb74ed58981823f400a433900fb8f963762331fbb8389d5dc" +checksum = "cad0d5174833b17b498d541d1ef62d73929a143ea56ea5eba719339c15cd0968" dependencies = [ - "aho-corasick", - "lalrpop", - "lalrpop-util", "log", + "miden-assembly-syntax-cst", "miden-core", "miden-debug-types", "miden-utils-diagnostics", @@ -1085,11 +1023,23 @@ dependencies = [ "thiserror", ] +[[package]] +name = "miden-assembly-syntax-cst" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff301e56d9201821a4458564ed19ae9b95c7a219662a422e47bb61d17e0fa7b1" +dependencies = [ + "miden-debug-types", + "miden-rowan", + "miden-utils-diagnostics", + "thiserror", +] + [[package]] name = "miden-base" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2465a5ecd9546c354cbc6121ffe427cc5c7f98cbca08852049d11c675eb5a4b" +checksum = "5635698d03259fd13404b5376ae5f6c3b2d9e95918befd9ce0799de91e3b036a" dependencies = [ "miden-base-sys", "miden-stdlib-sys", @@ -1097,9 +1047,9 @@ dependencies = [ [[package]] name = "miden-base-macros" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a840ad62ba5264b33e460fbd530efacfc3dadca4d40534316ed50609e291e071" +checksum = "0d4e1fad0a94d307b223dd59e5a54c39615f4b48cd3b0e58670912fc404bd480" dependencies = [ "heck", "miden-assembly-syntax", @@ -1112,7 +1062,7 @@ dependencies = [ "proc-macro2", "quote", "semver 1.0.28", - "syn 2.0.118", + "syn 2.0.119", "toml", "wit-bindgen-core", "wit-bindgen-rust", @@ -1120,19 +1070,29 @@ dependencies = [ [[package]] name = "miden-base-sys" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "933380029fdc065398ae07af3ebdebd8fb425a74b4fe231d23774bbf00e11d67" +checksum = "8156d21c2e9f6755b82502045b775cb98c5d10f80ab957d9bcfde509aa32b8dc" dependencies = [ "miden-field-repr", "miden-stdlib-sys", ] +[[package]] +name = "miden-constraint-compiler" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01ef51ec02f0899c5fc6aa4af11eb050094d98e5e6bf8767a4da555d210f2de6" +dependencies = [ + "miden-core", + "miden-crypto", +] + [[package]] name = "miden-core" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80657c32850817f5f67dcf114866495a4b055531778b7c26d0602646ce777eb8" +checksum = "3b27f9f91988c5e74b50b543c4e6d37ec729eabcf70db63cf752dedd780f8a90" dependencies = [ "derive_more", "log", @@ -1142,34 +1102,46 @@ dependencies = [ "miden-utils-core-derive", "miden-utils-indexing", "miden-utils-sync", - "num-derive", - "num-traits", "serde", "thiserror", ] [[package]] name = "miden-core-lib" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16410655f32f98537afc9ddf57b71cb6d1ca9d980da5f4eea164cafcaf891b2e" +checksum = "14df9652fc4963f20d11df9ceb576ccb7831b5dc72fabec5c1b602f51e57909c" dependencies = [ "env_logger", "fs-err", "miden-assembly", + "miden-assembly-syntax", "miden-core", + "miden-core-lib-codegen", "miden-crypto", + "miden-mast-package", "miden-package-registry", + "miden-precompiles", "miden-processor", "miden-utils-sync", "thiserror", ] +[[package]] +name = "miden-core-lib-codegen" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aad0b8badcf1636150cac0d74aabadd395ba7d570227eb0923ff14f02a278fff" +dependencies = [ + "miden-core", + "miden-precompiles", +] + [[package]] name = "miden-crypto" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35198bebd353cddc25ad4aafb5f4ef9e71b283d71c787b8938c575c16974135d" +checksum = "7c917b0342d911ae4b7a549bb3ca791c093dac4770f88b02e23b43f3fa8179f5" dependencies = [ "blake3", "cc", @@ -1196,10 +1168,8 @@ dependencies = [ "p3-maybe-rayon", "p3-symmetric", "p3-util", - "rand 0.9.4", - "rand_chacha", - "rand_core 0.9.5", - "rand_hc", + "rand 0.10.2", + "rand_chacha 0.10.0", "serde", "sha2", "sha3", @@ -1210,19 +1180,19 @@ dependencies = [ [[package]] name = "miden-crypto-derive" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9068c6554db0e051f62913575de9949841a46b96ae92d4b7d28e1fed5d8f052b" +checksum = "a7c3165dfd7fd6f587ea5731efd1cc8083ca55c23d2d9b3000f83a3948486044" dependencies = [ "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "miden-debug-types" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956708ccb2f643db398b4b3d4f8d0baf199b1bfb5e34c8be1cd1bc811c005e8e" +checksum = "4c9f3f8e4a8f54a36fbf00330ac8bd1947627c1786cd49b94a08b741590ed173" dependencies = [ "memchr", "miden-crypto", @@ -1235,22 +1205,23 @@ dependencies = [ "serde", "serde_spanned", "thiserror", + "zerocopy", ] [[package]] name = "miden-field" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379a39db52cd932a95d4017a18b712ee53ed0f86cfedf8c63ed72d687a18a191" +checksum = "58cf9de55b88ec86ad272ff4224d76b3e0cbda49e242e78776b0037ba9b0e857" dependencies = [ "miden-serde-utils", - "num-bigint", + "num-bigint 0.5.1", "p3-challenger", "p3-field", "p3-goldilocks", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", "subtle", "thiserror", @@ -1258,9 +1229,9 @@ dependencies = [ [[package]] name = "miden-field-repr" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed71d35f511b703d1620094fcc748cb9383dbf2bd7b304d0b28c506a354acdf" +checksum = "93e13ffca1264db045cc344e573f9460bd0153aa89b755fac454b9070b953cdc" dependencies = [ "miden-field", "miden-field-repr-derive", @@ -1268,13 +1239,13 @@ dependencies = [ [[package]] name = "miden-field-repr-derive" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37e87fe1408b7ebc083614469b761a29c5749a34072b0e33dd4cbdd8d34766c" +checksum = "bf0e54de280a41e83a99caa16b3ffb8670c857c888d3e245920e8a96f42fad58" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1288,11 +1259,12 @@ dependencies = [ [[package]] name = "miden-lifted-air" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789e0e469d1731012d8a018057317f31580611535c20d2a47c022213228cb733" +checksum = "f67e06d47e246db853a9f3e52ec87fa33a8ffc0fe5be0dd99288b2439312f206" dependencies = [ "p3-air", + "p3-challenger", "p3-field", "p3-matrix", "p3-util", @@ -1301,9 +1273,9 @@ dependencies = [ [[package]] name = "miden-lifted-stark" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f62cca91182917b22a47e150028b7c785df620a15b2974a39c64e2b1b7a889d3" +checksum = "a5ee320597c7712698d06811d9144b0e4f2275a21224ef0238652c947b01198b" dependencies = [ "miden-lifted-air", "miden-stark-transcript", @@ -1316,7 +1288,7 @@ dependencies = [ "p3-maybe-rayon", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", "serde", "thiserror", "tracing", @@ -1324,15 +1296,20 @@ dependencies = [ [[package]] name = "miden-mast-package" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f37c21836b40785ce297d363c57740d4e33edcc411f84185a524eddadd5f53c7" +checksum = "1355a2563a52af4399b4a93120a4398f81415b1fc4edb58310de5034cfa3781d" dependencies = [ + "hashbrown", + "log", "miden-assembly-syntax", "miden-core", "miden-debug-types", + "miden-utils-indexing", + "rustc-hash", "serde", "thiserror", + "zerocopy", ] [[package]] @@ -1351,9 +1328,9 @@ dependencies = [ "rustc_version 0.2.3", "rustversion", "serde_json", - "spin 0.9.8", + "spin 0.9.9", "strip-ansi-escapes", - "syn 2.0.118", + "syn 2.0.119", "textwrap", "thiserror", "trybuild", @@ -1368,14 +1345,14 @@ checksum = "86a905f3ea65634dd4d1041a4f0fd0a3e77aa4118341d265af1a94339182222f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "miden-package-registry" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ece6064beb0582d1c64ba30d0c548c4b7a45f87abae6d69e22fd49c8b343258" +checksum = "a799e66245492c193b0444c3e0ff0fe42418009ec668a3e80c40d9f5b1454aac" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -1387,16 +1364,50 @@ dependencies = [ "thiserror", ] +[[package]] +name = "miden-precompiles" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "073ebeeb4413b9a03c60b0b066f94b8edaa6f50150017a92dc09d3ace92d6976" +dependencies = [ + "miden-core", + "miden-crypto", +] + +[[package]] +name = "miden-precompiles-prover" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76663c4d90cc073f9e2d2aa2349b9dcd25bf6c40db5020d27ce59990b6bd5af" +dependencies = [ + "miden-air", + "miden-core", + "miden-crypto", + "miden-lifted-air", + "miden-lifted-stark", + "miden-precompiles", + "miden-serde-utils", + "ruint", + "serde", + "serde-wincode", + "thiserror", + "tracing", + "wincode", +] + [[package]] name = "miden-processor" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea972ca9e45dbf26aa396367e8508db0f7292adea6f6ddf8d39d0e334285fe2b" +checksum = "2c7331ab96f00f922d29e2f59285f539299061a44ffdeea31b853d2c071f8056" dependencies = [ + "hashbrown", "itertools", "miden-air", "miden-core", "miden-debug-types", + "miden-mast-package", + "miden-precompiles", "miden-utils-diagnostics", "miden-utils-indexing", "paste", @@ -1407,9 +1418,9 @@ dependencies = [ [[package]] name = "miden-project" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5320e7e5b562359bd6161ac752dfe43dd4f69bb06e87f94a21a27bb656e5a20d" +checksum = "6f8201d3a6d0c85c747092309c3c420de42e61e76f71df2189a46411100d120a" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -1424,13 +1435,13 @@ dependencies = [ [[package]] name = "miden-protocol" -version = "0.15.3" +version = "0.16.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66340243e37da5936cb278a8dd11037813f1dc6731c2fc866703b76ed465ebc3" +checksum = "e275feebbe9c2458c5877c5f2a03b8e2152831ce956376f015fc4c50acfffb50" dependencies = [ "bech32", "fs-err", - "getrandom 0.3.4", + "getrandom 0.4.3", "miden-assembly", "miden-assembly-syntax", "miden-core", @@ -1438,37 +1449,65 @@ dependencies = [ "miden-crypto", "miden-crypto-derive", "miden-mast-package", + "miden-package-registry", "miden-processor", + "miden-protocol-build-utils", "miden-utils-sync", "miden-verifier", - "rand 0.9.4", + "rand 0.10.2", "regex", "semver 1.0.28", "thiserror", +] + +[[package]] +name = "miden-protocol-build-utils" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d16cdd96c1d0b3b2d57342d37eaadd15cc7c633bda965fc8c3b23ca249965b4" +dependencies = [ + "fs-err", + "miden-assembly", + "miden-core", + "miden-mast-package", + "miden-package-registry", + "miden-project", + "regex", "walkdir", ] +[[package]] +name = "miden-rowan" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13695bf99aabaa21d6572b807c66bb26251aa3d9b75e828b3c99b97a3b1ce7e" +dependencies = [ + "hashbrown", + "rustc-hash", +] + [[package]] name = "miden-sdk-alloc" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ee9eb34cde96e3158c19e22fedddb03b6e5eb363e272d11cbae9aa963cc315" +checksum = "15deb9ba073e632ca1151fcf7b718227294b750a7be9ac0c655d5ae7f2a6dc43" [[package]] name = "miden-serde-utils" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78cd1d4fcad937312e544f7d53423485e453598aa4fb989d2b6374027a8c136" +checksum = "f5c21a2acdc1928f86803b3ff3c44564c3f614a7dc47dcd64969a5c856d27988" dependencies = [ "p3-field", "p3-goldilocks", + "wincode", ] [[package]] name = "miden-stark-transcript" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05901db2e30d3954243960fe21cea7fbec39f97c27774b56fd5031c28c4881ba" +checksum = "d503630c353389838fa5d668a0d4550130453c7b2a72b802d4adc1ea39ab5bee" dependencies = [ "p3-challenger", "p3-field", @@ -1478,9 +1517,9 @@ dependencies = [ [[package]] name = "miden-stateful-hasher" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faeb47a90c55c5d45051d23cf691588804dd531995b4582c79108b64e445a905" +checksum = "e8c2008195bdb552eeb744074bfc8822049552ccdf7aef3321a32e1ab6be92e6" dependencies = [ "p3-field", "p3-symmetric", @@ -1488,18 +1527,29 @@ dependencies = [ [[package]] name = "miden-stdlib-sys" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "015cb758041aeaae5b2e5062af67459fb71cdacd199838a4a43795eb82f9a11d" +checksum = "152e858a662e3c4524e06becfb98d6727ec7cbc9d51cf9bb8b8bea9e17af5072" dependencies = [ "miden-field", ] +[[package]] +name = "miden-tx-script-args" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c32d126b51f111ff9e8aed25d1ccefc0e3e093b361b88b51e1ab2fd70f96a7" +dependencies = [ + "miden-field", + "miden-field-repr", + "miden-stdlib-sys", +] + [[package]] name = "miden-utils-core-derive" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0b1ee4662beb049a824e11bb21f95a79746c52874967983c9999f1b19a2f471" +checksum = "107d04fcd05b0308e6347113ee6dc13599755e5b4d05ecc08d8b5c05f36a5a39" dependencies = [ "proc-macro2", "quote", @@ -1508,11 +1558,10 @@ dependencies = [ [[package]] name = "miden-utils-diagnostics" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fdc1cd4eda372e1c4b99b9c3677e9b1f87a4d2e362a9f4b8f904273d395efc9" +checksum = "f3b444d204bf082cdab14015ff10d5b0b43a10fba662fef09e4753f6d07faf1f" dependencies = [ - "miden-crypto", "miden-debug-types", "miden-miette", "tracing", @@ -1520,11 +1569,11 @@ dependencies = [ [[package]] name = "miden-utils-indexing" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31444125649f4dad9cde647f614309b6be4f918fed276ada4eb99c01e8b9ca7" +checksum = "f6ff225060e2a5cc4dd6c898eef1f04739461d3401b6de1692bf443cfdd302b0" dependencies = [ - "miden-crypto", + "miden-serde-utils", "proptest", "serde", "thiserror", @@ -1532,9 +1581,9 @@ dependencies = [ [[package]] name = "miden-utils-sync" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "807c8ae625b7652ae7246b225c907c05da72927c31a0fd71c835c4f80931e92e" +checksum = "76b9cb00f01787f8687447cd8a45b3888b470eb35a132df1be9729779d311fd7" dependencies = [ "lock_api", "loom", @@ -1544,34 +1593,37 @@ dependencies = [ [[package]] name = "miden-verifier" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec5556dac919a1c13edeb2bd7181fc6a4c2ce52764a3e518bcdcd9ed48e5b38e" +checksum = "5e049df6008af1fea5a66df8ce98075cc9e00f16122fd5f4e7c4be9a263cae46" dependencies = [ - "bincode", "miden-air", "miden-core", "miden-crypto", + "miden-precompiles", + "miden-precompiles-prover", + "miden-serde-utils", "serde", + "serde-wincode", "thiserror", - "tracing", ] [[package]] name = "midenc-frontend-wasm-metadata" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3303cecb0858b92395b5c3710d52aae96d28e12f13966208731712e83803d" +checksum = "be2bc4e14ad915ca2b51b521bffbfc91bee1b94520277db144b27bd111cd60a7" dependencies = [ + "miden-mast-package", "serde", "serde_json", ] [[package]] name = "midenc-hir-type" -version = "0.6.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff0511aa2201f7098995e38a3c97a319d379c3b2d26fb83677b21b71f61a7b4" +checksum = "dcdf2257de8f3486c8f3e93c45219b782bafad62a8694798c05d5b8f3f79c64e" dependencies = [ "miden-formatting", "miden-serde-utils", @@ -1581,21 +1633,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom 0.2.17", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -1611,7 +1648,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "num-bigint", + "num-bigint 0.4.8", "num-complex", "num-integer", "num-iter", @@ -1621,50 +1658,48 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" dependencies = [ "num-integer", "num-traits", ] [[package]] -name = "num-complex" -version = "0.4.6" +name = "num-bigint" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +checksum = "93e7820bc0a80a0238e650327316f929ba18d5be054b647490a3a6a339f3e7c0" dependencies = [ + "num-integer", "num-traits", ] [[package]] -name = "num-derive" -version = "0.4.2" +name = "num-complex" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", + "num-traits", ] [[package]] name = "num-integer" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" dependencies = [ "num-traits", ] [[package]] name = "num-iter" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -1675,7 +1710,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "num-bigint", + "num-bigint 0.4.8", "num-integer", "num-traits", ] @@ -1706,23 +1741,17 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "owo-colors" -version = "4.3.0" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" +checksum = "13c45bb4a6ae1280ec0803b1ef9d3455eb50f01efbbe1447ab020f1d54fba9d8" [[package]] name = "p3-air" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c824e8d7c7ddf208b742eac8d48e0b2d52d22fa013578a7762bf6931dbab1f46" +checksum = "ddb1be05c0d6f691afe0c9f468018a9a37cfa904dee78a8081ec96eb3cdd88e8" dependencies = [ "p3-field", "p3-matrix", @@ -1731,9 +1760,9 @@ dependencies = [ [[package]] name = "p3-blake3" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2733229a713bd83ccf5eb749e8f8e7380c1052674394a25c0422a772204a20af" +checksum = "6f202f5fbcceb6f56f783d98efb5de27e5a171470e3364de97b0923b39c87ab5" dependencies = [ "blake3", "p3-symmetric", @@ -1742,9 +1771,9 @@ dependencies = [ [[package]] name = "p3-challenger" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8972ccd1d5dc90e46cdb1f2ab4ee2bae49b3917e5e98aa533f0c2b779c010445" +checksum = "84d5d5e1ecf2c80b09b48ce870e8abd08b643454101c5dc9d0fd71bfbd78224d" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -1756,42 +1785,42 @@ dependencies = [ [[package]] name = "p3-dft" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17771aca44632f9cc11f2718d7ea7ec06794946c4190ef3a985bfc893f14c18a" +checksum = "4321a952da2721ecd85ca593ea189798dfb4e439a2cc1378ce1442091880f173" dependencies = [ "itertools", "p3-field", "p3-matrix", "p3-maybe-rayon", "p3-util", - "spin 0.10.0", + "spin 0.12.3", "tracing", ] [[package]] name = "p3-field" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3eb24d0591fd4d282d89cbe4e4efba5571c699375006f80b2cbf53ce83461c" +checksum = "53db75d38e04fc255826f388eca9d05976733dc9754aa3db411bc9ea1a37c1a0" dependencies = [ "itertools", - "num-bigint", + "num-bigint 0.5.1", "p3-maybe-rayon", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", "tracing", ] [[package]] name = "p3-goldilocks" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5751c6591a0d2397d726620c2c29a7436ec6c5e19d2ed74ca5d078d4fbb18eb5" +checksum = "d03b3f31080df31be723b876709246f8f1e532e1c5b82efb5281d705c8304c63" dependencies = [ - "num-bigint", + "num-bigint 0.5.1", "p3-challenger", "p3-dft", "p3-field", @@ -1801,15 +1830,16 @@ dependencies = [ "p3-symmetric", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", + "spin 0.12.3", ] [[package]] name = "p3-keccak" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a7df174ff0c19a8742eb4698eaa1667c5f858d018e2faf09c55f1f24a6f9c3" +checksum = "ae50c8c37eb847c660298fb275e53c025c49b2623a8cfabf67f5322258b2b4db" dependencies = [ "p3-symmetric", "p3-util", @@ -1818,46 +1848,46 @@ dependencies = [ [[package]] name = "p3-matrix" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9c94c0714944e7b8a9a62e6340b1e3e1d3f8ecfd3e35c08798360200e73eff" +checksum = "473eb920c446a6f4536e0d3528fbdca2a23c0e24e1d0d7767452e6d385dd335c" dependencies = [ "itertools", "p3-field", "p3-maybe-rayon", "p3-util", - "rand 0.10.1", + "rand 0.10.2", "serde", "tracing", ] [[package]] name = "p3-maybe-rayon" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebc233a34b1ab0273f35b4052fa2eeb3114b22ba4575bd7da00716e878ffb77" +checksum = "e6fddfd435f96394769414cf5590b77058aa506659bf20d6592e9d1989e04440" [[package]] name = "p3-mds" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b5441fa8116246ec9e6c835f15273cb27777ca572960ec87476b67fef13e01e" +checksum = "551ba0ab2cccd89f85a99450224898aff224e323bbf61f777ba6344f0896ef10" dependencies = [ "p3-dft", "p3-field", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-monty-31" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8724f330ea6d19dd4f2436aa0f88b5fcbf88f0f55ca7fccd3fea8b736dbcddad" +checksum = "871f635f7340cd0868b17e43e0c98fefdafdaed90469d0725caf6d8372a2a47c" dependencies = [ "itertools", - "num-bigint", + "num-bigint 0.5.1", "p3-dft", "p3-field", "p3-matrix", @@ -1868,41 +1898,42 @@ dependencies = [ "p3-symmetric", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", - "spin 0.10.0", + "spin 0.12.3", "tracing", ] [[package]] name = "p3-poseidon1" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e2a562fea210baae390a32f9ecf0dd8724ae3f4352d1c8e413077b6f00a162" +checksum = "8d0d304e9a1f29c0d66534aa84e69528e2118351fdce08dcf5898af4e0fecc32" dependencies = [ "p3-field", + "p3-mds", "p3-symmetric", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-poseidon2" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06394851c161d17e4aa4ad2aad5557d32f14cadd1dc838f965d8e1821a63b8c5" +checksum = "43eb8a73a26d14becaed1c67c3e8a047e4311d7909b402383c82ca9643ba17c6" dependencies = [ "p3-field", "p3-mds", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-symmetric" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac1a276d421f8ef3361bb7d8c39a02c93c6b3f10eeaa559cc4c50222f9a5b82" +checksum = "2015ea80cad969b6aabf27a04884286fe1354393b166d968ee0d80a95126b2a4" dependencies = [ "itertools", "p3-field", @@ -1912,12 +1943,11 @@ dependencies = [ [[package]] name = "p3-util" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d08a58162a4c264269ef454f0b28dcda89939490eecacb2b2cf5b00f719b80f6" +checksum = "6c5466fc40e6df89d3b291a2eff16b33e68e8571207790370137ec18090aadab" dependencies = [ "serde", - "transpose", ] [[package]] @@ -1950,23 +1980,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] -name = "petgraph" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" -dependencies = [ - "fixedbitset", - "indexmap", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" +name = "pastey" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher", -] +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" [[package]] name = "pin-project-lite" @@ -1976,9 +1993,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkcs8" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ "der", "spki", @@ -1986,26 +2003,25 @@ dependencies = [ [[package]] name = "poly1305" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +checksum = "6e2d0073b297041425c7c3df6eb4792d598a15323fe63346852b092eca02904c" dependencies = [ - "cpufeatures 0.2.17", - "opaque-debug", + "cpufeatures", "universal-hash", ] [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "portable-atomic-util" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" dependencies = [ "portable-atomic", ] @@ -2019,12 +2035,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - [[package]] name = "prettyplease" version = "0.2.37" @@ -2032,47 +2042,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] -name = "priority-queue" -version = "2.7.0" +name = "primefield" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" +checksum = "c555a6e4eb7d4e158fcb028c835c3b8642206ddc279b5c6b202ef9a8bdb592f4" dependencies = [ - "equivalent", - "indexmap", - "serde", + "crypto-bigint", + "crypto-common", + "ff", + "rand_core 0.10.1", + "subtle", + "zeroize", ] [[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" +name = "primeorder" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +checksum = "5c9f42978c78a00e3d68f69fc03e57a234debae69da4020a4fb588fcdcd07b06" dependencies = [ - "proc-macro2", - "quote", + "elliptic-curve", + "primefield", + "serdect", + "wnaf", ] [[package]] -name = "proc-macro-error2" -version = "2.0.1" +name = "priority-queue" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" dependencies = [ - "proc-macro-error-attr2", - "proc-macro2", - "quote", - "syn 2.0.118", + "equivalent", + "indexmap", + "serde", ] [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -2083,10 +2097,10 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.1", "num-traits", - "rand 0.9.4", - "rand_chacha", + "rand 0.9.5", + "rand_chacha 0.9.0", "rand_xorshift", "regex-syntax", "unarray", @@ -2108,9 +2122,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.46" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -2121,22 +2135,30 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "rand" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ - "rand_chacha", + "rand_chacha 0.9.0", "rand_core 0.9.5", ] [[package]] name = "rand" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ + "chacha20", + "getrandom 0.4.3", "rand_core 0.10.1", ] @@ -2151,12 +2173,13 @@ dependencies = [ ] [[package]] -name = "rand_core" -version = "0.6.4" +name = "rand_chacha" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "3e6af7f3e25ded52c41df4e0b1af2d047e45896c2f3281792ed68a1c243daedb" dependencies = [ - "getrandom 0.2.17", + "ppv-lite86", + "rand_core 0.10.1", ] [[package]] @@ -2174,15 +2197,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" -[[package]] -name = "rand_hc" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b363d4f6370f88d62bf586c80405657bde0f0e1b8945d47d2ad59b906cb4f54" -dependencies = [ - "rand_core 0.6.4", -] - [[package]] name = "rand_xorshift" version = "0.4.0" @@ -2218,14 +2232,14 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.1", ] [[package]] name = "regex" -version = "1.12.4" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -2235,9 +2249,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -2252,19 +2266,34 @@ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rfc6979" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +checksum = "b4a459cddafb3fe76b31fd8f1108007566c40301feb64dc7b54656eb7388172b" dependencies = [ + "crypto-bigint", "hmac", - "subtle", ] +[[package]] +name = "ruint" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e99bff0393163bb25029a6af25d3d8d202ba5b5438a74d1bd8789f5c822970" +dependencies = [ + "ruint-macro", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustc_version" @@ -2286,9 +2315,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "same-file" @@ -2313,14 +2342,14 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sec1" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" dependencies = [ "base16ct", + "ctutils", "der", - "generic-array", - "pkcs8", + "hybrid-array", "subtle", "zeroize", ] @@ -2352,9 +2381,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -2372,31 +2401,42 @@ dependencies = [ "typeid", ] +[[package]] +name = "serde-wincode" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa9d3a86c66cf10ce79df36f555a5a4c8d72a82515d9ea8ca420e02c925c30f" +dependencies = [ + "serde", + "thiserror", + "wincode", +] + [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", ] [[package]] name = "serde_json" -version = "1.0.150" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -2407,13 +2447,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", ] [[package]] @@ -2425,25 +2465,36 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serdect" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66cf8fedced2fcf12406bcb34223dffb92eaf34908ede12fed414c82b7f00b3e" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "sha2" -version = "0.10.9" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures", "digest", ] [[package]] name = "sha3" -version = "0.10.9" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +checksum = "bc9bad02c26382724b2d2692c6f179285e4b54eeecd7968f52a50059c3c11759" dependencies = [ "digest", "keccak", + "sponge-cursor", ] [[package]] @@ -2463,31 +2514,19 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signature" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" dependencies = [ "digest", - "rand_core 0.6.4", + "rand_core 0.10.1", ] -[[package]] -name = "siphasher" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" - -[[package]] -name = "slab" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - [[package]] name = "smallvec" -version = "1.15.2" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +checksum = "b9be42f50aa861c555654aa3a37f52f4b1074bacf4e48fe0ef7fa584e80f1f0f" dependencies = [ "serde", ] @@ -2500,49 +2539,37 @@ checksum = "e8e2fb0f499abb4d162f2bedad68f5ef91a1682b5a03596ddb67efd37768d100" [[package]] name = "spin" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" dependencies = [ "lock_api", ] [[package]] name = "spin" -version = "0.10.0" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +checksum = "0134f9043ed38b087ac4f7d4af44c79e2c9e5094421fe3164f435ce585953b10" dependencies = [ "lock_api", ] [[package]] name = "spki" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" dependencies = [ "base64ct", "der", ] [[package]] -name = "strength_reduce" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" - -[[package]] -name = "string_cache" -version = "0.8.9" +name = "sponge-cursor" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" -dependencies = [ - "new_debug_unreachable", - "parking_lot", - "phf_shared", - "precomputed-hash", -] +checksum = "3a0219bd7d979d58245a4f41f695e1ac9f8befdffadd7f61f1bae9e39abc6620" [[package]] name = "strip-ansi-escapes" @@ -2572,9 +2599,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.118" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" dependencies = [ "proc-macro2", "quote", @@ -2582,19 +2609,21 @@ dependencies = [ ] [[package]] -name = "target-triple" -version = "1.0.0" +name = "syn" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" +checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] -name = "term" -version = "1.2.1" +name = "target-tuple" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1" -dependencies = [ - "windows-sys", -] +checksum = "876fef147edbcbddc8ac5cbbba92c7b86519e314e86638596c09673b2ed01e7f" [[package]] name = "termcolor" @@ -2618,29 +2647,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] @@ -2656,9 +2685,9 @@ dependencies = [ [[package]] name = "toml" -version = "1.1.2+spec-1.1.0" +version = "1.1.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +checksum = "12c0ba9680044b4ce98d391a62094047eada0d64860b80166c39f4a6b5640785" dependencies = [ "indexmap", "serde_core", @@ -2680,18 +2709,18 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ "winnow", ] [[package]] name = "toml_writer" -version = "1.1.1+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" [[package]] name = "tracing" @@ -2712,7 +2741,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -2754,28 +2783,18 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "transpose" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" -dependencies = [ - "num-integer", - "strength_reduce", -] - [[package]] name = "trybuild" -version = "1.0.117" +version = "1.0.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0710d4dfbeae4f9c390baa784c49858a7468fa433f3fe5d0ec5ebef651cf59f9" +checksum = "c0cabaa10be1917331a313866bd94526343e03c77bcf69144b62b072ad35d47c" dependencies = [ "dissimilar", "glob", "serde", "serde_derive", "serde_json", - "target-triple", + "target-tuple", "termcolor", "toml", ] @@ -2830,12 +2849,12 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" dependencies = [ "crypto-common", - "subtle", + "ctutils", ] [[package]] @@ -2859,12 +2878,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - [[package]] name = "vte" version = "0.14.1" @@ -2884,12 +2897,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - [[package]] name = "wasip2" version = "1.0.4+wasi-0.2.12" @@ -2901,9 +2908,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf" dependencies = [ "cfg-if", "once_cell", @@ -2914,9 +2921,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2924,22 +2931,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e" dependencies = [ "unicode-ident", ] @@ -2972,7 +2979,7 @@ version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e6fb4c2bee46c5ea4d40f8cdb5c131725cd976718ec56f1c8e82fbde5fa2a80" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.1", "hashbrown", "indexmap", "semver 1.0.28", @@ -2987,6 +2994,18 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "wincode" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfc6339f1ba427bf7ad7c42403b28e524832ba2ddb5eef1bb2cc3b85db6b7b75" +dependencies = [ + "pastey", + "proc-macro2", + "quote", + "thiserror", +] + [[package]] name = "windows-link" version = "0.2.1" @@ -3013,9 +3032,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" [[package]] name = "wit-bindgen" @@ -3047,7 +3066,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn 2.0.118", + "syn 2.0.119", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -3063,7 +3082,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -3075,7 +3094,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d567162a6b9843080e5e0053f696623ff694bae8ae017c9ec536d1873bbe3d8" dependencies = [ "anyhow", - "bitflags 2.13.0", + "bitflags 2.13.1", "indexmap", "log", "serde", @@ -3106,34 +3125,46 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "wnaf" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "795ca18b3fdb5e62bf982199278341ddcf7ebf7d32e25e212ad05d496e95f6fa" +dependencies = [ + "ff", + "group", + "hybrid-array", + "primefield", +] + [[package]] name = "x25519-dalek" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +checksum = "e7e8131a03190127fb2263afc72b322ecadae46b6ff8c6f399ff5d02f5559af6" dependencies = [ "curve25519-dalek", - "rand_core 0.6.4", + "rand_core 0.10.1", ] [[package]] name = "zerocopy" -version = "0.8.52" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" +checksum = "d35102a9f36d089ccae9e4c6802bc118be4487b80aaffc0ab4e0cf5ce92d2873" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.52" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" +checksum = "146c01f5ab44258da43cf276c74a2763db2ff3969c9c652c3f2de07041d0b2bc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -3144,6 +3175,6 @@ checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/examples/miden-bank/contracts/deposit-note/Cargo.toml b/examples/miden-bank/contracts/deposit-note/Cargo.toml index 9cbc3f32..b43ab43d 100644 --- a/examples/miden-bank/contracts/deposit-note/Cargo.toml +++ b/examples/miden-bank/contracts/deposit-note/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -miden = "0.13" +miden = "=0.14.0" diff --git a/examples/miden-bank/contracts/deposit-note/miden-project.toml b/examples/miden-bank/contracts/deposit-note/miden-project.toml index 6a6f1657..1bbe651d 100644 --- a/examples/miden-bank/contracts/deposit-note/miden-project.toml +++ b/examples/miden-bank/contracts/deposit-note/miden-project.toml @@ -3,6 +3,7 @@ name = "deposit-note" version = "0.1.0" [lib] +path = "src/lib.rs" kind = "note" namespace = "miden:deposit-note/miden-deposit-note@0.1.0" @@ -10,7 +11,3 @@ namespace = "miden:deposit-note/miden-deposit-note@0.1.0" miden-core = "*" miden-protocol = "*" bank-account = { path = "../bank-account" } - -# WIT for the account component this note calls, produced by building bank-account. -[package.metadata.miden.dependencies] -bank-account = { wit = "../bank-account/target/generated-wit/" } diff --git a/examples/miden-bank/contracts/deposit-note/src/lib.rs b/examples/miden-bank/contracts/deposit-note/src/lib.rs index 5f82e3c3..31e7b82e 100644 --- a/examples/miden-bank/contracts/deposit-note/src/lib.rs +++ b/examples/miden-bank/contracts/deposit-note/src/lib.rs @@ -34,7 +34,7 @@ impl DepositNote { let depositor = active_note::get_sender(); // Get all assets attached to this note - let assets = active_note::get_assets(); + let assets = active_note::get_initial_assets(); // Deposit each asset into the bank for asset in assets { diff --git a/examples/miden-bank/contracts/init-tx-script/Cargo.lock b/examples/miden-bank/contracts/init-tx-script/Cargo.lock index 3a2e1537..fc867cfa 100644 --- a/examples/miden-bank/contracts/init-tx-script/Cargo.lock +++ b/examples/miden-bank/contracts/init-tx-script/Cargo.lock @@ -4,19 +4,19 @@ version = 4 [[package]] name = "aead" -version = "0.5.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +checksum = "1973cfbc1a2daf9cf550e74e1f088c28e7f7d8c1e1418fb6c9dc5184b7e84c99" dependencies = [ "crypto-common", - "generic-array", + "inout", ] [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] @@ -73,30 +73,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" - -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "arrayvec" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe" - -[[package]] -name = "ascii-canvas" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" -dependencies = [ - "term", -] +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] name = "autocfg" @@ -106,9 +91,9 @@ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "base16ct" -version = "0.2.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" [[package]] name = "base64ct" @@ -122,30 +107,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bit-set" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" - [[package]] name = "bitflags" version = "1.3.2" @@ -154,31 +115,30 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.13.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "blake3" -version = "1.8.5" +version = "1.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce" +checksum = "6d9e454fc11f76977dc803893aff6304ed33d6a26efae8696573bea74baa27ae" dependencies = [ - "arrayref", "arrayvec", "cc", "cfg-if", "constant_time_eq", - "cpufeatures 0.3.0", + "cpufeatures", ] [[package]] name = "block-buffer" -version = "0.10.4" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -189,9 +149,9 @@ checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "cc" -version = "1.2.65" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" +checksum = "005ec2760ca554fae18df7a11195552ec576cd665632a881bc011d5bb2fd4d80" dependencies = [ "find-msvc-tools", "jobserver", @@ -207,39 +167,45 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chacha20" -version = "0.9.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" dependencies = [ "cfg-if", "cipher", - "cpufeatures 0.2.17", + "cpufeatures", + "rand_core 0.10.1", ] [[package]] name = "chacha20poly1305" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +checksum = "9b89e1c441e926b9c82a8d023f6e1b7ae0adcfaa7d621814e4d60789bac751cb" dependencies = [ "aead", "chacha20", "cipher", "poly1305", - "zeroize", ] [[package]] name = "cipher" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ + "block-buffer", "crypto-common", "inout", - "zeroize", ] +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "colorchoice" version = "1.0.5" @@ -248,9 +214,9 @@ checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "const-oid" -version = "0.9.6" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" [[package]] name = "constant_time_eq" @@ -259,19 +225,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" [[package]] -name = "cpufeatures" -version = "0.2.17" +name = "cpubits" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" [[package]] name = "cpufeatures" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" dependencies = [ "libc", ] @@ -284,9 +247,9 @@ checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-deque" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -294,18 +257,18 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" [[package]] name = "crunchy" @@ -315,35 +278,47 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" -version = "0.5.5" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +checksum = "1a52aa3fcda4e6302a9f48734f234d35d4721b96f8fe07d073f07ce9df4f0271" dependencies = [ - "generic-array", - "rand_core 0.6.4", + "cpubits", + "ctutils", + "hybrid-array", + "num-traits", + "rand_core 0.10.1", "subtle", "zeroize", ] [[package]] name = "crypto-common" -version = "0.1.7" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ - "generic-array", - "rand_core 0.6.4", - "typenum", + "hybrid-array", + "rand_core 0.10.1", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", + "subtle", ] [[package]] name = "curve25519-dalek" -version = "4.1.3" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "b5eed333089e2e1c1ac8c6c0398e5e2497b4c9926ca6d0365ed1e099afa5bc23" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures", "curve25519-dalek-derive", "digest", "fiat-crypto", @@ -360,14 +335,14 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "defmt" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6e524506490a1953d237cb87b1cfc1e46f88c18f10a22dfe0f507dc6bfc7f7f" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" dependencies = [ "bitflags 1.3.2", "defmt-macros", @@ -375,15 +350,14 @@ dependencies = [ [[package]] name = "defmt-macros" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a27770e9c8f719a79d8b638281f4d828f77d8fd61e0bd94451b9b85e576a0b" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" dependencies = [ "defmt-parser", - "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -397,9 +371,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.10" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "a878c850e9e421b20262e9b41f9c860e4785fa07541c266b62ff9d1ef998a80a" dependencies = [ "const-oid", "zeroize", @@ -423,19 +397,19 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "digest" -version = "0.10.7" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer", "const-oid", "crypto-common", - "subtle", + "ctutils", ] [[package]] @@ -446,9 +420,9 @@ checksum = "aeda16ab4059c5fd2a83f2b9c9e9c981327b18aa8e3b313f7e6563799d4f093e" [[package]] name = "ecdsa" -version = "0.16.9" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +checksum = "c0681a4fc24c767085329728d8dfba959af91228aa4610cca4f8ce317ba46ae0" dependencies = [ "der", "digest", @@ -456,13 +430,14 @@ dependencies = [ "rfc6979", "signature", "spki", + "zeroize", ] [[package]] name = "ed25519" -version = "2.2.3" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +checksum = "29fcf32e6c73d1079f83ab4d782de2d81620346a5f38c6237a86a22f8368980a" dependencies = [ "pkcs8", "signature", @@ -470,53 +445,46 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +checksum = "6ebaa1a2bf1290ab3bfe5a7b771d050ebffab2711c19a81691c683a5144a25de" dependencies = [ "curve25519-dalek", "ed25519", "serde", "sha2", + "signature", "subtle", "zeroize", ] [[package]] name = "either" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "elliptic-curve" -version = "0.13.8" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "9d65aa39b3a5c1c9c1b745c9a019234bb7a21b77abcb4f4d266d706e2d577d65" dependencies = [ "base16ct", "crypto-bigint", + "crypto-common", "digest", "ff", - "generic-array", "group", "hkdf", + "hybrid-array", "pkcs8", - "rand_core 0.6.4", + "rand_core 0.10.1", "sec1", "subtle", "zeroize", ] -[[package]] -name = "ena" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" -dependencies = [ - "log", -] - [[package]] name = "env_filter" version = "2.0.0" @@ -559,42 +527,33 @@ dependencies = [ [[package]] name = "ff" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +checksum = "a1f686ab92a9fb0eaf188f6c6c87b89490baa6fdb0db4544ba4dc47f7942489f" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "fixedbitset" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d" [[package]] name = "flume" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "spin 0.9.8", + "spin 0.9.9", ] [[package]] @@ -605,18 +564,18 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "fs-err" -version = "3.3.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fde052dbfc920003cfd2c8e2c6e6d4cc7c1091538c3a24226cec0665ab08c0" +checksum = "b91aa448ca50d7e79433bdf3ee8d99215430d2ec02ade5aefab2a073a1822e8a" dependencies = [ "autocfg", ] [[package]] name = "futures" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" dependencies = [ "futures-channel", "futures-core", @@ -628,9 +587,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -638,39 +597,38 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-io" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-sink" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-core", "futures-sink", "futures-task", "pin-project-lite", - "slab", ] [[package]] @@ -688,58 +646,46 @@ dependencies = [ "windows-result", ] -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - [[package]] name = "getrandom" -version = "0.2.17" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", - "js-sys", "libc", - "wasi", - "wasm-bindgen", + "r-efi 5.3.0", + "wasip2", ] [[package]] name = "getrandom" -version = "0.3.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", - "wasip2", + "r-efi 6.0.0", + "rand_core 0.10.1", "wasm-bindgen", ] [[package]] name = "glob" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" [[package]] name = "group" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] @@ -760,22 +706,33 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hkdf" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" dependencies = [ "hmac", ] [[package]] name = "hmac" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ "digest", ] +[[package]] +name = "hybrid-array" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17" +dependencies = [ + "subtle", + "typenum", + "zeroize", +] + [[package]] name = "id-arena" version = "2.3.0" @@ -790,9 +747,9 @@ checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" -version = "2.14.0" +version = "2.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" dependencies = [ "equivalent", "hashbrown", @@ -809,11 +766,11 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -824,9 +781,9 @@ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc" dependencies = [ "either", ] @@ -839,11 +796,12 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.29" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f877a98676d2fb664698d74cc6a51ce6c484ce8c770f05d0108ec9090aeb46" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" dependencies = [ "defmt", + "jiff-core", "jiff-static", "log", "portable-atomic", @@ -851,89 +809,69 @@ dependencies = [ "serde_core", ] +[[package]] +name = "jiff-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +dependencies = [ + "defmt", +] + [[package]] name = "jiff-static" -version = "0.2.29" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0666b5ab5ecaca213fc2a85b8c0083d9004e84ee2d5f9a7e0017aaf50986f25f" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" dependencies = [ + "jiff-core", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.103" +version = "0.3.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +checksum = "ce57d20d1ea864ce2ac172ab472d409214f4fd359f0b2a2775abdf522e2af99e" dependencies = [ "cfg-if", - "futures-util", "wasm-bindgen", ] [[package]] name = "k256" -version = "0.13.4" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +checksum = "93f50113171a713f4a4231ef82eb26703607139b35dcb56241f0ceab2ae1f7d8" dependencies = [ - "cfg-if", + "cpubits", "ecdsa", "elliptic-curve", - "once_cell", + "primeorder", "sha2", - "signature", + "wnaf", ] [[package]] name = "keccak" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" -dependencies = [ - "cpufeatures 0.2.17", -] - -[[package]] -name = "lalrpop" -version = "0.22.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" -dependencies = [ - "ascii-canvas", - "bit-set", - "ena", - "itertools", - "lalrpop-util", - "petgraph", - "regex", - "regex-syntax", - "sha3", - "string_cache", - "term", - "unicode-xid", - "walkdir", -] - -[[package]] -name = "lalrpop-util" -version = "0.22.2" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" +checksum = "d8f198d1db720e4940b5a493201d199d9f24f568f8f746bd13706243a2f71598" dependencies = [ - "rustversion", + "cfg-if", + "cpufeatures", ] [[package]] @@ -950,9 +888,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.186" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libm" @@ -971,9 +909,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "loom" @@ -999,15 +937,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.2" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "miden" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab74b8469fe68b32551bbd85943580800c1b5f2e4683c85ad3e88a628c4e28a7" +checksum = "d0cad08495d4826f7e40ee0cd69bc207f81cc5376844e1718ccb9a3e9e0ba0d6" dependencies = [ "miden-base", "miden-base-macros", @@ -1016,15 +954,17 @@ dependencies = [ "miden-field-repr", "miden-sdk-alloc", "miden-stdlib-sys", + "miden-tx-script-args", "wit-bindgen", ] [[package]] name = "miden-ace-codegen" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd45076fe4fef71f0f8b30aa0f018eb39c3086eeb5f3cafc0e12d60cd28339e" +checksum = "00ff2a44c7f7dc497ac56c74dca5b3465b4b46be066fa88c2c58a8eb1bcb2dc8" dependencies = [ + "miden-constraint-compiler", "miden-core", "miden-crypto", "thiserror", @@ -1032,24 +972,24 @@ dependencies = [ [[package]] name = "miden-air" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f1a80330b3e3d3f98e08817dc6a5e3d90d11ab5e88aa9c0dad5d3b4202598b" +checksum = "84b6d3f3336c8a2da5cd0924c42dd1f339e6c3d5adf3221bc1c005b444fd0bf0" dependencies = [ "miden-ace-codegen", "miden-core", "miden-crypto", - "miden-lifted-stark", "miden-utils-indexing", + "p3-field", "thiserror", "tracing", ] [[package]] name = "miden-assembly" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8582d184360be35eb2111a99245f556f43e1066ed09192fbcd0f218c466862a5" +checksum = "644b31bdda941328f9ff2088382b7de41569c1cc83d6090f63e43d261e9cd262" dependencies = [ "log", "miden-assembly-syntax", @@ -1064,14 +1004,12 @@ dependencies = [ [[package]] name = "miden-assembly-syntax" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffa307bc2cbd1f0cb74ed58981823f400a433900fb8f963762331fbb8389d5dc" +checksum = "cad0d5174833b17b498d541d1ef62d73929a143ea56ea5eba719339c15cd0968" dependencies = [ - "aho-corasick", - "lalrpop", - "lalrpop-util", "log", + "miden-assembly-syntax-cst", "miden-core", "miden-debug-types", "miden-utils-diagnostics", @@ -1085,11 +1023,23 @@ dependencies = [ "thiserror", ] +[[package]] +name = "miden-assembly-syntax-cst" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff301e56d9201821a4458564ed19ae9b95c7a219662a422e47bb61d17e0fa7b1" +dependencies = [ + "miden-debug-types", + "miden-rowan", + "miden-utils-diagnostics", + "thiserror", +] + [[package]] name = "miden-base" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2465a5ecd9546c354cbc6121ffe427cc5c7f98cbca08852049d11c675eb5a4b" +checksum = "5635698d03259fd13404b5376ae5f6c3b2d9e95918befd9ce0799de91e3b036a" dependencies = [ "miden-base-sys", "miden-stdlib-sys", @@ -1097,9 +1047,9 @@ dependencies = [ [[package]] name = "miden-base-macros" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a840ad62ba5264b33e460fbd530efacfc3dadca4d40534316ed50609e291e071" +checksum = "0d4e1fad0a94d307b223dd59e5a54c39615f4b48cd3b0e58670912fc404bd480" dependencies = [ "heck", "miden-assembly-syntax", @@ -1112,7 +1062,7 @@ dependencies = [ "proc-macro2", "quote", "semver 1.0.28", - "syn 2.0.118", + "syn 2.0.119", "toml", "wit-bindgen-core", "wit-bindgen-rust", @@ -1120,19 +1070,29 @@ dependencies = [ [[package]] name = "miden-base-sys" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "933380029fdc065398ae07af3ebdebd8fb425a74b4fe231d23774bbf00e11d67" +checksum = "8156d21c2e9f6755b82502045b775cb98c5d10f80ab957d9bcfde509aa32b8dc" dependencies = [ "miden-field-repr", "miden-stdlib-sys", ] +[[package]] +name = "miden-constraint-compiler" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01ef51ec02f0899c5fc6aa4af11eb050094d98e5e6bf8767a4da555d210f2de6" +dependencies = [ + "miden-core", + "miden-crypto", +] + [[package]] name = "miden-core" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80657c32850817f5f67dcf114866495a4b055531778b7c26d0602646ce777eb8" +checksum = "3b27f9f91988c5e74b50b543c4e6d37ec729eabcf70db63cf752dedd780f8a90" dependencies = [ "derive_more", "log", @@ -1142,34 +1102,46 @@ dependencies = [ "miden-utils-core-derive", "miden-utils-indexing", "miden-utils-sync", - "num-derive", - "num-traits", "serde", "thiserror", ] [[package]] name = "miden-core-lib" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16410655f32f98537afc9ddf57b71cb6d1ca9d980da5f4eea164cafcaf891b2e" +checksum = "14df9652fc4963f20d11df9ceb576ccb7831b5dc72fabec5c1b602f51e57909c" dependencies = [ "env_logger", "fs-err", "miden-assembly", + "miden-assembly-syntax", "miden-core", + "miden-core-lib-codegen", "miden-crypto", + "miden-mast-package", "miden-package-registry", + "miden-precompiles", "miden-processor", "miden-utils-sync", "thiserror", ] +[[package]] +name = "miden-core-lib-codegen" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aad0b8badcf1636150cac0d74aabadd395ba7d570227eb0923ff14f02a278fff" +dependencies = [ + "miden-core", + "miden-precompiles", +] + [[package]] name = "miden-crypto" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35198bebd353cddc25ad4aafb5f4ef9e71b283d71c787b8938c575c16974135d" +checksum = "7c917b0342d911ae4b7a549bb3ca791c093dac4770f88b02e23b43f3fa8179f5" dependencies = [ "blake3", "cc", @@ -1196,10 +1168,8 @@ dependencies = [ "p3-maybe-rayon", "p3-symmetric", "p3-util", - "rand 0.9.4", - "rand_chacha", - "rand_core 0.9.5", - "rand_hc", + "rand 0.10.2", + "rand_chacha 0.10.0", "serde", "sha2", "sha3", @@ -1210,19 +1180,19 @@ dependencies = [ [[package]] name = "miden-crypto-derive" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9068c6554db0e051f62913575de9949841a46b96ae92d4b7d28e1fed5d8f052b" +checksum = "a7c3165dfd7fd6f587ea5731efd1cc8083ca55c23d2d9b3000f83a3948486044" dependencies = [ "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "miden-debug-types" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956708ccb2f643db398b4b3d4f8d0baf199b1bfb5e34c8be1cd1bc811c005e8e" +checksum = "4c9f3f8e4a8f54a36fbf00330ac8bd1947627c1786cd49b94a08b741590ed173" dependencies = [ "memchr", "miden-crypto", @@ -1235,22 +1205,23 @@ dependencies = [ "serde", "serde_spanned", "thiserror", + "zerocopy", ] [[package]] name = "miden-field" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379a39db52cd932a95d4017a18b712ee53ed0f86cfedf8c63ed72d687a18a191" +checksum = "58cf9de55b88ec86ad272ff4224d76b3e0cbda49e242e78776b0037ba9b0e857" dependencies = [ "miden-serde-utils", - "num-bigint", + "num-bigint 0.5.1", "p3-challenger", "p3-field", "p3-goldilocks", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", "subtle", "thiserror", @@ -1258,9 +1229,9 @@ dependencies = [ [[package]] name = "miden-field-repr" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed71d35f511b703d1620094fcc748cb9383dbf2bd7b304d0b28c506a354acdf" +checksum = "93e13ffca1264db045cc344e573f9460bd0153aa89b755fac454b9070b953cdc" dependencies = [ "miden-field", "miden-field-repr-derive", @@ -1268,13 +1239,13 @@ dependencies = [ [[package]] name = "miden-field-repr-derive" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37e87fe1408b7ebc083614469b761a29c5749a34072b0e33dd4cbdd8d34766c" +checksum = "bf0e54de280a41e83a99caa16b3ffb8670c857c888d3e245920e8a96f42fad58" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1288,11 +1259,12 @@ dependencies = [ [[package]] name = "miden-lifted-air" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789e0e469d1731012d8a018057317f31580611535c20d2a47c022213228cb733" +checksum = "f67e06d47e246db853a9f3e52ec87fa33a8ffc0fe5be0dd99288b2439312f206" dependencies = [ "p3-air", + "p3-challenger", "p3-field", "p3-matrix", "p3-util", @@ -1301,9 +1273,9 @@ dependencies = [ [[package]] name = "miden-lifted-stark" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f62cca91182917b22a47e150028b7c785df620a15b2974a39c64e2b1b7a889d3" +checksum = "a5ee320597c7712698d06811d9144b0e4f2275a21224ef0238652c947b01198b" dependencies = [ "miden-lifted-air", "miden-stark-transcript", @@ -1316,7 +1288,7 @@ dependencies = [ "p3-maybe-rayon", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", "serde", "thiserror", "tracing", @@ -1324,15 +1296,20 @@ dependencies = [ [[package]] name = "miden-mast-package" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f37c21836b40785ce297d363c57740d4e33edcc411f84185a524eddadd5f53c7" +checksum = "1355a2563a52af4399b4a93120a4398f81415b1fc4edb58310de5034cfa3781d" dependencies = [ + "hashbrown", + "log", "miden-assembly-syntax", "miden-core", "miden-debug-types", + "miden-utils-indexing", + "rustc-hash", "serde", "thiserror", + "zerocopy", ] [[package]] @@ -1351,9 +1328,9 @@ dependencies = [ "rustc_version 0.2.3", "rustversion", "serde_json", - "spin 0.9.8", + "spin 0.9.9", "strip-ansi-escapes", - "syn 2.0.118", + "syn 2.0.119", "textwrap", "thiserror", "trybuild", @@ -1368,14 +1345,14 @@ checksum = "86a905f3ea65634dd4d1041a4f0fd0a3e77aa4118341d265af1a94339182222f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "miden-package-registry" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ece6064beb0582d1c64ba30d0c548c4b7a45f87abae6d69e22fd49c8b343258" +checksum = "a799e66245492c193b0444c3e0ff0fe42418009ec668a3e80c40d9f5b1454aac" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -1387,16 +1364,50 @@ dependencies = [ "thiserror", ] +[[package]] +name = "miden-precompiles" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "073ebeeb4413b9a03c60b0b066f94b8edaa6f50150017a92dc09d3ace92d6976" +dependencies = [ + "miden-core", + "miden-crypto", +] + +[[package]] +name = "miden-precompiles-prover" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76663c4d90cc073f9e2d2aa2349b9dcd25bf6c40db5020d27ce59990b6bd5af" +dependencies = [ + "miden-air", + "miden-core", + "miden-crypto", + "miden-lifted-air", + "miden-lifted-stark", + "miden-precompiles", + "miden-serde-utils", + "ruint", + "serde", + "serde-wincode", + "thiserror", + "tracing", + "wincode", +] + [[package]] name = "miden-processor" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea972ca9e45dbf26aa396367e8508db0f7292adea6f6ddf8d39d0e334285fe2b" +checksum = "2c7331ab96f00f922d29e2f59285f539299061a44ffdeea31b853d2c071f8056" dependencies = [ + "hashbrown", "itertools", "miden-air", "miden-core", "miden-debug-types", + "miden-mast-package", + "miden-precompiles", "miden-utils-diagnostics", "miden-utils-indexing", "paste", @@ -1407,9 +1418,9 @@ dependencies = [ [[package]] name = "miden-project" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5320e7e5b562359bd6161ac752dfe43dd4f69bb06e87f94a21a27bb656e5a20d" +checksum = "6f8201d3a6d0c85c747092309c3c420de42e61e76f71df2189a46411100d120a" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -1424,13 +1435,13 @@ dependencies = [ [[package]] name = "miden-protocol" -version = "0.15.3" +version = "0.16.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66340243e37da5936cb278a8dd11037813f1dc6731c2fc866703b76ed465ebc3" +checksum = "e275feebbe9c2458c5877c5f2a03b8e2152831ce956376f015fc4c50acfffb50" dependencies = [ "bech32", "fs-err", - "getrandom 0.3.4", + "getrandom 0.4.3", "miden-assembly", "miden-assembly-syntax", "miden-core", @@ -1438,37 +1449,65 @@ dependencies = [ "miden-crypto", "miden-crypto-derive", "miden-mast-package", + "miden-package-registry", "miden-processor", + "miden-protocol-build-utils", "miden-utils-sync", "miden-verifier", - "rand 0.9.4", + "rand 0.10.2", "regex", "semver 1.0.28", "thiserror", +] + +[[package]] +name = "miden-protocol-build-utils" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d16cdd96c1d0b3b2d57342d37eaadd15cc7c633bda965fc8c3b23ca249965b4" +dependencies = [ + "fs-err", + "miden-assembly", + "miden-core", + "miden-mast-package", + "miden-package-registry", + "miden-project", + "regex", "walkdir", ] +[[package]] +name = "miden-rowan" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13695bf99aabaa21d6572b807c66bb26251aa3d9b75e828b3c99b97a3b1ce7e" +dependencies = [ + "hashbrown", + "rustc-hash", +] + [[package]] name = "miden-sdk-alloc" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ee9eb34cde96e3158c19e22fedddb03b6e5eb363e272d11cbae9aa963cc315" +checksum = "15deb9ba073e632ca1151fcf7b718227294b750a7be9ac0c655d5ae7f2a6dc43" [[package]] name = "miden-serde-utils" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78cd1d4fcad937312e544f7d53423485e453598aa4fb989d2b6374027a8c136" +checksum = "f5c21a2acdc1928f86803b3ff3c44564c3f614a7dc47dcd64969a5c856d27988" dependencies = [ "p3-field", "p3-goldilocks", + "wincode", ] [[package]] name = "miden-stark-transcript" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05901db2e30d3954243960fe21cea7fbec39f97c27774b56fd5031c28c4881ba" +checksum = "d503630c353389838fa5d668a0d4550130453c7b2a72b802d4adc1ea39ab5bee" dependencies = [ "p3-challenger", "p3-field", @@ -1478,9 +1517,9 @@ dependencies = [ [[package]] name = "miden-stateful-hasher" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faeb47a90c55c5d45051d23cf691588804dd531995b4582c79108b64e445a905" +checksum = "e8c2008195bdb552eeb744074bfc8822049552ccdf7aef3321a32e1ab6be92e6" dependencies = [ "p3-field", "p3-symmetric", @@ -1488,18 +1527,29 @@ dependencies = [ [[package]] name = "miden-stdlib-sys" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "015cb758041aeaae5b2e5062af67459fb71cdacd199838a4a43795eb82f9a11d" +checksum = "152e858a662e3c4524e06becfb98d6727ec7cbc9d51cf9bb8b8bea9e17af5072" dependencies = [ "miden-field", ] +[[package]] +name = "miden-tx-script-args" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c32d126b51f111ff9e8aed25d1ccefc0e3e093b361b88b51e1ab2fd70f96a7" +dependencies = [ + "miden-field", + "miden-field-repr", + "miden-stdlib-sys", +] + [[package]] name = "miden-utils-core-derive" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0b1ee4662beb049a824e11bb21f95a79746c52874967983c9999f1b19a2f471" +checksum = "107d04fcd05b0308e6347113ee6dc13599755e5b4d05ecc08d8b5c05f36a5a39" dependencies = [ "proc-macro2", "quote", @@ -1508,11 +1558,10 @@ dependencies = [ [[package]] name = "miden-utils-diagnostics" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fdc1cd4eda372e1c4b99b9c3677e9b1f87a4d2e362a9f4b8f904273d395efc9" +checksum = "f3b444d204bf082cdab14015ff10d5b0b43a10fba662fef09e4753f6d07faf1f" dependencies = [ - "miden-crypto", "miden-debug-types", "miden-miette", "tracing", @@ -1520,11 +1569,11 @@ dependencies = [ [[package]] name = "miden-utils-indexing" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31444125649f4dad9cde647f614309b6be4f918fed276ada4eb99c01e8b9ca7" +checksum = "f6ff225060e2a5cc4dd6c898eef1f04739461d3401b6de1692bf443cfdd302b0" dependencies = [ - "miden-crypto", + "miden-serde-utils", "proptest", "serde", "thiserror", @@ -1532,9 +1581,9 @@ dependencies = [ [[package]] name = "miden-utils-sync" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "807c8ae625b7652ae7246b225c907c05da72927c31a0fd71c835c4f80931e92e" +checksum = "76b9cb00f01787f8687447cd8a45b3888b470eb35a132df1be9729779d311fd7" dependencies = [ "lock_api", "loom", @@ -1544,34 +1593,37 @@ dependencies = [ [[package]] name = "miden-verifier" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec5556dac919a1c13edeb2bd7181fc6a4c2ce52764a3e518bcdcd9ed48e5b38e" +checksum = "5e049df6008af1fea5a66df8ce98075cc9e00f16122fd5f4e7c4be9a263cae46" dependencies = [ - "bincode", "miden-air", "miden-core", "miden-crypto", + "miden-precompiles", + "miden-precompiles-prover", + "miden-serde-utils", "serde", + "serde-wincode", "thiserror", - "tracing", ] [[package]] name = "midenc-frontend-wasm-metadata" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3303cecb0858b92395b5c3710d52aae96d28e12f13966208731712e83803d" +checksum = "be2bc4e14ad915ca2b51b521bffbfc91bee1b94520277db144b27bd111cd60a7" dependencies = [ + "miden-mast-package", "serde", "serde_json", ] [[package]] name = "midenc-hir-type" -version = "0.6.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff0511aa2201f7098995e38a3c97a319d379c3b2d26fb83677b21b71f61a7b4" +checksum = "dcdf2257de8f3486c8f3e93c45219b782bafad62a8694798c05d5b8f3f79c64e" dependencies = [ "miden-formatting", "miden-serde-utils", @@ -1581,21 +1633,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom 0.2.17", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -1611,7 +1648,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "num-bigint", + "num-bigint 0.4.8", "num-complex", "num-integer", "num-iter", @@ -1621,50 +1658,48 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" dependencies = [ "num-integer", "num-traits", ] [[package]] -name = "num-complex" -version = "0.4.6" +name = "num-bigint" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +checksum = "93e7820bc0a80a0238e650327316f929ba18d5be054b647490a3a6a339f3e7c0" dependencies = [ + "num-integer", "num-traits", ] [[package]] -name = "num-derive" -version = "0.4.2" +name = "num-complex" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", + "num-traits", ] [[package]] name = "num-integer" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" dependencies = [ "num-traits", ] [[package]] name = "num-iter" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -1675,7 +1710,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "num-bigint", + "num-bigint 0.4.8", "num-integer", "num-traits", ] @@ -1706,23 +1741,17 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "owo-colors" -version = "4.3.0" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" +checksum = "13c45bb4a6ae1280ec0803b1ef9d3455eb50f01efbbe1447ab020f1d54fba9d8" [[package]] name = "p3-air" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c824e8d7c7ddf208b742eac8d48e0b2d52d22fa013578a7762bf6931dbab1f46" +checksum = "ddb1be05c0d6f691afe0c9f468018a9a37cfa904dee78a8081ec96eb3cdd88e8" dependencies = [ "p3-field", "p3-matrix", @@ -1731,9 +1760,9 @@ dependencies = [ [[package]] name = "p3-blake3" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2733229a713bd83ccf5eb749e8f8e7380c1052674394a25c0422a772204a20af" +checksum = "6f202f5fbcceb6f56f783d98efb5de27e5a171470e3364de97b0923b39c87ab5" dependencies = [ "blake3", "p3-symmetric", @@ -1742,9 +1771,9 @@ dependencies = [ [[package]] name = "p3-challenger" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8972ccd1d5dc90e46cdb1f2ab4ee2bae49b3917e5e98aa533f0c2b779c010445" +checksum = "84d5d5e1ecf2c80b09b48ce870e8abd08b643454101c5dc9d0fd71bfbd78224d" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -1756,42 +1785,42 @@ dependencies = [ [[package]] name = "p3-dft" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17771aca44632f9cc11f2718d7ea7ec06794946c4190ef3a985bfc893f14c18a" +checksum = "4321a952da2721ecd85ca593ea189798dfb4e439a2cc1378ce1442091880f173" dependencies = [ "itertools", "p3-field", "p3-matrix", "p3-maybe-rayon", "p3-util", - "spin 0.10.0", + "spin 0.12.3", "tracing", ] [[package]] name = "p3-field" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3eb24d0591fd4d282d89cbe4e4efba5571c699375006f80b2cbf53ce83461c" +checksum = "53db75d38e04fc255826f388eca9d05976733dc9754aa3db411bc9ea1a37c1a0" dependencies = [ "itertools", - "num-bigint", + "num-bigint 0.5.1", "p3-maybe-rayon", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", "tracing", ] [[package]] name = "p3-goldilocks" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5751c6591a0d2397d726620c2c29a7436ec6c5e19d2ed74ca5d078d4fbb18eb5" +checksum = "d03b3f31080df31be723b876709246f8f1e532e1c5b82efb5281d705c8304c63" dependencies = [ - "num-bigint", + "num-bigint 0.5.1", "p3-challenger", "p3-dft", "p3-field", @@ -1801,15 +1830,16 @@ dependencies = [ "p3-symmetric", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", + "spin 0.12.3", ] [[package]] name = "p3-keccak" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a7df174ff0c19a8742eb4698eaa1667c5f858d018e2faf09c55f1f24a6f9c3" +checksum = "ae50c8c37eb847c660298fb275e53c025c49b2623a8cfabf67f5322258b2b4db" dependencies = [ "p3-symmetric", "p3-util", @@ -1818,46 +1848,46 @@ dependencies = [ [[package]] name = "p3-matrix" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9c94c0714944e7b8a9a62e6340b1e3e1d3f8ecfd3e35c08798360200e73eff" +checksum = "473eb920c446a6f4536e0d3528fbdca2a23c0e24e1d0d7767452e6d385dd335c" dependencies = [ "itertools", "p3-field", "p3-maybe-rayon", "p3-util", - "rand 0.10.1", + "rand 0.10.2", "serde", "tracing", ] [[package]] name = "p3-maybe-rayon" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebc233a34b1ab0273f35b4052fa2eeb3114b22ba4575bd7da00716e878ffb77" +checksum = "e6fddfd435f96394769414cf5590b77058aa506659bf20d6592e9d1989e04440" [[package]] name = "p3-mds" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b5441fa8116246ec9e6c835f15273cb27777ca572960ec87476b67fef13e01e" +checksum = "551ba0ab2cccd89f85a99450224898aff224e323bbf61f777ba6344f0896ef10" dependencies = [ "p3-dft", "p3-field", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-monty-31" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8724f330ea6d19dd4f2436aa0f88b5fcbf88f0f55ca7fccd3fea8b736dbcddad" +checksum = "871f635f7340cd0868b17e43e0c98fefdafdaed90469d0725caf6d8372a2a47c" dependencies = [ "itertools", - "num-bigint", + "num-bigint 0.5.1", "p3-dft", "p3-field", "p3-matrix", @@ -1868,41 +1898,42 @@ dependencies = [ "p3-symmetric", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", - "spin 0.10.0", + "spin 0.12.3", "tracing", ] [[package]] name = "p3-poseidon1" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e2a562fea210baae390a32f9ecf0dd8724ae3f4352d1c8e413077b6f00a162" +checksum = "8d0d304e9a1f29c0d66534aa84e69528e2118351fdce08dcf5898af4e0fecc32" dependencies = [ "p3-field", + "p3-mds", "p3-symmetric", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-poseidon2" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06394851c161d17e4aa4ad2aad5557d32f14cadd1dc838f965d8e1821a63b8c5" +checksum = "43eb8a73a26d14becaed1c67c3e8a047e4311d7909b402383c82ca9643ba17c6" dependencies = [ "p3-field", "p3-mds", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-symmetric" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac1a276d421f8ef3361bb7d8c39a02c93c6b3f10eeaa559cc4c50222f9a5b82" +checksum = "2015ea80cad969b6aabf27a04884286fe1354393b166d968ee0d80a95126b2a4" dependencies = [ "itertools", "p3-field", @@ -1912,12 +1943,11 @@ dependencies = [ [[package]] name = "p3-util" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d08a58162a4c264269ef454f0b28dcda89939490eecacb2b2cf5b00f719b80f6" +checksum = "6c5466fc40e6df89d3b291a2eff16b33e68e8571207790370137ec18090aadab" dependencies = [ "serde", - "transpose", ] [[package]] @@ -1950,23 +1980,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] -name = "petgraph" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" -dependencies = [ - "fixedbitset", - "indexmap", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" +name = "pastey" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher", -] +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" [[package]] name = "pin-project-lite" @@ -1976,9 +1993,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkcs8" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ "der", "spki", @@ -1986,26 +2003,25 @@ dependencies = [ [[package]] name = "poly1305" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +checksum = "6e2d0073b297041425c7c3df6eb4792d598a15323fe63346852b092eca02904c" dependencies = [ - "cpufeatures 0.2.17", - "opaque-debug", + "cpufeatures", "universal-hash", ] [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "portable-atomic-util" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" dependencies = [ "portable-atomic", ] @@ -2019,12 +2035,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - [[package]] name = "prettyplease" version = "0.2.37" @@ -2032,47 +2042,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] -name = "priority-queue" -version = "2.7.0" +name = "primefield" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" +checksum = "c555a6e4eb7d4e158fcb028c835c3b8642206ddc279b5c6b202ef9a8bdb592f4" dependencies = [ - "equivalent", - "indexmap", - "serde", + "crypto-bigint", + "crypto-common", + "ff", + "rand_core 0.10.1", + "subtle", + "zeroize", ] [[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" +name = "primeorder" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +checksum = "5c9f42978c78a00e3d68f69fc03e57a234debae69da4020a4fb588fcdcd07b06" dependencies = [ - "proc-macro2", - "quote", + "elliptic-curve", + "primefield", + "serdect", + "wnaf", ] [[package]] -name = "proc-macro-error2" -version = "2.0.1" +name = "priority-queue" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" dependencies = [ - "proc-macro-error-attr2", - "proc-macro2", - "quote", - "syn 2.0.118", + "equivalent", + "indexmap", + "serde", ] [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -2083,10 +2097,10 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.1", "num-traits", - "rand 0.9.4", - "rand_chacha", + "rand 0.9.5", + "rand_chacha 0.9.0", "rand_xorshift", "regex-syntax", "unarray", @@ -2108,9 +2122,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.46" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -2121,22 +2135,30 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "rand" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ - "rand_chacha", + "rand_chacha 0.9.0", "rand_core 0.9.5", ] [[package]] name = "rand" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ + "chacha20", + "getrandom 0.4.3", "rand_core 0.10.1", ] @@ -2151,12 +2173,13 @@ dependencies = [ ] [[package]] -name = "rand_core" -version = "0.6.4" +name = "rand_chacha" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "3e6af7f3e25ded52c41df4e0b1af2d047e45896c2f3281792ed68a1c243daedb" dependencies = [ - "getrandom 0.2.17", + "ppv-lite86", + "rand_core 0.10.1", ] [[package]] @@ -2174,15 +2197,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" -[[package]] -name = "rand_hc" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b363d4f6370f88d62bf586c80405657bde0f0e1b8945d47d2ad59b906cb4f54" -dependencies = [ - "rand_core 0.6.4", -] - [[package]] name = "rand_xorshift" version = "0.4.0" @@ -2218,14 +2232,14 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.1", ] [[package]] name = "regex" -version = "1.12.4" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -2235,9 +2249,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -2252,19 +2266,34 @@ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rfc6979" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +checksum = "b4a459cddafb3fe76b31fd8f1108007566c40301feb64dc7b54656eb7388172b" dependencies = [ + "crypto-bigint", "hmac", - "subtle", ] +[[package]] +name = "ruint" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e99bff0393163bb25029a6af25d3d8d202ba5b5438a74d1bd8789f5c822970" +dependencies = [ + "ruint-macro", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustc_version" @@ -2286,9 +2315,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "same-file" @@ -2313,14 +2342,14 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sec1" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" dependencies = [ "base16ct", + "ctutils", "der", - "generic-array", - "pkcs8", + "hybrid-array", "subtle", "zeroize", ] @@ -2352,9 +2381,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -2372,31 +2401,42 @@ dependencies = [ "typeid", ] +[[package]] +name = "serde-wincode" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa9d3a86c66cf10ce79df36f555a5a4c8d72a82515d9ea8ca420e02c925c30f" +dependencies = [ + "serde", + "thiserror", + "wincode", +] + [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", ] [[package]] name = "serde_json" -version = "1.0.150" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -2407,13 +2447,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", ] [[package]] @@ -2425,25 +2465,36 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serdect" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66cf8fedced2fcf12406bcb34223dffb92eaf34908ede12fed414c82b7f00b3e" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "sha2" -version = "0.10.9" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures", "digest", ] [[package]] name = "sha3" -version = "0.10.9" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +checksum = "bc9bad02c26382724b2d2692c6f179285e4b54eeecd7968f52a50059c3c11759" dependencies = [ "digest", "keccak", + "sponge-cursor", ] [[package]] @@ -2463,31 +2514,19 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signature" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" dependencies = [ "digest", - "rand_core 0.6.4", + "rand_core 0.10.1", ] -[[package]] -name = "siphasher" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" - -[[package]] -name = "slab" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - [[package]] name = "smallvec" -version = "1.15.2" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +checksum = "b9be42f50aa861c555654aa3a37f52f4b1074bacf4e48fe0ef7fa584e80f1f0f" dependencies = [ "serde", ] @@ -2500,49 +2539,37 @@ checksum = "e8e2fb0f499abb4d162f2bedad68f5ef91a1682b5a03596ddb67efd37768d100" [[package]] name = "spin" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" dependencies = [ "lock_api", ] [[package]] name = "spin" -version = "0.10.0" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +checksum = "0134f9043ed38b087ac4f7d4af44c79e2c9e5094421fe3164f435ce585953b10" dependencies = [ "lock_api", ] [[package]] name = "spki" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" dependencies = [ "base64ct", "der", ] [[package]] -name = "strength_reduce" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" - -[[package]] -name = "string_cache" -version = "0.8.9" +name = "sponge-cursor" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" -dependencies = [ - "new_debug_unreachable", - "parking_lot", - "phf_shared", - "precomputed-hash", -] +checksum = "3a0219bd7d979d58245a4f41f695e1ac9f8befdffadd7f61f1bae9e39abc6620" [[package]] name = "strip-ansi-escapes" @@ -2572,9 +2599,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.118" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" dependencies = [ "proc-macro2", "quote", @@ -2582,19 +2609,21 @@ dependencies = [ ] [[package]] -name = "target-triple" -version = "1.0.0" +name = "syn" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" +checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] -name = "term" -version = "1.2.1" +name = "target-tuple" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1" -dependencies = [ - "windows-sys", -] +checksum = "876fef147edbcbddc8ac5cbbba92c7b86519e314e86638596c09673b2ed01e7f" [[package]] name = "termcolor" @@ -2618,29 +2647,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] @@ -2656,9 +2685,9 @@ dependencies = [ [[package]] name = "toml" -version = "1.1.2+spec-1.1.0" +version = "1.1.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +checksum = "12c0ba9680044b4ce98d391a62094047eada0d64860b80166c39f4a6b5640785" dependencies = [ "indexmap", "serde_core", @@ -2680,18 +2709,18 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ "winnow", ] [[package]] name = "toml_writer" -version = "1.1.1+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" [[package]] name = "tracing" @@ -2712,7 +2741,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -2754,28 +2783,18 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "transpose" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" -dependencies = [ - "num-integer", - "strength_reduce", -] - [[package]] name = "trybuild" -version = "1.0.117" +version = "1.0.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0710d4dfbeae4f9c390baa784c49858a7468fa433f3fe5d0ec5ebef651cf59f9" +checksum = "c0cabaa10be1917331a313866bd94526343e03c77bcf69144b62b072ad35d47c" dependencies = [ "dissimilar", "glob", "serde", "serde_derive", "serde_json", - "target-triple", + "target-tuple", "termcolor", "toml", ] @@ -2830,12 +2849,12 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" dependencies = [ "crypto-common", - "subtle", + "ctutils", ] [[package]] @@ -2859,12 +2878,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - [[package]] name = "vte" version = "0.14.1" @@ -2884,12 +2897,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - [[package]] name = "wasip2" version = "1.0.4+wasi-0.2.12" @@ -2901,9 +2908,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf" dependencies = [ "cfg-if", "once_cell", @@ -2914,9 +2921,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2924,22 +2931,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e" dependencies = [ "unicode-ident", ] @@ -2972,7 +2979,7 @@ version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e6fb4c2bee46c5ea4d40f8cdb5c131725cd976718ec56f1c8e82fbde5fa2a80" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.1", "hashbrown", "indexmap", "semver 1.0.28", @@ -2987,6 +2994,18 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "wincode" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfc6339f1ba427bf7ad7c42403b28e524832ba2ddb5eef1bb2cc3b85db6b7b75" +dependencies = [ + "pastey", + "proc-macro2", + "quote", + "thiserror", +] + [[package]] name = "windows-link" version = "0.2.1" @@ -3013,9 +3032,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" [[package]] name = "wit-bindgen" @@ -3047,7 +3066,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn 2.0.118", + "syn 2.0.119", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -3063,7 +3082,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -3075,7 +3094,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d567162a6b9843080e5e0053f696623ff694bae8ae017c9ec536d1873bbe3d8" dependencies = [ "anyhow", - "bitflags 2.13.0", + "bitflags 2.13.1", "indexmap", "log", "serde", @@ -3106,34 +3125,46 @@ dependencies = [ "wasmparser", ] +[[package]] +name = "wnaf" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "795ca18b3fdb5e62bf982199278341ddcf7ebf7d32e25e212ad05d496e95f6fa" +dependencies = [ + "ff", + "group", + "hybrid-array", + "primefield", +] + [[package]] name = "x25519-dalek" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +checksum = "e7e8131a03190127fb2263afc72b322ecadae46b6ff8c6f399ff5d02f5559af6" dependencies = [ "curve25519-dalek", - "rand_core 0.6.4", + "rand_core 0.10.1", ] [[package]] name = "zerocopy" -version = "0.8.52" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" +checksum = "d35102a9f36d089ccae9e4c6802bc118be4487b80aaffc0ab4e0cf5ce92d2873" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.52" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" +checksum = "146c01f5ab44258da43cf276c74a2763db2ff3969c9c652c3f2de07041d0b2bc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -3144,6 +3175,6 @@ checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/examples/miden-bank/contracts/init-tx-script/Cargo.toml b/examples/miden-bank/contracts/init-tx-script/Cargo.toml index 4439b39b..4e5cabad 100644 --- a/examples/miden-bank/contracts/init-tx-script/Cargo.toml +++ b/examples/miden-bank/contracts/init-tx-script/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -miden = "0.13" +miden = "=0.14.0" diff --git a/examples/miden-bank/contracts/init-tx-script/miden-project.toml b/examples/miden-bank/contracts/init-tx-script/miden-project.toml index 1b383d20..2ad3b5f6 100644 --- a/examples/miden-bank/contracts/init-tx-script/miden-project.toml +++ b/examples/miden-bank/contracts/init-tx-script/miden-project.toml @@ -3,6 +3,7 @@ name = "init-tx-script" version = "0.1.0" [lib] +path = "src/lib.rs" kind = "tx-script" namespace = "miden:base/transaction-script@1.0.0" @@ -10,6 +11,3 @@ namespace = "miden:base/transaction-script@1.0.0" miden-core = "*" miden-protocol = "*" bank-account = { path = "../bank-account" } - -[package.metadata.miden.dependencies] -bank-account = { wit = "../bank-account/target/generated-wit/" } diff --git a/examples/miden-bank/contracts/init-tx-script/src/lib.rs b/examples/miden-bank/contracts/init-tx-script/src/lib.rs index 4fdf4282..0a1a7bdd 100644 --- a/examples/miden-bank/contracts/init-tx-script/src/lib.rs +++ b/examples/miden-bank/contracts/init-tx-script/src/lib.rs @@ -17,7 +17,7 @@ pub struct Wallet; /// 1. Transaction is created with this script attached /// 2. Script executes in the context of the bank account /// 3. Calls `account.initialize()` to enable deposits -/// 4. Bank account is now "deployed" and visible on chain +/// 4. Bank is ready to process deposits after the transaction commits /// /// # Arguments /// * `_arg` - Transaction script argument (unused in this script) diff --git a/examples/miden-bank/contracts/withdraw-request-note/Cargo.lock b/examples/miden-bank/contracts/withdraw-request-note/Cargo.lock index 00304361..851985a3 100644 --- a/examples/miden-bank/contracts/withdraw-request-note/Cargo.lock +++ b/examples/miden-bank/contracts/withdraw-request-note/Cargo.lock @@ -4,19 +4,19 @@ version = 4 [[package]] name = "aead" -version = "0.5.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +checksum = "1973cfbc1a2daf9cf550e74e1f088c28e7f7d8c1e1418fb6c9dc5184b7e84c99" dependencies = [ "crypto-common", - "generic-array", + "inout", ] [[package]] name = "aho-corasick" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba" dependencies = [ "memchr", ] @@ -73,30 +73,15 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.102" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" - -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" +checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" [[package]] name = "arrayvec" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe" - -[[package]] -name = "ascii-canvas" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef1e3e699d84ab1b0911a1010c5c106aa34ae89aeac103be5ce0c3859db1e891" -dependencies = [ - "term", -] +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" [[package]] name = "autocfg" @@ -106,9 +91,9 @@ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "base16ct" -version = "0.2.0" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" +checksum = "fd307490d624467aa6f74b0eabb77633d1f758a7b25f12bceb0b22e08d9726f6" [[package]] name = "base64ct" @@ -122,30 +107,6 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - -[[package]] -name = "bit-set" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" -dependencies = [ - "bit-vec", -] - -[[package]] -name = "bit-vec" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" - [[package]] name = "bitflags" version = "1.3.2" @@ -154,31 +115,30 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.13.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" [[package]] name = "blake3" -version = "1.8.5" +version = "1.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa83c34e62843d924f905e0f5c866eb1dd6545fc4d719e803d9ba6030371fce" +checksum = "6d9e454fc11f76977dc803893aff6304ed33d6a26efae8696573bea74baa27ae" dependencies = [ - "arrayref", "arrayvec", "cc", "cfg-if", "constant_time_eq", - "cpufeatures 0.3.0", + "cpufeatures", ] [[package]] name = "block-buffer" -version = "0.10.4" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -189,9 +149,9 @@ checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "cc" -version = "1.2.65" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" +checksum = "005ec2760ca554fae18df7a11195552ec576cd665632a881bc011d5bb2fd4d80" dependencies = [ "find-msvc-tools", "jobserver", @@ -207,39 +167,45 @@ checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "chacha20" -version = "0.9.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +checksum = "65c35e4b699c7e15ccbe7ee35c005e4fc0a278d22238a2857e6ce2dadeda1b06" dependencies = [ "cfg-if", "cipher", - "cpufeatures 0.2.17", + "cpufeatures", + "rand_core 0.10.1", ] [[package]] name = "chacha20poly1305" -version = "0.10.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +checksum = "9b89e1c441e926b9c82a8d023f6e1b7ae0adcfaa7d621814e4d60789bac751cb" dependencies = [ "aead", "chacha20", "cipher", "poly1305", - "zeroize", ] [[package]] name = "cipher" -version = "0.4.4" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" dependencies = [ + "block-buffer", "crypto-common", "inout", - "zeroize", ] +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "colorchoice" version = "1.0.5" @@ -248,9 +214,9 @@ checksum = "1d07550c9036bf2ae0c684c4297d503f838287c83c53686d05370d0e139ae570" [[package]] name = "const-oid" -version = "0.9.6" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" [[package]] name = "constant_time_eq" @@ -259,19 +225,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" [[package]] -name = "cpufeatures" -version = "0.2.17" +name = "cpubits" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" [[package]] name = "cpufeatures" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +checksum = "5ca28b0ae3115b884660db4118d803791fd6756b6e88f39c0f3f7859060d7566" dependencies = [ "libc", ] @@ -284,9 +247,9 @@ checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" [[package]] name = "crossbeam-deque" -version = "0.8.6" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +checksum = "622f3fc73690be383c7214310406f28a90e6edeadc3cea882f9d71e495b9711a" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -294,18 +257,18 @@ dependencies = [ [[package]] name = "crossbeam-epoch" -version = "0.9.18" +version = "0.9.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +checksum = "dc74980687109a3b14c72fd458107bf0baa1da1a1a805e178d15501ba9b86d9d" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.21" +version = "0.8.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +checksum = "a31eee39dddec8330830986fcd7625edb5a24ec90ea038215273bbc3adb08ac6" [[package]] name = "crunchy" @@ -315,35 +278,47 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" -version = "0.5.5" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +checksum = "1a52aa3fcda4e6302a9f48734f234d35d4721b96f8fe07d073f07ce9df4f0271" dependencies = [ - "generic-array", - "rand_core 0.6.4", + "cpubits", + "ctutils", + "hybrid-array", + "num-traits", + "rand_core 0.10.1", "subtle", "zeroize", ] [[package]] name = "crypto-common" -version = "0.1.7" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" dependencies = [ - "generic-array", - "rand_core 0.6.4", - "typenum", + "hybrid-array", + "rand_core 0.10.1", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", + "subtle", ] [[package]] name = "curve25519-dalek" -version = "4.1.3" +version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +checksum = "b5eed333089e2e1c1ac8c6c0398e5e2497b4c9926ca6d0365ed1e099afa5bc23" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures", "curve25519-dalek-derive", "digest", "fiat-crypto", @@ -360,14 +335,14 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "defmt" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6e524506490a1953d237cb87b1cfc1e46f88c18f10a22dfe0f507dc6bfc7f7f" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" dependencies = [ "bitflags 1.3.2", "defmt-macros", @@ -375,15 +350,14 @@ dependencies = [ [[package]] name = "defmt-macros" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0a27770e9c8f719a79d8b638281f4d828f77d8fd61e0bd94451b9b85e576a0b" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" dependencies = [ "defmt-parser", - "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -397,9 +371,9 @@ dependencies = [ [[package]] name = "der" -version = "0.7.10" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +checksum = "a878c850e9e421b20262e9b41f9c860e4785fa07541c266b62ff9d1ef998a80a" dependencies = [ "const-oid", "zeroize", @@ -423,19 +397,19 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "digest" -version = "0.10.7" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer", "const-oid", "crypto-common", - "subtle", + "ctutils", ] [[package]] @@ -446,9 +420,9 @@ checksum = "aeda16ab4059c5fd2a83f2b9c9e9c981327b18aa8e3b313f7e6563799d4f093e" [[package]] name = "ecdsa" -version = "0.16.9" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +checksum = "c0681a4fc24c767085329728d8dfba959af91228aa4610cca4f8ce317ba46ae0" dependencies = [ "der", "digest", @@ -456,13 +430,14 @@ dependencies = [ "rfc6979", "signature", "spki", + "zeroize", ] [[package]] name = "ed25519" -version = "2.2.3" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +checksum = "29fcf32e6c73d1079f83ab4d782de2d81620346a5f38c6237a86a22f8368980a" dependencies = [ "pkcs8", "signature", @@ -470,53 +445,46 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +checksum = "6ebaa1a2bf1290ab3bfe5a7b771d050ebffab2711c19a81691c683a5144a25de" dependencies = [ "curve25519-dalek", "ed25519", "serde", "sha2", + "signature", "subtle", "zeroize", ] [[package]] name = "either" -version = "1.16.0" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" +checksum = "252afb9ae5eaa683babdc6a068b3f5726eb19e05070c731f9b2a23a7c3e8ed34" [[package]] name = "elliptic-curve" -version = "0.13.8" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +checksum = "9d65aa39b3a5c1c9c1b745c9a019234bb7a21b77abcb4f4d266d706e2d577d65" dependencies = [ "base16ct", "crypto-bigint", + "crypto-common", "digest", "ff", - "generic-array", "group", "hkdf", + "hybrid-array", "pkcs8", - "rand_core 0.6.4", + "rand_core 0.10.1", "sec1", "subtle", "zeroize", ] -[[package]] -name = "ena" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eabffdaee24bd1bf95c5ef7cec31260444317e72ea56c4c91750e8b7ee58d5f1" -dependencies = [ - "log", -] - [[package]] name = "env_filter" version = "2.0.0" @@ -559,42 +527,33 @@ dependencies = [ [[package]] name = "ff" -version = "0.13.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +checksum = "a1f686ab92a9fb0eaf188f6c6c87b89490baa6fdb0db4544ba4dc47f7942489f" dependencies = [ - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] [[package]] name = "fiat-crypto" -version = "0.2.9" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" [[package]] name = "find-msvc-tools" -version = "0.1.9" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" - -[[package]] -name = "fixedbitset" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" +checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d" [[package]] name = "flume" -version = "0.11.1" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095" +checksum = "5e139bc46ca777eb5efaf62df0ab8cc5fd400866427e56c68b22e414e53bd3be" dependencies = [ - "futures-core", - "futures-sink", - "nanorand", - "spin 0.9.8", + "spin 0.9.9", ] [[package]] @@ -605,18 +564,18 @@ checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" [[package]] name = "fs-err" -version = "3.3.0" +version = "3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fde052dbfc920003cfd2c8e2c6e6d4cc7c1091538c3a24226cec0665ab08c0" +checksum = "b91aa448ca50d7e79433bdf3ee8d99215430d2ec02ade5aefab2a073a1822e8a" dependencies = [ "autocfg", ] [[package]] name = "futures" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" +checksum = "9a31d2a3fbaaeb2af2368bbdd904aa8e812d3c04a1ee10d3171f52d556e5d0a3" dependencies = [ "futures-channel", "futures-core", @@ -628,9 +587,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +checksum = "b1f9e3d69d39e4862ffed03ed071a76f9a13ba1d9109d355b0f0aa6b15e393c4" dependencies = [ "futures-core", "futures-sink", @@ -638,39 +597,38 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" [[package]] name = "futures-io" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" +checksum = "53c0fa8157de1303bfffdaa1cc2a673bfffb60102f76b0ef4441659124373fed" [[package]] name = "futures-sink" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" +checksum = "1944426bf7d03f1d14f708785e4b33efd750b36d48a157b836b3efc15ede8e1d" [[package]] name = "futures-task" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" [[package]] name = "futures-util" -version = "0.3.32" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" dependencies = [ "futures-core", "futures-sink", "futures-task", "pin-project-lite", - "slab", ] [[package]] @@ -688,58 +646,46 @@ dependencies = [ "windows-result", ] -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - [[package]] name = "getrandom" -version = "0.2.17" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", - "js-sys", "libc", - "wasi", - "wasm-bindgen", + "r-efi 5.3.0", + "wasip2", ] [[package]] name = "getrandom" -version = "0.3.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", - "wasip2", + "r-efi 6.0.0", + "rand_core 0.10.1", "wasm-bindgen", ] [[package]] name = "glob" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +checksum = "e4eba85ea1d0a966a983acd07deee566e67395d2d96b6fb39e62b5a833f1eb0b" [[package]] name = "group" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +checksum = "7fd1a1c7a5206c5b7a3f5a0d7ccd3ff85d0c8f5133d62a02680255b0004af5f4" dependencies = [ "ff", - "rand_core 0.6.4", + "rand_core 0.10.1", "subtle", ] @@ -760,22 +706,33 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hkdf" -version = "0.12.4" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +checksum = "4aaa26c720c68b866f2c96ef5c1264b3e6f473fe5d4ce61cd44bbe913e553018" dependencies = [ "hmac", ] [[package]] name = "hmac" -version = "0.12.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ "digest", ] +[[package]] +name = "hybrid-array" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27f864f10dfb56725ce5ce5472bc52252c8f93a4ab86327122cebf62c5f59a17" +dependencies = [ + "subtle", + "typenum", + "zeroize", +] + [[package]] name = "id-arena" version = "2.3.0" @@ -790,9 +747,9 @@ checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" [[package]] name = "indexmap" -version = "2.14.0" +version = "2.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +checksum = "cc4e190f5d26ca7051642629da2c52fc03bde85a03197c99408dcd291734c855" dependencies = [ "equivalent", "hashbrown", @@ -802,11 +759,11 @@ dependencies = [ [[package]] name = "inout" -version = "0.1.4" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" dependencies = [ - "generic-array", + "hybrid-array", ] [[package]] @@ -817,9 +774,9 @@ checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" -version = "0.14.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +checksum = "8b4baf93f58d4425749ca49a51c50ebab072c5df6994d08fed93541c331481dc" dependencies = [ "either", ] @@ -832,11 +789,12 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jiff" -version = "0.2.29" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34f877a98676d2fb664698d74cc6a51ce6c484ce8c770f05d0108ec9090aeb46" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" dependencies = [ "defmt", + "jiff-core", "jiff-static", "log", "portable-atomic", @@ -844,89 +802,69 @@ dependencies = [ "serde_core", ] +[[package]] +name = "jiff-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +dependencies = [ + "defmt", +] + [[package]] name = "jiff-static" -version = "0.2.29" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0666b5ab5ecaca213fc2a85b8c0083d9004e84ee2d5f9a7e0017aaf50986f25f" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" dependencies = [ + "jiff-core", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "jobserver" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" +checksum = "1c00acbd29eabad4a2392fa0e921c874934dbbf4194312ad20f04a0ed67a3cb3" dependencies = [ - "getrandom 0.3.4", + "getrandom 0.4.3", "libc", ] [[package]] name = "js-sys" -version = "0.3.103" +version = "0.3.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" +checksum = "ce57d20d1ea864ce2ac172ab472d409214f4fd359f0b2a2775abdf522e2af99e" dependencies = [ "cfg-if", - "futures-util", "wasm-bindgen", ] [[package]] name = "k256" -version = "0.13.4" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +checksum = "93f50113171a713f4a4231ef82eb26703607139b35dcb56241f0ceab2ae1f7d8" dependencies = [ - "cfg-if", + "cpubits", "ecdsa", "elliptic-curve", - "once_cell", + "primeorder", "sha2", - "signature", + "wnaf", ] [[package]] name = "keccak" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" -dependencies = [ - "cpufeatures 0.2.17", -] - -[[package]] -name = "lalrpop" -version = "0.22.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba4ebbd48ce411c1d10fb35185f5a51a7bfa3d8b24b4e330d30c9e3a34129501" -dependencies = [ - "ascii-canvas", - "bit-set", - "ena", - "itertools", - "lalrpop-util", - "petgraph", - "regex", - "regex-syntax", - "sha3", - "string_cache", - "term", - "unicode-xid", - "walkdir", -] - -[[package]] -name = "lalrpop-util" -version = "0.22.2" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5baa5e9ff84f1aefd264e6869907646538a52147a755d494517a8007fb48733" +checksum = "d8f198d1db720e4940b5a493201d199d9f24f568f8f746bd13706243a2f71598" dependencies = [ - "rustversion", + "cfg-if", + "cpufeatures", ] [[package]] @@ -943,9 +881,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.186" +version = "0.2.189" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" [[package]] name = "libm" @@ -964,9 +902,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.33" +version = "0.4.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" +checksum = "f9f8bd3e56ce4dfc153cf470fffbfa98c7620958b312ca5c3a4b8d5181fd13c6" [[package]] name = "loom" @@ -992,15 +930,15 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.2" +version = "2.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" [[package]] name = "miden" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab74b8469fe68b32551bbd85943580800c1b5f2e4683c85ad3e88a628c4e28a7" +checksum = "d0cad08495d4826f7e40ee0cd69bc207f81cc5376844e1718ccb9a3e9e0ba0d6" dependencies = [ "miden-base", "miden-base-macros", @@ -1009,15 +947,17 @@ dependencies = [ "miden-field-repr", "miden-sdk-alloc", "miden-stdlib-sys", + "miden-tx-script-args", "wit-bindgen", ] [[package]] name = "miden-ace-codegen" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd45076fe4fef71f0f8b30aa0f018eb39c3086eeb5f3cafc0e12d60cd28339e" +checksum = "00ff2a44c7f7dc497ac56c74dca5b3465b4b46be066fa88c2c58a8eb1bcb2dc8" dependencies = [ + "miden-constraint-compiler", "miden-core", "miden-crypto", "thiserror", @@ -1025,24 +965,24 @@ dependencies = [ [[package]] name = "miden-air" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69f1a80330b3e3d3f98e08817dc6a5e3d90d11ab5e88aa9c0dad5d3b4202598b" +checksum = "84b6d3f3336c8a2da5cd0924c42dd1f339e6c3d5adf3221bc1c005b444fd0bf0" dependencies = [ "miden-ace-codegen", "miden-core", "miden-crypto", - "miden-lifted-stark", "miden-utils-indexing", + "p3-field", "thiserror", "tracing", ] [[package]] name = "miden-assembly" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8582d184360be35eb2111a99245f556f43e1066ed09192fbcd0f218c466862a5" +checksum = "644b31bdda941328f9ff2088382b7de41569c1cc83d6090f63e43d261e9cd262" dependencies = [ "log", "miden-assembly-syntax", @@ -1057,14 +997,12 @@ dependencies = [ [[package]] name = "miden-assembly-syntax" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffa307bc2cbd1f0cb74ed58981823f400a433900fb8f963762331fbb8389d5dc" +checksum = "cad0d5174833b17b498d541d1ef62d73929a143ea56ea5eba719339c15cd0968" dependencies = [ - "aho-corasick", - "lalrpop", - "lalrpop-util", "log", + "miden-assembly-syntax-cst", "miden-core", "miden-debug-types", "miden-utils-diagnostics", @@ -1078,11 +1016,23 @@ dependencies = [ "thiserror", ] +[[package]] +name = "miden-assembly-syntax-cst" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff301e56d9201821a4458564ed19ae9b95c7a219662a422e47bb61d17e0fa7b1" +dependencies = [ + "miden-debug-types", + "miden-rowan", + "miden-utils-diagnostics", + "thiserror", +] + [[package]] name = "miden-base" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2465a5ecd9546c354cbc6121ffe427cc5c7f98cbca08852049d11c675eb5a4b" +checksum = "5635698d03259fd13404b5376ae5f6c3b2d9e95918befd9ce0799de91e3b036a" dependencies = [ "miden-base-sys", "miden-stdlib-sys", @@ -1090,9 +1040,9 @@ dependencies = [ [[package]] name = "miden-base-macros" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a840ad62ba5264b33e460fbd530efacfc3dadca4d40534316ed50609e291e071" +checksum = "0d4e1fad0a94d307b223dd59e5a54c39615f4b48cd3b0e58670912fc404bd480" dependencies = [ "heck", "miden-assembly-syntax", @@ -1105,7 +1055,7 @@ dependencies = [ "proc-macro2", "quote", "semver 1.0.28", - "syn 2.0.118", + "syn 2.0.119", "toml", "wit-bindgen-core", "wit-bindgen-rust", @@ -1113,19 +1063,29 @@ dependencies = [ [[package]] name = "miden-base-sys" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "933380029fdc065398ae07af3ebdebd8fb425a74b4fe231d23774bbf00e11d67" +checksum = "8156d21c2e9f6755b82502045b775cb98c5d10f80ab957d9bcfde509aa32b8dc" dependencies = [ "miden-field-repr", "miden-stdlib-sys", ] +[[package]] +name = "miden-constraint-compiler" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01ef51ec02f0899c5fc6aa4af11eb050094d98e5e6bf8767a4da555d210f2de6" +dependencies = [ + "miden-core", + "miden-crypto", +] + [[package]] name = "miden-core" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80657c32850817f5f67dcf114866495a4b055531778b7c26d0602646ce777eb8" +checksum = "3b27f9f91988c5e74b50b543c4e6d37ec729eabcf70db63cf752dedd780f8a90" dependencies = [ "derive_more", "log", @@ -1135,34 +1095,46 @@ dependencies = [ "miden-utils-core-derive", "miden-utils-indexing", "miden-utils-sync", - "num-derive", - "num-traits", "serde", "thiserror", ] [[package]] name = "miden-core-lib" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16410655f32f98537afc9ddf57b71cb6d1ca9d980da5f4eea164cafcaf891b2e" +checksum = "14df9652fc4963f20d11df9ceb576ccb7831b5dc72fabec5c1b602f51e57909c" dependencies = [ "env_logger", "fs-err", "miden-assembly", + "miden-assembly-syntax", "miden-core", + "miden-core-lib-codegen", "miden-crypto", + "miden-mast-package", "miden-package-registry", + "miden-precompiles", "miden-processor", "miden-utils-sync", "thiserror", ] +[[package]] +name = "miden-core-lib-codegen" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aad0b8badcf1636150cac0d74aabadd395ba7d570227eb0923ff14f02a278fff" +dependencies = [ + "miden-core", + "miden-precompiles", +] + [[package]] name = "miden-crypto" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35198bebd353cddc25ad4aafb5f4ef9e71b283d71c787b8938c575c16974135d" +checksum = "7c917b0342d911ae4b7a549bb3ca791c093dac4770f88b02e23b43f3fa8179f5" dependencies = [ "blake3", "cc", @@ -1189,10 +1161,8 @@ dependencies = [ "p3-maybe-rayon", "p3-symmetric", "p3-util", - "rand 0.9.4", - "rand_chacha", - "rand_core 0.9.5", - "rand_hc", + "rand 0.10.2", + "rand_chacha 0.10.0", "serde", "sha2", "sha3", @@ -1203,19 +1173,19 @@ dependencies = [ [[package]] name = "miden-crypto-derive" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9068c6554db0e051f62913575de9949841a46b96ae92d4b7d28e1fed5d8f052b" +checksum = "a7c3165dfd7fd6f587ea5731efd1cc8083ca55c23d2d9b3000f83a3948486044" dependencies = [ "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "miden-debug-types" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "956708ccb2f643db398b4b3d4f8d0baf199b1bfb5e34c8be1cd1bc811c005e8e" +checksum = "4c9f3f8e4a8f54a36fbf00330ac8bd1947627c1786cd49b94a08b741590ed173" dependencies = [ "memchr", "miden-crypto", @@ -1228,22 +1198,23 @@ dependencies = [ "serde", "serde_spanned", "thiserror", + "zerocopy", ] [[package]] name = "miden-field" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "379a39db52cd932a95d4017a18b712ee53ed0f86cfedf8c63ed72d687a18a191" +checksum = "58cf9de55b88ec86ad272ff4224d76b3e0cbda49e242e78776b0037ba9b0e857" dependencies = [ "miden-serde-utils", - "num-bigint", + "num-bigint 0.5.1", "p3-challenger", "p3-field", "p3-goldilocks", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", "subtle", "thiserror", @@ -1251,9 +1222,9 @@ dependencies = [ [[package]] name = "miden-field-repr" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed71d35f511b703d1620094fcc748cb9383dbf2bd7b304d0b28c506a354acdf" +checksum = "93e13ffca1264db045cc344e573f9460bd0153aa89b755fac454b9070b953cdc" dependencies = [ "miden-field", "miden-field-repr-derive", @@ -1261,13 +1232,13 @@ dependencies = [ [[package]] name = "miden-field-repr-derive" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e37e87fe1408b7ebc083614469b761a29c5749a34072b0e33dd4cbdd8d34766c" +checksum = "bf0e54de280a41e83a99caa16b3ffb8670c857c888d3e245920e8a96f42fad58" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -1281,11 +1252,12 @@ dependencies = [ [[package]] name = "miden-lifted-air" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "789e0e469d1731012d8a018057317f31580611535c20d2a47c022213228cb733" +checksum = "f67e06d47e246db853a9f3e52ec87fa33a8ffc0fe5be0dd99288b2439312f206" dependencies = [ "p3-air", + "p3-challenger", "p3-field", "p3-matrix", "p3-util", @@ -1294,9 +1266,9 @@ dependencies = [ [[package]] name = "miden-lifted-stark" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f62cca91182917b22a47e150028b7c785df620a15b2974a39c64e2b1b7a889d3" +checksum = "a5ee320597c7712698d06811d9144b0e4f2275a21224ef0238652c947b01198b" dependencies = [ "miden-lifted-air", "miden-stark-transcript", @@ -1309,7 +1281,7 @@ dependencies = [ "p3-maybe-rayon", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", "serde", "thiserror", "tracing", @@ -1317,15 +1289,20 @@ dependencies = [ [[package]] name = "miden-mast-package" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f37c21836b40785ce297d363c57740d4e33edcc411f84185a524eddadd5f53c7" +checksum = "1355a2563a52af4399b4a93120a4398f81415b1fc4edb58310de5034cfa3781d" dependencies = [ + "hashbrown", + "log", "miden-assembly-syntax", "miden-core", "miden-debug-types", + "miden-utils-indexing", + "rustc-hash", "serde", "thiserror", + "zerocopy", ] [[package]] @@ -1344,9 +1321,9 @@ dependencies = [ "rustc_version 0.2.3", "rustversion", "serde_json", - "spin 0.9.8", + "spin 0.9.9", "strip-ansi-escapes", - "syn 2.0.118", + "syn 2.0.119", "textwrap", "thiserror", "trybuild", @@ -1361,14 +1338,14 @@ checksum = "86a905f3ea65634dd4d1041a4f0fd0a3e77aa4118341d265af1a94339182222f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] name = "miden-package-registry" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ece6064beb0582d1c64ba30d0c548c4b7a45f87abae6d69e22fd49c8b343258" +checksum = "a799e66245492c193b0444c3e0ff0fe42418009ec668a3e80c40d9f5b1454aac" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -1380,16 +1357,50 @@ dependencies = [ "thiserror", ] +[[package]] +name = "miden-precompiles" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "073ebeeb4413b9a03c60b0b066f94b8edaa6f50150017a92dc09d3ace92d6976" +dependencies = [ + "miden-core", + "miden-crypto", +] + +[[package]] +name = "miden-precompiles-prover" +version = "0.29.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76663c4d90cc073f9e2d2aa2349b9dcd25bf6c40db5020d27ce59990b6bd5af" +dependencies = [ + "miden-air", + "miden-core", + "miden-crypto", + "miden-lifted-air", + "miden-lifted-stark", + "miden-precompiles", + "miden-serde-utils", + "ruint", + "serde", + "serde-wincode", + "thiserror", + "tracing", + "wincode", +] + [[package]] name = "miden-processor" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea972ca9e45dbf26aa396367e8508db0f7292adea6f6ddf8d39d0e334285fe2b" +checksum = "2c7331ab96f00f922d29e2f59285f539299061a44ffdeea31b853d2c071f8056" dependencies = [ + "hashbrown", "itertools", "miden-air", "miden-core", "miden-debug-types", + "miden-mast-package", + "miden-precompiles", "miden-utils-diagnostics", "miden-utils-indexing", "paste", @@ -1400,9 +1411,9 @@ dependencies = [ [[package]] name = "miden-project" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5320e7e5b562359bd6161ac752dfe43dd4f69bb06e87f94a21a27bb656e5a20d" +checksum = "6f8201d3a6d0c85c747092309c3c420de42e61e76f71df2189a46411100d120a" dependencies = [ "miden-assembly-syntax", "miden-core", @@ -1417,13 +1428,13 @@ dependencies = [ [[package]] name = "miden-protocol" -version = "0.15.3" +version = "0.16.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66340243e37da5936cb278a8dd11037813f1dc6731c2fc866703b76ed465ebc3" +checksum = "e275feebbe9c2458c5877c5f2a03b8e2152831ce956376f015fc4c50acfffb50" dependencies = [ "bech32", "fs-err", - "getrandom 0.3.4", + "getrandom 0.4.3", "miden-assembly", "miden-assembly-syntax", "miden-core", @@ -1431,37 +1442,65 @@ dependencies = [ "miden-crypto", "miden-crypto-derive", "miden-mast-package", + "miden-package-registry", "miden-processor", + "miden-protocol-build-utils", "miden-utils-sync", "miden-verifier", - "rand 0.9.4", + "rand 0.10.2", "regex", "semver 1.0.28", "thiserror", +] + +[[package]] +name = "miden-protocol-build-utils" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d16cdd96c1d0b3b2d57342d37eaadd15cc7c633bda965fc8c3b23ca249965b4" +dependencies = [ + "fs-err", + "miden-assembly", + "miden-core", + "miden-mast-package", + "miden-package-registry", + "miden-project", + "regex", "walkdir", ] +[[package]] +name = "miden-rowan" +version = "0.16.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13695bf99aabaa21d6572b807c66bb26251aa3d9b75e828b3c99b97a3b1ce7e" +dependencies = [ + "hashbrown", + "rustc-hash", +] + [[package]] name = "miden-sdk-alloc" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ee9eb34cde96e3158c19e22fedddb03b6e5eb363e272d11cbae9aa963cc315" +checksum = "15deb9ba073e632ca1151fcf7b718227294b750a7be9ac0c655d5ae7f2a6dc43" [[package]] name = "miden-serde-utils" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d78cd1d4fcad937312e544f7d53423485e453598aa4fb989d2b6374027a8c136" +checksum = "f5c21a2acdc1928f86803b3ff3c44564c3f614a7dc47dcd64969a5c856d27988" dependencies = [ "p3-field", "p3-goldilocks", + "wincode", ] [[package]] name = "miden-stark-transcript" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05901db2e30d3954243960fe21cea7fbec39f97c27774b56fd5031c28c4881ba" +checksum = "d503630c353389838fa5d668a0d4550130453c7b2a72b802d4adc1ea39ab5bee" dependencies = [ "p3-challenger", "p3-field", @@ -1471,9 +1510,9 @@ dependencies = [ [[package]] name = "miden-stateful-hasher" -version = "0.25.1" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faeb47a90c55c5d45051d23cf691588804dd531995b4582c79108b64e445a905" +checksum = "e8c2008195bdb552eeb744074bfc8822049552ccdf7aef3321a32e1ab6be92e6" dependencies = [ "p3-field", "p3-symmetric", @@ -1481,18 +1520,29 @@ dependencies = [ [[package]] name = "miden-stdlib-sys" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "015cb758041aeaae5b2e5062af67459fb71cdacd199838a4a43795eb82f9a11d" +checksum = "152e858a662e3c4524e06becfb98d6727ec7cbc9d51cf9bb8b8bea9e17af5072" dependencies = [ "miden-field", ] +[[package]] +name = "miden-tx-script-args" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c32d126b51f111ff9e8aed25d1ccefc0e3e093b361b88b51e1ab2fd70f96a7" +dependencies = [ + "miden-field", + "miden-field-repr", + "miden-stdlib-sys", +] + [[package]] name = "miden-utils-core-derive" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0b1ee4662beb049a824e11bb21f95a79746c52874967983c9999f1b19a2f471" +checksum = "107d04fcd05b0308e6347113ee6dc13599755e5b4d05ecc08d8b5c05f36a5a39" dependencies = [ "proc-macro2", "quote", @@ -1501,11 +1551,10 @@ dependencies = [ [[package]] name = "miden-utils-diagnostics" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fdc1cd4eda372e1c4b99b9c3677e9b1f87a4d2e362a9f4b8f904273d395efc9" +checksum = "f3b444d204bf082cdab14015ff10d5b0b43a10fba662fef09e4753f6d07faf1f" dependencies = [ - "miden-crypto", "miden-debug-types", "miden-miette", "tracing", @@ -1513,11 +1562,11 @@ dependencies = [ [[package]] name = "miden-utils-indexing" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c31444125649f4dad9cde647f614309b6be4f918fed276ada4eb99c01e8b9ca7" +checksum = "f6ff225060e2a5cc4dd6c898eef1f04739461d3401b6de1692bf443cfdd302b0" dependencies = [ - "miden-crypto", + "miden-serde-utils", "proptest", "serde", "thiserror", @@ -1525,9 +1574,9 @@ dependencies = [ [[package]] name = "miden-utils-sync" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "807c8ae625b7652ae7246b225c907c05da72927c31a0fd71c835c4f80931e92e" +checksum = "76b9cb00f01787f8687447cd8a45b3888b470eb35a132df1be9729779d311fd7" dependencies = [ "lock_api", "loom", @@ -1537,34 +1586,37 @@ dependencies = [ [[package]] name = "miden-verifier" -version = "0.23.4" +version = "0.29.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec5556dac919a1c13edeb2bd7181fc6a4c2ce52764a3e518bcdcd9ed48e5b38e" +checksum = "5e049df6008af1fea5a66df8ce98075cc9e00f16122fd5f4e7c4be9a263cae46" dependencies = [ - "bincode", "miden-air", "miden-core", "miden-crypto", + "miden-precompiles", + "miden-precompiles-prover", + "miden-serde-utils", "serde", + "serde-wincode", "thiserror", - "tracing", ] [[package]] name = "midenc-frontend-wasm-metadata" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3303cecb0858b92395b5c3710d52aae96d28e12f13966208731712e83803d" +checksum = "be2bc4e14ad915ca2b51b521bffbfc91bee1b94520277db144b27bd111cd60a7" dependencies = [ + "miden-mast-package", "serde", "serde_json", ] [[package]] name = "midenc-hir-type" -version = "0.6.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ff0511aa2201f7098995e38a3c97a319d379c3b2d26fb83677b21b71f61a7b4" +checksum = "dcdf2257de8f3486c8f3e93c45219b782bafad62a8694798c05d5b8f3f79c64e" dependencies = [ "miden-formatting", "miden-serde-utils", @@ -1574,21 +1626,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "nanorand" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" -dependencies = [ - "getrandom 0.2.17", -] - -[[package]] -name = "new_debug_unreachable" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" - [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -1604,7 +1641,7 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" dependencies = [ - "num-bigint", + "num-bigint 0.4.8", "num-complex", "num-integer", "num-iter", @@ -1614,50 +1651,48 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.6" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" dependencies = [ "num-integer", "num-traits", ] [[package]] -name = "num-complex" -version = "0.4.6" +name = "num-bigint" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +checksum = "93e7820bc0a80a0238e650327316f929ba18d5be054b647490a3a6a339f3e7c0" dependencies = [ + "num-integer", "num-traits", ] [[package]] -name = "num-derive" -version = "0.4.2" +name = "num-complex" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.118", + "num-traits", ] [[package]] name = "num-integer" -version = "0.1.46" +version = "0.1.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" dependencies = [ "num-traits", ] [[package]] name = "num-iter" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +checksum = "c92800bd69a1eac91786bcfe9da64a897eb72911b8dc3095decbd07429e8048b" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -1668,7 +1703,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" dependencies = [ - "num-bigint", + "num-bigint 0.4.8", "num-integer", "num-traits", ] @@ -1699,23 +1734,17 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - [[package]] name = "owo-colors" -version = "4.3.0" +version = "4.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" +checksum = "13c45bb4a6ae1280ec0803b1ef9d3455eb50f01efbbe1447ab020f1d54fba9d8" [[package]] name = "p3-air" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c824e8d7c7ddf208b742eac8d48e0b2d52d22fa013578a7762bf6931dbab1f46" +checksum = "ddb1be05c0d6f691afe0c9f468018a9a37cfa904dee78a8081ec96eb3cdd88e8" dependencies = [ "p3-field", "p3-matrix", @@ -1724,9 +1753,9 @@ dependencies = [ [[package]] name = "p3-blake3" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2733229a713bd83ccf5eb749e8f8e7380c1052674394a25c0422a772204a20af" +checksum = "6f202f5fbcceb6f56f783d98efb5de27e5a171470e3364de97b0923b39c87ab5" dependencies = [ "blake3", "p3-symmetric", @@ -1735,9 +1764,9 @@ dependencies = [ [[package]] name = "p3-challenger" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8972ccd1d5dc90e46cdb1f2ab4ee2bae49b3917e5e98aa533f0c2b779c010445" +checksum = "84d5d5e1ecf2c80b09b48ce870e8abd08b643454101c5dc9d0fd71bfbd78224d" dependencies = [ "p3-field", "p3-maybe-rayon", @@ -1749,42 +1778,42 @@ dependencies = [ [[package]] name = "p3-dft" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17771aca44632f9cc11f2718d7ea7ec06794946c4190ef3a985bfc893f14c18a" +checksum = "4321a952da2721ecd85ca593ea189798dfb4e439a2cc1378ce1442091880f173" dependencies = [ "itertools", "p3-field", "p3-matrix", "p3-maybe-rayon", "p3-util", - "spin 0.10.0", + "spin 0.12.3", "tracing", ] [[package]] name = "p3-field" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3eb24d0591fd4d282d89cbe4e4efba5571c699375006f80b2cbf53ce83461c" +checksum = "53db75d38e04fc255826f388eca9d05976733dc9754aa3db411bc9ea1a37c1a0" dependencies = [ "itertools", - "num-bigint", + "num-bigint 0.5.1", "p3-maybe-rayon", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", "tracing", ] [[package]] name = "p3-goldilocks" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5751c6591a0d2397d726620c2c29a7436ec6c5e19d2ed74ca5d078d4fbb18eb5" +checksum = "d03b3f31080df31be723b876709246f8f1e532e1c5b82efb5281d705c8304c63" dependencies = [ - "num-bigint", + "num-bigint 0.5.1", "p3-challenger", "p3-dft", "p3-field", @@ -1794,15 +1823,16 @@ dependencies = [ "p3-symmetric", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", + "spin 0.12.3", ] [[package]] name = "p3-keccak" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a7df174ff0c19a8742eb4698eaa1667c5f858d018e2faf09c55f1f24a6f9c3" +checksum = "ae50c8c37eb847c660298fb275e53c025c49b2623a8cfabf67f5322258b2b4db" dependencies = [ "p3-symmetric", "p3-util", @@ -1811,46 +1841,46 @@ dependencies = [ [[package]] name = "p3-matrix" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea9c94c0714944e7b8a9a62e6340b1e3e1d3f8ecfd3e35c08798360200e73eff" +checksum = "473eb920c446a6f4536e0d3528fbdca2a23c0e24e1d0d7767452e6d385dd335c" dependencies = [ "itertools", "p3-field", "p3-maybe-rayon", "p3-util", - "rand 0.10.1", + "rand 0.10.2", "serde", "tracing", ] [[package]] name = "p3-maybe-rayon" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eebc233a34b1ab0273f35b4052fa2eeb3114b22ba4575bd7da00716e878ffb77" +checksum = "e6fddfd435f96394769414cf5590b77058aa506659bf20d6592e9d1989e04440" [[package]] name = "p3-mds" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b5441fa8116246ec9e6c835f15273cb27777ca572960ec87476b67fef13e01e" +checksum = "551ba0ab2cccd89f85a99450224898aff224e323bbf61f777ba6344f0896ef10" dependencies = [ "p3-dft", "p3-field", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-monty-31" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8724f330ea6d19dd4f2436aa0f88b5fcbf88f0f55ca7fccd3fea8b736dbcddad" +checksum = "871f635f7340cd0868b17e43e0c98fefdafdaed90469d0725caf6d8372a2a47c" dependencies = [ "itertools", - "num-bigint", + "num-bigint 0.5.1", "p3-dft", "p3-field", "p3-matrix", @@ -1861,41 +1891,42 @@ dependencies = [ "p3-symmetric", "p3-util", "paste", - "rand 0.10.1", + "rand 0.10.2", "serde", - "spin 0.10.0", + "spin 0.12.3", "tracing", ] [[package]] name = "p3-poseidon1" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e2a562fea210baae390a32f9ecf0dd8724ae3f4352d1c8e413077b6f00a162" +checksum = "8d0d304e9a1f29c0d66534aa84e69528e2118351fdce08dcf5898af4e0fecc32" dependencies = [ "p3-field", + "p3-mds", "p3-symmetric", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-poseidon2" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06394851c161d17e4aa4ad2aad5557d32f14cadd1dc838f965d8e1821a63b8c5" +checksum = "43eb8a73a26d14becaed1c67c3e8a047e4311d7909b402383c82ca9643ba17c6" dependencies = [ "p3-field", "p3-mds", "p3-symmetric", "p3-util", - "rand 0.10.1", + "rand 0.10.2", ] [[package]] name = "p3-symmetric" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac1a276d421f8ef3361bb7d8c39a02c93c6b3f10eeaa559cc4c50222f9a5b82" +checksum = "2015ea80cad969b6aabf27a04884286fe1354393b166d968ee0d80a95126b2a4" dependencies = [ "itertools", "p3-field", @@ -1905,12 +1936,11 @@ dependencies = [ [[package]] name = "p3-util" -version = "0.5.3" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d08a58162a4c264269ef454f0b28dcda89939490eecacb2b2cf5b00f719b80f6" +checksum = "6c5466fc40e6df89d3b291a2eff16b33e68e8571207790370137ec18090aadab" dependencies = [ "serde", - "transpose", ] [[package]] @@ -1943,23 +1973,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] -name = "petgraph" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" -dependencies = [ - "fixedbitset", - "indexmap", -] - -[[package]] -name = "phf_shared" -version = "0.11.3" +name = "pastey" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" -dependencies = [ - "siphasher", -] +checksum = "2ee67f1008b1ba2321834326597b8e186293b049a023cdef258527550b9935b4" [[package]] name = "pin-project-lite" @@ -1969,9 +1986,9 @@ checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pkcs8" -version = "0.10.2" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ "der", "spki", @@ -1979,26 +1996,25 @@ dependencies = [ [[package]] name = "poly1305" -version = "0.8.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +checksum = "6e2d0073b297041425c7c3df6eb4792d598a15323fe63346852b092eca02904c" dependencies = [ - "cpufeatures 0.2.17", - "opaque-debug", + "cpufeatures", "universal-hash", ] [[package]] name = "portable-atomic" -version = "1.13.1" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" [[package]] name = "portable-atomic-util" -version = "0.2.7" +version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +checksum = "10ab3eb7f3becc3a1cbc4f2c6f20267996cfc1a6467a873763411b136a122715" dependencies = [ "portable-atomic", ] @@ -2012,12 +2028,6 @@ dependencies = [ "zerocopy", ] -[[package]] -name = "precomputed-hash" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" - [[package]] name = "prettyplease" version = "0.2.37" @@ -2025,47 +2035,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] -name = "priority-queue" -version = "2.7.0" +name = "primefield" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" +checksum = "c555a6e4eb7d4e158fcb028c835c3b8642206ddc279b5c6b202ef9a8bdb592f4" dependencies = [ - "equivalent", - "indexmap", - "serde", + "crypto-bigint", + "crypto-common", + "ff", + "rand_core 0.10.1", + "subtle", + "zeroize", ] [[package]] -name = "proc-macro-error-attr2" -version = "2.0.0" +name = "primeorder" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +checksum = "5c9f42978c78a00e3d68f69fc03e57a234debae69da4020a4fb588fcdcd07b06" dependencies = [ - "proc-macro2", - "quote", + "elliptic-curve", + "primefield", + "serdect", + "wnaf", ] [[package]] -name = "proc-macro-error2" -version = "2.0.1" +name = "priority-queue" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +checksum = "93980406f12d9f8140ed5abe7155acb10bb1e69ea55c88960b9c2f117445ef96" dependencies = [ - "proc-macro-error-attr2", - "proc-macro2", - "quote", - "syn 2.0.118", + "equivalent", + "indexmap", + "serde", ] [[package]] name = "proc-macro2" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" dependencies = [ "unicode-ident", ] @@ -2076,10 +2090,10 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.1", "num-traits", - "rand 0.9.4", - "rand_chacha", + "rand 0.9.5", + "rand_chacha 0.9.0", "rand_xorshift", "regex-syntax", "unarray", @@ -2101,9 +2115,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.46" +version = "1.0.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" dependencies = [ "proc-macro2", ] @@ -2114,22 +2128,30 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "rand" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c5af06bb1b7d3216d91932aed5265164bf384dc89cd6ba05cf59a35f5f76ea" +checksum = "b9ef1d0d795eb7d84685bca4f72f3649f064e6641543d3a8c415898726a57b41" dependencies = [ - "rand_chacha", + "rand_chacha 0.9.0", "rand_core 0.9.5", ] [[package]] name = "rand" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" dependencies = [ + "chacha20", + "getrandom 0.4.3", "rand_core 0.10.1", ] @@ -2144,12 +2166,13 @@ dependencies = [ ] [[package]] -name = "rand_core" -version = "0.6.4" +name = "rand_chacha" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "3e6af7f3e25ded52c41df4e0b1af2d047e45896c2f3281792ed68a1c243daedb" dependencies = [ - "getrandom 0.2.17", + "ppv-lite86", + "rand_core 0.10.1", ] [[package]] @@ -2167,15 +2190,6 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" -[[package]] -name = "rand_hc" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b363d4f6370f88d62bf586c80405657bde0f0e1b8945d47d2ad59b906cb4f54" -dependencies = [ - "rand_core 0.6.4", -] - [[package]] name = "rand_xorshift" version = "0.4.0" @@ -2211,14 +2225,14 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.1", ] [[package]] name = "regex" -version = "1.12.4" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1292b7759ae1cb9ec195452d1390a074f0cd8541ab7a5a8c31cd6db45d4a6ba" +checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d" dependencies = [ "aho-corasick", "memchr", @@ -2228,9 +2242,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.14" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2" dependencies = [ "aho-corasick", "memchr", @@ -2245,19 +2259,34 @@ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4" [[package]] name = "rfc6979" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +checksum = "b4a459cddafb3fe76b31fd8f1108007566c40301feb64dc7b54656eb7388172b" dependencies = [ + "crypto-bigint", "hmac", - "subtle", ] +[[package]] +name = "ruint" +version = "1.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e99bff0393163bb25029a6af25d3d8d202ba5b5438a74d1bd8789f5c822970" +dependencies = [ + "ruint-macro", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "6b1e7f9a428571be2dc5bc0505c13fb6bf936822b894ec87abf8a08a4e51742d" [[package]] name = "rustc_version" @@ -2279,9 +2308,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.22" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" [[package]] name = "same-file" @@ -2306,14 +2335,14 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sec1" -version = "0.7.3" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" dependencies = [ "base16ct", + "ctutils", "der", - "generic-array", - "pkcs8", + "hybrid-array", "subtle", "zeroize", ] @@ -2345,9 +2374,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" dependencies = [ "serde_core", "serde_derive", @@ -2365,31 +2394,42 @@ dependencies = [ "typeid", ] +[[package]] +name = "serde-wincode" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aa9d3a86c66cf10ce79df36f555a5a4c8d72a82515d9ea8ca420e02c925c30f" +dependencies = [ + "serde", + "thiserror", + "wincode", +] + [[package]] name = "serde_core" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.228" +version = "1.0.229" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", ] [[package]] name = "serde_json" -version = "1.0.150" +version = "1.0.151" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" dependencies = [ "itoa", "memchr", @@ -2400,13 +2440,13 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.20" +version = "0.1.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +checksum = "8d3b1629de253c70a0508c3899572da79ca359fdab27c7920ff00406df418906" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", ] [[package]] @@ -2418,25 +2458,36 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serdect" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66cf8fedced2fcf12406bcb34223dffb92eaf34908ede12fed414c82b7f00b3e" +dependencies = [ + "base16ct", + "serde", +] + [[package]] name = "sha2" -version = "0.10.9" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", + "cpufeatures", "digest", ] [[package]] name = "sha3" -version = "0.10.9" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +checksum = "bc9bad02c26382724b2d2692c6f179285e4b54eeecd7968f52a50059c3c11759" dependencies = [ "digest", "keccak", + "sponge-cursor", ] [[package]] @@ -2456,31 +2507,19 @@ checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signature" -version = "2.2.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" dependencies = [ "digest", - "rand_core 0.6.4", + "rand_core 0.10.1", ] -[[package]] -name = "siphasher" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" - -[[package]] -name = "slab" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" - [[package]] name = "smallvec" -version = "1.15.2" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +checksum = "b9be42f50aa861c555654aa3a37f52f4b1074bacf4e48fe0ef7fa584e80f1f0f" dependencies = [ "serde", ] @@ -2493,49 +2532,37 @@ checksum = "e8e2fb0f499abb4d162f2bedad68f5ef91a1682b5a03596ddb67efd37768d100" [[package]] name = "spin" -version = "0.9.8" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" dependencies = [ "lock_api", ] [[package]] name = "spin" -version = "0.10.0" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +checksum = "0134f9043ed38b087ac4f7d4af44c79e2c9e5094421fe3164f435ce585953b10" dependencies = [ "lock_api", ] [[package]] name = "spki" -version = "0.7.3" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" dependencies = [ "base64ct", "der", ] [[package]] -name = "strength_reduce" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82" - -[[package]] -name = "string_cache" -version = "0.8.9" +name = "sponge-cursor" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" -dependencies = [ - "new_debug_unreachable", - "parking_lot", - "phf_shared", - "precomputed-hash", -] +checksum = "3a0219bd7d979d58245a4f41f695e1ac9f8befdffadd7f61f1bae9e39abc6620" [[package]] name = "strip-ansi-escapes" @@ -2565,9 +2592,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.118" +version = "2.0.119" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" dependencies = [ "proc-macro2", "quote", @@ -2575,19 +2602,21 @@ dependencies = [ ] [[package]] -name = "target-triple" -version = "1.0.0" +name = "syn" +version = "3.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "591ef38edfb78ca4771ee32cf494cb8771944bee237a9b91fc9c1424ac4b777b" +checksum = "12df2e0110f65b775f769bb17ef989067a1d931b2eb822bd4346631eeada89f9" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] [[package]] -name = "term" -version = "1.2.1" +name = "target-tuple" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8c27177b12a6399ffc08b98f76f7c9a1f4fe9fc967c784c5a071fa8d93cf7e1" -dependencies = [ - "windows-sys", -] +checksum = "876fef147edbcbddc8ac5cbbba92c7b86519e314e86638596c09673b2ed01e7f" [[package]] name = "termcolor" @@ -2611,29 +2640,29 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "2.0.18" +version = "2.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", ] [[package]] name = "thread_local" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +checksum = "1ad99c4c6d32803332c548b1af0540b357b3f5fc0be8f6c6bfe8b2e6ae784070" dependencies = [ "cfg-if", ] @@ -2649,9 +2678,9 @@ dependencies = [ [[package]] name = "toml" -version = "1.1.2+spec-1.1.0" +version = "1.1.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81f3d15e84cbcd896376e6730314d59fb5a87f31e4b038454184435cd57defee" +checksum = "12c0ba9680044b4ce98d391a62094047eada0d64860b80166c39f4a6b5640785" dependencies = [ "indexmap", "serde_core", @@ -2673,18 +2702,18 @@ dependencies = [ [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.1.3+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "1d38ac1cf9b95face32296c0a3ede1fdc270627c9d9c02a7274dd6d960dc4d56" dependencies = [ "winnow", ] [[package]] name = "toml_writer" -version = "1.1.1+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "756daf9b1013ebe47a8776667b466417e2d4c5679d441c26230efd9ef78692db" +checksum = "7d56353a2a665ad0f41a421187180aab746c8c325620617ad883a99a1cbe66d2" [[package]] name = "tracing" @@ -2705,7 +2734,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -2747,28 +2776,18 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "transpose" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e" -dependencies = [ - "num-integer", - "strength_reduce", -] - [[package]] name = "trybuild" -version = "1.0.117" +version = "1.0.121" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0710d4dfbeae4f9c390baa784c49858a7468fa433f3fe5d0ec5ebef651cf59f9" +checksum = "c0cabaa10be1917331a313866bd94526343e03c77bcf69144b62b072ad35d47c" dependencies = [ "dissimilar", "glob", "serde", "serde_derive", "serde_json", - "target-triple", + "target-tuple", "termcolor", "toml", ] @@ -2823,12 +2842,12 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "universal-hash" -version = "0.5.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +checksum = "f4987bdc12753382e0bec4a65c50738ffaabc998b9cdd1f952fb5f39b0048a96" dependencies = [ "crypto-common", - "subtle", + "ctutils", ] [[package]] @@ -2852,12 +2871,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - [[package]] name = "vte" version = "0.14.1" @@ -2877,12 +2890,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - [[package]] name = "wasip2" version = "1.0.4+wasi-0.2.12" @@ -2894,9 +2901,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" +checksum = "aecb87a33d3b0c5e3b7aa46336eaf486cffafbd281b195e4c8b80d50df2351bf" dependencies = [ "cfg-if", "once_cell", @@ -2907,9 +2914,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" +checksum = "a690d511e3c1a8b3a55e33511e3c2c00c78415cd23650f32b808627f5696b9ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2917,22 +2924,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" +checksum = "411e4887f0071ef2d2164a9d5fdf2d20efbef78fccd3a78b0c10a1dc5295e48a" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.118", + "syn 3.0.5", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.126" +version = "0.2.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" +checksum = "81941cd78d0c92026c33e5e01312845a4cb1e9af3407f9134b100dd03144103e" dependencies = [ "unicode-ident", ] @@ -2965,7 +2972,7 @@ version = "0.247.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e6fb4c2bee46c5ea4d40f8cdb5c131725cd976718ec56f1c8e82fbde5fa2a80" dependencies = [ - "bitflags 2.13.0", + "bitflags 2.13.1", "hashbrown", "indexmap", "semver 1.0.28", @@ -2980,6 +2987,18 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "wincode" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfc6339f1ba427bf7ad7c42403b28e524832ba2ddb5eef1bb2cc3b85db6b7b75" +dependencies = [ + "pastey", + "proc-macro2", + "quote", + "thiserror", +] + [[package]] name = "windows-link" version = "0.2.1" @@ -3006,9 +3025,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +checksum = "23b97319f7b8343df12cc98938e5c3eb436064524c8d2b4e30a1d3a36eecdf81" [[package]] name = "wit-bindgen" @@ -3040,7 +3059,7 @@ dependencies = [ "heck", "indexmap", "prettyplease", - "syn 2.0.118", + "syn 2.0.119", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -3056,7 +3075,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -3068,7 +3087,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d567162a6b9843080e5e0053f696623ff694bae8ae017c9ec536d1873bbe3d8" dependencies = [ "anyhow", - "bitflags 2.13.0", + "bitflags 2.13.1", "indexmap", "log", "serde", @@ -3106,34 +3125,46 @@ dependencies = [ "miden", ] +[[package]] +name = "wnaf" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "795ca18b3fdb5e62bf982199278341ddcf7ebf7d32e25e212ad05d496e95f6fa" +dependencies = [ + "ff", + "group", + "hybrid-array", + "primefield", +] + [[package]] name = "x25519-dalek" -version = "2.0.1" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +checksum = "e7e8131a03190127fb2263afc72b322ecadae46b6ff8c6f399ff5d02f5559af6" dependencies = [ "curve25519-dalek", - "rand_core 0.6.4", + "rand_core 0.10.1", ] [[package]] name = "zerocopy" -version = "0.8.52" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce1022995ff5ff5d841ad7d994facc23098cd40152f2c1d11cd607c6f530653f" +checksum = "d35102a9f36d089ccae9e4c6802bc118be4487b80aaffc0ab4e0cf5ce92d2873" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.52" +version = "0.8.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ae7f38b72ec2a254e2b87ef277cf2cd4fb97cbebf944faa6f33354da0867930" +checksum = "146c01f5ab44258da43cf276c74a2763db2ff3969c9c652c3f2de07041d0b2bc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.118", + "syn 2.0.119", ] [[package]] @@ -3144,6 +3175,6 @@ checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" [[package]] name = "zmij" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/examples/miden-bank/contracts/withdraw-request-note/Cargo.toml b/examples/miden-bank/contracts/withdraw-request-note/Cargo.toml index 63e24fec..2eb9f0b6 100644 --- a/examples/miden-bank/contracts/withdraw-request-note/Cargo.toml +++ b/examples/miden-bank/contracts/withdraw-request-note/Cargo.toml @@ -7,4 +7,4 @@ edition = "2021" crate-type = ["cdylib"] [dependencies] -miden = "0.13" +miden = "=0.14.0" diff --git a/examples/miden-bank/contracts/withdraw-request-note/miden-project.toml b/examples/miden-bank/contracts/withdraw-request-note/miden-project.toml index 7f4a5ad1..b3f772dd 100644 --- a/examples/miden-bank/contracts/withdraw-request-note/miden-project.toml +++ b/examples/miden-bank/contracts/withdraw-request-note/miden-project.toml @@ -3,6 +3,7 @@ name = "withdraw-request-note" version = "0.1.0" [lib] +path = "src/lib.rs" kind = "note" namespace = "miden:withdraw-request-note/miden-withdraw-request-note@0.1.0" @@ -10,7 +11,3 @@ namespace = "miden:withdraw-request-note/miden-withdraw-request-note@0.1.0" miden-core = "*" miden-protocol = "*" bank-account = { path = "../bank-account" } - -# WIT for the account component this note calls, produced by building bank-account. -[package.metadata.miden.dependencies] -bank-account = { wit = "../bank-account/target/generated-wit/" } diff --git a/examples/miden-bank/contracts/withdraw-request-note/src/lib.rs b/examples/miden-bank/contracts/withdraw-request-note/src/lib.rs index 7c23bfb8..16f85fe7 100644 --- a/examples/miden-bank/contracts/withdraw-request-note/src/lib.rs +++ b/examples/miden-bank/contracts/withdraw-request-note/src/lib.rs @@ -24,13 +24,13 @@ pub struct Wallet; /// /// # Note Storage (14 Felts) /// [0-3]: withdraw asset, encoded as [amount, 0, faucet_suffix(+metadata), faucet_prefix]. -/// Reconstructed into the v0.15 vault key [0, 0, storage[2], storage[3]] and value +/// Reconstructed into the v0.16 vault key [0, 0, storage[2], storage[3]] and value /// [amount, 0, 0, 0]. `storage[2]` carries the faucet suffix with the asset's metadata -/// byte in its low 8 bits (host side: `FungibleAsset::to_key_word()[2]`), not the raw +/// byte in its low 8 bits (host side: `FungibleAsset::to_id_word()[2]`), not the raw /// suffix — so the bank reconstructs exactly the key the depositor's asset had. /// [4-7]: serial_num (random/unique per note) /// [8]: tag (P2ID note tag for routing) -/// [9]: note_type (1 = Public, 2 = Private) +/// [9]: note_type (1 = Public, 0 = Private) /// [10-13]: P2ID script_root (MAST root of the P2ID note script, Poseidon2-hashed). /// Consumed by the bank account directly from the active note's storage inside /// `Bank::withdraw`, so it never appears on the call — this keeps that @@ -49,7 +49,7 @@ impl WithdrawRequestNote { "Withdraw request requires exactly 14 storage items" ); - // Asset: reconstruct the v0.15 fungible-asset key/value from the note storage. + // Asset: reconstruct the v0.16 fungible-asset key/value from the note storage. // key = [0, 0, storage[2], storage[3]] where storage[2] = faucet suffix + metadata // byte (low 8 bits) and storage[3] = faucet prefix. // value = [amount, 0, 0, 0] @@ -64,7 +64,7 @@ impl WithdrawRequestNote { // Tag: single Felt for P2ID note routing let tag = storage[8]; - // Note type: 1 = Public, 2 = Private + // Note type: 1 = Public, 0 = Private let note_type = storage[9]; // Note: P2ID script root (storage[10..13]) is read by the bank account directly diff --git a/examples/miden-bank/integration/Cargo.toml b/examples/miden-bank/integration/Cargo.toml index 021b2eb6..606d3518 100644 --- a/examples/miden-bank/integration/Cargo.toml +++ b/examples/miden-bank/integration/Cargo.toml @@ -4,12 +4,11 @@ version = "0.1.0" edition.workspace = true [dependencies] -cargo-miden = "0.9" -miden-client = { version = "0.15", features = ["tonic"] } -miden-client-sqlite-store = { version = "0.15", package = "miden-client-sqlite-store" } -miden-standards = { version = "0.15", features = ["testing"] } -miden-testing = "0.15" -miden-mast-package = { version = "0.23", default-features = false } +miden-client = { version = "0.16", features = ["tonic"] } +miden-client-sqlite-store = { version = "0.16", package = "miden-client-sqlite-store" } +miden-standards = { version = "0.16", features = ["testing"] } +miden-testing = "0.16" +miden-protocol = "0.16" tokio = { version = "1.48", features = ["rt-multi-thread", "net", "macros", "fs"] } -rand = { version = "0.9" } +rand = { version = "0.10" } anyhow = "1.0" diff --git a/examples/miden-bank/integration/src/bin/deposit.rs b/examples/miden-bank/integration/src/bin/deposit.rs index 1ecd270f..11fc252b 100644 --- a/examples/miden-bank/integration/src/bin/deposit.rs +++ b/examples/miden-bank/integration/src/bin/deposit.rs @@ -18,14 +18,18 @@ //! ``` use integration::helpers::{ - build_project_in_dir, create_basic_wallet_account, create_note_from_package, - setup_client, AccountCreationConfig, ClientSetup, NoteCreationConfig, + build_project_in_dir, create_basic_wallet_account, create_note_from_package, setup_client, + wait_for_native_funding, wait_for_transaction, AccountCreationConfig, ClientSetup, + NoteCreationConfig, }; use anyhow::{bail, Context, Result}; use miden_client::{ - account::AccountId, + account::{AccountId, StorageMapKey, StorageSlotName}, + asset::FungibleAsset, + note::NoteAssets, transaction::TransactionRequestBuilder, + Word, }; use std::{env, path::Path, sync::Arc}; @@ -61,7 +65,10 @@ async fn main() -> Result<()> { } = setup_client().await?; let sync_summary = client.sync_state().await?; - println!("Connected to network. Latest block: {}", sync_summary.block_num); + println!( + "Connected to network. Latest block: {}", + sync_summary.block_num + ); // Verify the bank account exists in our client let bank_account_record = client @@ -90,27 +97,38 @@ async fn main() -> Result<()> { ); println!(" ✓ Deposit note contract built"); - // Create a sender account (the depositor) with assets + // Create the sender account, then receive funding before publishing its deposit. println!("\nCreating depositor wallet..."); let sender_cfg = AccountCreationConfig::default(); let sender_account = create_basic_wallet_account(&mut client, keystore.clone(), sender_cfg) .await .context("Failed to create sender wallet account")?; - println!(" ✓ Depositor wallet created: {}", sender_account.id().to_hex()); - - // For this demo, we'll create a deposit note without actual assets - // In a real scenario, you would have a faucet or existing assets - println!("\nCreating deposit note..."); - println!(" Deposit amount: {} tokens", DEFAULT_DEPOSIT_AMOUNT); + println!( + " ✓ Depositor wallet created: {}", + sender_account.id().to_hex() + ); - // Create the deposit note - // Note: In a real scenario, you would attach actual assets from a faucet - // For now, we create the note structure (assets would come from the sender's vault) + wait_for_native_funding(&mut client, sender_account.id(), DEFAULT_DEPOSIT_AMOUNT).await?; + + // Deposit native tokens; the sender also needs enough native tokens to pay fees. + let faucet_id = client + .get_latest_block_header() + .await? + .fee_parameters() + .fee_faucet_id(); + let deposit_asset = FungibleAsset::new(faucet_id, DEFAULT_DEPOSIT_AMOUNT)?; + println!( + "\nCreating deposit note with {} native base units...", + DEFAULT_DEPOSIT_AMOUNT + ); let deposit_note = create_note_from_package( &mut client, deposit_note_package.clone(), sender_account.id(), - NoteCreationConfig::default(), + NoteCreationConfig { + assets: NoteAssets::new(vec![deposit_asset.into()])?, + ..Default::default() + }, ) .context("Failed to create deposit note")?; @@ -130,11 +148,7 @@ async fn main() -> Result<()> { println!(" ✓ Note published: {}", note_publish_tx_id.to_hex()); - // Sync state - client - .sync_state() - .await - .context("Failed to sync state after publishing note")?; + wait_for_transaction(&mut client, note_publish_tx_id).await?; // Consume the deposit note with the bank account println!("\nExecuting deposit (bank consuming the note)..."); @@ -150,11 +164,24 @@ async fn main() -> Result<()> { println!(" ✓ Deposit transaction: {}", consume_tx_id.to_hex()); - // Final sync - client - .sync_state() - .await - .context("Failed to sync state after deposit")?; + wait_for_transaction(&mut client, consume_tx_id).await?; + let bank = client + .get_account(bank_account_id) + .await? + .context("Bank missing after deposit")?; + let key = deposit_asset.to_id_word(); + let depositor_key = StorageMapKey::new(Word::from([ + sender_account.id().prefix().as_felt(), + sender_account.id().suffix(), + key[3], + key[2], + ])); + let balances_slot = StorageSlotName::new("bank_account::bank::balances")?; + let balance = bank.storage().get_map_item(&balances_slot, depositor_key)?; + anyhow::ensure!( + balance[0].as_canonical_u64() == DEFAULT_DEPOSIT_AMOUNT, + "Depositor ledger does not match the deposited assets" + ); println!("\n=== Deposit Complete ==="); println!("\nDepositor: {}", sender_account.id().to_hex()); diff --git a/examples/miden-bank/integration/src/bin/initialize.rs b/examples/miden-bank/integration/src/bin/initialize.rs index d6943391..e1b9b1fe 100644 --- a/examples/miden-bank/integration/src/bin/initialize.rs +++ b/examples/miden-bank/integration/src/bin/initialize.rs @@ -13,13 +13,16 @@ //! Prints the bank account ID that should be used for subsequent deposits. use integration::helpers::{ - build_project_in_dir, build_tx_script_from_package, create_account_from_package, - create_basic_wallet_account, setup_client, AccountCreationConfig, ClientSetup, + build_project_in_dir, build_tx_script_from_package, create_account_from_package, setup_client, + wait_for_native_funding, wait_for_transaction, AccountCreationConfig, ClientSetup, }; use anyhow::{Context, Result}; use miden_client::{ - account::{component::{InitStorageData, StorageValueName}, StorageSlotName}, + account::{ + component::{InitStorageData, StorageValueName}, + StorageSlotName, + }, transaction::TransactionRequestBuilder, Word, }; @@ -36,7 +39,10 @@ async fn main() -> Result<()> { } = setup_client().await?; let sync_summary = client.sync_state().await?; - println!("Connected to network. Latest block: {}", sync_summary.block_num); + println!( + "Connected to network. Latest block: {}", + sync_summary.block_num + ); // Build contracts println!("\nBuilding contracts..."); @@ -56,8 +62,8 @@ async fn main() -> Result<()> { // be seeded (here with a zero Word = uninitialized) or `from_package` errors with // `InitValueNotProvided`; the `balances` map defaults to empty. println!("\nCreating bank account..."); - let initialized_slot = StorageSlotName::new("bank_account::bank::initialized") - .context("Valid slot name")?; + let initialized_slot = + StorageSlotName::new("bank_account::bank::initialized").context("Valid slot name")?; let mut init_storage_data = InitStorageData::default(); init_storage_data.insert_value( StorageValueName::from_slot_name(&initialized_slot), @@ -68,21 +74,15 @@ async fn main() -> Result<()> { ..Default::default() }; - let bank_account = create_account_from_package(&mut client, bank_package.clone(), bank_cfg) - .await - .context("Failed to create bank account")?; + let bank_account = + create_account_from_package(&mut client, keystore, bank_package.clone(), bank_cfg) + .await + .context("Failed to create bank account")?; println!(" ✓ Bank account created"); println!(" Bank Account ID: {}", bank_account.id().to_hex()); - // Create a sender account to execute the init transaction - // (The bank account itself uses NoAuth, so we need a separate authenticated account) - println!("\nCreating admin wallet for initialization..."); - let admin_cfg = AccountCreationConfig::default(); - let admin_account = create_basic_wallet_account(&mut client, keystore.clone(), admin_cfg) - .await - .context("Failed to create admin wallet account")?; - println!(" ✓ Admin wallet created: {}", admin_account.id().to_hex()); + wait_for_native_funding(&mut client, bank_account.id(), 0).await?; // Build and execute the initialization transaction println!("\nInitializing bank account..."); @@ -104,17 +104,24 @@ async fn main() -> Result<()> { println!(" ✓ Init transaction submitted: {}", init_tx_id.to_hex()); - // Sync to confirm the transaction - client - .sync_state() - .await - .context("Failed to sync state after initialization")?; + wait_for_transaction(&mut client, init_tx_id).await?; + let bank = client + .get_account(bank_account.id()) + .await? + .context("Bank missing after init")?; + anyhow::ensure!( + bank.storage().get_item(&initialized_slot)?[0].as_canonical_u64() == 1, + "Bank did not initialize" + ); println!("\n=== Initialization Complete ==="); println!("\nBank Account ID (use this for deposits):"); println!(" {}", bank_account.id().to_hex()); println!("\nTo make a deposit, run:"); - println!(" cargo run --bin deposit -- {}", bank_account.id().to_hex()); + println!( + " cargo run --bin deposit -- {}", + bank_account.id().to_hex() + ); Ok(()) } diff --git a/examples/miden-bank/integration/src/helpers.rs b/examples/miden-bank/integration/src/helpers.rs index 3ee4f760..1b9e8041 100644 --- a/examples/miden-bank/integration/src/helpers.rs +++ b/examples/miden-bank/integration/src/helpers.rs @@ -1,15 +1,17 @@ //! Common helper functions for scripts and tests -use std::{path::Path, sync::Arc}; +use std::{ + path::Path, + sync::{Arc, Mutex}, +}; use anyhow::{bail, Context, Result}; -use cargo_miden::run; use miden_client::{ account::{ - component::{BasicWallet, InitStorageData, NoAuth}, + component::{BasicWallet, InitStorageData}, Account, AccountBuilder, AccountComponent, AccountType, }, - auth::{AuthSchemeId, AuthSecretKey, AuthSingleSig}, + auth::{AuthSecretKey, AuthSingleSig, NoAuth}, builder::ClientBuilder, crypto::{FeltRng, RandomCoin}, keystore::{FilesystemKeyStore, Keystore}, @@ -20,9 +22,9 @@ use miden_client::{ Client, Word, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; -use miden_mast_package::{Package, PackageExport, TargetType}; +use miden_protocol::assembly::Package; use miden_standards::testing::note::NoteBuilder; -use rand::RngCore; +use rand::Rng; /// Test setup configuration containing initialized client and keystore pub struct ClientSetup { @@ -38,17 +40,16 @@ pub async fn setup_client() -> Result { 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 = Path::new(env!("CARGO_MANIFEST_DIR")).join("../keystore"); let keystore = Arc::new(FilesystemKeyStore::new(keystore_path).context("Failed to initialize keystore")?); - let store_path = std::path::PathBuf::from("../store.sqlite3"); + let store_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("../store.sqlite3"); let client = ClientBuilder::new() .rpc(rpc_client) .sqlite_store(store_path) .authenticator(keystore.clone()) - .in_debug_mode(true.into()) .build() .await .context("Failed to build Miden client")?; @@ -56,33 +57,52 @@ pub async fn setup_client() -> Result { Ok(ClientSetup { client, keystore }) } -/// Builds a Miden project in the specified directory via the `cargo-miden` library -/// and returns the compiled [`Package`]. +/// Builds a Miden project with the `miden` CLI installed by midenup and returns its [`Package`]. +/// `CARGO_MIDEN` can select a standalone cargo-miden binary instead. pub fn build_project_in_dir(dir: &Path, release: bool) -> Result { - let profile = if release { "--release" } else { "--debug" }; - let manifest_path = dir.join("Cargo.toml"); - let manifest_arg = manifest_path.to_string_lossy(); - - let args = vec![ - "cargo", - "miden", - "build", - profile, - "--manifest-path", - &manifest_arg, - ]; - - let output = run(args.into_iter().map(String::from)) - .context("Failed to compile project")? - .context("Cargo miden build returned None")?; - - let artifact_path = match output { - cargo_miden::CommandOutput::BuildCommandOutput { output } => output - .into_iter() - .next() - .context("cargo miden build produced no artifact")?, - other => bail!("Expected BuildCommandOutput, got {:?}", other), + // Parallel tests share the compiled package paths. Hold the lock through + // deserialization so another build cannot replace an artifact while it is read. + static BUILD_LOCK: Mutex<()> = Mutex::new(()); + let _guard = BUILD_LOCK + .lock() + .map_err(|_| anyhow::anyhow!("Miden build lock poisoned"))?; + let dir = Path::new(env!("CARGO_MANIFEST_DIR")).join(dir); + let profile_dir = if release { "release" } else { "dev" }; + let mut command = match std::env::var_os("CARGO_MIDEN") { + Some(binary) => { + let mut command = std::process::Command::new(binary); + command.arg("miden"); + command + } + None => std::process::Command::new("miden"), }; + command + .arg("build") + .current_dir(&dir) + .env_remove("CARGO_TARGET_DIR") + .env_remove("RUSTUP_TOOLCHAIN") + .env_remove("CARGO") + .env_remove("RUSTC") + .env_remove("RUSTDOC"); + if release { + command.arg("--release"); + } + let status = command + .status() + .context("Failed to run Miden contract build")?; + if !status.success() { + bail!("Miden contract build failed with {status}"); + } + let artifact_dir = dir.join("target/miden").join(profile_dir); + let mut artifacts = std::fs::read_dir(&artifact_dir)? + .filter_map(|entry| entry.ok().map(|entry| entry.path())) + .filter(|path| path.extension().is_some_and(|ext| ext == "masp")); + let artifact_path = artifacts + .next() + .context("Miden contract build produced no MASP artifact")?; + if artifacts.next().is_some() { + bail!("expected one MASP artifact in {}", artifact_dir.display()); + } let package_bytes = std::fs::read(&artifact_path).context(format!( "Failed to read compiled package from {}", @@ -91,52 +111,14 @@ pub fn build_project_in_dir(dir: &Path, release: bool) -> Result { Package::read_from_bytes(&package_bytes).context("Failed to deserialize package from bytes") } -/// Builds a [`TransactionScript`] from a compiled transaction-script package. -/// -/// A `kind = "tx-script"` contract compiles to a `TransactionScript`-kind package (not an -/// `Executable`), so `TransactionScript::from_package` / `Package::unwrap_program` do not apply. -/// This mirrors the compiler's own helper: locate the `main`/`run` export and build the script -/// from the package's MAST forest plus that entrypoint. +/// Loads the procedure marked `@transaction_script` from a compiled package. pub fn build_tx_script_from_package(package: &Package) -> Result { - if package.kind != TargetType::TransactionScript { - bail!( - "expected a transaction-script package, got {:?}", - package.kind - ); - } - - let mut first_procedure = None; - let mut selected_procedure = None; - let mut num_procedures = 0usize; - for export in package.manifest.exports() { - let PackageExport::Procedure(procedure) = export else { - continue; - }; - num_procedures += 1; - first_procedure.get_or_insert(procedure); - if matches!(export.name(), "main" | "run") { - selected_procedure = Some(procedure); - } - } - - let procedure = selected_procedure - .or_else(|| (num_procedures == 1).then(|| first_procedure.unwrap())) - .context("transaction-script package should export exactly one entry procedure")?; - let entrypoint = package - .mast - .mast_forest() - .find_procedure_root(procedure.digest) - .context("transaction-script main export should have a MAST node")?; - - Ok(TransactionScript::from_parts( - package.mast.mast_forest().clone(), - entrypoint, - )) + TransactionScript::from_package(package).context("Failed to load transaction script") } /// Configuration for creating an account with a custom component. pub struct AccountCreationConfig { - /// The account type to create. In protocol v0.15 this also encodes the + /// The account type to create. In protocol v0.16 this also encodes the /// storage visibility (`AccountType::Public` / `AccountType::Private`). pub account_type: AccountType, /// Initial component storage data keyed by storage slot schema. @@ -161,9 +143,10 @@ pub fn account_component_from_package( .context("Failed to create account component from package") } -/// Creates an account with a custom component from a compiled package. +/// Creates an owner-authenticated account with a custom component from a compiled package. pub async fn create_account_from_package( client: &mut Client, + keystore: Arc, package: Arc, config: AccountCreationConfig, ) -> Result { @@ -171,11 +154,13 @@ pub async fn create_account_from_package( let mut init_seed = [0_u8; 32]; client.rng().fill_bytes(&mut init_seed); + let key_pair = AuthSecretKey::new_falcon512_poseidon2_with_rng(client.rng()); let account = AccountBuilder::new(init_seed) .account_type(config.account_type) .with_component(account_component) - .with_auth_component(NoAuth) + .with_component(BasicWallet) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .build() .context("Failed to build account")?; @@ -186,10 +171,15 @@ pub async fn create_account_from_package( .await .context("Failed to add account to client")?; + keystore + .add_key(&key_pair, account.id()) + .await + .context("Failed to add bank owner key to keystore")?; + Ok(account) } -/// Creates an existing (pre-built) account instance from a compiled package for testing. +/// Creates an existing account with NoAuth for isolated MockChain tests only. pub fn create_testing_account_from_package( package: Arc, config: AccountCreationConfig, @@ -199,7 +189,8 @@ pub fn create_testing_account_from_package( let account = AccountBuilder::new([3u8; 32]) .account_type(config.account_type) .with_component(account_component) - .with_auth_component(NoAuth) + .with_component(BasicWallet) + .with_component(NoAuth) .build_existing() .context("Failed to build account")?; @@ -241,16 +232,19 @@ pub fn create_note_from_package( .context("Failed to build note script from package")?; let serial_num = client.rng().draw_word(); - NoteBuilder::new(sender_id, &mut RandomCoin::new(Word::from(note_script.root()))) - .package((*package).clone()) - .note_type(config.note_type) - .tag(config.tag.into()) - .add_assets(config.assets.iter().copied()) - .note_storage(config.storage) - .context("Failed to attach note storage")? - .serial_number(serial_num) - .build() - .context("Failed to build note from package") + NoteBuilder::new( + sender_id, + &mut RandomCoin::new(Word::from(note_script.root())), + ) + .package((*package).clone()) + .note_type(config.note_type) + .tag(config.tag.into()) + .add_assets(config.assets.iter().copied()) + .note_storage(config.storage) + .context("Failed to attach note storage")? + .serial_number(serial_num) + .build() + .context("Failed to build note from package") } /// Creates a deterministic note from a compiled note-script package for testing. @@ -291,10 +285,7 @@ pub async fn create_basic_wallet_account( let builder = AccountBuilder::new(init_seed) .account_type(config.account_type) - .with_auth_component(AuthSingleSig::new( - key_pair.public_key().to_commitment(), - AuthSchemeId::Falcon512Poseidon2, - )) + .with_component(AuthSingleSig::from_public_key(key_pair.public_key())) .with_component(BasicWallet); let account = builder @@ -313,3 +304,91 @@ pub async fn create_basic_wallet_account( Ok(account) } + +/// Waits for an on-chain commitment before reporting a successful operation. +pub async fn wait_for_transaction( + client: &mut Client, + tx_id: miden_client::transaction::TransactionId, +) -> Result<()> { + use miden_client::{store::TransactionFilter, transaction::TransactionStatus}; + for _ in 0..36 { + client.sync_state().await?; + let records = client + .get_transactions(TransactionFilter::Ids(vec![tx_id])) + .await?; + if let Some(record) = records.first() { + match &record.status { + TransactionStatus::Committed { block_number, .. } => { + println!( + "Transaction committed: {} at block {}", + tx_id.to_hex(), + block_number + ); + return Ok(()); + } + TransactionStatus::Discarded(cause) => { + bail!("Transaction {tx_id} discarded: {cause}") + } + TransactionStatus::Pending => {} + } + } + tokio::time::sleep(std::time::Duration::from_secs(5)).await; + } + bail!("Transaction {tx_id} was not committed within 180 seconds") +} + +/// Waits for a public native-token P2ID sent to a newly created account, then consumes it. +/// Funding is requested externally while this binary is running. +pub async fn wait_for_native_funding( + client: &mut Client, + account_id: miden_client::account::AccountId, + amount_to_spend: u64, +) -> Result<()> { + use miden_client::{ + asset::{Asset, FungibleAsset}, + note::P2idNote, + transaction::TransactionRequestBuilder, + }; + + client.sync_state().await?; + let header = client.get_latest_block_header().await?; + let faucet_id = header.fee_parameters().fee_faucet_id(); + if amount_to_spend == 0 && header.fee_parameters().verification_base_fee() == 0 { + return Ok(()); + } + let native_id = FungibleAsset::new(faucet_id, 1)?.id(); + println!( + "Send a public P2ID with native testnet tokens to {}.\n\ + Request the faucet's standard amount to cover {amount_to_spend} base units plus fees.\n\ + Waiting up to 10 minutes for funding...", + account_id.to_hex() + ); + for _ in 0..120 { + client.sync_state().await?; + let account = client + .get_account(account_id) + .await? + .context("Funding account missing")?; + if u64::from(account.vault().get_balance(native_id)?) > amount_to_spend { + return Ok(()); + } + let notes = client.get_consumable_notes(Some(account_id)).await?; + let funding = notes.into_iter().find(|(record, _)| { + record.is_committed() + && record.details().script().root() == P2idNote::script_root() + && record.details().assets().iter().any(|asset| { + matches!(asset, Asset::Fungible(asset) if asset.faucet_id() == faucet_id) + }) + }); + if let Some((record, _)) = funding { + let request = + TransactionRequestBuilder::new().build_consume_notes(vec![record.try_into()?])?; + client.sync_state().await?; + let tx_id = client.submit_new_transaction(account_id, request).await?; + wait_for_transaction(client, tx_id).await?; + } else { + tokio::time::sleep(std::time::Duration::from_secs(5)).await; + } + } + bail!("No sufficient native funding received for {account_id}") +} diff --git a/examples/miden-bank/integration/tests/deposit_test.rs b/examples/miden-bank/integration/tests/deposit_test.rs index e9f56f0f..5dc9a500 100644 --- a/examples/miden-bank/integration/tests/deposit_test.rs +++ b/examples/miden-bank/integration/tests/deposit_test.rs @@ -3,14 +3,17 @@ use integration::helpers::{ create_testing_note_from_package, AccountCreationConfig, NoteCreationConfig, }; +use miden_client::asset::{Asset, FungibleAsset, NonFungibleAsset}; use miden_client::{ - account::{component::{InitStorageData, StorageValueName}, StorageSlotName}, - auth::AuthSchemeId, + account::{ + component::{InitStorageData, StorageValueName}, + StorageSlotName, + }, + auth::AuthScheme, note::NoteAssets, transaction::RawOutputNote, Felt, Word, }; -use miden_client::asset::{Asset, FungibleAsset}; use miden_testing::{Auth, MockChain}; use std::{path::Path, sync::Arc}; @@ -21,14 +24,65 @@ use std::{path::Path, sync::Arc}; /// `InitValueNotProvided`). The `balances` map slot defaults to empty and needs no entry. fn bank_storage_slots() -> (StorageSlotName, StorageSlotName) { let initialized_slot = - StorageSlotName::new("bank_account::bank::initialized") - .expect("Valid slot name"); + StorageSlotName::new("bank_account::bank::initialized").expect("Valid slot name"); let balances_slot = - StorageSlotName::new("bank_account::bank::balances") - .expect("Valid slot name"); + StorageSlotName::new("bank_account::bank::balances").expect("Valid slot name"); (initialized_slot, balances_slot) } +/// An NFT can have zero in value[1]; that is not a fungibility check in v0.16. +#[tokio::test] +async fn deposit_nft_with_zero_padding_should_fail() -> anyhow::Result<()> { + let mut builder = MockChain::builder(); + let faucet = builder.add_existing_non_fungible_faucet(Auth::IncrNonce, "NFT")?; + let sender = builder.add_existing_wallet_with_assets(Auth::IncrNonce, [])?; + let nft = NonFungibleAsset::from_parts(faucet.id(), Word::from([25u32, 0, 7, 0])); + let bank_package = Arc::new(build_project_in_dir( + Path::new("../contracts/bank-account"), + true, + )?); + let deposit_package = Arc::new(build_project_in_dir( + Path::new("../contracts/deposit-note"), + true, + )?); + let (initialized_slot, _) = bank_storage_slots(); + let mut init_storage_data = InitStorageData::default(); + init_storage_data.insert_value( + StorageValueName::from_slot_name(&initialized_slot), + Word::from([1u32, 0, 0, 0]), + )?; + let bank = create_testing_account_from_package( + bank_package, + AccountCreationConfig { + init_storage_data, + ..Default::default() + }, + )?; + let note = create_testing_note_from_package( + deposit_package, + sender.id(), + NoteCreationConfig { + assets: NoteAssets::new(vec![nft.into()])?, + ..Default::default() + }, + )?; + builder.add_account(bank.clone())?; + builder.add_output_note(RawOutputNote::Full(note.clone())); + let chain = builder.build()?; + let error = chain + .build_transaction(bank.id()) + .authenticated_input_note(note.id()) + .build()? + .execute() + .await + .expect_err("an NFT with zero padding must not be credited as fungible tokens"); + assert!( + format!("{error:?}").contains("FailedAssertion"), + "unexpected failure: {error:?}" + ); + Ok(()) +} + #[tokio::test] async fn deposit_test() -> anyhow::Result<()> { // Test that after executing the deposit note, the depositor's balance is updated @@ -37,7 +91,7 @@ async fn deposit_test() -> anyhow::Result<()> { // Create a faucet to mint test assets let faucet = builder.add_existing_basic_faucet( Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, + auth_scheme: AuthScheme::Falcon512Poseidon2, }, "TEST", 1000, @@ -47,7 +101,7 @@ async fn deposit_test() -> anyhow::Result<()> { // Create note sender account (the depositor) let sender = builder.add_existing_wallet_with_assets( Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, + auth_scheme: AuthScheme::Falcon512Poseidon2, }, [FungibleAsset::new(faucet.id(), 100)?.into()], )?; @@ -82,8 +136,7 @@ async fn deposit_test() -> anyhow::Result<()> { ..Default::default() }; - let mut bank_account = - create_testing_account_from_package(bank_package.clone(), bank_cfg)?; + let mut bank_account = create_testing_account_from_package(bank_package.clone(), bank_cfg)?; // Create a fungible asset to deposit let deposit_amount: u64 = 1000; @@ -117,14 +170,14 @@ async fn deposit_test() -> anyhow::Result<()> { let init_tx_script = build_tx_script_from_package(init_tx_script_package.as_ref())?; let init_tx_context = mock_chain - .build_tx_context(bank_account.id(), &[], &[])? + .build_transaction(bank_account.id()) .tx_script(init_tx_script) .build()?; let executed_init = init_tx_context.execute().await?; - bank_account.apply_delta(&executed_init.account_delta())?; mock_chain.add_pending_executed_transaction(&executed_init)?; mock_chain.prove_next_block()?; + bank_account = mock_chain.committed_account(bank_account.id())?.clone(); println!("Bank initialized successfully"); @@ -134,27 +187,28 @@ async fn deposit_test() -> anyhow::Result<()> { // Build the transaction context where bank consumes the deposit note let tx_context = mock_chain - .build_tx_context(bank_account.id(), &[deposit_note.id()], &[])? + .build_transaction(bank_account.id()) + .authenticated_input_note(deposit_note.id()) .build()?; // Execute the transaction let executed_transaction = tx_context.execute().await?; // Apply the account delta to the bank account - bank_account.apply_delta(&executed_transaction.account_delta())?; // Add the executed transaction to the mockchain and prove mock_chain.add_pending_executed_transaction(&executed_transaction)?; mock_chain.prove_next_block()?; + bank_account = mock_chain.committed_account(bank_account.id())?.clone(); // Create the key for the depositor (sender) in the storage map. // Key format: [depositor_prefix, depositor_suffix, asset.key[3], asset.key[2]]. - // In v0.15 the fungible-asset vault key is - // [asset_id_suffix, asset_id_prefix, faucet_suffix | metadata_byte, faucet_prefix], - // so `key[2]` is the faucet suffix combined with a metadata byte (composition + - // callback flag) — not the raw faucet suffix. Derive the read key from the asset's + // In v0.16 the fungible-asset vault key is + // [asset_class_suffix, asset_class_prefix, faucet_suffix | metadata_byte, faucet_prefix], + // so `key[2]` is the faucet suffix combined with composition metadata, + // not the raw faucet suffix. Derive the read key from the asset's // actual key word so it matches the key the contract writes. - let asset_key_word = FungibleAsset::new(faucet.id(), deposit_amount)?.to_key_word(); + let asset_key_word = FungibleAsset::new(faucet.id(), deposit_amount)?.to_id_word(); let depositor_key = Word::from([ sender.id().prefix().as_felt(), sender.id().suffix(), @@ -163,7 +217,10 @@ async fn deposit_test() -> anyhow::Result<()> { ]); // Get the depositor's balance from the bank's storage using named slot - let balance = bank_account.storage().get_map_item(&balances_slot, depositor_key)?; + let balance = bank_account.storage().get_map_item( + &balances_slot, + miden_client::account::StorageMapKey::new(depositor_key), + )?; // The contract stores `balance` as a `Felt`; reading the map returns the // single-Felt value widened into a Word at position [0] ([amount, 0, 0, 0]). @@ -197,7 +254,7 @@ async fn deposit_exceeds_max_should_fail() -> anyhow::Result<()> { let large_amount: u64 = 2_000_000; // Exceeds MAX_DEPOSIT_AMOUNT let faucet = builder.add_existing_basic_faucet( Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, + auth_scheme: AuthScheme::Falcon512Poseidon2, }, "TEST", large_amount, @@ -207,7 +264,7 @@ async fn deposit_exceeds_max_should_fail() -> anyhow::Result<()> { // Create note sender account (the depositor) with large asset balance let sender = builder.add_existing_wallet_with_assets( Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, + auth_scheme: AuthScheme::Falcon512Poseidon2, }, [FungibleAsset::new(faucet.id(), large_amount)?.into()], )?; @@ -240,8 +297,7 @@ async fn deposit_exceeds_max_should_fail() -> anyhow::Result<()> { ..Default::default() }; - let mut bank_account = - create_testing_account_from_package(bank_package.clone(), bank_cfg)?; + let mut bank_account = create_testing_account_from_package(bank_package.clone(), bank_cfg)?; // Create a deposit note with amount exceeding the max let fungible_asset = FungibleAsset::new(faucet.id(), large_amount)?; @@ -267,26 +323,28 @@ async fn deposit_exceeds_max_should_fail() -> anyhow::Result<()> { let init_tx_script = build_tx_script_from_package(init_tx_script_package.as_ref())?; let init_tx_context = mock_chain - .build_tx_context(bank_account.id(), &[], &[])? + .build_transaction(bank_account.id()) .tx_script(init_tx_script) .build()?; let executed_init = init_tx_context.execute().await?; - bank_account.apply_delta(&executed_init.account_delta())?; mock_chain.add_pending_executed_transaction(&executed_init)?; mock_chain.prove_next_block()?; + bank_account = mock_chain.committed_account(bank_account.id())?.clone(); // Build the transaction context let tx_context = mock_chain - .build_tx_context(bank_account.id(), &[deposit_note.id()], &[])? + .build_transaction(bank_account.id()) + .authenticated_input_note(deposit_note.id()) .build()?; // Execute should fail due to max deposit constraint let result = tx_context.execute().await; + let error = result.expect_err("deposit above the maximum must fail"); assert!( - result.is_err(), - "Expected transaction to fail due to exceeding max deposit amount, but it succeeded" + format!("{error:?}").contains("FailedAssertion"), + "unexpected failure: {error:?}" ); println!( @@ -308,7 +366,7 @@ async fn deposit_without_init_should_fail() -> anyhow::Result<()> { // Create a faucet to mint test assets let faucet = builder.add_existing_basic_faucet( Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, + auth_scheme: AuthScheme::Falcon512Poseidon2, }, "TEST", 1000, @@ -318,7 +376,7 @@ async fn deposit_without_init_should_fail() -> anyhow::Result<()> { // Create note sender account (the depositor) let sender = builder.add_existing_wallet_with_assets( Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, + auth_scheme: AuthScheme::Falcon512Poseidon2, }, [FungibleAsset::new(faucet.id(), 100)?.into()], )?; @@ -348,8 +406,7 @@ async fn deposit_without_init_should_fail() -> anyhow::Result<()> { ..Default::default() }; - let bank_account = - create_testing_account_from_package(bank_package.clone(), bank_cfg)?; + let bank_account = create_testing_account_from_package(bank_package.clone(), bank_cfg)?; // Create a deposit note let deposit_amount: u64 = 1000; @@ -374,15 +431,17 @@ async fn deposit_without_init_should_fail() -> anyhow::Result<()> { // Try to deposit WITHOUT initializing the bank first let tx_context = mock_chain - .build_tx_context(bank_account.id(), &[deposit_note.id()], &[])? + .build_transaction(bank_account.id()) + .authenticated_input_note(deposit_note.id()) .build()?; // Execute should fail because the bank is not initialized let result = tx_context.execute().await; + let error = result.expect_err("deposit before initialization must fail"); assert!( - result.is_err(), - "Expected deposit to fail when bank not initialized, but it succeeded" + format!("{error:?}").contains("FailedAssertion"), + "unexpected failure: {error:?}" ); println!("Uninitialized deposit correctly rejected - bank must be initialized first"); diff --git a/examples/miden-bank/integration/tests/init_test.rs b/examples/miden-bank/integration/tests/init_test.rs index d46d426a..9b93af36 100644 --- a/examples/miden-bank/integration/tests/init_test.rs +++ b/examples/miden-bank/integration/tests/init_test.rs @@ -4,8 +4,11 @@ use integration::helpers::{ }; use miden_client::{ - account::{component::{InitStorageData, StorageValueName}, StorageSlotName}, - auth::AuthSchemeId, + account::{ + component::{InitStorageData, StorageValueName}, + StorageSlotName, + }, + auth::AuthScheme, Word, }; use miden_testing::{Auth, MockChain}; @@ -33,8 +36,8 @@ async fn init_test() -> anyhow::Result<()> { // The `initialized` value slot has no schema default, so `AccountComponent::from_package` // requires it to be seeded (with a zero Word = uninitialized) or it errors with // `InitValueNotProvided`. The `balances` map slot defaults to empty. - let initialized_slot = StorageSlotName::new("bank_account::bank::initialized") - .expect("Valid slot name"); + let initialized_slot = + StorageSlotName::new("bank_account::bank::initialized").expect("Valid slot name"); let bank_cfg = AccountCreationConfig { init_storage_data: { @@ -48,19 +51,25 @@ async fn init_test() -> anyhow::Result<()> { ..Default::default() }; - let mut bank_account = - create_testing_account_from_package(bank_package.clone(), bank_cfg)?; + let mut bank_account = create_testing_account_from_package(bank_package.clone(), bank_cfg)?; // Verify bank starts uninitialized let before = bank_account.storage().get_item(&initialized_slot)?; - assert_eq!(before[0].as_canonical_u64(), 0, "Bank should start uninitialized"); - println!("Before init: initialized = {}", before[0].as_canonical_u64()); + assert_eq!( + before[0].as_canonical_u64(), + 0, + "Bank should start uninitialized" + ); + println!( + "Before init: initialized = {}", + before[0].as_canonical_u64() + ); // Build mock chain let mut builder = MockChain::builder(); builder.add_existing_basic_faucet( Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, + auth_scheme: AuthScheme::Falcon512Poseidon2, }, "TEST", 10_000_000, @@ -73,14 +82,14 @@ async fn init_test() -> anyhow::Result<()> { let init_tx_script = build_tx_script_from_package(init_tx_script_package.as_ref())?; let init_tx_context = mock_chain - .build_tx_context(bank_account.id(), &[], &[])? + .build_transaction(bank_account.id()) .tx_script(init_tx_script) .build()?; let executed_init = init_tx_context.execute().await?; - bank_account.apply_delta(&executed_init.account_delta())?; mock_chain.add_pending_executed_transaction(&executed_init)?; mock_chain.prove_next_block()?; + bank_account = mock_chain.committed_account(bank_account.id())?.clone(); // Verify initialized flag flipped to 1 let after = bank_account.storage().get_item(&initialized_slot)?; diff --git a/examples/miden-bank/integration/tests/withdraw_test.rs b/examples/miden-bank/integration/tests/withdraw_test.rs index 78d545e1..90100cbe 100644 --- a/examples/miden-bank/integration/tests/withdraw_test.rs +++ b/examples/miden-bank/integration/tests/withdraw_test.rs @@ -3,14 +3,17 @@ use integration::helpers::{ create_testing_note_from_package, AccountCreationConfig, NoteCreationConfig, }; +use miden_client::asset::{Asset, FungibleAsset}; use miden_client::{ - account::{component::{InitStorageData, StorageValueName}, StorageSlotName}, - auth::AuthSchemeId, + account::{ + component::{InitStorageData, StorageValueName}, + StorageSlotName, + }, + auth::AuthScheme, note::{Note, NoteAssets, NoteTag, NoteType, P2idNote, P2idNoteStorage, PartialNoteMetadata}, transaction::RawOutputNote, Felt, Word, }; -use miden_client::asset::{Asset, FungibleAsset}; use miden_testing::{Auth, MockChain}; use std::{path::Path, sync::Arc}; @@ -18,21 +21,26 @@ use std::{path::Path, sync::Arc}; /// seeded via `InitStorageData` (no schema default); the `balances` map defaults to empty. fn bank_storage_slots() -> (StorageSlotName, StorageSlotName) { let initialized_slot = - StorageSlotName::new("bank_account::bank::initialized") - .expect("Valid slot name"); + StorageSlotName::new("bank_account::bank::initialized").expect("Valid slot name"); let balances_slot = - StorageSlotName::new("bank_account::bank::balances") - .expect("Valid slot name"); + StorageSlotName::new("bank_account::bank::balances").expect("Valid slot name"); (initialized_slot, balances_slot) } #[tokio::test] async fn withdraw_test() -> anyhow::Result<()> { + for note_type in [NoteType::Public, NoteType::Private] { + withdraw_flow(note_type).await?; + } + Ok(()) +} + +async fn withdraw_flow(note_type: NoteType) -> anyhow::Result<()> { // ********************************************************************************* // SETUP // ********************************************************************************* - // Test that after executing the deposit note, the depositor's balance is updated + // Verify withdrawal through consumption of the resulting P2ID note. let mut builder = MockChain::builder(); // Define the deposit amount @@ -41,7 +49,7 @@ async fn withdraw_test() -> anyhow::Result<()> { // Create a faucet to mint test assets let faucet = builder.add_existing_basic_faucet( Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, + auth_scheme: AuthScheme::Falcon512Poseidon2, }, "TEST", deposit_amount, @@ -51,7 +59,7 @@ async fn withdraw_test() -> anyhow::Result<()> { // Create note sender account (the depositor) let sender = builder.add_existing_wallet_with_assets( Auth::BasicAuth { - auth_scheme: AuthSchemeId::Falcon512Poseidon2, + auth_scheme: AuthScheme::Falcon512Poseidon2, }, [FungibleAsset::new(faucet.id(), deposit_amount)?.into()], )?; @@ -73,7 +81,7 @@ async fn withdraw_test() -> anyhow::Result<()> { // Create the bank account. The `initialized` value slot has no schema default, so it must // be seeded (here with a zero Word = uninitialized) or `from_package` errors with // `InitValueNotProvided`; the `balances` map defaults to empty. - let (initialized_slot, _balances_slot) = bank_storage_slots(); + let (initialized_slot, balances_slot) = bank_storage_slots(); let bank_cfg = AccountCreationConfig { init_storage_data: { let mut data = InitStorageData::default(); @@ -86,8 +94,7 @@ async fn withdraw_test() -> anyhow::Result<()> { ..Default::default() }; - let mut bank_account = - create_testing_account_from_package(bank_package.clone(), bank_cfg)?; + let mut bank_account = create_testing_account_from_package(bank_package.clone(), bank_cfg)?; // ********************************************************************************* // STEP 1: CRAFT DEPOSIT NOTE @@ -136,22 +143,22 @@ async fn withdraw_test() -> anyhow::Result<()> { println!("Serial num (random): {:?}", p2id_output_note_serial_num); // Note type for the P2ID output note - let note_type_felt = Felt::new_unchecked(1); // 1 = Public note (stored on-chain) + let note_type_felt = Felt::from(note_type); // Public = 1, Private = 0 // Get the P2ID script root (Poseidon2-hashed MAST root). `script_root()` returns - // a `NoteScriptRoot` in v0.15; convert to a `Word` so its felts can be indexed. + // a `NoteScriptRoot` in v0.16; convert to a `Word` so its felts can be indexed. let p2id_script_root = Word::from(P2idNote::script_root()); // Note storage layout (14 Felts): // [0-3]: withdraw asset encoded as [amount, 0, asset.key[2] (faucet suffix + metadata byte), asset.key[3] (faucet prefix)] // [4-7]: serial_num (random/unique per note) // [8]: tag (P2ID note tag for routing) - // [9]: note_type (1 = Public, 2 = Private) + // [9]: note_type (1 = Public, 0 = Private) // [10-13]: P2ID script_root (MAST root for recipient computation) - // In v0.15 the fungible-asset vault key encodes the faucet suffix together with a + // In v0.16 the fungible-asset vault key encodes the faucet suffix together with a // metadata byte at index [2] (and the faucet prefix at [3]). Encode the asset from the // asset's real key word so the bank reconstructs the same key it deposited under. - let withdraw_asset_key_word = FungibleAsset::new(faucet.id(), withdraw_amount)?.to_key_word(); + let withdraw_asset_key_word = FungibleAsset::new(faucet.id(), withdraw_amount)?.to_id_word(); let withdraw_request_note_storage = vec![ // WITHDRAW ASSET ENCODING Felt::new_unchecked(withdraw_amount), @@ -165,7 +172,7 @@ async fn withdraw_test() -> anyhow::Result<()> { p2id_output_note_serial_num[3], // TAG (directly passed, no advice provider needed) p2id_tag_felt, - // NOTE TYPE (1 = Public) + // NOTE TYPE (1 = Public, 0 = Private) note_type_felt, // P2ID SCRIPT ROOT (4 Felts) p2id_script_root[0], @@ -201,14 +208,14 @@ async fn withdraw_test() -> anyhow::Result<()> { let init_tx_script = build_tx_script_from_package(init_tx_script_package.as_ref())?; let init_tx_context = mock_chain - .build_tx_context(bank_account.id(), &[], &[])? + .build_transaction(bank_account.id()) .tx_script(init_tx_script) .build()?; let executed_init = init_tx_context.execute().await?; - bank_account.apply_delta(&executed_init.account_delta())?; mock_chain.add_pending_executed_transaction(&executed_init)?; mock_chain.prove_next_block()?; + bank_account = mock_chain.committed_account(bank_account.id())?.clone(); println!("Bank initialized successfully"); @@ -218,18 +225,17 @@ async fn withdraw_test() -> anyhow::Result<()> { // Build the transaction context where bank consumes the deposit note let deposit_tx_context = mock_chain - .build_tx_context(bank_account.id(), &[deposit_note.id()], &[])? + .build_transaction(bank_account.id()) + .authenticated_input_note(deposit_note.id()) .build()?; // Execute the transaction let executed_deposit_transaction = deposit_tx_context.execute().await?; - // Apply the account delta to the bank account - bank_account.apply_delta(&executed_deposit_transaction.account_delta())?; - // Add the executed transaction to the mockchain and prove mock_chain.add_pending_executed_transaction(&executed_deposit_transaction)?; mock_chain.prove_next_block()?; + bank_account = mock_chain.committed_account(bank_account.id())?.clone(); println!("Bank deposit successful"); @@ -241,8 +247,8 @@ async fn withdraw_test() -> anyhow::Result<()> { let recipient = P2idNoteStorage::new(sender.id()).into_recipient(p2id_output_note_serial_num); let p2id_output_note_asset = FungibleAsset::new(faucet.id(), withdraw_amount)?; let p2id_output_note_assets = NoteAssets::new(vec![p2id_output_note_asset.into()])?; - let p2id_output_note_metadata = PartialNoteMetadata::new(bank_account.id(), NoteType::Public) - .with_tag(p2id_tag); + let p2id_output_note_metadata = + PartialNoteMetadata::new(bank_account.id(), note_type).with_tag(p2id_tag); println!("Recipient digest: {:?}", recipient.digest().to_hex()); @@ -253,18 +259,72 @@ async fn withdraw_test() -> anyhow::Result<()> { ); let withdraw_request_tx_context = mock_chain - .build_tx_context(bank_account.id(), &[withdraw_request_note.id()], &[])? - .extend_expected_output_notes(vec![RawOutputNote::Full(p2id_output_note)]) + .build_transaction(bank_account.id()) + .authenticated_input_note(withdraw_request_note.id()) + .expected_output_notes(vec![RawOutputNote::Full(p2id_output_note.clone())]) .build()?; let executed_withdraw_request_transaction = withdraw_request_tx_context.execute().await?; - bank_account.apply_delta(&executed_withdraw_request_transaction.account_delta())?; - mock_chain.add_pending_executed_transaction(&executed_withdraw_request_transaction)?; mock_chain.prove_next_block()?; + bank_account = mock_chain.committed_account(bank_account.id())?.clone(); + + let remaining = deposit_amount - withdraw_amount; + let asset = FungibleAsset::new(faucet.id(), withdraw_amount)?; + let asset_key = asset.to_id_word(); + let depositor_key = miden_client::account::StorageMapKey::new(Word::from([ + sender.id().prefix().as_felt(), + sender.id().suffix(), + asset_key[3], + asset_key[2], + ])); + let balance = bank_account + .storage() + .get_map_item(&balances_slot, depositor_key)?; + assert_eq!(balance[0].as_canonical_u64(), remaining); + assert_eq!( + u64::from(bank_account.vault().get_balance(asset.id())?), + remaining + ); + assert_eq!( + executed_withdraw_request_transaction + .output_notes() + .num_notes(), + 1 + ); + // MockChain retains only headers for newly committed private notes. Supply their + // full details explicitly, as the recipient would receive them out of band. + let consume_p2id = |account_id| { + let tx = mock_chain.build_transaction(account_id); + if note_type == NoteType::Public { + tx.authenticated_input_note(p2id_output_note.id()) + } else { + tx.unauthenticated_input_note(p2id_output_note.clone()) + } + }; - println!("Withdraw test passed!"); + // P2ID must reject a consumer other than the depositor. + let error = consume_p2id(bank_account.id()) + .build()? + .execute() + .await + .expect_err("only the depositor may consume the withdrawal note"); + assert!( + format!("{error:?}").contains("FailedAssertion"), + "unexpected failure: {error:?}" + ); + + let sender_balance_before = u64::from(sender.vault().get_balance(asset.id())?); + let executed_receive = consume_p2id(sender.id()).build()?.execute().await?; + mock_chain.add_pending_executed_transaction(&executed_receive)?; + mock_chain.prove_next_block()?; + let sender_after = mock_chain.committed_account(sender.id())?; + assert_eq!( + u64::from(sender_after.vault().get_balance(asset.id())?), + sender_balance_before + withdraw_amount + ); + println!("{note_type:?} withdrawal consumed by depositor! Remaining bank balance: {remaining}"); Ok(()) } diff --git a/examples/miden-bank/miden-toolchain.toml b/examples/miden-bank/miden-toolchain.toml new file mode 100644 index 00000000..8f1310ba --- /dev/null +++ b/examples/miden-bank/miden-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "0.16.0" +profile = "empty" +components = ["midenc", "cargo-miden", "core", "protocol"] diff --git a/examples/miden-bank/rust-toolchain.toml b/examples/miden-bank/rust-toolchain.toml index 7735c77a..9148f62f 100644 --- a/examples/miden-bank/rust-toolchain.toml +++ b/examples/miden-bank/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] -channel = "nightly-2026-04-30" +channel = "nightly-2026-09-01" components = ["rustfmt", "rust-src", "clippy"] targets = ["wasm32-wasip2"] profile = "minimal" diff --git a/rust-client/src/bin/unauthenticated_note_transfer.rs b/rust-client/src/bin/unauthenticated_note_transfer.rs index aaed1470..af165dc1 100644 --- a/rust-client/src/bin/unauthenticated_note_transfer.rs +++ b/rust-client/src/bin/unauthenticated_note_transfer.rs @@ -22,6 +22,7 @@ use miden_client::{ Client, ClientError, }; use miden_client_sqlite_store::ClientBuilderSqliteExt; +use miden_protocol::transaction::InputNote; use rust_client::{fund_account_for_fees, FeeConfig, TutorialNetwork}; /// Waits for a specific transaction to be committed. @@ -257,8 +258,10 @@ async fn main() -> Result<(), ClientError> { let deserialized_p2id_note = Note::read_from_bytes(&serialized).unwrap(); // Time consume note request building - let consume_note_request = - TransactionRequestBuilder::new().build_consume_notes(vec![deserialized_p2id_note])?; + // Keep this input unauthenticated even if syncing has already fetched its proof. + let consume_note_request = TransactionRequestBuilder::new() + .explicit_input_notes([(InputNote::unauthenticated(deserialized_p2id_note), None)]) + .build()?; let tx_id = client .submit_tutorial_transaction(accounts[i + 1].id(), consume_note_request) From bf779c6073b33e355bbfbbff90bded05f8aee4ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Vigara=20Fern=C3=A1ndez?= <312482795+0xrouss-miden@users.noreply.github.com> Date: Sun, 13 Sep 2026 20:49:40 +0200 Subject: [PATCH 3/3] fix: format bank tutorial markdown --- docs/src/miden-bank/01-account-components.md | 1 - docs/src/miden-bank/02-constants-constraints.md | 1 - docs/src/miden-bank/04-note-scripts.md | 1 - 3 files changed, 3 deletions(-) diff --git a/docs/src/miden-bank/01-account-components.md b/docs/src/miden-bank/01-account-components.md index 7ac9a605..9198ed6d 100644 --- a/docs/src/miden-bank/01-account-components.md +++ b/docs/src/miden-bank/01-account-components.md @@ -266,7 +266,6 @@ This compiles the Rust code to Miden Assembly and generates: - `target/miden/dev/bank-account.masp` - The compiled package - The package embeds the WIT interface used by dependent contracts - ## Optional: Verify Your Code :::note diff --git a/docs/src/miden-bank/02-constants-constraints.md b/docs/src/miden-bank/02-constants-constraints.md index 36edd6a5..61db85c5 100644 --- a/docs/src/miden-bank/02-constants-constraints.md +++ b/docs/src/miden-bank/02-constants-constraints.md @@ -271,7 +271,6 @@ cd contracts/bank-account miden build ``` - ## Optional: Verify Constraints Work :::note diff --git a/docs/src/miden-bank/04-note-scripts.md b/docs/src/miden-bank/04-note-scripts.md index 4dd48f64..c37bdda9 100644 --- a/docs/src/miden-bank/04-note-scripts.md +++ b/docs/src/miden-bank/04-note-scripts.md @@ -231,7 +231,6 @@ cd ../.. - ## Execution Flow Diagram ```text