From 0e289c08a44c0434d8089a761c96cb3e3d5a0100 Mon Sep 17 00:00:00 2001 From: hubcycle Date: Mon, 24 Nov 2025 06:17:06 +0000 Subject: [PATCH 1/8] feat: bump miden-client to v0.12 in crates - drop the usage of miden-multisig-coordinator-utils - use `Signature::to_prepared_signature` to obtain `Vec` to be passed as tx args - make miden-multisig-client crate no_std - fix unit and integration tests to be compatible with the testnet using miden-client v0.12 --- Cargo.lock | 943 +++++++++++++----- Cargo.toml | 30 +- bin/coordinator-server/Cargo.toml | 2 - bin/coordinator-server/src/error.rs | 14 +- bin/coordinator-server/src/payload.rs | 17 +- bin/coordinator-server/src/routes.rs | 87 +- crates/coordinator/domain/Cargo.toml | 1 - crates/coordinator/domain/src/account.rs | 128 +-- crates/coordinator/domain/src/tx.rs | 11 +- crates/coordinator/domain/src/with_serde.rs | 86 +- crates/coordinator/engine/Cargo.toml | 24 +- crates/coordinator/engine/README.md | 12 +- crates/coordinator/engine/src/error.rs | 15 +- crates/coordinator/engine/src/lib.rs | 104 +- .../engine/src/multisig_client_runtime.rs | 40 +- .../engine/src/multisig_client_runtime/msg.rs | 30 +- .../coordinator/engine/src/types/request.rs | 46 +- .../coordinator/engine/src/types/response.rs | 3 +- .../engine/tests/multisig_engine_test.rs | 65 +- crates/coordinator/store/Cargo.toml | 2 - crates/coordinator/store/README.md | 20 +- crates/coordinator/store/src/error.rs | 2 +- crates/coordinator/store/src/lib.rs | 113 +-- crates/coordinator/utils/Cargo.toml | 18 - crates/coordinator/utils/src/address.rs | 32 - crates/coordinator/utils/src/lib.rs | 9 - crates/coordinator/utils/src/signature.rs | 80 -- crates/miden-multisig-client/Cargo.toml | 14 +- crates/miden-multisig-client/src/error.rs | 101 ++ crates/miden-multisig-client/src/lib.rs | 277 ++--- crates/miden-multisig-client/src/tests.rs | 73 +- crates/test-utils/Cargo.toml | 7 +- crates/test-utils/src/lib.rs | 11 +- store | Bin 196608 -> 0 bytes 34 files changed, 1408 insertions(+), 1009 deletions(-) delete mode 100644 crates/coordinator/utils/Cargo.toml delete mode 100644 crates/coordinator/utils/src/address.rs delete mode 100644 crates/coordinator/utils/src/lib.rs delete mode 100644 crates/coordinator/utils/src/signature.rs create mode 100644 crates/miden-multisig-client/src/error.rs delete mode 100644 store diff --git a/Cargo.lock b/Cargo.lock index bef0179..c1f564c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,16 @@ # 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" @@ -17,6 +27,16 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + [[package]] name = "aho-corasick" version = "1.1.4" @@ -96,6 +116,9 @@ name = "anyhow" version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +dependencies = [ + "backtrace", +] [[package]] name = "arrayref" @@ -181,9 +204,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "axum" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18ed336352031311f4e0b4dd2ff392d4fbb370777c9d18d7fc9d7359f73871" +checksum = "5b098575ebe77cb6d14fc7f32749631a6e44edbef6b796f89b020e99ba20d425" dependencies = [ "axum-core", "bytes", @@ -255,6 +278,12 @@ dependencies = [ "backtrace", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.21.7" @@ -372,7 +401,7 @@ dependencies = [ "tokio", "tokio-stream", "tokio-util", - "tonic 0.14.2", + "tonic", "tower-service", "url", "winapi", @@ -386,7 +415,7 @@ checksum = "85a885520bf6249ab931a764ffdb87b0ceef48e6e7d807cfdb21b751e086e1ad" dependencies = [ "prost 0.14.1", "prost-types 0.14.1", - "tonic 0.14.2", + "tonic", "tonic-prost", "ureq", ] @@ -453,9 +482,9 @@ checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "cc" -version = "1.2.46" +version = "1.2.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97463e1064cb1b1c1384ad0a0b9c8abd0988e2a91f52606c80ef14aadb63e36" +checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07" dependencies = [ "find-msvc-tools", "jobserver", @@ -469,6 +498,30 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + [[package]] name = "chrono" version = "0.4.42" @@ -483,6 +536,17 @@ dependencies = [ "windows-link 0.2.1", ] +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + [[package]] name = "colorchoice" version = "1.0.4" @@ -563,6 +627,18 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.7" @@ -570,9 +646,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", + "rand_core 0.6.4", "typenum", ] +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "rustc_version 0.4.1", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "darling" version = "0.21.3" @@ -762,6 +866,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] @@ -831,12 +936,70 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", +] + [[package]] name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "ena" version = "0.14.3" @@ -846,6 +1009,18 @@ dependencies = [ "log", ] +[[package]] +name = "enum_dispatch" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" +dependencies = [ + "once_cell", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "env_filter" version = "0.1.4" @@ -920,6 +1095,22 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "filetime" version = "0.2.26" @@ -950,6 +1141,18 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe" +[[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", +] + [[package]] name = "fnv" version = "1.0.7" @@ -962,6 +1165,12 @@ 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" @@ -971,6 +1180,15 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fs-err" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62d91fd049c123429b018c47887d3f75a265540dd3c30ba9cb7bae9197edb03a" +dependencies = [ + "autocfg", +] + [[package]] name = "futures" version = "0.3.31" @@ -1082,6 +1300,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -1091,8 +1310,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1121,6 +1342,17 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + [[package]] name = "h2" version = "0.4.12" @@ -1133,7 +1365,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.12.0", + "indexmap 2.12.1", "slab", "tokio", "tokio-util", @@ -1152,18 +1384,22 @@ version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "allocator-api2", - "equivalent", - "foldhash", - "rayon", - "serde", + "foldhash 0.1.5", ] [[package]] name = "hashbrown" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash 0.2.0", + "rayon", + "serde", + "serde_core", +] [[package]] name = "hashlink" @@ -1192,6 +1428,15 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + [[package]] name = "hmac" version = "0.12.1" @@ -1354,7 +1599,7 @@ dependencies = [ "hyper", "libc", "pin-project-lite", - "socket2 0.6.1", + "socket2", "tokio", "tower-service", "tracing", @@ -1526,16 +1771,25 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown 0.16.0", + "hashbrown 0.16.1", "serde", "serde_core", ] +[[package]] +name = "inout" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" +dependencies = [ + "generic-array", +] + [[package]] name = "is_ci" version = "1.2.0" @@ -1607,6 +1861,20 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + [[package]] name = "keccak" version = "0.1.5" @@ -1832,11 +2100,12 @@ checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "miden-air" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2871bc4f392053cd115d4532e4b0fb164791829cc94b35641ed72480547dfd1" +checksum = "06acfd2ddc25b68f9d23d2add3f15c0ec3f9890ce6418409d71bea9dc6590bd0" dependencies = [ "miden-core", + "miden-utils-indexing", "thiserror 2.0.17", "winter-air", "winter-prover", @@ -1844,9 +2113,9 @@ dependencies = [ [[package]] name = "miden-assembly" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345ae47710bbb4c6956dcc669a537c5cf2081879b6238c0df6da50e84a77ea3f" +checksum = "d1219b9e48bb286b58a23bb65cf74baa1b24ddbcb462ca625b38186674571047" dependencies = [ "log", "miden-assembly-syntax", @@ -1858,9 +2127,9 @@ dependencies = [ [[package]] name = "miden-assembly-syntax" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ab186ac7061b47415b923cf2da88df505f25c333f7caace80fb7760cf9c0590" +checksum = "1eeaef2853061c54527bb2664c0c832ce3d1f80847c79512455fec3b93057f2a" dependencies = [ "aho-corasick", "lalrpop", @@ -1870,6 +2139,7 @@ dependencies = [ "miden-debug-types", "miden-utils-diagnostics", "midenc-hir-type", + "proptest", "regex", "rustc_version 0.4.1", "semver 1.0.27", @@ -1879,9 +2149,9 @@ dependencies = [ [[package]] name = "miden-block-prover" -version = "0.11.5" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb160f7251d6cc5935eb3394df6f05d7eab404009ffd44608f0cdb6d984ab584" +checksum = "abd33a60630977df766a901e9c89342e1632673071e13fb5711410a25610aa3e" dependencies = [ "miden-lib", "miden-objects", @@ -1890,46 +2160,71 @@ dependencies = [ [[package]] name = "miden-client" -version = "0.11.11" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8bc83f3bad7a94b30ccf0f77313bb21d0aa2e180df9c053e0e0ebe76d08e072" +checksum = "20c061c44b345267a9d144fb1cb2d2f7b47a9257f52d7907004297df8a3de1d7" dependencies = [ "anyhow", "async-trait", "chrono", - "deadpool", - "deadpool-sync", + "futures", + "getrandom 0.3.4", "hex", "miden-lib", "miden-node-proto-build", + "miden-note-transport-proto-build", "miden-objects", "miden-remote-prover-client", "miden-testing", "miden-tx", "miette", - "prost 0.13.5", + "prost 0.14.1", "prost-build", + "prost-types 0.14.1", "protox 0.7.2", "rand", - "rusqlite", - "rusqlite_migration", "thiserror 2.0.17", - "tonic 0.13.1", + "tonic", "tonic-build", + "tonic-health", + "tonic-prost", + "tonic-prost-build", + "tonic-web-wasm-client", "tracing", "uuid", "web-sys", ] +[[package]] +name = "miden-client-sqlite-store" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57f806b34687798a0545177619196017362cb3b67bd0c7003081d1fd5d179c70" +dependencies = [ + "anyhow", + "async-trait", + "chrono", + "deadpool", + "deadpool-sync", + "miden-client", + "miden-objects", + "rusqlite", + "rusqlite_migration", + "thiserror 2.0.17", + "tokio", +] + [[package]] name = "miden-core" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "395ad0b07592486e02de3ff7f3bff1d7fa81b1a7120f7f0b1027d650d810bbab" +checksum = "452a00429d05c416001ec0578291eb88e115cf94fc22b3308267abfdcd813440" dependencies = [ + "enum_dispatch", "miden-crypto", "miden-debug-types", "miden-formatting", + "miden-utils-indexing", "num-derive", "num-traits", "thiserror 2.0.17", @@ -1939,40 +2234,61 @@ dependencies = [ [[package]] name = "miden-crypto" -version = "0.15.9" +version = "0.18.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4329275a11c7d8328b14a7129b21d40183056dcd0d871c3069be6e550d6ca40" +checksum = "0048d2d987f215bc9633ced499a8c488d0e2474350c765f904b87cae3462acb7" dependencies = [ "blake3", "cc", + "chacha20poly1305", + "ed25519-dalek", + "flume", "glob", - "hashbrown 0.15.5", + "hashbrown 0.16.1", + "hkdf", + "k256", + "miden-crypto-derive", "num", "num-complex", "rand", - "rand_core", + "rand_chacha", + "rand_core 0.9.3", + "rand_hc", "rayon", "sha3", + "subtle", "thiserror 2.0.17", "winter-crypto", "winter-math", "winter-utils", + "x25519-dalek", +] + +[[package]] +name = "miden-crypto-derive" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3b38aace84e157fb02aba8f8ae85bbf8c3afdcdbdf8190fbe7476f3be7ef44" +dependencies = [ + "quote", + "syn", ] [[package]] name = "miden-debug-types" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c84e5b15ea6fe0f80688fde2d6e4f5a3b66417d2541388b7a6cf967c6a8a2bc0" +checksum = "97eed62ac0ca7420e49148fd306c74786b23a8d31df6da6277c671ba3e5c619a" dependencies = [ "memchr", "miden-crypto", "miden-formatting", "miden-miette", + "miden-utils-indexing", "miden-utils-sync", "paste", "serde", - "serde_spanned 1.0.3", + "serde_spanned", "thiserror 2.0.17", ] @@ -1987,11 +2303,14 @@ dependencies = [ [[package]] name = "miden-lib" -version = "0.11.5" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "797551e1f2515691852c55c1b186d302dd62e147cf3252c4fcf64d26ca8197f7" +checksum = "015992e9a31a4a2667adf2ee795d5f02927a6e9f4e21490ce02fb6395eb6bd41" dependencies = [ + "Inflector", + "fs-err", "miden-assembly", + "miden-core", "miden-objects", "miden-processor", "miden-stdlib", @@ -2003,13 +2322,14 @@ dependencies = [ [[package]] name = "miden-mast-package" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9d87c128f467874b272fec318e792385e35b14d200408a10d30909228db864" +checksum = "1d13e6ba2b357551598f13396ed52f8f21aa99979aa3b338bb5521feeda19c8a" dependencies = [ "derive_more", "miden-assembly-syntax", "miden-core", + "thiserror 2.0.17", ] [[package]] @@ -2058,14 +2378,11 @@ dependencies = [ name = "miden-multisig-client" version = "0.1.0" dependencies = [ - "anyhow", "miden-client", "miden-multisig-test-utils", - "miden-objects", "rand", "thiserror 2.0.17", "tokio", - "url", ] [[package]] @@ -2076,7 +2393,6 @@ dependencies = [ "chrono", "dissolve-derive", "miden-client", - "miden-objects", "serde", "serde_with", "strum", @@ -2092,12 +2408,10 @@ dependencies = [ "diesel_migrations", "dissolve-derive", "miden-client", + "miden-client-sqlite-store", "miden-multisig-client", "miden-multisig-coordinator-domain", "miden-multisig-coordinator-store", - "miden-multisig-coordinator-utils", - "miden-objects", - "miden-testing", "openssl-sys", "pq-sys", "rand", @@ -2126,8 +2440,6 @@ dependencies = [ "miden-multisig-coordinator-domain", "miden-multisig-coordinator-engine", "miden-multisig-coordinator-store", - "miden-multisig-coordinator-utils", - "miden-objects", "openssl-sys", "pq-sys", "serde", @@ -2152,8 +2464,6 @@ dependencies = [ "futures", "miden-client", "miden-multisig-coordinator-domain", - "miden-multisig-coordinator-utils", - "miden-objects", "oblux", "rustls", "rustls-native-certs", @@ -2165,51 +2475,55 @@ dependencies = [ "uuid", ] -[[package]] -name = "miden-multisig-coordinator-utils" -version = "0.0.1-pre" -dependencies = [ - "miden-crypto", - "miden-objects", - "miden-tx", - "rand", - "rand_chacha", - "thiserror 2.0.17", -] - [[package]] name = "miden-multisig-test-utils" version = "0.0.1-pre" dependencies = [ "miden-client", + "miden-client-sqlite-store", "miden-testing", "rand", ] [[package]] name = "miden-node-proto-build" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1674a01e850ad65e8cdd7fa864b728dddc17e3d90944b1ff96933211bb1c806b" +checksum = "f083bf3a275076f207fa36d4e247c1554e7310c9b85c245b2fc5fbb69934f437" dependencies = [ - "anyhow", - "prost 0.13.5", - "protox 0.8.0", - "tonic-build", + "fs-err", + "miette", + "protox 0.9.0", + "tonic-prost-build", +] + +[[package]] +name = "miden-note-transport-proto-build" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86d7a7b3a64c71d33f771d32cde58559207819a64ada9add0acb31857e111b9d" +dependencies = [ + "fs-err", + "miette", + "protox 0.9.0", + "tonic-prost-build", ] [[package]] name = "miden-objects" -version = "0.11.5" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b513a36886b910d71c39b17f37e48179e251fca49cebcbcf57094bef9941f63" +checksum = "57ea15ca33d7735e08e81afd9c9f4f02fc0259ec019fcb4ec44192c205743553" dependencies = [ "bech32", "getrandom 0.3.4", "miden-assembly", + "miden-assembly-syntax", "miden-core", "miden-crypto", + "miden-mast-package", "miden-processor", + "miden-stdlib", "miden-utils-sync", "miden-verifier", "rand", @@ -2217,20 +2531,24 @@ dependencies = [ "semver 1.0.27", "serde", "thiserror 2.0.17", - "toml 0.8.23", + "toml", "winter-rand-utils", ] [[package]] name = "miden-processor" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64304339292cc4e50a7b534197326824eeb21f3ffaadd955be63cc57093854ed" +checksum = "d2ef77929651b8755965cde8f589bd38e2345a619d54cab6427f91aa23c47f6a" dependencies = [ + "itertools", "miden-air", "miden-core", "miden-debug-types", "miden-utils-diagnostics", + "miden-utils-indexing", + "paste", + "rayon", "thiserror 2.0.17", "tokio", "tracing", @@ -2239,9 +2557,9 @@ dependencies = [ [[package]] name = "miden-prover" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f21637f9dcca045f7bf65da20d42f37f86373b43092ae9df9a230cffb86f4d6d" +checksum = "84c30a5d10baeec17b9336de8544cb7f9b96b32de757c4cfb8d95ee0521bb5cd" dependencies = [ "miden-air", "miden-debug-types", @@ -2253,34 +2571,35 @@ dependencies = [ [[package]] name = "miden-remote-prover-client" -version = "0.11.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a421a9b5e8f09bda3d91a2d17f7d6804107bd5bb775a61a82b4fe47204d1f3ae" +checksum = "23a02c8c0a548982dc7871df53df6c703119d47c6a3c746604de2979bcff4b42" dependencies = [ "getrandom 0.3.4", "miden-node-proto-build", "miden-objects", "miden-tx", "miette", - "prost 0.13.5", - "prost-build", - "protox 0.8.0", + "prost 0.14.1", "thiserror 2.0.17", "tokio", - "tonic 0.13.1", - "tonic-build", + "tonic", + "tonic-prost", + "tonic-prost-build", "tonic-web-wasm-client", ] [[package]] name = "miden-stdlib" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7308c32ec08dd75c29653315a0f395786d391c2fe55a5318ec39662a31de6a26" +checksum = "5e90a5de45a1e6213ff17b66fff8accde0bbc64264e2c22bbcb9a895f8f3b767" dependencies = [ "env_logger", + "fs-err", "miden-assembly", "miden-core", + "miden-crypto", "miden-processor", "miden-utils-sync", "thiserror 2.0.17", @@ -2288,9 +2607,9 @@ dependencies = [ [[package]] name = "miden-testing" -version = "0.11.5" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "974f253caf5eb68d5de708923cd5e1db539607db4a5a676f6bcdf61ed259d65b" +checksum = "8107f897f415813a85677f49a9b4470d0562b13ada3d0bbaaa161e53a4a665d0" dependencies = [ "anyhow", "itertools", @@ -2299,18 +2618,18 @@ dependencies = [ "miden-objects", "miden-processor", "miden-tx", + "miden-tx-batch-prover", "rand", "rand_chacha", "thiserror 2.0.17", - "tokio", "winterfell", ] [[package]] name = "miden-tx" -version = "0.11.5" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99ae7a15bb02ecd7f7213387c33e857b12e56e8690f9220c7bc6ad3733bf4c94" +checksum = "94f5295f8646bc84829ebda923448aebffa2a36f88ef2112b7b4538901e1b34b" dependencies = [ "miden-lib", "miden-objects", @@ -2322,11 +2641,21 @@ dependencies = [ "tokio", ] +[[package]] +name = "miden-tx-batch-prover" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4a7e1a2a2fd9224f5048b69181c1aaaad796b671efa4fdda2bae5c76ad83e6" +dependencies = [ + "miden-objects", + "miden-tx", +] + [[package]] name = "miden-utils-diagnostics" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9bf9a2c1cf3e3694d0eb347695a291602a57f817dd001ac838f300799576a69" +checksum = "1a3ff4c019d96539a7066626efb4dce5c9fb7b0e44e961b0c2571e78f34236d5" dependencies = [ "miden-crypto", "miden-debug-types", @@ -2335,11 +2664,20 @@ dependencies = [ "tracing", ] +[[package]] +name = "miden-utils-indexing" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c798250bee4e856d4f18c161e91cdcbef1906f6614d00cf0063b47031c0f8cc6" +dependencies = [ + "thiserror 2.0.17", +] + [[package]] name = "miden-utils-sync" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb026e69ae937b2a83bf69ea86577e0ec2450cb22cce163190b9fd42f2972b63" +checksum = "feebe7d896c013ea74dbc98de978836606356a044d4ed3b61ded54d3b319d89f" dependencies = [ "lock_api", "loom", @@ -2348,9 +2686,9 @@ dependencies = [ [[package]] name = "miden-verifier" -version = "0.17.2" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a305e5e2c68d10bcb8e2ed3dc38e54bc3a538acc9eadc154b713d5bb47af22" +checksum = "b8f8e47b78bba1fe1b31faee8f12aafd95385f6d6a8b108b03e92f5d743bb29f" dependencies = [ "miden-air", "miden-core", @@ -2361,9 +2699,9 @@ dependencies = [ [[package]] name = "midenc-hir-type" -version = "0.1.5" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e381ba23e4f57ffa0d6039113f6d6004e5b8c7ae6cb909329b48f2ab525e8680" +checksum = "9d4cfab04baffdda3fb9eafa5f873604059b89a1699aa95e4f1057397a69f0b5" dependencies = [ "miden-formatting", "smallvec", @@ -2407,7 +2745,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "36c791ecdf977c99f45f23280405d7723727470f6689a5e6dbf513ac547ae10d" dependencies = [ "serde", - "toml 0.9.8", + "toml", ] [[package]] @@ -2453,6 +2791,15 @@ 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" @@ -2596,6 +2943,12 @@ 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" @@ -2703,7 +3056,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" dependencies = [ "fixedbitset", - "indexmap 2.12.0", + "indexmap 2.12.1", ] [[package]] @@ -2766,12 +3119,33 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "portable-atomic" version = "1.11.1" @@ -2887,6 +3261,21 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proptest" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" +dependencies = [ + "bitflags", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax", + "unarray", +] + [[package]] name = "prost" version = "0.13.5" @@ -2909,9 +3298,9 @@ dependencies = [ [[package]] name = "prost-build" -version = "0.13.5" +version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf" +checksum = "ac6c3320f9abac597dcbc668774ef006702672474aad53c6d596b62e487b40b1" dependencies = [ "heck", "itertools", @@ -2920,8 +3309,10 @@ dependencies = [ "once_cell", "petgraph", "prettyplease", - "prost 0.13.5", - "prost-types 0.13.5", + "prost 0.14.1", + "prost-types 0.14.1", + "pulldown-cmark", + "pulldown-cmark-to-cmark", "regex", "syn", "tempfile", @@ -2968,14 +3359,14 @@ dependencies = [ [[package]] name = "prost-reflect" -version = "0.15.3" +version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37587d5a8a1b3dc9863403d084fc2254b91ab75a702207098837950767e2260b" +checksum = "89a3ac73ec9a9118131a4594c9d336631a07852220a1d0ae03ee36b04503a063" dependencies = [ "logos 0.15.1", "miette", - "prost 0.13.5", - "prost-types 0.13.5", + "prost 0.14.1", + "prost-types 0.14.1", ] [[package]] @@ -3013,16 +3404,16 @@ dependencies = [ [[package]] name = "protox" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "424c2bd294b69c49b949f3619362bc3c5d28298cd1163b6d1a62df37c16461aa" +checksum = "8555716f64c546306ddf3383065dc40d4232609e79e0a4c50e94e87d54f30fb4" dependencies = [ "bytes", "miette", - "prost 0.13.5", - "prost-reflect 0.15.3", - "prost-types 0.13.5", - "protox-parse 0.8.0", + "prost 0.14.1", + "prost-reflect 0.16.2", + "prost-types 0.14.1", + "protox-parse 0.9.0", "thiserror 2.0.17", ] @@ -3040,16 +3431,36 @@ dependencies = [ [[package]] name = "protox-parse" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57927f9dbeeffcce7192404deee6157a640cbb3fe8ac11eabbe571565949ab75" +checksum = "072eee358134396a4643dff81cfff1c255c9fbd3fb296be14bdb6a26f9156366" dependencies = [ "logos 0.15.1", "miette", - "prost-types 0.13.5", + "prost-types 0.14.1", "thiserror 2.0.17", ] +[[package]] +name = "pulldown-cmark" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" +dependencies = [ + "bitflags", + "memchr", + "unicase", +] + +[[package]] +name = "pulldown-cmark-to-cmark" +version = "21.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8246feae3db61428fd0bb94285c690b460e4517d83152377543ca802357785f1" +dependencies = [ + "pulldown-cmark", +] + [[package]] name = "quote" version = "1.0.42" @@ -3072,7 +3483,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha", - "rand_core", + "rand_core 0.9.3", ] [[package]] @@ -3082,7 +3493,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", ] [[package]] @@ -3094,13 +3514,31 @@ dependencies = [ "getrandom 0.3.4", ] +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.3", +] + [[package]] name = "rand_xoshiro" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" dependencies = [ - "rand_core", + "rand_core 0.9.3", ] [[package]] @@ -3181,6 +3619,16 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "ring" version = "0.17.14" @@ -3420,6 +3868,20 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "security-framework" version = "3.5.1" @@ -3533,15 +3995,6 @@ dependencies = [ "syn", ] -[[package]] -name = "serde_spanned" -version = "0.6.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" -dependencies = [ - "serde", -] - [[package]] name = "serde_spanned" version = "1.0.3" @@ -3565,15 +4018,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.15.1" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa66c845eee442168b2c8134fec70ac50dc20e760769c8ba0ad1319ca1959b04" +checksum = "10574371d41b0d9b2cff89418eda27da52bcaff2cc8741db26382a77c29131f1" dependencies = [ "base64 0.22.1", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.12.0", + "indexmap 2.12.1", "schemars 0.9.0", "schemars 1.1.0", "serde_core", @@ -3584,9 +4037,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.15.1" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91a903660542fced4e99881aa481bdbaec1634568ee02e0b8bd57c64cb38955" +checksum = "08a72d8216842fdd57820dc78d840bef99248e35fb2554ff923319e60f2d686b" dependencies = [ "darling", "proc-macro2", @@ -3632,13 +4085,23 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.6" +version = "1.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +checksum = "7664a098b8e616bdfcc2dc0e9ac44eb231eedf41db4e9fe95d8d32ec728dedad" dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + [[package]] name = "siphasher" version = "1.0.1" @@ -3663,16 +4126,6 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" -[[package]] -name = "socket2" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "socket2" version = "0.6.1" @@ -3688,6 +4141,9 @@ name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] [[package]] name = "spki" @@ -3816,9 +4272,9 @@ checksum = "b7401a30af6cb5818bb64852270bb722533397edcfc7344954a38f420819ece2" [[package]] name = "syn" -version = "2.0.110" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -4085,7 +4541,7 @@ dependencies = [ "mio", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.1", + "socket2", "tokio-macros", "windows-sys 0.61.2", ] @@ -4121,7 +4577,7 @@ dependencies = [ "postgres-protocol", "postgres-types", "rand", - "socket2 0.6.1", + "socket2", "tokio", "tokio-util", "whoami", @@ -4161,6 +4617,7 @@ dependencies = [ "futures-core", "pin-project-lite", "tokio", + "tokio-util", ] [[package]] @@ -4176,42 +4633,21 @@ dependencies = [ "tokio", ] -[[package]] -name = "toml" -version = "0.8.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" -dependencies = [ - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_edit", -] - [[package]] name = "toml" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" dependencies = [ - "indexmap 2.12.0", + "indexmap 2.12.1", "serde_core", - "serde_spanned 1.0.3", - "toml_datetime 0.7.3", + "serde_spanned", + "toml_datetime", "toml_parser", "toml_writer", "winnow", ] -[[package]] -name = "toml_datetime" -version = "0.6.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" -dependencies = [ - "serde", -] - [[package]] name = "toml_datetime" version = "0.7.3" @@ -4221,20 +4657,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "toml_edit" -version = "0.22.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" -dependencies = [ - "indexmap 2.12.0", - "serde", - "serde_spanned 0.6.9", - "toml_datetime 0.6.11", - "toml_write", - "winnow", -] - [[package]] name = "toml_parser" version = "1.0.4" @@ -4244,48 +4666,12 @@ dependencies = [ "winnow", ] -[[package]] -name = "toml_write" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" - [[package]] name = "toml_writer" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" -[[package]] -name = "tonic" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e581ba15a835f4d9ea06c55ab1bd4dce26fc53752c69a04aac00703bfb49ba9" -dependencies = [ - "async-trait", - "base64 0.22.1", - "bytes", - "h2", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-timeout", - "hyper-util", - "percent-encoding", - "pin-project", - "prost 0.13.5", - "rustls-native-certs", - "socket2 0.5.10", - "tokio", - "tokio-rustls", - "tokio-stream", - "tower", - "tower-layer", - "tower-service", - "tracing", -] - [[package]] name = "tonic" version = "0.14.2" @@ -4305,9 +4691,11 @@ dependencies = [ "hyper-util", "percent-encoding", "pin-project", - "socket2 0.6.1", + "rustls-native-certs", + "socket2", "sync_wrapper", "tokio", + "tokio-rustls", "tokio-stream", "tower", "tower-layer", @@ -4317,18 +4705,29 @@ dependencies = [ [[package]] name = "tonic-build" -version = "0.13.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac6f67be712d12f0b41328db3137e0d0757645d8904b4cb7d51cd9c2279e847" +checksum = "4c40aaccc9f9eccf2cd82ebc111adc13030d23e887244bc9cfa5d1d636049de3" dependencies = [ "prettyplease", "proc-macro2", - "prost-build", - "prost-types 0.13.5", "quote", "syn", ] +[[package]] +name = "tonic-health" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a82868bf299e0a1d2e8dce0dc33a46c02d6f045b2c1f1d6cc8dc3d0bf1812ef" +dependencies = [ + "prost 0.14.1", + "tokio", + "tokio-stream", + "tonic", + "tonic-prost", +] + [[package]] name = "tonic-prost" version = "0.14.2" @@ -4337,14 +4736,30 @@ checksum = "66bd50ad6ce1252d87ef024b3d64fe4c3cf54a86fb9ef4c631fdd0ded7aeaa67" dependencies = [ "bytes", "prost 0.14.1", - "tonic 0.14.2", + "tonic", +] + +[[package]] +name = "tonic-prost-build" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4a16cba4043dc3ff43fcb3f96b4c5c154c64cbd18ca8dce2ab2c6a451d058a2" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "prost-types 0.14.1", + "quote", + "syn", + "tempfile", + "tonic-build", ] [[package]] name = "tonic-web-wasm-client" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66e3bb7acca55e6790354be650f4042d418fcf8e2bc42ac382348f2b6bf057e5" +checksum = "898cd44be5e23e59d2956056538f1d6b3c5336629d384ffd2d92e76f87fb98ff" dependencies = [ "base64 0.22.1", "byteorder", @@ -4357,7 +4772,7 @@ dependencies = [ "js-sys", "pin-project", "thiserror 2.0.17", - "tonic 0.13.1", + "tonic", "tower-service", "wasm-bindgen", "wasm-bindgen-futures", @@ -4373,7 +4788,7 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "indexmap 2.12.0", + "indexmap 2.12.1", "pin-project-lite", "slab", "sync_wrapper", @@ -4493,7 +4908,7 @@ dependencies = [ "serde_json", "target-triple", "termcolor", - "toml 0.9.8", + "toml", ] [[package]] @@ -4518,6 +4933,18 @@ dependencies = [ "web-time", ] +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" + [[package]] name = "unicode-bidi" version = "0.3.18" @@ -4569,6 +4996,16 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + [[package]] name = "untrusted" version = "0.9.0" @@ -4593,9 +5030,9 @@ dependencies = [ [[package]] name = "ureq-proto" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b4531c118335662134346048ddb0e54cc86bd7e81866757873055f0e38f5d2" +checksum = "d81f9efa9df032be5934a46a068815a10a042b494b6a58cb0a1a97bb5467ed6f" dependencies = [ "base64 0.22.1", "http", @@ -5367,6 +5804,16 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +[[package]] +name = "x25519-dalek" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +dependencies = [ + "curve25519-dalek", + "rand_core 0.6.4", +] + [[package]] name = "x509-cert" version = "0.2.5" @@ -5414,18 +5861,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.27" +version = "0.8.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +checksum = "43fa6694ed34d6e57407afbccdeecfa268c470a7d2a5b0cf49ce9fcc345afb90" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.27" +version = "0.8.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +checksum = "c640b22cd9817fae95be82f0d2f90b11f7605f6c319d16705c459b27ac2cbc26" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index b37aa20..09d310b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,31 +13,29 @@ members = [ "crates/coordinator/domain", "crates/coordinator/engine", "crates/coordinator/store", - "crates/coordinator/utils", "crates/miden-multisig-client", "crates/test-utils", ] resolver = "3" [workspace.dependencies] -miden-client = "0.11.9" miden-multisig-client = { path = "crates/miden-multisig-client" } miden-multisig-coordinator-domain = { path = "crates/coordinator/domain" } miden-multisig-coordinator-engine = { path = "crates/coordinator/engine" } miden-multisig-coordinator-store = { path = "crates/coordinator/store" } -miden-multisig-coordinator-utils = { path = "crates/coordinator/utils" } miden-multisig-test-utils = { path = "crates/test-utils" } -miden-objects = "0.11" -anyhow = "1" -bon = { default-features = false, version = "3" } -chrono = { default-features = false, version = "0.4" } -dissolve-derive = "0.1.2" -rand = "0.9" -serde = { default-features = false, version = "1" } -serde_with = { default-features = false, version = "3" } -thiserror = { default-features = false, version = "2" } -tokio = { default-features = false, version = "1.40" } -tracing = "0.1" -url = "2.5" -uuid = { default-features = false, version = "1" } +anyhow = "1" +bon = { default-features = false, version = "3" } +chrono = { default-features = false, version = "0.4" } +dissolve-derive = "0.1.4" +miden-client = { default-features = false, version = "0.12" } +miden-client-sqlite-store = "0.12" +rand = "0.9" +serde = { default-features = false, version = "1" } +serde_with = { default-features = false, version = "3" } +thiserror = { default-features = false, version = "2" } +tokio = { default-features = false, version = "1.40" } +tracing = "0.1" +url = "2.5" +uuid = { default-features = false, version = "1" } diff --git a/bin/coordinator-server/Cargo.toml b/bin/coordinator-server/Cargo.toml index f2d4dfb..4e4bf81 100644 --- a/bin/coordinator-server/Cargo.toml +++ b/bin/coordinator-server/Cargo.toml @@ -27,8 +27,6 @@ miden-client = { workspace = true } miden-multisig-coordinator-domain = { features = ["serde"], workspace = true } miden-multisig-coordinator-engine = { workspace = true } miden-multisig-coordinator-store = { workspace = true } -miden-multisig-coordinator-utils = { workspace = true } -miden-objects = { workspace = true } openssl-sys = { features = ["vendored"], optional = true, version = "0.9" } pq-sys = { features = ["bundled"], optional = true, version = "0.7" } serde = { features = ["derive"], workspace = true } diff --git a/bin/coordinator-server/src/error.rs b/bin/coordinator-server/src/error.rs index 39e7fbb..8d3c7bc 100644 --- a/bin/coordinator-server/src/error.rs +++ b/bin/coordinator-server/src/error.rs @@ -4,8 +4,8 @@ use axum::{ http::StatusCode, response::{IntoResponse, Response}, }; +use miden_client::AccountIdError; use miden_multisig_coordinator_engine::{MultisigEngineError, request::RequestError}; -use miden_multisig_coordinator_utils::AccountIdAddressError; use tokio::task::JoinError; #[derive(Debug, thiserror::Error)] @@ -16,8 +16,8 @@ pub(crate) enum AppError { #[error("invalid network id error")] InvalidNetworkId, - #[error("invalid account id address: {0}")] - InvalidAccountIdAddress(Cow<'static, str>), + #[error("account id error: {0}")] + AccountId(#[from] AccountIdError), #[error("invalid pub key commit error")] InvalidPubKeyCommit, @@ -61,17 +61,11 @@ impl From for AppError { } } -impl From for AppError { - fn from(err: AccountIdAddressError) -> Self { - Self::InvalidAccountIdAddress(err.to_string().into()) - } -} - impl IntoResponse for AppError { fn into_response(self) -> Response { let code = match self { AppError::InvalidNetworkId - | AppError::InvalidAccountIdAddress(_) + | AppError::AccountId(_) | AppError::InvalidPubKeyCommit | AppError::InvalidTransactionRequest | AppError::InvalidSignature diff --git a/bin/coordinator-server/src/payload.rs b/bin/coordinator-server/src/payload.rs index 4d907ad..b9311cd 100644 --- a/bin/coordinator-server/src/payload.rs +++ b/bin/coordinator-server/src/payload.rs @@ -7,7 +7,6 @@ use bon::Builder; use chrono::{DateTime, Utc}; use miden_client::{ Word, - account::Address, note::{NoteFile, NoteId}, utils::Serializable, }; @@ -80,7 +79,7 @@ pub struct NoteIdPayload { impl From for MultisigAccountPayload { fn from(account: MultisigAccount) -> Self { Self::builder() - .address(Address::AccountId(account.address()).to_bech32(account.network_id())) + .address(account.account_id().to_bech32(account.network_id().clone())) .kind(account.kind().to_string()) .threshold(account.threshold()) .created_at(account.aux().created_at()) @@ -91,11 +90,15 @@ impl From for MultisigAccountPayload { impl From for MultisigApproverPayload { fn from(approver: MultisigApprover) -> Self { - let MultisigApproverDissolved { address, network_id, pub_key_commit, aux } = - approver.dissolve(); + let MultisigApproverDissolved { + account_id, + network_id, + pub_key_commit, + aux, + } = approver.dissolve(); Self::builder() - .address(Address::AccountId(address).to_bech32(network_id)) + .address(account_id.to_bech32(network_id)) .pub_key_commit(Word::from(pub_key_commit).to_bytes()) .created_at(aux.created_at()) .updated_at(aux.updated_at()) @@ -107,7 +110,7 @@ impl From for MultisigTxPayload { fn from(tx: MultisigTx) -> Self { let MultisigTxDissolved { id, - address, + multisig_account_id, network_id, status, tx_request, @@ -119,7 +122,7 @@ impl From for MultisigTxPayload { Self::builder() .id(id.into()) - .multisig_account_address(Address::AccountId(address).to_bech32(network_id)) + .multisig_account_address(multisig_account_id.to_bech32(network_id)) .status(status) .tx_request(tx_request.to_bytes()) .tx_summary(tx_summary.to_bytes()) diff --git a/bin/coordinator-server/src/routes.rs b/bin/coordinator-server/src/routes.rs index ae5d1c5..36a0759 100644 --- a/bin/coordinator-server/src/routes.rs +++ b/bin/coordinator-server/src/routes.rs @@ -2,7 +2,7 @@ use axum::{Json, extract::State, http::StatusCode}; use itertools::Itertools; use miden_client::{ Word, - account::Address, + account::AccountId, utils::{Deserializable, Serializable}, }; use miden_multisig_coordinator_engine::{ @@ -18,7 +18,6 @@ use miden_multisig_coordinator_engine::{ ListMultisigTxResponseDissolved, ProposeMultisigTxResponseDissolved, }, }; -use miden_objects::crypto::dsa::rpo_falcon512::PublicKey; use tokio::task; use crate::{ @@ -60,18 +59,18 @@ pub async fn create_multisig_account( let CreateMultisigAccountRequestPayloadDissolved { threshold, approvers, pub_key_commits } = payload.dissolve(); - let engine_network_id = engine.network_id(); + let engine_network_id = engine.network_id().clone(); let CreateMultisigAccountResponseDissolved { multisig_account, .. } = task::spawn_blocking(move || { let approvers = approvers .iter() .map(AsRef::as_ref) - .map(miden_multisig_coordinator_utils::extract_network_id_account_id_address_pair) + .map(AccountId::from_bech32) .map(|res| res.map_err(From::from)) - .map_ok(|(network_id, account_id_address)| { + .map_ok(|(network_id, account_id)| { engine_network_id .eq(&network_id) - .then_some(account_id_address) + .then_some(account_id) .ok_or(AppError::InvalidNetworkId) }) .map(Result::flatten) @@ -81,7 +80,7 @@ pub async fn create_multisig_account( .iter() .map(AsRef::as_ref) .map(Word::read_from_bytes) - .map_ok(PublicKey::new) + .map_ok(From::from) .try_collect() .map_err(|_| AppError::InvalidPubKeyCommit)?; @@ -99,9 +98,7 @@ pub async fn create_multisig_account( .map(CreateMultisigAccountResponse::dissolve)?; let response = CreateMultisigAccountResponsePayload::builder() - .address( - Address::AccountId(multisig_account.address()).to_bech32(multisig_account.network_id()), - ) + .address(multisig_account.account_id().to_bech32(multisig_account.network_id().clone())) .created_at(multisig_account.aux().created_at()) .updated_at(multisig_account.aux().updated_at()) .build(); @@ -122,18 +119,17 @@ pub async fn propose_multisig_tx( } = payload.dissolve(); let request = { - let account_id_address = - miden_multisig_coordinator_utils::extract_network_id_account_id_address_pair(&address) - .map(|(network_id, address)| { - engine.network_id().eq(&network_id).then_some(address) - })? - .ok_or(AppError::InvalidNetworkId)?; + let account_id_address = AccountId::from_bech32(&address) + .map(|(network_id, account_id)| { + engine.network_id().eq(&network_id).then_some(account_id) + })? + .ok_or(AppError::InvalidNetworkId)?; let tx_request = Deserializable::read_from_bytes(&tx_request) .map_err(|_| AppError::InvalidTransactionRequest)?; ProposeMultisigTxRequest::builder() - .address(account_id_address) + .multisig_account_id(account_id_address) .tx_request(tx_request) .build() }; @@ -159,12 +155,11 @@ pub async fn add_signature( let AddSignatureRequestPayloadDissolved { tx_id, approver, signature } = payload.dissolve(); let request = { - let approver = - miden_multisig_coordinator_utils::extract_network_id_account_id_address_pair(&approver) - .map(|(network_id, address)| { - engine.network_id().eq(&network_id).then_some(address) - })? - .ok_or(AppError::InvalidNetworkId)?; + let approver = AccountId::from_bech32(&approver) + .map(|(network_id, account_id)| { + engine.network_id().eq(&network_id).then_some(account_id) + })? + .ok_or(AppError::InvalidNetworkId)?; let signature = Deserializable::read_from_bytes(&signature).map_err(|_| AppError::InvalidSignature)?; @@ -192,20 +187,20 @@ pub async fn list_consumable_notes( let ListConsumableNotesRequestPayloadDissolved { address } = payload.dissolve(); - let account_id_address = address + let account_id = address .as_deref() - .map(miden_multisig_coordinator_utils::extract_network_id_account_id_address_pair) + .map(AccountId::from_bech32) .transpose()? - .map(|(network_id, address)| { + .map(|(network_id, account_id)| { engine .network_id() .eq(&network_id) - .then_some(address) + .then_some(account_id) .ok_or(AppError::InvalidNetworkId) }) .transpose()?; - let request = GetConsumableNotesRequest::builder().maybe_address(account_id_address).build(); + let request = GetConsumableNotesRequest::builder().maybe_account_id(account_id).build(); let note_ids = engine .get_consumable_notes(request) @@ -229,15 +224,12 @@ pub async fn get_multisig_account_details( let GetMultisigAccountDetailsRequestPayloadDissolved { multisig_account_address } = payload.dissolve(); - let multisig_account_id_address = - miden_multisig_coordinator_utils::extract_network_id_account_id_address_pair( - &multisig_account_address, - ) - .map(|(network_id, address)| engine.network_id().eq(&network_id).then_some(address))? + let multisig_account_id = AccountId::from_bech32(&multisig_account_address) + .map(|(network_id, account_id)| engine.network_id().eq(&network_id).then_some(account_id))? .ok_or(AppError::InvalidNetworkId)?; let request = GetMultisigAccountRequest::builder() - .multisig_account_id_address(multisig_account_id_address) + .multisig_account_id(multisig_account_id) .build(); let GetMultisigAccountResponseDissolved { multisig_account } = @@ -262,15 +254,12 @@ pub async fn list_multisig_approvers( let ListMultisigApproverRequestPayloadDissolved { multisig_account_address } = payload.dissolve(); - let multisig_account_id_address = - miden_multisig_coordinator_utils::extract_network_id_account_id_address_pair( - &multisig_account_address, - ) - .map(|(network_id, address)| engine.network_id().eq(&network_id).then_some(address))? + let multisig_account_id = AccountId::from_bech32(&multisig_account_address) + .map(|(network_id, account_id)| engine.network_id().eq(&network_id).then_some(account_id))? .ok_or(AppError::InvalidNetworkId)?; let request = ListMultisigApproverRequest::builder() - .multisig_account_id_address(multisig_account_id_address) + .multisig_account_id(multisig_account_id) .build(); let ListMultisigApproverResponseDissolved { approvers } = @@ -291,15 +280,12 @@ pub async fn get_multisig_tx_stats( let GetMultisigTxStatsRequestPayloadDissolved { multisig_account_address } = payload.dissolve(); - let multisig_account_id_address = - miden_multisig_coordinator_utils::extract_network_id_account_id_address_pair( - &multisig_account_address, - ) - .map(|(network_id, address)| engine.network_id().eq(&network_id).then_some(address))? + let multisig_account_id = AccountId::from_bech32(&multisig_account_address) + .map(|(network_id, account_id)| engine.network_id().eq(&network_id).then_some(account_id))? .ok_or(AppError::InvalidNetworkId)?; let request = GetMultisigTxStatsRequest::builder() - .multisig_account_id_address(multisig_account_id_address) + .multisig_account_id(multisig_account_id) .build(); let GetMultisigTxStatsResponseDissolved { tx_stats } = @@ -322,11 +308,8 @@ pub async fn list_multisig_tx( tx_status_filter, } = payload.dissolve(); - let multisig_account_id_address = - miden_multisig_coordinator_utils::extract_network_id_account_id_address_pair( - &multisig_account_address, - ) - .map(|(network_id, address)| engine.network_id().eq(&network_id).then_some(address))? + let multisig_account_id = AccountId::from_bech32(&multisig_account_address) + .map(|(network_id, account_id)| engine.network_id().eq(&network_id).then_some(account_id))? .ok_or(AppError::InvalidNetworkId)?; let tx_status_filter = tx_status_filter @@ -336,7 +319,7 @@ pub async fn list_multisig_tx( .map_err(|_| AppError::InvalidMultisigTxStatus)?; let request = ListMultisigTxRequest::builder() - .multisig_account_id_address(multisig_account_id_address) + .multisig_account_id(multisig_account_id) .maybe_tx_status_filter(tx_status_filter) .build(); diff --git a/crates/coordinator/domain/Cargo.toml b/crates/coordinator/domain/Cargo.toml index a217285..79bc73f 100644 --- a/crates/coordinator/domain/Cargo.toml +++ b/crates/coordinator/domain/Cargo.toml @@ -16,7 +16,6 @@ bon = { workspace = true } chrono = { workspace = true } dissolve-derive = { workspace = true } miden-client = { workspace = true } -miden-objects = { workspace = true } serde = { default-features = false, features = ["derive"], optional = true, workspace = true } serde_with = { default-features = false, features = ["macros"], optional = true, workspace = true } strum = { features = ["derive"], version = "0.27" } diff --git a/crates/coordinator/domain/src/account.rs b/crates/coordinator/domain/src/account.rs index a572066..b90a271 100644 --- a/crates/coordinator/domain/src/account.rs +++ b/crates/coordinator/domain/src/account.rs @@ -6,8 +6,10 @@ use alloc::vec::Vec; use bon::Builder; use dissolve_derive::Dissolve; -use miden_client::account::{AccountIdAddress, AccountStorageMode, NetworkId}; -use miden_objects::crypto::dsa::rpo_falcon512::PublicKey; +use miden_client::{ + account::{AccountId, AccountStorageMode, NetworkId}, + auth::PublicKeyCommitment, +}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -19,7 +21,7 @@ use crate::with_serde; /// An approver authorized to sign multisig transactions. /// -/// Each approver is identified by their account address and has an associated +/// Each approver is identified by their account id and has an associated /// public key commitment used for signature verification. /// /// # Type Parameters @@ -28,9 +30,9 @@ use crate::with_serde; #[derive(Debug, Clone, Builder, Dissolve)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct MultisigApprover { - /// The account address of the approver. - #[cfg_attr(feature = "serde", serde(with = "with_serde::account_id_address"))] - address: AccountIdAddress, + /// The account id of the approver. + #[cfg_attr(feature = "serde", serde(with = "with_serde::account_id"))] + account_id: AccountId, /// The network this account belongs to. #[cfg_attr(feature = "serde", serde(with = "with_serde::network_id"))] @@ -38,7 +40,7 @@ pub struct MultisigApprover { /// The public key commitment used for signature verification. #[cfg_attr(feature = "serde", serde(with = "with_serde::pub_key_commit"))] - pub_key_commit: PublicKey, + pub_key_commit: PublicKeyCommitment, /// Auxiliary metadata associated with this approver. aux: AUX, @@ -61,7 +63,7 @@ pub struct MultisigApprover { /// ```ignore /// // Create a new multisig account /// let account = MultisigAccount::builder() -/// .address(address) +/// .account_id(account_id) /// .network_id(network_id) /// .kind(AccountStorageMode::Public) /// .threshold(2) @@ -77,9 +79,9 @@ pub struct MultisigApprover { #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct MultisigAccount { - /// The account's unique address identifier. - #[cfg_attr(feature = "serde", serde(with = "with_serde::account_id_address"))] - address: AccountIdAddress, + /// The account's unique identifier. + #[cfg_attr(feature = "serde", serde(with = "with_serde::account_id"))] + account_id: AccountId, /// The network this account belongs to. #[cfg_attr(feature = "serde", serde(with = "with_serde::network_id"))] @@ -104,13 +106,13 @@ pub struct MultisigAccount, + Vec, ); /// Type-state marker indicating that approvers have not been set. @@ -127,7 +129,8 @@ pub struct WithoutApprovers; #[derive(Debug, Clone)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] pub struct WithPubKeyCommits( - #[cfg_attr(feature = "serde", serde(with = "with_serde::vec_pub_key_commits"))] Vec, + #[cfg_attr(feature = "serde", serde(with = "with_serde::vec_pub_key_commits"))] + Vec, ); /// Type-state marker indicating that public key commitments have not been set. @@ -146,14 +149,14 @@ impl MultisigAccount { /// to populate the account with approvers and their public key commiements. #[builder] pub fn new( - address: AccountIdAddress, + account_id: AccountId, network_id: NetworkId, kind: AccountStorageMode, threshold: NonZeroU32, aux: AUX, ) -> Self { Self { - address, + account_id, network_id, kind, threshold, @@ -175,7 +178,7 @@ impl MultisigAccount { /// A tuple of (new account with `AUX2`, old `AUX1` value) pub fn with_aux(self, aux: AUX2) -> (MultisigAccount, AUX1) { let multisig_account = MultisigAccount { - address: self.address, + account_id: self.account_id, network_id: self.network_id, kind: self.kind, threshold: self.threshold, @@ -200,15 +203,15 @@ impl MultisigAccount { /// * `None` if there are fewer approvers than the threshold pub fn with_approvers( self, - approver_addresses: Vec, + approver_account_ids: Vec, ) -> Option> { // TODO: ascertain whether casting u32 to usize will always be safe - (approver_addresses.len() >= self.threshold.get() as usize).then(|| MultisigAccount { - address: self.address, + (approver_account_ids.len() >= self.threshold.get() as usize).then(|| MultisigAccount { + account_id: self.account_id, network_id: self.network_id, kind: self.kind, threshold: self.threshold, - approvers: WithApprovers(approver_addresses), + approvers: WithApprovers(approver_account_ids), pub_key_commits: WithoutPubKeyCommits, aux: self.aux, }) @@ -225,11 +228,11 @@ impl MultisigAccount { /// * `None` if there are fewer public keys than the threshold pub fn with_pub_key_commits( self, - pub_key_commits: Vec, + pub_key_commits: Vec, ) -> Option> { // TODO: ascertain whether casting u32 to usize will always be safe (pub_key_commits.len() >= self.threshold.get() as usize).then(|| MultisigAccount { - address: self.address, + account_id: self.account_id, network_id: self.network_id, kind: self.kind, threshold: self.threshold, @@ -250,10 +253,10 @@ impl MultisigAccount { /// * `None` if the counts don't match pub fn with_pub_key_commits( self, - pub_key_commits: Vec, + pub_key_commits: Vec, ) -> Option> { (self.approvers.get().len() == pub_key_commits.len()).then(|| MultisigAccount { - address: self.address, + account_id: self.account_id, network_id: self.network_id, kind: self.kind, threshold: self.threshold, @@ -274,14 +277,14 @@ impl MultisigAccount { /// * `None` if the counts don't match pub fn with_approvers( self, - approver_addresses: Vec, + approver_account_ids: Vec, ) -> Option> { - (self.pub_key_commits.get().len() == approver_addresses.len()).then(|| MultisigAccount { - address: self.address, + (self.pub_key_commits.get().len() == approver_account_ids.len()).then(|| MultisigAccount { + account_id: self.account_id, network_id: self.network_id, kind: self.kind, threshold: self.threshold, - approvers: WithApprovers(approver_addresses), + approvers: WithApprovers(approver_account_ids), pub_key_commits: self.pub_key_commits, aux: self.aux, }) @@ -289,14 +292,14 @@ impl MultisigAccount { } impl MultisigAccount { - /// Returns the account's address. - pub fn address(&self) -> AccountIdAddress { - self.address + /// Returns the account id. + pub fn account_id(&self) -> AccountId { + self.account_id } /// Returns the network ID this account belongs to. - pub fn network_id(&self) -> NetworkId { - self.network_id + pub fn network_id(&self) -> &NetworkId { + &self.network_id } /// Returns the account kind. @@ -316,15 +319,15 @@ impl MultisigAccount { } impl MultisigAccount { - /// Returns the list of approver addresses. - pub fn approvers(&self) -> &[AccountIdAddress] { + /// Returns the list of approver account ids. + pub fn approvers(&self) -> &[AccountId] { self.approvers.get() } } impl MultisigAccount { /// Returns the list of public key commitments. - pub fn pub_key_commits(&self) -> &[PublicKey] { + pub fn pub_key_commits(&self) -> &[PublicKeyCommitment] { self.pub_key_commits.get() } } @@ -344,17 +347,13 @@ impl MultisigAccount { /// /// Returns a tuple of: /// 1. A bare account (no approvers, no pub keys, `()` as auxiliary data) - /// 2. The list of approver addresses + /// 2. The list of approver account ids /// 3. The original auxiliary data pub fn dissolve( self, - ) -> ( - MultisigAccount, - Vec, - AUX, - ) { + ) -> (MultisigAccount, Vec, AUX) { let multisig_account = MultisigAccount { - address: self.address, + account_id: self.account_id, network_id: self.network_id, kind: self.kind, threshold: self.threshold, @@ -376,9 +375,13 @@ impl MultisigAccount { /// 3. The original auxiliary data pub fn dissolve( self, - ) -> (MultisigAccount, Vec, AUX) { + ) -> ( + MultisigAccount, + Vec, + AUX, + ) { let multisig_account = MultisigAccount { - address: self.address, + account_id: self.account_id, network_id: self.network_id, kind: self.kind, threshold: self.threshold, @@ -396,19 +399,19 @@ impl MultisigAccount { /// /// Returns a tuple of: /// 1. A bare account - (no approvers, no public key commitments, `()` as auxiliary data) - /// 2. The list of approver addresses + /// 2. The list of approver account ids /// 3. The list of public key commitments /// 4. The original auxiliary data pub fn dissolve( self, ) -> ( MultisigAccount, - Vec, - Vec, + Vec, + Vec, AUX, ) { let multisig_account = MultisigAccount { - address: self.address, + account_id: self.account_id, network_id: self.network_id, kind: self.kind, threshold: self.threshold, @@ -427,21 +430,21 @@ impl MultisigAccount { } impl WithApprovers { - fn get(&self) -> &[AccountIdAddress] { + fn get(&self) -> &[AccountId] { &self.0 } - fn into_inner(self) -> Vec { + fn into_inner(self) -> Vec { self.0 } } impl WithPubKeyCommits { - fn get(&self) -> &[PublicKey] { + fn get(&self) -> &[PublicKeyCommitment] { &self.0 } - fn into_inner(self) -> Vec { + fn into_inner(self) -> Vec { self.0 } } @@ -449,7 +452,8 @@ impl WithPubKeyCommits { impl From> for MultisigAccount { - /// Converts a fully configured account to a bare account, discarding approvers and public key commitments. + /// Converts a fully configured account to a bare account, + /// discarding approvers and public key commitments. fn from(multisig_account: MultisigAccount) -> Self { let (multisig_account, _, _, aux) = multisig_account.dissolve(); multisig_account.with_aux(aux).0 @@ -469,7 +473,8 @@ impl From> impl From> for MultisigAccount { - /// Converts an account with public key commitments to a bare account, discarding public key commitments + /// Converts an account with public key commitments to a bare account, + /// discarding public key commitments. fn from(multisig_account: MultisigAccount) -> Self { let (multisig_account, _, aux) = multisig_account.dissolve(); multisig_account.with_aux(aux).0 @@ -479,10 +484,11 @@ impl From> impl From> for MultisigAccount { - /// Converts a fully configured account to one without public key commitments, keeping approvers. + /// Converts a fully configured account to one without public key commitments, + /// keeping approvers. fn from( MultisigAccount { - address, + account_id, network_id, kind, threshold, @@ -492,7 +498,7 @@ impl From> }: MultisigAccount, ) -> Self { Self { - address, + account_id, network_id, kind, threshold, @@ -509,7 +515,7 @@ impl From> /// Converts a fully configured account to one without approvers, keeping public key commitments. fn from( MultisigAccount { - address, + account_id, network_id, kind, threshold, @@ -519,7 +525,7 @@ impl From> }: MultisigAccount, ) -> Self { Self { - address, + account_id, network_id, kind, threshold, diff --git a/crates/coordinator/domain/src/tx.rs b/crates/coordinator/domain/src/tx.rs index 6acb83d..6aaa706 100644 --- a/crates/coordinator/domain/src/tx.rs +++ b/crates/coordinator/domain/src/tx.rs @@ -6,10 +6,9 @@ use bon::Builder; use dissolve_derive::Dissolve; use miden_client::{ Word, - account::{AccountIdAddress, NetworkId}, - transaction::TransactionRequest, + account::{AccountId, NetworkId}, + transaction::{TransactionRequest, TransactionSummary}, }; -use miden_objects::transaction::TransactionSummary; use strum::{Display, EnumString, IntoStaticStr}; use uuid::Uuid; @@ -60,9 +59,9 @@ pub struct MultisigTx { /// The unique identifier for this transaction. id: MultisigTxId, - /// The multisig account address to which this transaction applies. - #[cfg_attr(feature = "serde", serde(with = "with_serde::account_id_address"))] - address: AccountIdAddress, + /// The multisig account id to which this transaction applies. + #[cfg_attr(feature = "serde", serde(with = "with_serde::account_id"))] + multisig_account_id: AccountId, /// The network this transaction is associated with. #[cfg_attr(feature = "serde", serde(with = "with_serde::network_id"))] diff --git a/crates/coordinator/domain/src/with_serde.rs b/crates/coordinator/domain/src/with_serde.rs index 788cfd7..604cecb 100644 --- a/crates/coordinator/domain/src/with_serde.rs +++ b/crates/coordinator/domain/src/with_serde.rs @@ -1,30 +1,25 @@ -use miden_client::account::AccountIdAddress; +use miden_client::account::AccountId; -fn serialize_account_id_address( - account_id_address: &AccountIdAddress, -) -> [u8; AccountIdAddress::SERIALIZED_SIZE] { - (*account_id_address).into() +fn serialize_account_id_address(account_id: &AccountId) -> [u8; AccountId::SERIALIZED_SIZE] { + (*account_id).into() } -pub mod account_id_address { - use miden_client::account::AccountIdAddress; +pub mod account_id { + use miden_client::account::AccountId; use serde::{Deserialize, Deserializer, Serializer, de::Error}; - pub fn serialize( - account_id_address: &AccountIdAddress, - serializer: S, - ) -> Result + pub fn serialize(account_id: &AccountId, serializer: S) -> Result where S: Serializer, { - serializer.serialize_bytes(&super::serialize_account_id_address(account_id_address)) + serializer.serialize_bytes(&super::serialize_account_id_address(account_id)) } - pub fn deserialize<'de, D>(deserializer: D) -> Result + pub fn deserialize<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { - <[u8; AccountIdAddress::SERIALIZED_SIZE]>::deserialize(deserializer) + <[u8; AccountId::SERIALIZED_SIZE]>::deserialize(deserializer) .map(TryFrom::try_from)? .map_err(D::Error::custom) } @@ -86,24 +81,26 @@ pub mod network_id { } pub mod pub_key_commit { - use miden_client::Word; - use miden_objects::crypto::dsa::rpo_falcon512::PublicKey; + use miden_client::{Word, auth::PublicKeyCommitment}; use serde::{Deserialize, Deserializer, Serializer, de::Error}; - pub fn serialize(&pub_key_commit: &PublicKey, serializer: S) -> Result + pub fn serialize( + &pub_key_commit: &PublicKeyCommitment, + serializer: S, + ) -> Result where S: Serializer, { serializer.serialize_bytes(&Word::from(pub_key_commit).as_bytes()) } - pub fn deserialize<'de, D>(deserializer: D) -> Result + pub fn deserialize<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { <[u8; Word::SERIALIZED_SIZE]>::deserialize(deserializer) .map(Word::try_from)? - .map(PublicKey::new) + .map(From::from) .map_err(D::Error::custom) } } @@ -133,8 +130,10 @@ pub mod transaction_request { } pub mod transaction_summary { - use miden_client::utils::{Deserializable, Serializable}; - use miden_objects::transaction::TransactionSummary; + use miden_client::{ + transaction::TransactionSummary, + utils::{Deserializable, Serializable}, + }; use serde::{Deserialize, Deserializer, Serializer, de::Error}; pub fn serialize(tx_summary: &TransactionSummary, serializer: S) -> Result @@ -160,37 +159,34 @@ pub mod vec_account_id_address { vec::Vec, }; - use miden_client::account::AccountIdAddress; + use miden_client::account::AccountId; use serde::{ Deserializer, Serializer, de::{self, SeqAccess, Visitor}, ser::SerializeSeq, }; - pub fn serialize( - account_id_addresses: &Vec, - serializer: S, - ) -> Result + pub fn serialize(account_id: &Vec, serializer: S) -> Result where S: Serializer, { - let mut seq = serializer.serialize_seq(account_id_addresses.len().into())?; + let mut seq = serializer.serialize_seq(account_id.len().into())?; - for account_id_address in account_id_addresses { + for account_id_address in account_id { seq.serialize_element(&super::serialize_account_id_address(account_id_address))?; } seq.end() } - pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> + pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { - struct AccountIdAddressVecVisitor; + struct AccountIdVecVisitor; - impl<'de> Visitor<'de> for AccountIdAddressVecVisitor { - type Value = Vec; + impl<'de> Visitor<'de> for AccountIdVecVisitor { + type Value = Vec; fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { formatter.write_str("a sequence of account ids") @@ -200,19 +196,17 @@ pub mod vec_account_id_address { where A: SeqAccess<'de>, { - let mut account_id_addresses = Vec::with_capacity(seq.size_hint().unwrap_or(0)); + let mut account_id = Vec::with_capacity(seq.size_hint().unwrap_or(0)); - while let Some(bz) = - seq.next_element::<[u8; AccountIdAddress::SERIALIZED_SIZE]>()? - { - account_id_addresses.push(bz.try_into().map_err(de::Error::custom)?); + while let Some(bz) = seq.next_element::<[u8; AccountId::SERIALIZED_SIZE]>()? { + account_id.push(bz.try_into().map_err(de::Error::custom)?); } - Ok(account_id_addresses) + Ok(account_id) } } - deserializer.deserialize_seq(AccountIdAddressVecVisitor) + deserializer.deserialize_seq(AccountIdVecVisitor) } } @@ -222,15 +216,17 @@ pub mod vec_pub_key_commits { vec::Vec, }; - use miden_client::Word; - use miden_objects::crypto::dsa::rpo_falcon512::PublicKey; + use miden_client::{Word, auth::PublicKeyCommitment}; use serde::{ Deserializer, Serializer, de::{self, SeqAccess, Visitor}, ser::SerializeSeq, }; - pub fn serialize(pub_key_commits: &Vec, serializer: S) -> Result + pub fn serialize( + pub_key_commits: &Vec, + serializer: S, + ) -> Result where S: Serializer, { @@ -243,14 +239,14 @@ pub mod vec_pub_key_commits { seq.end() } - pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> + pub fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> where D: Deserializer<'de>, { struct PubKeyCommitVecVisitor; impl<'de> Visitor<'de> for PubKeyCommitVecVisitor { - type Value = Vec; + type Value = Vec; fn expecting(&self, formatter: &mut Formatter) -> fmt::Result { formatter.write_str("a sequence of public key commitments") @@ -264,7 +260,7 @@ pub mod vec_pub_key_commits { while let Some(bz) = seq.next_element::<[u8; Word::SERIALIZED_SIZE]>()? { let pub_key_commit = - Word::try_from(bz).map(PublicKey::new).map_err(de::Error::custom)?; + Word::try_from(bz).map(From::from).map_err(de::Error::custom)?; pub_key_commits.push(pub_key_commit); } diff --git a/crates/coordinator/engine/Cargo.toml b/crates/coordinator/engine/Cargo.toml index 0c25117..711f5b2 100644 --- a/crates/coordinator/engine/Cargo.toml +++ b/crates/coordinator/engine/Cargo.toml @@ -10,24 +10,24 @@ workspace = true [dependencies] bon = { workspace = true } dissolve-derive = { workspace = true } -miden-client = { features = ["sqlite", "tonic"], workspace = true } +miden-client = { features = ["tonic"], workspace = true } +miden-client-sqlite-store = { workspace = true } miden-multisig-client = { workspace = true } miden-multisig-coordinator-domain = { workspace = true } miden-multisig-coordinator-store = { workspace = true } -miden-multisig-coordinator-utils = { workspace = true } -miden-objects = { workspace = true } thiserror = { workspace = true } tokio = { default-features = false, features = ["sync"], workspace = true } tracing = { workspace = true } url = { workspace = true } [dev-dependencies] -diesel = { features = ["postgres"], version = "2" } -diesel_migrations = "2" -miden-testing = "0.11" -openssl-sys = { features = ["vendored"], version = "0.9" } -pq-sys = { features = ["bundled"], version = "0.7" } -rand = "0.9" -tempfile = "3" -testcontainers = "0.25" -testcontainers-modules = { features = ["postgres"], version = "0.13" } +diesel = { features = ["postgres"], version = "2" } +diesel_migrations = "2" +miden-client = { features = ["tonic"], version = "0.12" } +miden-client-sqlite-store = "0.12" +openssl-sys = { features = ["vendored"], version = "0.9" } +pq-sys = { features = ["bundled"], version = "0.7" } +rand = "0.9" +tempfile = "3" +testcontainers = "0.25" +testcontainers-modules = { features = ["postgres"], version = "0.13" } diff --git a/crates/coordinator/engine/README.md b/crates/coordinator/engine/README.md index 2d7d7f5..12918f6 100644 --- a/crates/coordinator/engine/README.md +++ b/crates/coordinator/engine/README.md @@ -65,7 +65,7 @@ let (miden_account, multisig_account) = response.dissolve(); use miden_multisig_coordinator_engine::request::ProposeMultisigTxRequest; let request = ProposeMultisigTxRequest::builder() - .address(multisig_account_address) + .multisig_account_id(multisig_account_id) .tx_request(tx_request) .build(); @@ -80,7 +80,7 @@ use miden_multisig_coordinator_engine::request::AddSignatureRequest; let request = AddSignatureRequest::builder() .tx_id(tx_id) - .approver(approver_address) + .approver(approver_account_id) .signature(signature) .build(); @@ -98,7 +98,7 @@ if let Some(tx_result) = maybe_result { use miden_multisig_coordinator_engine::request::GetMultisigAccountRequest; let request = GetMultisigAccountRequest::builder() - .multisig_account_id_address(account_address) + .multisig_account_id(account_id) .build(); let response = engine.get_multisig_account(request).await?; @@ -115,7 +115,7 @@ if let Some(account) = maybe_account { use miden_multisig_coordinator_engine::request::ListMultisigApproverRequest; let request = ListMultisigApproverRequest::builder() - .multisig_account_id_address(multisig_account_address) + .multisig_account_id(multisig_account_id) .build(); let response = engine.list_multisig_approvers(request).await?; @@ -129,7 +129,7 @@ use miden_multisig_coordinator_engine::request::ListMultisigTxRequest; use miden_multisig_coordinator_domain::tx::MultisigTxStatus; let request = ListMultisigTxRequest::builder() - .multisig_account_id_address(account_address) + .multisig_account_id(account_id) .tx_status_filter(Some(MultisigTxStatus::Pending)) .build(); @@ -143,7 +143,7 @@ let txs = response.dissolve(); use miden_multisig_coordinator_engine::request::GetConsumableNotesRequest; let request = GetConsumableNotesRequest::builder() - .address(Some(account_address)) + .account_id(Some(account_id)) .build(); let notes = engine.get_consumable_notes(request).await?; diff --git a/crates/coordinator/engine/src/error.rs b/crates/coordinator/engine/src/error.rs index 0d23497..7dacf1e 100644 --- a/crates/coordinator/engine/src/error.rs +++ b/crates/coordinator/engine/src/error.rs @@ -1,12 +1,10 @@ use std::borrow::Cow; +use miden_multisig_client::MultisigClientError; use miden_multisig_coordinator_store::MultisigStoreError; use tokio::sync::oneshot; -use crate::multisig_client_runtime::{ - MultisigClientRuntimeError, - msg::{ProcessMultisigTxError, ProposeMultisigTxError}, -}; +use crate::multisig_client_runtime::MultisigClientRuntimeError; /// The main error type for multisig engine operations. #[derive(Debug, thiserror::Error)] @@ -18,6 +16,9 @@ pub(crate) enum MultisigEngineErrorKind { #[error("multisig client runtime error: {0}")] MultisigClientRuntime(#[from] MultisigClientRuntimeError), + #[error("multisig client error: {0}")] + MultisigClient(#[from] MultisigClientError), + #[error("multisig store error: {0}")] MultisigStore(#[from] MultisigStoreError), @@ -30,12 +31,6 @@ pub(crate) enum MultisigEngineErrorKind { #[error("not found error: {0}")] NotFound(Cow<'static, str>), - #[error("propose multisig tx error: {0}")] - ProposeMultisigTx(#[from] ProposeMultisigTxError), - - #[error("process multisig tx error: {0}")] - ProcessMultisigTx(#[from] ProcessMultisigTxError), - #[error("other error: {0}")] Other(Cow<'static, str>), } diff --git a/crates/coordinator/engine/src/lib.rs b/crates/coordinator/engine/src/lib.rs index 9e088e2..70526b4 100644 --- a/crates/coordinator/engine/src/lib.rs +++ b/crates/coordinator/engine/src/lib.rs @@ -126,14 +126,6 @@ mod error; mod multisig_client_runtime; mod types; -use crate::types::{ - request::{ - GetMultisigTxStatsRequest, GetMultisigTxStatsRequestDissolved, ListMultisigApproverRequest, - ListMultisigApproverRequestDissolved, - }, - response::{GetMultisigTxStatsResponse, ListMultisigApproverResponse}, -}; - pub use self::{ error::MultisigEngineError, multisig_client_runtime::MultisigClientRuntimeConfig, @@ -143,7 +135,7 @@ pub use self::{ use std::thread::JoinHandle; use miden_client::{ - account::{AccountIdAddress, AccountStorageMode, AddressInterface, NetworkId}, + account::{AccountStorageMode, NetworkId}, note::NoteConsumability, store::InputNoteRecord, transaction::TransactionResult, @@ -176,13 +168,15 @@ use self::{ AddSignatureRequest, AddSignatureRequestDissolved, CreateMultisigAccountRequest, CreateMultisigAccountRequestDissolved, GetConsumableNotesRequest, GetConsumableNotesRequestDissolved, GetMultisigAccountRequest, - GetMultisigAccountRequestDissolved, ListMultisigTxRequest, + GetMultisigAccountRequestDissolved, GetMultisigTxStatsRequest, + GetMultisigTxStatsRequestDissolved, ListMultisigApproverRequest, + ListMultisigApproverRequestDissolved, ListMultisigTxRequest, ListMultisigTxRequestDissolved, ProposeMultisigTxRequest, ProposeMultisigTxRequestDissolved, }, response::{ - CreateMultisigAccountResponse, GetMultisigAccountResponse, ListMultisigTxResponse, - ProposeMultisigTxResponse, + CreateMultisigAccountResponse, GetMultisigAccountResponse, GetMultisigTxStatsResponse, + ListMultisigApproverResponse, ListMultisigTxResponse, ProposeMultisigTxResponse, }, }, }; @@ -220,9 +214,9 @@ pub struct Started { } impl MultisigEngine { - /// Returns the network ID this engine is configured for. - pub fn network_id(&self) -> NetworkId { - self.network_id + /// Returns the network ID the engine is configured for. + pub fn network_id(&self) -> &NetworkId { + &self.network_id } } @@ -250,7 +244,7 @@ impl MultisigEngine { .map_err(MultisigEngineErrorKind::from)?; let addresses: Vec<_> = task::spawn_blocking(move || { - multisig_accounts.iter().map(MultisigAccount::address).collect() + multisig_accounts.iter().map(MultisigAccount::account_id).collect() }) .await .map_err(|e| MultisigEngineErrorKind::other(e.to_string()))?; @@ -263,7 +257,7 @@ impl MultisigEngine { ); let engine = MultisigEngine { - network_id: self.network_id(), + network_id: self.network_id, store: self.store, runtime: Started { sender, handle }, }; @@ -310,11 +304,14 @@ impl MultisigEngine { MultisigEngineErrorKind::mpsc_sender("failed to send create multisig account") })?; - let miden_account = receiver.await.map_err(MultisigEngineErrorKind::from)?; + let miden_account = receiver + .await + .map_err(MultisigEngineErrorKind::from)? + .map_err(MultisigEngineErrorKind::from)?; let multisig_account = MultisigAccount::builder() - .address(AccountIdAddress::new(miden_account.id(), AddressInterface::BasicWallet)) - .network_id(self.network_id()) + .account_id(miden_account.id()) + .network_id(self.network_id().clone()) .kind(AccountStorageMode::Public) // TODO: add support for private multisig accounts .threshold(threshold) .aux(()) @@ -342,13 +339,13 @@ impl MultisigEngine { &self, request: GetConsumableNotesRequest, ) -> Result)>, MultisigEngineError> { - let GetConsumableNotesRequestDissolved { address } = request.dissolve(); + let GetConsumableNotesRequestDissolved { account_id } = request.dissolve(); let (msg, receiver) = { let (sender, receiver) = oneshot::channel(); let msg = GetConsumableNotes::builder() - .maybe_account_id(address.as_ref().map(AccountIdAddress::id)) + .maybe_account_id(account_id) .sender(sender) .build(); @@ -394,13 +391,14 @@ impl MultisigEngine { &self, request: ProposeMultisigTxRequest, ) -> Result { - let ProposeMultisigTxRequestDissolved { address, tx_request } = request.dissolve(); + let ProposeMultisigTxRequestDissolved { multisig_account_id, tx_request } = + request.dissolve(); let (msg, receiver) = { let (sender, receiver) = oneshot::channel(); let msg = ProposeMultisigTx::builder() - .account_id(address.id()) + .multisig_account_id(multisig_account_id) .tx_request(tx_request.clone()) .sender(sender) .build(); @@ -413,7 +411,7 @@ impl MultisigEngine { })?; self.store - .get_multisig_account(self.network_id(), address) + .get_multisig_account(self.network_id().clone(), multisig_account_id) .await .map_err(MultisigEngineErrorKind::from)? .ok_or(MultisigEngineErrorKind::not_found("account not found"))?; @@ -425,7 +423,12 @@ impl MultisigEngine { let tx_id = self .store - .create_multisig_tx(self.network_id(), address, &tx_request, &tx_summary) + .create_multisig_tx( + self.network_id().clone(), + multisig_account_id, + &tx_request, + &tx_summary, + ) .await .map_err(MultisigEngineErrorKind::from)?; @@ -460,7 +463,7 @@ impl MultisigEngine { let threshold_met = self .store - .add_multisig_tx_signature(&tx_id, self.network_id(), approver, &signature) + .add_multisig_tx_signature(&tx_id, self.network_id().clone(), approver, &signature) .await .map_err(MultisigEngineErrorKind::from)? .ok_or(MultisigEngineErrorKind::other( @@ -478,11 +481,15 @@ impl MultisigEngine { let (msg, receiver) = { let (sender, receiver) = oneshot::channel(); - let MultisigTxDissolved { address, tx_request, tx_summary, .. } = - multisig_tx.dissolve(); + let MultisigTxDissolved { + multisig_account_id, + tx_request, + tx_summary, + .. + } = multisig_tx.dissolve(); let msg = ProcessMultisigTx::builder() - .account_id(address.id()) + .multisig_account_id(multisig_account_id) .tx_request(tx_request) .tx_summary(tx_summary) .signatures(signatures) @@ -520,7 +527,7 @@ impl MultisigEngine { Ok(None) } - /// Retrieves a multisig account by its address. + /// Retrieves a multisig account by its id. /// /// Queries the persistent store for multisig account metadata, including threshold, /// approvers, and public key commitments. @@ -529,11 +536,11 @@ impl MultisigEngine { &self, request: GetMultisigAccountRequest, ) -> Result { - let GetMultisigAccountRequestDissolved { multisig_account_id_address } = request.dissolve(); + let GetMultisigAccountRequestDissolved { multisig_account_id } = request.dissolve(); let multisig_account = self .store - .get_multisig_account(self.network_id(), multisig_account_id_address) + .get_multisig_account(self.network_id().clone(), multisig_account_id) .await .map_err(MultisigEngineErrorKind::from)?; @@ -552,13 +559,13 @@ impl MultisigEngine { &self, request: GetMultisigTxStatsRequest, ) -> Result { - let GetMultisigTxStatsRequestDissolved { multisig_account_id_address } = request.dissolve(); + let GetMultisigTxStatsRequestDissolved { multisig_account_id } = request.dissolve(); let tx_stats = self .store .get_multisig_tx_stats_by_multisig_account_address( - self.network_id(), - multisig_account_id_address, + self.network_id().clone(), + multisig_account_id, ) .await .map_err(MultisigEngineErrorKind::from)?; @@ -570,20 +577,19 @@ impl MultisigEngine { /// Lists all approvers for a specific multisig account. /// - /// Retrieves the list of approvers associated with the given multisig account address, - /// including their addresses and public key commitments. + /// Retrieves the list of approvers associated with the given multisig account id, + /// including their account ids and public key commitments. #[tracing::instrument(skip_all)] pub async fn list_multisig_approvers( &self, request: ListMultisigApproverRequest, ) -> Result { - let ListMultisigApproverRequestDissolved { multisig_account_id_address } = - request.dissolve(); + let ListMultisigApproverRequestDissolved { multisig_account_id } = request.dissolve(); self.store .get_approvers_by_multisig_account_address( - self.network_id(), - multisig_account_id_address, + self.network_id().clone(), + multisig_account_id, ) .await .map(|approvers| ListMultisigApproverResponse::builder().approvers(approvers).build()) @@ -593,22 +599,20 @@ impl MultisigEngine { /// Lists multisig transactions for a specific multisig account. /// - /// Returns transactions associated with the given account address, optionally + /// Returns transactions associated with the given account id, optionally /// filtered by status (Pending, Success, Failure). #[tracing::instrument(skip_all)] pub async fn list_multisig_tx( &self, request: ListMultisigTxRequest, // TODO: add pagination support ) -> Result { - let ListMultisigTxRequestDissolved { - multisig_account_id_address, - tx_status_filter, - } = request.dissolve(); + let ListMultisigTxRequestDissolved { multisig_account_id, tx_status_filter } = + request.dissolve(); self.store - .get_txs_by_multisig_account_address_with_status_filter( - self.network_id(), - multisig_account_id_address, + .get_txs_by_multisig_account_with_status_filter( + self.network_id().clone(), + multisig_account_id, tx_status_filter, ) .await diff --git a/crates/coordinator/engine/src/multisig_client_runtime.rs b/crates/coordinator/engine/src/multisig_client_runtime.rs index 62597c2..f515864 100644 --- a/crates/coordinator/engine/src/multisig_client_runtime.rs +++ b/crates/coordinator/engine/src/multisig_client_runtime.rs @@ -53,9 +53,13 @@ use std::{ use bon::Builder; use miden_client::{ - account::AccountIdAddress, auth::TransactionAuthenticator, builder::ClientBuilder, + Word, + account::AccountId, + auth::{Signature, TransactionAuthenticator}, + builder::ClientBuilder, keystore::FilesystemKeyStore, }; +use miden_client_sqlite_store::ClientBuilderSqliteExt; use miden_multisig_client::MultisigClient; use tokio::{runtime::Runtime, sync::mpsc, task::LocalSet}; use url::Url; @@ -97,7 +101,7 @@ pub fn spawn_new( config: MultisigClientRuntimeConfig, ) -> JoinHandle> where - A: Iterator + Send + 'static, + A: Iterator + Send + 'static, { thread::spawn(move || { let local = LocalSet::new(); @@ -138,7 +142,7 @@ async fn run_multisig_client_runtime( }: MultisigClientRuntimeConfig, ) -> Result<()> where - A: Iterator, + A: Iterator, { let keystore = FilesystemKeyStore::new(keystore_path) .map_err(|e| MultisigClientRuntimeError::other(e.to_string()))?; @@ -147,12 +151,8 @@ where MultisigClientRuntimeError::other(format!("failed to parse node url {node_url}: {e}")) })?; - let store_path = store_path - .to_str() - .ok_or(MultisigClientRuntimeError::other("invalid store path"))?; - let mut client = ClientBuilder::new() - .tonic_rpc_client(&endpoint, Some(timeout.as_millis() as u64)) + .grpc_client(&endpoint, Some(timeout.as_millis() as u64)) .authenticator(Arc::new(keystore)) .sqlite_store(store_path) .build() @@ -170,7 +170,7 @@ where .await .inspect_err(|e| tracing::error!("failed to sync state: {e}"))?; - for account_id in tracking_multisig_accounts.map(|address| address.id()) { + for account_id in tracking_multisig_accounts { let _ = client .import_account_by_id(account_id) .await @@ -224,7 +224,7 @@ where let CreateMultisigAccountDissolved { threshold, approvers, sender } = msg.dissolve(); - let account = client.setup_account(approvers, threshold.get()).await; + let account = client.setup_account(approvers, threshold).await; let _ = sender .send(account) @@ -264,12 +264,12 @@ where { client.sync_state().await?; - let ProposeMultisigTxDissolved { account_id, tx_request, sender } = msg.dissolve(); + let ProposeMultisigTxDissolved { multisig_account_id, tx_request, sender } = msg.dissolve(); - let tx_summary = client.propose_multisig_transaction(account_id, tx_request).await; + let tx_summary = client.propose_multisig_transaction(multisig_account_id, tx_request).await; let _ = sender - .send(tx_summary.map_err(From::from)) + .send(tx_summary) .inspect_err(|_| tracing::error!("oneshot sender failed to send tx summary")); Ok(()) @@ -286,30 +286,26 @@ where client.sync_state().await?; let ProcessMultisigTxDissolved { - account_id, + multisig_account_id, tx_request, tx_summary, signatures, sender, } = msg.dissolve(); - let account_record = client.try_get_account(account_id).await?; + let account_record = client.try_get_account(multisig_account_id).await?; let signatures = signatures .into_iter() - .map(|s| s.map(miden_multisig_coordinator_utils::rpo_falcon512_signature_into_felt_vec)) + .map(|s| s.map(|s| Signature::RpoFalcon512(s).to_prepared_signature(Word::empty()))) .collect(); let tx_result = client - .new_multisig_transaction(account_record.into(), tx_request, tx_summary, signatures) + .submit_new_multisig_transaction(account_record.into(), tx_request, tx_summary, signatures) .await; - if let Ok(tx_result) = &tx_result { - client.submit_transaction(tx_result.clone()).await?; - } - let _ = sender - .send(tx_result.map_err(From::from)) + .send(tx_result) .inspect_err(|_| tracing::error!("oneshot sender failed to send tx result")); Ok(()) diff --git a/crates/coordinator/engine/src/multisig_client_runtime/msg.rs b/crates/coordinator/engine/src/multisig_client_runtime/msg.rs index 75deefa..546d77c 100644 --- a/crates/coordinator/engine/src/multisig_client_runtime/msg.rs +++ b/crates/coordinator/engine/src/multisig_client_runtime/msg.rs @@ -4,15 +4,13 @@ use bon::Builder; use dissolve_derive::Dissolve; use miden_client::{ account::{Account, AccountId}, + auth::PublicKeyCommitment, + crypto::rpo_falcon512::Signature, note::NoteConsumability, store::InputNoteRecord, - transaction::{TransactionRequest, TransactionResult}, + transaction::{TransactionRequest, TransactionResult, TransactionSummary}, }; use miden_multisig_client::MultisigClientError; -use miden_objects::{ - crypto::dsa::rpo_falcon512::{PublicKey, Signature}, - transaction::TransactionSummary, -}; use tokio::sync::oneshot; #[allow(clippy::large_enum_variant)] @@ -27,8 +25,8 @@ pub enum MultisigClientRuntimeMsg { #[derive(Debug, Builder, Dissolve)] pub struct CreateMultisigAccount { threshold: NonZeroU32, - approvers: Vec, - sender: oneshot::Sender, + approvers: Vec, + sender: oneshot::Sender>, } #[derive(Debug, Builder, Dissolve)] @@ -39,26 +37,16 @@ pub struct GetConsumableNotes { #[derive(Debug, Builder, Dissolve)] pub struct ProposeMultisigTx { - account_id: AccountId, + multisig_account_id: AccountId, tx_request: TransactionRequest, - sender: oneshot::Sender>, + sender: oneshot::Sender>, } #[derive(Debug, Builder, Dissolve)] pub struct ProcessMultisigTx { - account_id: AccountId, + multisig_account_id: AccountId, tx_request: TransactionRequest, tx_summary: TransactionSummary, signatures: Vec>, - sender: oneshot::Sender>, + sender: oneshot::Sender>, } - -/// Error that occurs when proposing a multisig transaction. -#[derive(Debug, thiserror::Error)] -#[error("propose multisig tx error: {0}")] -pub struct ProposeMultisigTxError(#[from] MultisigClientError); - -/// Error that occurs when processing a multisig transaction. -#[derive(Debug, thiserror::Error)] -#[error("process multisig tx error: {0}")] -pub struct ProcessMultisigTxError(#[from] MultisigClientError); diff --git a/crates/coordinator/engine/src/types/request.rs b/crates/coordinator/engine/src/types/request.rs index 5abefc3..1668457 100644 --- a/crates/coordinator/engine/src/types/request.rs +++ b/crates/coordinator/engine/src/types/request.rs @@ -8,9 +8,11 @@ use core::num::NonZeroU32; use bon::Builder; use dissolve_derive::Dissolve; -use miden_client::{account::AccountIdAddress, transaction::TransactionRequest}; +use miden_client::{ + account::AccountId, auth::PublicKeyCommitment, crypto::rpo_falcon512::Signature, + transaction::TransactionRequest, +}; use miden_multisig_coordinator_domain::tx::{MultisigTxId, MultisigTxStatus}; -use miden_objects::crypto::dsa::rpo_falcon512::{PublicKey, Signature}; /// Request to create a new multisig account. /// @@ -24,25 +26,25 @@ pub struct CreateMultisigAccountRequest { /// Minimum number of signatures required to execute transactions threshold: NonZeroU32, - /// List of account addresses that can approve transactions - approvers: Vec, + /// List of accounts that can approve transactions + approvers: Vec, /// Corresponding public key commitments for each approver - pub_key_commits: Vec, + pub_key_commits: Vec, } /// Request to query consumable notes. #[derive(Debug, Builder, Dissolve)] pub struct GetConsumableNotesRequest { /// Optional account filter. If `None`, returns notes for all accounts. - address: Option, + account_id: Option, } /// Request to propose a new multisig transaction. #[derive(Debug, Builder, Dissolve)] pub struct ProposeMultisigTxRequest { - /// The multisig account address to which the transaction applies - address: AccountIdAddress, + /// The multisig account to which the transaction applies + multisig_account_id: AccountId, /// The transaction request tx_request: TransactionRequest, @@ -54,39 +56,39 @@ pub struct AddSignatureRequest { /// The transaction ID to add a signature to tx_id: MultisigTxId, - /// The accountaddress of the approver adding their signature - approver: AccountIdAddress, + /// The account of the approver adding their signature + approver: AccountId, /// The cryptographic signature signature: Signature, } -/// Request to retrieve a multisig account by address. +/// Request to retrieve a multisig account by id. #[derive(Debug, Builder, Dissolve)] pub struct GetMultisigAccountRequest { - /// The multisig account address to look up - multisig_account_id_address: AccountIdAddress, + /// The multisig account id to look up + multisig_account_id: AccountId, } /// Request to list approvers for a multisig account. #[derive(Debug, Builder, Dissolve)] pub struct ListMultisigApproverRequest { - /// The multisig account address to query - multisig_account_id_address: AccountIdAddress, + /// The multisig account id to query + multisig_account_id: AccountId, } /// Request to retrieve transaction statistics for a multisig account. #[derive(Debug, Builder, Dissolve)] pub struct GetMultisigTxStatsRequest { - /// The multisig account address to query - multisig_account_id_address: AccountIdAddress, + /// The multisig account id to query + multisig_account_id: AccountId, } /// Request to list transactions for a multisig account. #[derive(Debug, Builder, Dissolve)] pub struct ListMultisigTxRequest { - /// The multisig account address to query - multisig_account_id_address: AccountIdAddress, + /// The multisig account id to query + multisig_account_id: AccountId, /// Optional status filter (Pending, Success, Failure) tx_status_filter: Option, @@ -99,15 +101,15 @@ impl CreateMultisigAccountRequest { /// # Parameters /// /// * `threshold` - Number of signatures required (must not exceed the number of approvers) - /// * `approvers` - List of approver account addresses + /// * `approvers` - List of approver account ids /// * `pub_key_commits` - List of public key commitments (must match approver count) /// /// Returns an error if validation fails. #[builder] pub fn new( threshold: NonZeroU32, - approvers: Vec, - pub_key_commits: Vec, + approvers: Vec, + pub_key_commits: Vec, ) -> Result { if approvers.is_empty() { return Err(CreateMultisigAccountRequestError::EmptyApprovers); diff --git a/crates/coordinator/engine/src/types/response.rs b/crates/coordinator/engine/src/types/response.rs index 1f6381c..3ce5a57 100644 --- a/crates/coordinator/engine/src/types/response.rs +++ b/crates/coordinator/engine/src/types/response.rs @@ -1,12 +1,11 @@ //! Response types for multisig engine operations. use dissolve_derive::Dissolve; -use miden_client::account::Account; +use miden_client::{account::Account, transaction::TransactionSummary}; use miden_multisig_coordinator_domain::{ account::{MultisigAccount, MultisigApprover}, tx::{MultisigTx, MultisigTxId, MultisigTxStats}, }; -use miden_objects::transaction::TransactionSummary; /// Response from creating a multisig account. /// diff --git a/crates/coordinator/engine/tests/multisig_engine_test.rs b/crates/coordinator/engine/tests/multisig_engine_test.rs index eaff6d7..1a812d0 100644 --- a/crates/coordinator/engine/tests/multisig_engine_test.rs +++ b/crates/coordinator/engine/tests/multisig_engine_test.rs @@ -7,7 +7,7 @@ use core::{ use std::{ path::Path, - sync::{Arc, LazyLock, Mutex}, + sync::{LazyLock, Mutex}, }; use diesel::{Connection, PgConnection, RunQueryDsl}; @@ -15,19 +15,19 @@ use diesel_migrations::{EmbeddedMigrations, MigrationHarness}; use miden_client::{ Client, DebugMode, Felt, account::{ - Account, AccountBuilder, AccountIdAddress, AccountStorageMode, AccountType, - AddressInterface, NetworkId, + Account, AccountBuilder, AccountStorageMode, AccountType, NetworkId, component::{AuthRpoFalcon512, BasicFungibleFaucet, BasicWallet}, }, asset::{FungibleAsset, TokenSymbol}, auth::AuthSecretKey, builder::ClientBuilder, - crypto::SecretKey, + crypto::rpo_falcon512::SecretKey, keystore::FilesystemKeyStore, note::NoteType, - rpc::{Endpoint, TonicRpcClient}, + rpc::Endpoint, transaction::TransactionRequestBuilder, }; +use miden_client_sqlite_store::ClientBuilderSqliteExt; use miden_multisig_coordinator_engine::{ MultisigClientRuntimeConfig, MultisigEngine, Started, request::{ @@ -81,16 +81,13 @@ async fn single_note_consumption_works_using_multisig_engine_to_get_consumable_n let engine = start_testnet_multisig_engine(&temp_dir.join("multisig")).await; - let approvers = { - let alice_addr = AccountIdAddress::new(alice_account.id(), AddressInterface::BasicWallet); - let bob_addr = AccountIdAddress::new(bob_account.id(), AddressInterface::BasicWallet); - let charlie_addr = - AccountIdAddress::new(charlie_account.id(), AddressInterface::BasicWallet); + let approvers = vec![alice_account.id(), bob_account.id(), charlie_account.id()]; - vec![alice_addr, bob_addr, charlie_addr] - }; - - let pub_key_commits = vec![alice_sk.public_key(), bob_sk.public_key(), charlie_sk.public_key()]; + let pub_key_commits = vec![ + alice_sk.public_key().to_commitment().into(), + bob_sk.public_key().to_commitment().into(), + charlie_sk.public_key().to_commitment().into(), + ]; let create_account_request = CreateMultisigAccountRequest::builder() .threshold(NonZeroU32::new(2).unwrap()) @@ -109,14 +106,12 @@ async fn single_note_consumption_works_using_multisig_engine_to_get_consumable_n .unwrap(); ff_client.sync_state().await.unwrap(); - let tx_result = ff_client.new_transaction(ff_account.id(), mint_request).await.unwrap(); - - ff_client.submit_transaction(tx_result).await.unwrap(); + ff_client.submit_new_transaction(ff_account.id(), mint_request).await.unwrap(); tokio::time::sleep(Duration::from_secs(5)).await; let consume_notes_tx_request = { - let note_ids = engine + let note_ids: Vec<_> = engine .get_consumable_notes(GetConsumableNotesRequest::builder().build()) .await .unwrap() @@ -128,7 +123,7 @@ async fn single_note_consumption_works_using_multisig_engine_to_get_consumable_n }; let propose_request = ProposeMultisigTxRequest::builder() - .address(AccountIdAddress::new(multisig_account.id(), AddressInterface::BasicWallet)) + .multisig_account_id(multisig_account.id()) .tx_request(consume_notes_tx_request) .build(); @@ -140,7 +135,7 @@ async fn single_note_consumption_works_using_multisig_engine_to_get_consumable_n let add_sig_request = AddSignatureRequest::builder() .tx_id(tx_id.clone()) - .approver(AccountIdAddress::new(alice_account.id(), AddressInterface::BasicWallet)) + .approver(alice_account.id()) .signature(alice_sk.sign(tx_summary_commitment)) .build(); @@ -149,7 +144,7 @@ async fn single_note_consumption_works_using_multisig_engine_to_get_consumable_n let add_sig_request = AddSignatureRequest::builder() .tx_id(tx_id) - .approver(AccountIdAddress::new(charlie_account.id(), AddressInterface::BasicWallet)) + .approver(charlie_account.id()) .signature(charlie_sk.sign(tx_summary_commitment)) .build(); @@ -191,18 +186,18 @@ async fn setup_fungible_faucet_client( let symbol = TokenSymbol::new(symbol).unwrap(); let max_supply = Felt::new(max_supply); - let sk = SecretKey::with_rng(client.rng()); + let sk = AuthSecretKey::new_rpo_falcon512(); - let (account, seed) = AccountBuilder::new(init_seed) + let account = AccountBuilder::new(init_seed) .account_type(AccountType::FungibleFaucet) .storage_mode(miden_client::account::AccountStorageMode::Public) - .with_auth_component(AuthRpoFalcon512::new(sk.public_key())) + .with_auth_component(AuthRpoFalcon512::new(sk.public_key().to_commitment())) .with_component(BasicFungibleFaucet::new(symbol, decimals, max_supply).unwrap()) .build() .unwrap(); - client.add_account(&account, Some(seed), false).await.unwrap(); - keystore.add_key(&AuthSecretKey::RpoFalcon512(sk)).unwrap(); + client.add_account(&account, false).await.unwrap(); + keystore.add_key(&sk).unwrap(); (client, account) } @@ -215,18 +210,22 @@ async fn setup_regular_account_client( let mut init_seed = [0u8; 32]; client.rng().fill_bytes(&mut init_seed); - let sk = SecretKey::with_rng(client.rng()); + let sk = AuthSecretKey::new_rpo_falcon512(); - let (account, seed) = AccountBuilder::new(init_seed) + let account = AccountBuilder::new(init_seed) .account_type(AccountType::RegularAccountUpdatableCode) .storage_mode(AccountStorageMode::Public) - .with_auth_component(AuthRpoFalcon512::new(sk.public_key())) + .with_auth_component(AuthRpoFalcon512::new(sk.public_key().to_commitment())) .with_component(BasicWallet) .build() .unwrap(); - client.add_account(&account, Some(seed), false).await.unwrap(); - keystore.add_key(&AuthSecretKey::RpoFalcon512(sk.clone())).unwrap(); + client.add_account(&account, false).await.unwrap(); + keystore.add_key(&sk).unwrap(); + + let AuthSecretKey::RpoFalcon512(sk) = sk else { + panic!("secret key must be rpo falcon 512 scheme"); + }; (client, account, sk) } @@ -238,8 +237,8 @@ async fn setup_testnet_client( FilesystemKeyStore::new(temp_dir.join("keystore")).expect("failed to initialize keystore"); let client = ClientBuilder::new() - .rpc(Arc::new(TonicRpcClient::new(&Endpoint::testnet(), 10_000))) - .sqlite_store(temp_dir.join("store").as_os_str().to_str().unwrap()) + .grpc_client(&Endpoint::testnet(), Some(20_000)) + .sqlite_store(temp_dir.join("store")) .authenticator(keystore.clone().into()) .in_debug_mode(DebugMode::Enabled) .build() diff --git a/crates/coordinator/store/Cargo.toml b/crates/coordinator/store/Cargo.toml index 66a30d5..bbd3809 100644 --- a/crates/coordinator/store/Cargo.toml +++ b/crates/coordinator/store/Cargo.toml @@ -16,8 +16,6 @@ dissolve-derive = { workspace = true } futures = { default-features = false, version = "0.3" } miden-client = { workspace = true } miden-multisig-coordinator-domain = { workspace = true } -miden-multisig-coordinator-utils = { workspace = true } -miden-objects = { workspace = true } oblux = "0.1" rustls = { default-features = false, version = "0.23" } rustls-native-certs = "0.8" diff --git a/crates/coordinator/store/README.md b/crates/coordinator/store/README.md index 3289343..a24220b 100644 --- a/crates/coordinator/store/README.md +++ b/crates/coordinator/store/README.md @@ -40,13 +40,13 @@ let store = MultisigStore::new(pool); use miden_multisig_coordinator_domain::account::MultisigAccount; let account = MultisigAccount::builder() - .address(account_id_address) + .account_id(account_id) .network_id(network_id) .kind(AccountStorageMode::Public) .threshold(2.try_into()?) .aux(()) .build() - .with_approvers(approver_addresses)? + .with_approvers(approver_account_ids)? .with_pub_key_commits(pub_key_commits)?; let created_account = store.create_multisig_account(account).await?; @@ -57,7 +57,7 @@ let created_account = store.create_multisig_account(account).await?; ```rust let tx_id = store.create_multisig_tx( network_id, - account_address, + account_id, &tx_request, &tx_summary, ).await?; @@ -69,7 +69,7 @@ let tx_id = store.create_multisig_tx( let threshold_met = store.add_multisig_tx_signature( &tx_id, network_id, - approver_address, + approver_account_id, &signature, ).await?; ``` @@ -77,7 +77,7 @@ let threshold_met = store.add_multisig_tx_signature( ### get multisig account ```rust -let account = store.get_multisig_account(network_id, account_address).await?; +let account = store.get_multisig_account(network_id, account_id).await?; ``` ### get approvers by multisig account @@ -85,7 +85,7 @@ let account = store.get_multisig_account(network_id, account_address).await?; ```rust let approvers = store.get_approvers_by_multisig_account_address( network_id, - multisig_account_address, + multisig_account_id, ).await?; ``` @@ -95,16 +95,16 @@ let approvers = store.get_approvers_by_multisig_account_address( use miden_multisig_coordinator_domain::tx::MultisigTxStatus; // with status filter -let pending_txs = store.get_txs_by_multisig_account_address_with_status_filter( +let pending_txs = store.get_txs_by_multisig_account_with_status_filter( network_id, - account_address, + account_id, MultisigTxStatus::Pending, ).await?; // without filter (all transactions) -let all_txs = store.get_txs_by_multisig_account_address_with_status_filter( +let all_txs = store.get_txs_by_multisig_account_with_status_filter( network_id, - account_address, + account_id, None, ).await?; ``` diff --git a/crates/coordinator/store/src/error.rs b/crates/coordinator/store/src/error.rs index 4cfb072..1572264 100644 --- a/crates/coordinator/store/src/error.rs +++ b/crates/coordinator/store/src/error.rs @@ -24,7 +24,7 @@ pub enum MultisigStoreError { /// The requested resource was not found in the database. /// /// This is returned when querying for entities that don't exist, - /// such as non-existent transaction IDs or account addresses. + /// such as non-existent transaction IDs or account ids. #[error("not found error: {0}")] NotFound(Cow<'static, str>), diff --git a/crates/coordinator/store/src/lib.rs b/crates/coordinator/store/src/lib.rs index 07a95d9..97d8c91 100644 --- a/crates/coordinator/store/src/lib.rs +++ b/crates/coordinator/store/src/lib.rs @@ -28,10 +28,10 @@ //! let store = MultisigStore::new(pool); //! //! // Store operations -//! let account = store.get_multisig_account(network_id, address).await?; -//! let txs = store.get_txs_by_multisig_account_address_with_status_filter( +//! let account = store.get_multisig_account(network_id, account_id).await?; +//! let txs = store.get_txs_by_multisig_account_with_status_filter( //! network_id, -//! address, +//! account_id, //! Some(MultisigTxStatus::Pending) //! ).await?; //! ``` @@ -50,8 +50,10 @@ use diesel_async::AsyncConnection; use futures::{Stream, StreamExt, TryStreamExt}; use miden_client::{ Word, - account::{AccountIdAddress, Address, NetworkId}, - transaction::TransactionRequest, + account::{AccountId, NetworkId}, + auth::PublicKeyCommitment, + crypto::rpo_falcon512::Signature, + transaction::{TransactionRequest, TransactionSummary}, utils::{Deserializable, Serializable}, }; use miden_multisig_coordinator_domain::{ @@ -59,11 +61,6 @@ use miden_multisig_coordinator_domain::{ account::{MultisigAccount, MultisigApprover, WithApprovers, WithPubKeyCommits}, tx::{MultisigTx, MultisigTxId, MultisigTxStats, MultisigTxStatus}, }; -use miden_multisig_coordinator_utils::extract_network_id_account_id_address_pair; -use miden_objects::{ - crypto::dsa::rpo_falcon512::{PublicKey, Signature}, - transaction::TransactionSummary, -}; use oblux::U63; use self::{ @@ -115,12 +112,12 @@ impl MultisigStore { /// /// Returns an error if: /// - The database transaction fails - /// - An account with the same address already exists + /// - An account with the same account id already exists /// - Any approver data is invalid #[tracing::instrument( skip_all, fields( - address = %multisig_account.address().id().to_hex(), + address = %multisig_account.account_id().to_hex(), network_id = %multisig_account.network_id(), kind = %multisig_account.kind(), threshold = multisig_account.threshold(), @@ -135,8 +132,9 @@ impl MultisigStore { .await? .transaction(|conn| { Box::pin(async move { - let multisig_account_address = Address::AccountId(multisig_account.address()) - .to_bech32(multisig_account.network_id()); + let multisig_account_address = multisig_account + .account_id() + .to_bech32(multisig_account.network_id().clone()); let new_multisig_account = NewMultisigAccountRecord::builder() .address(&multisig_account_address) @@ -148,14 +146,14 @@ impl MultisigStore { .await .map(|t| Timestamps::builder().created_at(t).updated_at(t).build())?; - for (idx, (&approver_account_id_address, &pub_key_commit)) in multisig_account + for (idx, (&approver_account_id, &pub_key_commit)) in multisig_account .approvers() .iter() .zip(multisig_account.pub_key_commits()) .enumerate() { - let approver_address = Address::AccountId(approver_account_id_address) - .to_bech32(multisig_account.network_id()); + let approver_address = + approver_account_id.to_bech32(multisig_account.network_id().clone()); let pub_key_commit_bz = Word::from(pub_key_commit).as_bytes(); @@ -200,16 +198,16 @@ impl MultisigStore { /// - The database operation fails #[tracing::instrument( skip_all, - fields(%network_id, account_id_address = account_id_address.id().to_hex()), + fields(%network_id, account_id = account_id.to_hex()), )] pub async fn create_multisig_tx( &self, network_id: NetworkId, - account_id_address: AccountIdAddress, + account_id: AccountId, tx_request: &TransactionRequest, tx_summary: &TransactionSummary, ) -> Result { - let multisig_account_address = Address::AccountId(account_id_address).to_bech32(network_id); + let multisig_account_address = account_id.to_bech32(network_id); let tx_request_bz = tx_request.to_bytes(); let tx_summary_bz = tx_summary.to_bytes(); @@ -250,22 +248,21 @@ impl MultisigStore { fields( %tx_id, %network_id, - approver_account_id_address = %approver_account_id_address.id().to_hex(), + approver_account_id = %approver_account_id.to_hex(), ), )] pub async fn add_multisig_tx_signature( &self, tx_id: &MultisigTxId, network_id: NetworkId, - approver_account_id_address: AccountIdAddress, + approver_account_id: AccountId, signature: &Signature, ) -> Result> { self.get_conn() .await? .transaction(|conn| { Box::pin(async move { - let approver_address = - Address::AccountId(approver_account_id_address).to_bech32(network_id); + let approver_address = approver_account_id.to_bech32(network_id); if !store::validate_approver_address_by_tx_id( conn, @@ -332,10 +329,11 @@ impl MultisigStore { Ok(()) } - /// Retrieves a multisig account by its address. + /// Retrieves a multisig account by its `account_id`. /// - /// This method fetches the basic account information (address, network, kind, threshold) - /// but does not include the approvers or public key commitments. + /// This method fetches the basic account information + /// (`account_id`, `network`, `kind`, `threshold`) but does not include the approvers or their + /// public key commitments. /// /// # Returns /// @@ -350,17 +348,17 @@ impl MultisigStore { skip_all, fields( %network_id, - account_id_address = %account_id_address.id().to_hex(), + account_id = %account_id.to_hex(), ) )] pub async fn get_multisig_account( &self, network_id: NetworkId, - account_id_address: AccountIdAddress, + account_id: AccountId, ) -> Result> { let conn = &mut self.get_conn().await?; - let address = Address::AccountId(account_id_address).to_bech32(network_id); + let address = account_id.to_bech32(network_id.clone()); let Some(MultisigAccountRecordDissolved { kind, threshold, created_at, .. }) = store::fetch_mutisig_account_by_address(conn, &address) @@ -380,7 +378,7 @@ impl MultisigStore { Timestamps::builder().created_at(created_at).updated_at(created_at).build(); let multisig_account = MultisigAccount::builder() - .address(account_id_address) + .account_id(account_id) .network_id(network_id) .kind(kind.into_inner()) .threshold(threshold) @@ -408,8 +406,8 @@ impl MultisigStore { .await } - /// Retrieves all approvers for a multisig account address for the given network identified - /// by `network_id`. + /// Retrieves all approvers for a multisig account identified by `multisig_account_id` + /// for the given network identified by `network_id`. /// /// # Errors /// @@ -420,12 +418,11 @@ impl MultisigStore { pub async fn get_approvers_by_multisig_account_address( &self, network_id: NetworkId, - multisig_account_id_address: AccountIdAddress, + multisig_account_id: AccountId, ) -> Result> { let conn = &mut self.get_conn().await?; - let multisig_account_address = - Address::AccountId(multisig_account_id_address).to_bech32(network_id); + let multisig_account_address = multisig_account_id.to_bech32(network_id); store::stream_approvers_by_multisig_account_address(conn, &multisig_account_address) .await? @@ -438,7 +435,7 @@ impl MultisigStore { /// Retrieves all transactions for a multisig account, optionally filtered by status. /// - /// Fetches transactions associated with a specific account address, + /// Fetches transactions associated with a specific account id, /// with optional filtering by execution status (pending, success, failure). /// /// # Returns @@ -454,13 +451,13 @@ impl MultisigStore { skip_all, fields( %network_id, - address = %address.id().to_hex(), + account_id = %account_id.to_hex(), ), )] - pub async fn get_txs_by_multisig_account_address_with_status_filter( + pub async fn get_txs_by_multisig_account_with_status_filter( &self, network_id: NetworkId, - address: AccountIdAddress, + account_id: AccountId, tx_status_filter: TSF, // TODO: add support to filter on multiple `tx_status_filter` ) -> Result> where @@ -468,7 +465,7 @@ impl MultisigStore { { let conn = &mut self.get_conn().await?; - let address = Address::AccountId(address).to_bech32(network_id); + let address = account_id.to_bech32(network_id); fn transform_into_multisig_tx( stream: impl Stream>, @@ -523,7 +520,7 @@ impl MultisigStore { /// Retrieves aggregated transaction statistics for a multisig account. /// /// Computes and returns summary statistics (e.g., counts by status) for all - /// transactions associated with the provided multisig account address. + /// transactions associated with the provided multisig account id. /// /// # Returns /// @@ -536,17 +533,17 @@ impl MultisigStore { pub async fn get_multisig_tx_stats_by_multisig_account_address( &self, network_id: NetworkId, - multisig_account_id_address: AccountIdAddress, + multisig_account_id: AccountId, ) -> Result { let conn = &mut self.get_conn().await?; - let address = Address::AccountId(multisig_account_id_address).to_bech32(network_id); + let address = multisig_account_id.to_bech32(network_id); store::fetch_tx_stats_by_multisig_account_address(conn, &address) .await .map_err(From::from) } - /// Retrieves an approver by their account address. + /// Retrieves an approver by their account id. /// /// This method looks up an approver's information including their public key commitment. /// @@ -563,15 +560,15 @@ impl MultisigStore { skip_all, fields( %network_id, - approver_account_id_address = %approver_account_id_address.id().to_hex(), + approver_account_id = %approver_account_id.to_hex(), ) )] pub async fn get_approver_by_approver_address( &self, network_id: NetworkId, - approver_account_id_address: AccountIdAddress, + approver_account_id: AccountId, ) -> Result> { - let address = Address::AccountId(approver_account_id_address).to_bech32(network_id); + let address = approver_account_id.to_bech32(network_id); store::fetch_approver_by_approver_address(&mut self.get_conn().await?, &address) .await? .map(make_multisig_approver) @@ -638,7 +635,7 @@ fn make_multisig_account( let MultisigAccountRecordDissolved { address, kind, threshold, created_at } = multisig_account_record.dissolve(); - let (network_id, account_id_address) = extract_network_id_account_id_address_pair(&address) + let (network_id, account_id) = AccountId::from_bech32(&address) .map_err(|e| MultisigStoreError::Other(e.to_string().into()))?; let threshold = threshold @@ -650,7 +647,7 @@ fn make_multisig_account( let timestamps = Timestamps::builder().created_at(created_at).updated_at(created_at).build(); let multisig_account = MultisigAccount::builder() - .address(account_id_address) + .account_id(account_id) .network_id(network_id) .kind(kind.into_inner()) .threshold(threshold) @@ -671,10 +668,7 @@ fn make_multisig_tx(tx_record: TxRecord, signature_count: U63) -> Result Result Result Result<(NetworkId, AccountIdAddress), AccountIdAddressError> { - if let (network_id, Address::AccountId(address)) = Address::from_bech32(bech32)? { - return Ok((network_id, address)); - } - - Err(AccountIdAddressError::InvalidAccountIdAddress) -} - -/// Error that occurs while invoking [`extract_network_id_account_id_address_pair`]. -#[derive(Debug, thiserror::Error)] -pub enum AccountIdAddressError { - /// Address error - #[error("address error: {0}")] - Address(#[from] AddressError), - - /// When the bech32 string does not correspond to [`AccountIdAddress`] - #[error("invalid account id address error")] - InvalidAccountIdAddress, -} diff --git a/crates/coordinator/utils/src/lib.rs b/crates/coordinator/utils/src/lib.rs deleted file mode 100644 index c0bcc89..0000000 --- a/crates/coordinator/utils/src/lib.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! utils crate for multisig coordinator system. - -mod address; -mod signature; - -pub use self::{ - address::{AccountIdAddressError, extract_network_id_account_id_address_pair}, - signature::rpo_falcon512_signature_into_felt_vec, -}; diff --git a/crates/coordinator/utils/src/signature.rs b/crates/coordinator/utils/src/signature.rs deleted file mode 100644 index 8ef3c27..0000000 --- a/crates/coordinator/utils/src/signature.rs +++ /dev/null @@ -1,80 +0,0 @@ -use miden_crypto::{ - Felt, - dsa::rpo_falcon512::{Polynomial, Signature}, -}; -use miden_objects::Hasher; - -/// Turn RPO Falcon512 [`Signature`] into a `Vec` what would have been obtained using -/// [`TransactionAuthenticator::get_signature`](https://docs.rs/miden-client/0.11.11/miden_client/auth/trait.TransactionAuthenticator.html#tymethod.get_signature). -/// -/// Slightly modified implementation of [`miden_tx::auth::signatures::get_falcon_signature`](https://docs.rs/miden-tx/0.11.5/miden_tx/auth/signatures/fn.get_falcon_signature.html). -// TODO: deprecate this after miden-client v0.12 is available. -pub fn rpo_falcon512_signature_into_felt_vec(sig: Signature) -> Vec { - // The signature is composed of a nonce and a polynomial s2 - // The nonce is represented as 8 field elements. - let nonce = sig.nonce(); - - let s2 = sig.sig_poly(); - - // We also need in the VM the expanded key corresponding to the public key that was provided - // via the operand stack - let h = &sig.pk_poly().0; - - // Lastly, for the probabilistic product routine that is part of the verification procedure, - // we need to compute the product of the expanded key and the signature polynomial in - // the ring of polynomials with coefficients in the Miden field. - let pi = Polynomial::mul_modulo_p(h, s2); - - // We now push the expanded key, the signature polynomial, and the product of the - // expanded key and the signature polynomial to the advice stack. We also push - // the challenge point at which the previous polynomials will be evaluated. - // Finally, we push the nonce needed for the hash-to-point algorithm. - - let mut polynomials: Vec = - h.coefficients.iter().map(|a| Felt::from(a.value() as u32)).collect(); - polynomials.extend(s2.coefficients.iter().map(|a| Felt::from(a.value() as u32))); - polynomials.extend(pi.iter().map(|a| Felt::new(*a))); - - let digest_polynomials = Hasher::hash_elements(&polynomials); - let challenge = (digest_polynomials[0], digest_polynomials[1]); - - let mut result: Vec = vec![challenge.0, challenge.1]; - result.extend_from_slice(&polynomials); - result.extend_from_slice(&nonce.to_elements()); - - result.reverse(); - - result -} - -#[cfg(test)] -mod tests { - use miden_crypto::{ - dsa::rpo_falcon512::{SecretKey, Signature}, - hash::rpo::Rpo256, - }; - use miden_tx::auth::signatures; - use rand::SeedableRng; - use rand_chacha::ChaCha20Rng; - - const RNG_SEED: u64 = 8086; - - #[test] - fn turning_rpo_falcon512_signature_into_felt_vec_works() { - // Arrange - let sk = SecretKey::new(); - let msg = Rpo256::hash(b"miden will get multisig"); - - let sig: Signature = sk.sign_with_rng(msg, &mut ChaCha20Rng::seed_from_u64(RNG_SEED)); - - // Act - let felt_vec = super::rpo_falcon512_signature_into_felt_vec(sig); - - // Assert - let expected_felt_vec = - signatures::get_falcon_signature(&sk, msg, &mut ChaCha20Rng::seed_from_u64(RNG_SEED)) - .expect("valid secret key must be able to sign the message"); - - assert_eq!(felt_vec, expected_felt_vec); - } -} diff --git a/crates/miden-multisig-client/Cargo.toml b/crates/miden-multisig-client/Cargo.toml index f855637..441a77b 100644 --- a/crates/miden-multisig-client/Cargo.toml +++ b/crates/miden-multisig-client/Cargo.toml @@ -10,15 +10,11 @@ version = "0.1.0" workspace = true [dependencies] -miden-client = { features = ["sqlite", "tonic"], workspace = true } -miden-objects = { workspace = true } - -anyhow = { workspace = true } -rand = { workspace = true } -thiserror = { workspace = true } -tokio = { default-features = false, workspace = true } -url = { workspace = true } +miden-client = { features = ["tonic"], workspace = true } +rand = { workspace = true } +thiserror = { workspace = true } +tokio = { default-features = false, workspace = true } [dev-dependencies] -miden-client = { features = ["sqlite", "testing", "tonic"], version = "0.11" } +miden-client = { features = ["testing", "tonic"], version = "0.12" } miden-multisig-test-utils = { workspace = true } diff --git a/crates/miden-multisig-client/src/error.rs b/crates/miden-multisig-client/src/error.rs new file mode 100644 index 0000000..7409b36 --- /dev/null +++ b/crates/miden-multisig-client/src/error.rs @@ -0,0 +1,101 @@ +use alloc::{borrow::Cow, string::ToString}; + +use miden_client::{AccountError, ClientError}; + +/// Represents errors that can occur in the multisig client. +#[derive(Debug, thiserror::Error)] +pub enum MultisigClientError { + /// An error occurred while setting up multisig account. + #[error("setup account error: {0}")] + SetupAccount(Cow<'static, str>), + + /// An error occurred while proposing a new transaction. + #[error("tx proposal error: {0}")] + TxProposal(Cow<'static, str>), + + /// An error occurred while executing a transaction. + #[error("multisig tx execution error: {0}")] + TxExecution(Cow<'static, str>), + + /// An error occurred while executing and submitting a transaction. + #[error("tx submission error: {0}")] + TxSubmission(Cow<'static, str>), +} + +#[derive(Debug, thiserror::Error)] +pub(crate) enum SetupAccountError { + #[error("account error: {0}")] + Account(#[from] AccountError), + + #[error("client error: {0}")] + Client(#[from] ClientError), +} + +#[derive(Debug, thiserror::Error)] +pub(crate) enum TransactionProposalError { + #[error("dry run expected but transaction got executed")] + DryRunExpected, + + #[error("other error: {0}")] + Other(Cow<'static, str>), +} + +#[derive(Debug, thiserror::Error)] +pub(crate) enum TransactionExecutionError { + #[error("storage slot index out of bounds error: {0}")] + StorageSlotIndexOutOfBounds(Cow<'static, str>), + + #[error("missing number of approvers at the storage slot")] + MissingNumApprovers, + + #[error("invalid number of approvers at the storage slot")] + InvalidNumApprovers, + + #[error("unsupported number of approvers at the storage slot")] + UnsupportedNumApprovers, + + #[error("mismatch between number of signatures provided and number of approvers")] + NumSingaturesMismatch, + + #[error("public key retrieval failure from storage slot map")] + PubKeyStorageSlotMap, +} + +#[derive(Debug, thiserror::Error)] +pub(crate) enum TransactionSubmissionError { + #[error("tx execution error: {0}")] + TxExecution(#[from] TransactionExecutionError), + + #[error("tx prover error: {0}")] + TxProver(Cow<'static, str>), + + #[error("proven tx submission error: {0}")] + ProvenTxSubmission(Cow<'static, str>), + + #[error("apply tx error: {0}")] + ApplyTx(Cow<'static, str>), +} + +impl From for MultisigClientError { + fn from(err: SetupAccountError) -> Self { + Self::SetupAccount(err.to_string().into()) + } +} + +impl From for MultisigClientError { + fn from(err: TransactionProposalError) -> Self { + Self::TxProposal(err.to_string().into()) + } +} + +impl From for MultisigClientError { + fn from(err: TransactionExecutionError) -> Self { + Self::TxExecution(err.to_string().into()) + } +} + +impl From for MultisigClientError { + fn from(err: TransactionSubmissionError) -> Self { + Self::TxSubmission(err.to_string().into()) + } +} diff --git a/crates/miden-multisig-client/src/lib.rs b/crates/miden-multisig-client/src/lib.rs index 42ad1a7..c8fd416 100644 --- a/crates/miden-multisig-client/src/lib.rs +++ b/crates/miden-multisig-client/src/lib.rs @@ -1,196 +1,217 @@ //! A client for managing multisig transactions. +#![cfg_attr(not(test), no_std)] + extern crate alloc; +mod error; + #[cfg(test)] mod tests; +pub use self::error::MultisigClientError; + use core::{ + num::NonZeroU32, ops::{Deref, DerefMut}, - time::Duration, -}; - -use alloc::{ - string::{String, ToString}, - sync::Arc, - vec::Vec, }; -use std::path::PathBuf; +use alloc::{string::ToString, vec::Vec}; -use anyhow::Context; use miden_client::{ Client, ClientError, Felt, Word, ZERO, account::{ - Account, AccountBuilder, AccountFile, AccountId, AccountStorageMode, AccountType, - component::{AuthRpoFalcon512Multisig, BasicWallet}, + Account, AccountBuilder, AccountId, AccountStorageMode, AccountType, + component::{AuthRpoFalcon512Multisig, AuthRpoFalcon512MultisigConfig, BasicWallet}, + }, + auth::{PublicKeyCommitment, TransactionAuthenticator}, + crypto::Rpo256, + transaction::{ + TransactionExecutorError, TransactionRequest, TransactionResult, TransactionSummary, }, - auth::TransactionAuthenticator, - builder::ClientBuilder, - keystore::FilesystemKeyStore, - rpc::Endpoint, - transaction::{TransactionExecutorError, TransactionRequest, TransactionResult}, }; -use miden_objects::{ - Hasher, assembly::diagnostics::tracing::info, crypto::dsa::rpo_falcon512::PublicKey, - transaction::TransactionSummary, +use rand::RngCore; + +use self::error::{ + SetupAccountError, TransactionExecutionError, TransactionProposalError, + TransactionSubmissionError, }; -use rand::{RngCore, rngs::StdRng}; -use thiserror::Error; -use url::Url; - -/// Represents errors that can occur in the multisig client. -#[derive(Debug, Error)] -pub enum MultisigClientError { - /// An error occurred while proposing a new transaction. - #[error("multisig transaction proposal error: {0}")] - TxProposalError(String), - - /// An error occurred while executing a transaction. - #[error("multisig transaction execution error: {0}")] - TxExecutionError(String), -} /// A client for interacting with multisig accounts. -pub struct MultisigClient { +pub struct MultisigClient { client: Client, } -impl MultisigClient -where - AUTH: TransactionAuthenticator + Sync + 'static, -{ - /// Construct a `MultisigClient`. +impl MultisigClient { + /// Construct a `MultisigClient` by providing a [Client]. pub fn new(client: Client) -> Self { Self { client } } } -impl MultisigClient> { - /// Loads the multisig client. - /// - /// A client is instantiated with the provided store path, node url and timeout. The account is - /// loaded from the provided account file. If the account is already tracked by the current - /// store, it is loaded. Otherwise, the account is added from the file state. - /// - /// If a remote transaction prover url is provided, it is used to prove transactions. Otherwise, - /// a local transaction prover is used. - pub async fn load( - store_path: PathBuf, - account_files: Vec, - node_url: &Url, - timeout: Duration, - ) -> anyhow::Result { - let keystore = FilesystemKeyStore::::new(PathBuf::from("keystore")) - .context("failed to create keystore")?; - for key in account_files.iter().flat_map(|f| f.auth_secret_keys.iter()) { - keystore.add_key(key)?; - } - let url: &str = node_url.as_str().trim_end_matches('/'); - let endpoint = Endpoint::try_from(url) - .map_err(anyhow::Error::msg) - .with_context(|| format!("failed to parse node url: {node_url}"))?; - - let mut client = ClientBuilder::new() - .tonic_rpc_client(&endpoint, Some(timeout.as_millis() as u64)) - .authenticator(Arc::new(keystore)) - .sqlite_store(store_path.to_str().context("invalid store path")?) - .build() - .await?; - - info!("Fetching faucet state from node"); - - client.ensure_genesis_in_place().await?; - - Ok(Self { client }) - } -} - -impl Deref for MultisigClient { - type Target = Client; - - fn deref(&self) -> &Self::Target { - &self.client - } -} - -impl DerefMut for MultisigClient { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.client - } -} - -impl MultisigClient { - /// Sets up a new multisig account with the specified approvers and threshold. - pub async fn setup_account(&mut self, approvers: Vec, threshold: u32) -> Account { +impl MultisigClient +where + AUTH: TransactionAuthenticator, +{ + /// Sets up a new multisig account with the specified `approvers` and `threshold`. + /// The parameter `threshold` must not exceed the total number of `approvers`. + pub async fn setup_account( + &mut self, + approvers: Vec, + threshold: NonZeroU32, + ) -> Result { let mut init_seed = [0u8; 32]; self.rng().fill_bytes(&mut init_seed); - let multisig_auth_component = AuthRpoFalcon512Multisig::new(threshold, approvers).unwrap(); - let (multisig_account, seed) = AccountBuilder::new(init_seed) + let multisig_auth_component = + AuthRpoFalcon512MultisigConfig::new(approvers, threshold.get()) + .and_then(AuthRpoFalcon512Multisig::new) + .map_err(SetupAccountError::from)?; + + let multisig_account = AccountBuilder::new(init_seed) .with_auth_component(multisig_auth_component) .account_type(AccountType::RegularAccountImmutableCode) .storage_mode(AccountStorageMode::Public) .with_component(BasicWallet) .build() - .unwrap(); + .map_err(SetupAccountError::from)?; - self.add_account(&multisig_account, Some(seed), false).await.unwrap(); + self.add_account(&multisig_account, false) + .await + .map_err(SetupAccountError::from)?; - multisig_account + Ok(multisig_account) } } -impl MultisigClient { - /// Propose a multisig transaction. This is expected to "dry-run" and only return - /// `TransactionSummary`. +impl MultisigClient +where + AUTH: TransactionAuthenticator + Sync + 'static, +{ + const CONFIG_STORAGE_SLOT_INDEX: u8 = 0; + + const PUB_KEYS_STORAGE_SLOT_INDEX: u8 = 1; + + const NUM_APPROVERS_INDEX: usize = 1; + + /// Propose a multisig transaction. + /// This is expected to "dry-run" and only return the [TransactionSummary]. pub async fn propose_multisig_transaction( &mut self, account_id: AccountId, - transaction_request: TransactionRequest, + tx_request: TransactionRequest, ) -> Result { - let tx_result = self.new_transaction(account_id, transaction_request).await; + let tx_result = self.execute_transaction(account_id, tx_request).await; match tx_result { - Ok(_) => Err(MultisigClientError::TxProposalError( - "expecting a dry run, but tx was executed".to_string(), - )), + Ok(_) => Err(TransactionProposalError::DryRunExpected)?, // otherwise match on Unauthorized Err(ClientError::TransactionExecutorError(TransactionExecutorError::Unauthorized( summary, ))) => Ok(*summary), - Err(e) => Err(MultisigClientError::TxProposalError(e.to_string())), + Err(e) => Err(TransactionProposalError::Other(e.to_string().into()))?, } } /// Creates and executes a transaction specified by the request against the specified multisig /// account. It is expected to have at least `threshold` signatures from the approvers. - pub async fn new_multisig_transaction( + pub async fn execute_multisig_transaction( &mut self, account: Account, - mut transaction_request: TransactionRequest, - transaction_summary: TransactionSummary, + mut tx_request: TransactionRequest, + tx_summary: TransactionSummary, signatures: Vec>>, ) -> Result { + let num_approvers: u32 = { + let felt = *account + .storage() + .get_item(Self::CONFIG_STORAGE_SLOT_INDEX) + .map_err(|e| { + TransactionExecutionError::StorageSlotIndexOutOfBounds(e.to_string().into()) + })? + .as_elements() + .get(Self::NUM_APPROVERS_INDEX) + .ok_or(TransactionExecutionError::MissingNumApprovers)?; + + felt.try_into().map_err(|_| TransactionExecutionError::InvalidNumApprovers)? + }; + + if signatures.len() + != usize::try_from(num_approvers) + .map_err(|_| TransactionExecutionError::UnsupportedNumApprovers)? + { + Err(TransactionExecutionError::NumSingaturesMismatch)?; + } + + let msg = tx_summary.to_commitment(); + // Add signatures to the advice provider - let advice_inputs = transaction_request.advice_map_mut(); - let msg = transaction_summary.to_commitment(); - let num_approvers: u32 = - account.storage().get_item(0).unwrap().as_elements()[1].try_into().unwrap(); - - for i in 0..num_approvers as usize { - let pub_key_index_word = Word::from([Felt::from(i as u32), ZERO, ZERO, ZERO]); - let pub_key = account.storage().get_map_item(1, pub_key_index_word).unwrap(); - let sig_key = Hasher::merge(&[pub_key, msg]); - if let Some(signature) = signatures.get(i).and_then(|s| s.as_ref()) { - advice_inputs.extend(vec![(sig_key, signature.clone())]); - } + for (i, sig) in + (0..num_approvers).zip(signatures).filter_map(|(i, sig)| sig.map(|s| (i, s))) + { + let sig_key = { + let pub_key = { + let pub_key_index_word = Word::from([Felt::from(i), ZERO, ZERO, ZERO]); + account + .storage() + .get_map_item(Self::PUB_KEYS_STORAGE_SLOT_INDEX, pub_key_index_word) + .map_err(|_| TransactionExecutionError::PubKeyStorageSlotMap)? + }; + Rpo256::merge(&[pub_key, msg]) + }; + + tx_request.advice_map_mut().insert(sig_key, sig); } // TODO as sanity check we should verify that we have enough signatures - self.new_transaction(account.id(), transaction_request) + self.execute_transaction(account.id(), tx_request) + .await + .map_err(|e| MultisigClientError::TxExecution(e.to_string().into())) + } + + /// Creates and executes a transaction specified by the request against the specified multisig + /// account, submits it to the network, and update the local database. + /// It is expected to have at least `threshold` signatures from the approvers. + pub async fn submit_new_multisig_transaction( + &mut self, + account: Account, + tx_request: TransactionRequest, + tx_summary: TransactionSummary, + signatures: Vec>>, + ) -> Result { + let tx_result = self + .execute_multisig_transaction(account, tx_request, tx_summary, signatures) + .await?; + + let proven_tx = self + .prove_transaction(&tx_result) + .await + .map_err(|e| TransactionSubmissionError::TxProver(e.to_string().into()))?; + + let submission_height = self + .submit_proven_transaction(proven_tx, &tx_result) + .await + .map_err(|e| TransactionSubmissionError::ProvenTxSubmission(e.to_string().into()))?; + + self.apply_transaction(&tx_result, submission_height) .await - .map_err(|e| MultisigClientError::TxExecutionError(e.to_string())) + .map_err(|e| TransactionSubmissionError::ApplyTx(e.to_string().into()))?; + + Ok(tx_result) + } +} + +impl Deref for MultisigClient { + type Target = Client; + + fn deref(&self) -> &Self::Target { + &self.client + } +} + +impl DerefMut for MultisigClient { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.client } } diff --git a/crates/miden-multisig-client/src/tests.rs b/crates/miden-multisig-client/src/tests.rs index 673b40b..12ef87d 100644 --- a/crates/miden-multisig-client/src/tests.rs +++ b/crates/miden-multisig-client/src/tests.rs @@ -4,7 +4,7 @@ use miden_client::{ auth::SigningInputs, note::NoteType, testing::{ - common::{TestClientKeyStore, insert_new_fungible_faucet, insert_new_wallet, mint_note}, + common::{self, TestClientKeyStore}, mock::MockRpcApi, }, transaction::TransactionRequestBuilder, @@ -12,14 +12,9 @@ use miden_client::{ use super::*; -type TestMultisigClient = MultisigClient; +const AUTH_SCHEME_ID: u8 = 0; -async fn setup_multisig_client() -> (TestMultisigClient, MockRpcApi, TestClientKeyStore) { - let (client, mock_rpc_api, keystore) = - miden_multisig_test_utils::create_test_client(std::env::temp_dir()).await; - - (MultisigClient { client }, mock_rpc_api, keystore) -} +type TestMultisigClient = MultisigClient; #[tokio::test] async fn multisig() { @@ -31,31 +26,43 @@ async fn multisig() { let (mut coordinator_client, mock_rpc_api, coordinator_keystore) = setup_multisig_client().await; - let (_, _, secret_key_a) = - insert_new_wallet(&mut signer_a_client, AccountStorageMode::Private, &authenticator_a) - .await - .unwrap(); - let pub_key_a = secret_key_a.public_key(); + let (_, secret_key_a) = common::insert_new_wallet( + &mut signer_a_client, + AccountStorageMode::Private, + &authenticator_a, + AUTH_SCHEME_ID, + ) + .await + .unwrap(); + let pub_key_commit_a = secret_key_a.public_key().to_commitment(); - let (_, _, secret_key_b) = - insert_new_wallet(&mut signer_b_client, AccountStorageMode::Private, &authenticator_b) - .await - .unwrap(); - let pub_key_b = secret_key_b.public_key(); + let (_, secret_key_b) = common::insert_new_wallet( + &mut signer_b_client, + AccountStorageMode::Private, + &authenticator_b, + AUTH_SCHEME_ID, + ) + .await + .unwrap(); + let pub_key_commit_b = secret_key_b.public_key().to_commitment(); - let multisig_account = coordinator_client.setup_account(vec![pub_key_a, pub_key_b], 2).await; + let multisig_account = coordinator_client + .setup_account(vec![pub_key_commit_a, pub_key_commit_b], 2.try_into().unwrap()) + .await + .unwrap(); // we insert the faucet to the coordinator client for convenience - let (faucet_account, ..) = insert_new_fungible_faucet( + let (faucet_account, ..) = common::insert_new_fungible_faucet( coordinator_client.deref_mut(), AccountStorageMode::Public, &coordinator_keystore, + AUTH_SCHEME_ID, ) .await .unwrap(); // mint a note to the multisig account - let (_tx_id, note) = mint_note( + let (_tx_id, note) = common::mint_note( &mut coordinator_client, multisig_account.id(), faucet_account.id(), @@ -88,13 +95,20 @@ async fn multisig() { let signing_inputs = SigningInputs::TransactionSummary(Box::new(tx_summary.clone())); - let signature_a = - authenticator_a.get_signature(pub_key_a.into(), &signing_inputs).await.unwrap(); - let signature_b = - authenticator_b.get_signature(pub_key_b.into(), &signing_inputs).await.unwrap(); + let signature_a = authenticator_a + .get_signature(pub_key_commit_a, &signing_inputs) + .await + .unwrap() + .to_prepared_signature(Word::empty()); + + let signature_b = authenticator_b + .get_signature(pub_key_commit_b, &signing_inputs) + .await + .unwrap() + .to_prepared_signature(Word::empty()); let tx_result = coordinator_client - .new_multisig_transaction( + .execute_multisig_transaction( multisig_account, tx_request, tx_summary, @@ -104,3 +118,10 @@ async fn multisig() { assert!(tx_result.is_ok()); } + +async fn setup_multisig_client() -> (TestMultisigClient, MockRpcApi, TestClientKeyStore) { + let (client, mock_rpc_api, keystore) = + miden_multisig_test_utils::create_test_client(std::env::temp_dir()).await; + + (MultisigClient { client }, mock_rpc_api, keystore) +} diff --git a/crates/test-utils/Cargo.toml b/crates/test-utils/Cargo.toml index 59ecd65..99c6dc4 100644 --- a/crates/test-utils/Cargo.toml +++ b/crates/test-utils/Cargo.toml @@ -8,6 +8,7 @@ version.workspace = true workspace = true [dependencies] -miden-client = { workspace = true } -miden-testing = "0.11" -rand = { workspace = true } +miden-client = { features = ["testing"], workspace = true } +miden-client-sqlite-store = { workspace = true } +miden-testing = "0.12" +rand = { workspace = true } diff --git a/crates/test-utils/src/lib.rs b/crates/test-utils/src/lib.rs index 0bb9274..9925b95 100644 --- a/crates/test-utils/src/lib.rs +++ b/crates/test-utils/src/lib.rs @@ -14,7 +14,6 @@ use miden_client::{ crypto::RpoRandomCoin, keystore::FilesystemKeyStore, note::{NoteExecutionMode, NoteTag, NoteType}, - store::sqlite_store::SqliteStore, testing::{ NoteBuilder, common::{TestClientKeyStore, create_test_store_path}, @@ -22,6 +21,7 @@ use miden_client::{ }, transaction::OutputNote, }; +use miden_client_sqlite_store::SqliteStore; use miden_testing::{MockChain, MockChainBuilder}; use rand::{Rng, rngs::StdRng}; @@ -90,6 +90,7 @@ async fn create_prebuilt_mock_chain() -> MockChain { .tag(NoteTag::for_public_use_case(0, 0, NoteExecutionMode::Local).unwrap().into()) .build() .unwrap(); + mock_chain_builder.add_output_note(OutputNote::Full(note_first)); let note_second = NoteBuilder::new(mock_account.id(), RpoRandomCoin::new([0, 0, 0, 1].map(Felt::new).into())) @@ -97,10 +98,11 @@ async fn create_prebuilt_mock_chain() -> MockChain { .tag(NoteTag::for_local_use_case(0, 0).unwrap().into()) .build() .unwrap(); + mock_chain_builder.add_output_note(OutputNote::Full(note_second.clone())); + let mut mock_chain = mock_chain_builder.build().unwrap(); - // Block 1: Create first note - mock_chain.add_pending_note(OutputNote::Full(note_first)); + // Block 1 mock_chain.prove_next_block().unwrap(); // Block 2 @@ -109,8 +111,7 @@ async fn create_prebuilt_mock_chain() -> MockChain { // Block 3 mock_chain.prove_next_block().unwrap(); - // Block 4: Create second note - mock_chain.add_pending_note(OutputNote::Full(note_second.clone())); + // Block 4 mock_chain.prove_next_block().unwrap(); let transaction = Box::pin( diff --git a/store b/store deleted file mode 100644 index 43fec45aec59217b1da67026ecb1feef2431f9d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 196608 zcmeI4&vP8db;ox=VwYGF0x5|e%Mzr9DHvE2pa8)%O)Ip6A1i82a90Ar5*e2~9?Uj? zF?VOcnOTyM?NkA@rBtfy@+F7dTu%NGR}MM3QpsPC@*yXm?J7HmyzZW#yR%Eu0;@Kt z?~(v!`p4^jpZEIp>lu)nAFbN~XFIOfHUqX)IA74T!rwAhC=^EMYk|I^&m>)(j&A6u zMqj5=_j#8ig)5(ZeUxfOCjKbu-=6r(#2?3hcb1R+>Fk?hUTI_OYVr4@>&1W89*n+T z_;ca6^ym3L*Ip^=x2Cm%?KJsg|3QniG0aZj%6lX5Ovg8^z;+$qSWMr&+PP5DuTN@+ zQ?jMqd~BGO<#wFFu-tar4%*xa!V>@G)s5=%R+ZhU*FL&aWwrWR^)Acr!WwlJb(`&# zSowTrqNGnwYQLNc%T% zR%4_ra9Oa&Bh^T5lS_$y;Cklnvk4t2F%%?)J~TV6!0=o*7&t@8jf8H9hVD*!f`$~q zZgcN`i?hJvT)}i)$Kt{YgNzW`BL!1-%bLUIyvbJ98!NeXR3cImWb=+seTd{Pcep3a zBao7vS@rQgw*pnU&80-KxEYN*@9;+vc3;wIxz>F#cB8RgU9R_arHIa!*Wt|0&|$XE zl$1HPW43%*@3?`|@WYMT?d6So>{j(2%UcU`au)A5Hmc;)s#TX?RoF)L{pv=wzFOUk z=1y+c|yP3>%JjK8Kn59+;iFL2i4VEY*s9nS!KH$Y=JG; z*J7~}Y;99At5nLBcg`2})yaO5C0ek?Vsv%k=zHTO{pwZiXV>J?ChXkaby8ua$@9uy z$}IW37HaiJ%a@`+X4&?xw%S^k6H7i_X!{8nw6-LADJ<8tc9U!&yyXje`+r4!D%lKx&rI~?ta^QQ0fz?ab>VylYALyPpr`Baxwpf^&MgMPk{$dy+lTxvSw zGZhu7s}!_jb}SwkcGKAR_>TSfY4S)=*f5-@5O7J3m0IvBX6Wma*T|33!ZaIVS^N=$nf6TqTZ zOC^12Nqgc-C(UV>Q*4|3Oyy&iwRcB0hNV&!y@%n zRReqHm|GdTdZwt~Tk2=%90JB-PT|<$>0(K*UCzrjqvpwW7P(JYQ|d8zSA%pGmgJsB z*gd^ZKKa4vl79KJ_8Db#N$MH3>=HYgF?LsFXy|0pgBLtmA=R`i0SqT9UBGX-6h%ZP zKRD4PfvQzxR_Yh6;vRWv-{=!CNM7LX&$swP-s*A~A$gWx*}XCsr9NVkBJVMU=Q2AW z-RPuXJ1U~cJs?pgIM}BwQ6_hN5_J)>Wvi4fbIj+SZMN)Bd9yblB`m33OpM~vjnSh1 z(dB;b+GWEeFond5ho6j;^yz8s=%*R~5P3t?S6rXU^$bz-3~n*d6@(0_t`ydX8c9gt zM9G^xM&u-&2`a*K?bM*7Vp_$7jhKlz^qvu?(!&omd3HNe3y8Lkz;<@U79xL+WWYqF zAr!}KbJn#?q^`<6m+SY!G&U2AM6WQXN~O1vXhT#RwogfJVDR>Sa1f=rE$-|Fd$Y1T z`wm+m?HMJAN=ZZw2~`4+ww&2!H?xfB*=900@8p2!H?x zfWYt)_?uJjeA3*WZ`-@{CXilq&+nQ3Uh^A^3)in-U%dJ)Yl&Zb_nNtAe&gMDzp=2m zV109GVR75MZduo?Z!L@qz0MD>a+nzifB*=900@8p2!H?xfB*=900@A<7bhUz|Kt4s z#W_L(2!H?xfB*=900@8p2!H?xfB*;#GXcE+A7<-dZXf^xAOHd&00JNY0w4eaAOHd& za6AO?{{MJ5LJA0g00@8p2!H?xfB*=900@8p2n;g;od1W}I+z;>fB*=900@8p2!H?x zfB*=900S z9p6|C@1Ab}YW-J?AxC_*bD^YPpVSVgJ9q3v%Wqj8l*n+^K4lG zV70X?vU@m23JBY(-c3Y=Jfx&lcRw%#&Jv1JmgP2iUqM}SAz7=j4Orl^V2?+tk=!Pi z68*sS%-v@bI#6OLND6&uc3Oeqxo(hEwQGiw8wuSI4c(pe1Pv*I-R9o?7H5ISxq|7q zj>Ux)1{oo=M+&CwmNkdZd6TWIH&$}(s6?bB$mSiN`Vh%o?r=|-M<69Tv+Co0ZUw4x zn@fpo$MqPEJMZvE5q4kFX}Q*YF?OS|UR|#Db)|^Tme=9T&d_1D&ym*W|N_KUU_- zQqF3lzPYurEbL+JaqGSzNExK~r`&Vd>Ic=;TWnS=msw@I8*G6s*VkgP5^QZ#GOJX| zm76aW_3vNpx3mc=w|AXXl%WN&m{&S+^u6(te)X#Mvukq6=e5ZzdnpqN@>-~<5G`wp z4w>cL<>TZ+wY4timfX6K_Y*?>`>tYX5-BX# zp9j8N>=6=GG#-NNjq|B4sX%Y2;#md*?t#DpfDXk~0Vg$l1oarYwm(G+Pvif;}@}9;bnQlI*LP zEnI-vj=YgN$uTlcDR|B)g$+`e7W#W+9#vGI=gW0ox=U{U&^-%3-l-cTxUi7_Dnw) z+ZL(4vB%9O_vlQYxxIAw%{NN=)RcClvRZjcH2ed{O0M3@5)|i1*&<}9-wA{XXxCm$-@Wk< z3tuYfmo90)nvo02cH)Mq%hxhGrz#@HA;FYcb-7MYn$uGt!U{nU^P=YfQbU!dJ|!IW z2$Ct35S3bXEt@b>z)}*Wa8+xBxce;LrwQ+}mYBR0F0uH>IdjEDSVSFdeao}=pY`OQ zQX|Byx@U54F+!5g{)nD>u}5~W7hAq$L2M5^@t=4Bn zDwR2}rd%rXSV9PnjX#@iRjypsi+b%+zxbMp4#r~Y<|{{UysGkfL;6zc(Q4#mIYoLV z^5irKBT#CF&*qjyb1Qkc%T#~4Hk9S%Qj@0ddgRdK*Qy|E@?Oz7R!Pm7B6#)UpgcZD z^Z0qRcvc)C{4#BZG7tExpE>{h?_QP});~V#Hj|&4g#SuE!}y^^o_jm!vIsrbNgWJ? z!#^}V+wJ%wPv3VPaXwZK-Q<+oww@#M(nyk8{h&*MZkLL; z>z-xbM>5G<5y?ul;n34E8JJbhVD5^1K46dbY)b{~v?7m8pYg}s>QJOnIj0Cf9iN{3 zQqoS*b5PKXJ$h62k>Ew2@Nox){x~|4Ii719?ZaJ7?%BgrO4Z2oGeJr{najjLdR|wq z6bhr``o)Xd(GBI?<}QuA>rZ8!nMy(@rpl-4M`r5EJgAofJA^dy_qk2 zmMcq>Mg8VfzfdcvspM0f>7#3Q_>-@c^qCp$iArKKp*(XlnNd4a^##IeowknNcp9%a znT3W%8xUWKix9La<8bDzDbZ$3n+>Fe!m0o4pZ;gGG!`?rZ+`yDmu2kxg)QA9ohYZT zU(aw$*M!)F)MLtr=^SA1+Z61KroBs>|Fi9Gv6qGJB_s6BSv( z!xu?({IhrWQu)_YqG3o;1>Uf)xf4(doJ3!Vm>#)AV~96d^s*|<_R1t;tFhMjHXU}n zwtQ+5tr4lbi0#UexMJmpAUQTh)8z%6I3A`sTb=u$?A<>_2GP z0XNJ};L3ZWTcokrU9#}^UoYv^Y3=YW*~4x=7M&d5v;y08e52!7Zo6#<0dJ~XWnJ>S?f zeZz4B?q`bUdnS;nPI`&)GgY(d&grx(?Bfrr8&xJouv#{E0yPl3!4^BSC4HH&T!?4o zc7pv**uro+t(LuGb1z*w*E6SdZPG_fDP1!gORGGXDe2$6q#cgO!`e>HsHwusJ%gqy zvty@>aucMwegj86>KqMnawFcGhlI9!{6^>xAz0SYldPL)f3E zODa9W)3vI74>BpmXxhHz*=^eqp5(n<(ytLaJsvluuo9ChnC%%gRhbN$DwLkfvt#aE zqA@46!?AeGhy;NlZ*nXi70mPu7}dm0yGYJ4DS)k2H&-i1FHe>98#lBk*JNnfH@(0% zTZVLIYtOVD8m-Cwe&y5Q=ql9oYn6nYJN3=l&3bi>t<-L^T0IFra}<*1=b7!yyB@7i zx}de(=a?;a`}PJ+zR6_-6Ble{y|EITouzB2Syv zWkt$K1wJMmtz2n*wWwP+`bEEfS{jS}YQ9E$$r-VqTxUi7_Dny)nRsF>W^OM%S$eCa z&&+6_O-n;%Dl<1<&6p%p71}|SQKVvn%t82MLq-j^xhGMn;5i7oz)wAWPGPuZf6AMo z5Y4V;Cgn3R&%xHY{`#Qh zD6MXYonSxkjm6CEn}Fi+{{#FZYDFDXR1Qw)d+^?xUHP#y6rf}`G<>nKu5UKo*>xJpD zisz!e_=Jv~!l>*YtE8e;IwyQKtw_EKM47JP)+KbAV;!G1NYdg#hkFNX`#^P&AXV1^ z=}i~F=vIsx#{sEnC{#+#9mizfB*=900@8p2!H?xfB*=900@A< ziy?sD|9>%DAr%Bb00ck)1V8`;KmY_l00ck)1cr$K&i}(?4a@}uKmY_l00ck)1V8`; zKmY_l00dqP0i6F|3|B}60T2KI5C8!X009sH0T2KI5CDN;B7pP%Fj)h00Ra#I0T2KI z5C8!X009sH0T2Lz7efH&{};m*Qb7O&KmY_l00ck)1V8`;KmY_lV3-Kt{69?Az+6B8 z1V8`;KmY_l00ck)1V8`;K;Xp?!1@2haD`M5009sH0T2KI5C8!X009sH0T37_0yzH< zlQl3G5C8!X009sH0T2KI5C8!X009tqF$8e_e=%Gk6$C&41V8`;KmY_l00ck)1V8`; zhKazqn9TWMni1v#0w4eaAOHd&00JNY0w4eaAOHd&aNGp&{{Og%LLLZ!00@8p2!H?x RfB*=900@8p2n-*A{{u)oIEerN From f58624780ff91641f738cf83dcdde6b0333e06f6 Mon Sep 17 00:00:00 2001 From: hubcycle Date: Mon, 24 Nov 2025 06:32:05 +0000 Subject: [PATCH 2/8] fix: fix typo --- crates/miden-multisig-client/src/error.rs | 2 +- crates/miden-multisig-client/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/miden-multisig-client/src/error.rs b/crates/miden-multisig-client/src/error.rs index 7409b36..43e48c5 100644 --- a/crates/miden-multisig-client/src/error.rs +++ b/crates/miden-multisig-client/src/error.rs @@ -55,7 +55,7 @@ pub(crate) enum TransactionExecutionError { UnsupportedNumApprovers, #[error("mismatch between number of signatures provided and number of approvers")] - NumSingaturesMismatch, + NumSignaturesMismatch, #[error("public key retrieval failure from storage slot map")] PubKeyStorageSlotMap, diff --git a/crates/miden-multisig-client/src/lib.rs b/crates/miden-multisig-client/src/lib.rs index c8fd416..0d70425 100644 --- a/crates/miden-multisig-client/src/lib.rs +++ b/crates/miden-multisig-client/src/lib.rs @@ -140,7 +140,7 @@ where != usize::try_from(num_approvers) .map_err(|_| TransactionExecutionError::UnsupportedNumApprovers)? { - Err(TransactionExecutionError::NumSingaturesMismatch)?; + Err(TransactionExecutionError::NumSignaturesMismatch)?; } let msg = tx_summary.to_commitment(); From 3d4e834a54958cb50887dfb3d4517dae914ac9f6 Mon Sep 17 00:00:00 2001 From: rotorship Date: Tue, 25 Nov 2025 09:58:15 +0000 Subject: [PATCH 3/8] build: use cargo chef to cache dependencies during docker build --- Dockerfile.coordinator | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/Dockerfile.coordinator b/Dockerfile.coordinator index 2888df8..d942fc9 100644 --- a/Dockerfile.coordinator +++ b/Dockerfile.coordinator @@ -1,4 +1,4 @@ -FROM rust:1.90-alpine AS builder +FROM rust:1.90-alpine AS chef RUN apk add --no-cache \ musl-dev \ @@ -8,12 +8,28 @@ RUN apk add --no-cache \ perl \ make +FROM rust:1.90-alpine AS chef + WORKDIR /build +FROM chef AS planner + COPY Cargo.toml Cargo.lock ./ COPY bin ./bin COPY crates ./crates +RUN cargo chef prepare --recipe-path recipe.json + +FROM chef AS builder + +COPY --from=planner /build/recipe.json recipe.json + +RUN cargo chef cook --release --recipe-path recipe.json --features sysbundle + +COPY Cargo.toml Cargo.lock ./ +COPY bin/coordinator-server ./bin/coordinator-server +COPY crates ./crates + RUN cargo build --release --bin miden-multisig-coordinator-server --features sysbundle FROM alpine:3.22 AS runtime From aa3e9b60af9da82a86febd4a54b86c180203be73 Mon Sep 17 00:00:00 2001 From: rotorship Date: Tue, 25 Nov 2025 10:03:40 +0000 Subject: [PATCH 4/8] fix: fix decoding the approver address in json payload --- Cargo.lock | 17 ++++++++--------- bin/coordinator-server/src/routes.rs | 26 +++++++++++++++++++------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c1f564c..3728eb9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1457,12 +1457,11 @@ dependencies = [ [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ] @@ -4801,9 +4800,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "9cf146f99d442e8e68e585f5d798ccd3cad9a7835b917e09728880a862706456" dependencies = [ "bitflags", "bytes", @@ -5861,18 +5860,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.28" +version = "0.8.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43fa6694ed34d6e57407afbccdeecfa268c470a7d2a5b0cf49ce9fcc345afb90" +checksum = "4ea879c944afe8a2b25fef16bb4ba234f47c694565e97383b36f3a878219065c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.28" +version = "0.8.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c640b22cd9817fae95be82f0d2f90b11f7605f6c319d16705c459b27ac2cbc26" +checksum = "cf955aa904d6040f70dc8e9384444cb1030aed272ba3cb09bbc4ab9e7c1f34f5" dependencies = [ "proc-macro2", "quote", diff --git a/bin/coordinator-server/src/routes.rs b/bin/coordinator-server/src/routes.rs index 36a0759..9fda75e 100644 --- a/bin/coordinator-server/src/routes.rs +++ b/bin/coordinator-server/src/routes.rs @@ -3,6 +3,7 @@ use itertools::Itertools; use miden_client::{ Word, account::AccountId, + address::{Address, AddressId}, utils::{Deserializable, Serializable}, }; use miden_multisig_coordinator_engine::{ @@ -65,16 +66,24 @@ pub async fn create_multisig_account( let approvers = approvers .iter() .map(AsRef::as_ref) - .map(AccountId::from_bech32) - .map(|res| res.map_err(From::from)) - .map_ok(|(network_id, account_id)| { + .map(Address::decode) + .map(|res| { + res.map_err(|e| AppError::other(format!("failed to decode address: {e}"))) + }) + .map_ok(|(network_id, address)| { engine_network_id .eq(&network_id) - .then_some(account_id) + .then_some(address) .ok_or(AppError::InvalidNetworkId) }) .map(Result::flatten) - .try_collect()?; + .map_ok(|a| match a.id() { + AddressId::AccountId(id) => Ok(id), + _ => Err(AppError::other("approver address must be account id")), + }) + .map(Result::flatten) + .try_collect() + .inspect_err(|e| tracing::error!("failed to decode approvers: {e}"))?; let pub_key_commits = pub_key_commits .iter() @@ -82,7 +91,8 @@ pub async fn create_multisig_account( .map(Word::read_from_bytes) .map_ok(From::from) .try_collect() - .map_err(|_| AppError::InvalidPubKeyCommit)?; + .map_err(|_| AppError::InvalidPubKeyCommit) + .inspect_err(|e| tracing::error!("failed to decode public key commitments: {e}"))?; CreateMultisigAccountRequest::builder() .threshold(threshold) @@ -91,11 +101,13 @@ pub async fn create_multisig_account( .build() .map_err(RequestError::from) .map_err(AppError::from) + .inspect_err(|e| tracing::error!("failed to create request: {e}")) }) .await? .map(|request| engine.create_multisig_account(request))? .await - .map(CreateMultisigAccountResponse::dissolve)?; + .map(CreateMultisigAccountResponse::dissolve) + .inspect_err(|e| tracing::error!("failed to create multisig account: {e}"))?; let response = CreateMultisigAccountResponsePayload::builder() .address(multisig_account.account_id().to_bech32(multisig_account.network_id().clone())) From e316965fef0ae0a530609e8cfddbbf88a2306959 Mon Sep 17 00:00:00 2001 From: hubcycle Date: Sat, 29 Nov 2025 01:46:12 +0530 Subject: [PATCH 5/8] feat: bump miden-web-sdk to v0.12.3 and miden-wallet-adapter v0.10.0 in coordinator-frontend (#20) * Restore coordinator-frontend changes: remove createFaucet, update AccountInterface to BasicWallet, use NoteFile.deserialize() * fix: fix cargo chef error in Dockerfile of coordinator backend * add network param to wallet adapter components * fix: fix decoding account address and bump miden wallet adapter dependency to v0.10.0 * fix: fix wallet not connected error and invalid signature error * chore: remove miden-wallet-adapter-react dependencies --------- Co-authored-by: Pradyumna-Bhardwaj --- Cargo.lock | 24 +- Dockerfile.coordinator | 19 +- bin/coordinator-frontend/package-lock.json | 261 +++++++++++------- bin/coordinator-frontend/package.json | 12 +- .../dashboard/components/PendingActions.tsx | 13 +- .../components/RecentTransactions.tsx | 5 +- .../src/app/dashboard/components/Taskbar.tsx | 2 +- .../dashboard/settings/components/General.tsx | 2 +- .../src/components/DynamicWalletButton.tsx | 5 +- .../src/components/Providers.tsx | 4 +- .../src/components/SimpleWalletButton.tsx | 3 +- .../src/components/WalletConnection.tsx | 2 + .../src/components/WalletStatus.tsx | 2 + .../src/hooks/useFungibleAssets.ts | 2 +- .../src/hooks/useMidenSdk.tsx | 48 +--- .../src/interactions/ReceiveFundTransfer.tsx | 4 +- bin/coordinator-frontend/src/types/hooks.ts | 8 - bin/coordinator-server/src/routes.rs | 56 ++-- 18 files changed, 243 insertions(+), 229 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3728eb9..eea22c7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -797,9 +797,9 @@ dependencies = [ [[package]] name = "diesel" -version = "2.3.3" +version = "2.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e7624a3bb9fffd82fff016be9a7f163d20e5a89eb8d28f9daaa6b30fff37500" +checksum = "0c415189028b232660655e4893e8bc25ca7aee8e96888db66d9edb400535456a" dependencies = [ "bitflags", "byteorder", @@ -828,9 +828,9 @@ dependencies = [ [[package]] name = "diesel_derives" -version = "2.3.4" +version = "2.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9daac6489a36e42570da165a10c424f3edcefdff70c5fd55e1847c23f3dd7562" +checksum = "8587cbca3c929fb198e7950d761d31ca72b80aa6e07c1b7bec5879d187720436" dependencies = [ "diesel_table_macro_syntax", "dsl_auto_type", @@ -841,9 +841,9 @@ dependencies = [ [[package]] name = "diesel_migrations" -version = "2.3.0" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee060f709c3e3b1cadd83fcd0f61711f7a8cf493348f758d3a1c1147d70b3c97" +checksum = "745fd255645f0f1135f9ec55c7b00e0882192af9683ab4731e4bba3da82b8f9c" dependencies = [ "diesel", "migrations_internals", @@ -4840,9 +4840,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.30" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", @@ -4851,9 +4851,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.34" +version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" dependencies = [ "once_cell", "valuable", @@ -5671,9 +5671,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" dependencies = [ "memchr", ] diff --git a/Dockerfile.coordinator b/Dockerfile.coordinator index d942fc9..440b040 100644 --- a/Dockerfile.coordinator +++ b/Dockerfile.coordinator @@ -1,21 +1,16 @@ FROM rust:1.90-alpine AS chef RUN apk add --no-cache \ - musl-dev \ - pkgconfig \ - openssl-dev \ - openssl-libs-static \ - perl \ - make + musl-dev -FROM rust:1.90-alpine AS chef +RUN cargo install cargo-chef --locked WORKDIR /build FROM chef AS planner COPY Cargo.toml Cargo.lock ./ -COPY bin ./bin +COPY bin/coordinator-server ./bin/coordinator-server COPY crates ./crates RUN cargo chef prepare --recipe-path recipe.json @@ -24,6 +19,14 @@ FROM chef AS builder COPY --from=planner /build/recipe.json recipe.json + +RUN apk add --no-cache \ + pkgconfig \ + openssl-dev \ + openssl-libs-static \ + perl \ + make + RUN cargo chef cook --release --recipe-path recipe.json --features sysbundle COPY Cargo.toml Cargo.lock ./ diff --git a/bin/coordinator-frontend/package-lock.json b/bin/coordinator-frontend/package-lock.json index 5be6e99..6f8881d 100644 --- a/bin/coordinator-frontend/package-lock.json +++ b/bin/coordinator-frontend/package-lock.json @@ -8,12 +8,10 @@ "name": "miden_wallet", "version": "0.1.0", "dependencies": { - "@demox-labs/miden-sdk": "^0.11.11", - "@demox-labs/miden-wallet-adapter": "^0.8.0", - "@demox-labs/miden-wallet-adapter-base": "^0.8.0", - "@demox-labs/miden-wallet-adapter-miden": "^0.8.0", - "@demox-labs/miden-wallet-adapter-react": "^0.8.0", - "@demox-labs/miden-wallet-adapter-reactui": "^0.8.0", + "@demox-labs/miden-sdk": "^0.12.3", + "@demox-labs/miden-wallet-adapter": "^0.10.0", + "@demox-labs/miden-wallet-adapter-base": "^0.10.0", + "@demox-labs/miden-wallet-adapter-miden": "^0.10.0", "@reduxjs/toolkit": "^2.8.2", "framer-motion": "^12.23.12", "next": "15.4.5", @@ -49,12 +47,12 @@ } }, "node_modules/@demox-labs/miden-sdk": { - "version": "0.11.11", - "resolved": "https://registry.npmjs.org/@demox-labs/miden-sdk/-/miden-sdk-0.11.11.tgz", - "integrity": "sha512-HcKadGQQynW/UZrVLSAZsl3Luwt1d0Pmhkd/2MBbyJ0IoIN/tySsAx3f7XrmMSwX4RwUnM2tY5aeM/bf0V/ZEw==", + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/@demox-labs/miden-sdk/-/miden-sdk-0.12.3.tgz", + "integrity": "sha512-iHomtLaZrY1cb8FVevij9x2foXo33qxRnUNNszKDmdlvgEgt1XmZlZUP8+bb4OFPMJF5lRsJaLcfd5pODvF6JQ==", "license": "MIT*", "dependencies": { - "chai-as-promised": "^8.0.0", + "@rollup/plugin-typescript": "^12.3.0", "dexie": "^4.0.1", "glob": "^11.0.0" } @@ -141,15 +139,15 @@ } }, "node_modules/@demox-labs/miden-wallet-adapter": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@demox-labs/miden-wallet-adapter/-/miden-wallet-adapter-0.8.0.tgz", - "integrity": "sha512-CcGRreeUGki8OZY6emJPYElKq36eJnZATQKuQ5/SgVla+UbRrDQaYOHL67Di2GLJKt+WbL182DDg8z4/6Vc5Lw==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@demox-labs/miden-wallet-adapter/-/miden-wallet-adapter-0.10.0.tgz", + "integrity": "sha512-pCyV1vnhwNebBf8MEI6Tz6pbnMe5Kt9I/XiwOskA200o1wK1Sp7z8b3MdLnjyXNe7CXn3gJJFdBqzbU96vF1Lg==", "license": "MIT", "dependencies": { - "@demox-labs/miden-wallet-adapter-base": "^0.8.0", - "@demox-labs/miden-wallet-adapter-miden": "^0.8.0", - "@demox-labs/miden-wallet-adapter-react": "^0.8.0", - "@demox-labs/miden-wallet-adapter-reactui": "^0.8.0" + "@demox-labs/miden-wallet-adapter-base": "^0.10.0", + "@demox-labs/miden-wallet-adapter-miden": "^0.10.0", + "@demox-labs/miden-wallet-adapter-react": "^0.10.0", + "@demox-labs/miden-wallet-adapter-reactui": "^0.10.0" }, "peerDependencies": { "@types/react": "^19.0.0", @@ -159,21 +157,21 @@ } }, "node_modules/@demox-labs/miden-wallet-adapter-base": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@demox-labs/miden-wallet-adapter-base/-/miden-wallet-adapter-base-0.8.0.tgz", - "integrity": "sha512-U2cSyAVDem03/U8eob0i4b6W5ftv9QCId7pdMa/GXwuRrO6Tlxz7zoyZC21xtw0w3dX83nJ8eRErgTFxow25zA==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@demox-labs/miden-wallet-adapter-base/-/miden-wallet-adapter-base-0.10.0.tgz", + "integrity": "sha512-BLPJdIz1eq/s8iUOkwGttpo04ShyqExaflS14lmgnyhXEDevTs5xWAu3ipgrVNEf79gYNeh4AQ/KKC29DsVXcQ==", "license": "MIT", "dependencies": { "eventemitter3": "^5.0.1" } }, "node_modules/@demox-labs/miden-wallet-adapter-miden": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@demox-labs/miden-wallet-adapter-miden/-/miden-wallet-adapter-miden-0.8.0.tgz", - "integrity": "sha512-kuqOPqlam8Uf5ZYFaNohXTvPVeSql4g5vLtGKE8arPgqRo/THTJfsaLhMCq5akwDE7VCGFc1iLd6MSy4cLyWeQ==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@demox-labs/miden-wallet-adapter-miden/-/miden-wallet-adapter-miden-0.10.0.tgz", + "integrity": "sha512-yvZVNRBRY+lvYnyZ+I/VdPBNH9GrMEw6iG//7pztHTQSicxIC8mQZSFEoV1xWWvQglMlpycyZnDMM+R5zv2AwQ==", "license": "MIT", "dependencies": { - "@demox-labs/miden-wallet-adapter-base": "^0.8.0", + "@demox-labs/miden-wallet-adapter-base": "^0.10.0", "nanoid": "^5.0.9" }, "peerDependencies": { @@ -199,25 +197,25 @@ } }, "node_modules/@demox-labs/miden-wallet-adapter-react": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@demox-labs/miden-wallet-adapter-react/-/miden-wallet-adapter-react-0.8.0.tgz", - "integrity": "sha512-cZbE13Tiy7Nw2TdvXnkr7CkZQBVp8P43p9MJhwUgABDJjFsSb6a5PnBA4zV4RzNTAQUpF7UO8L5vF/Ju11p3sw==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@demox-labs/miden-wallet-adapter-react/-/miden-wallet-adapter-react-0.10.0.tgz", + "integrity": "sha512-498XMpvY5QyEDjYbS6CUjzgAuD7BZFL1LxYIWskIglK/TOEGWZEOINT+bsXgan4Bgd+ybfKcJNYY0aAmyPtc2A==", "license": "MIT", "dependencies": { - "@demox-labs/miden-wallet-adapter-base": "^0.8.0" + "@demox-labs/miden-wallet-adapter-base": "^0.10.0" }, "peerDependencies": { "react": "^19.1.1" } }, "node_modules/@demox-labs/miden-wallet-adapter-reactui": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@demox-labs/miden-wallet-adapter-reactui/-/miden-wallet-adapter-reactui-0.8.0.tgz", - "integrity": "sha512-2gFxnj4A1Tq2h2f/VOJ8TQi5QRWRGjqM/NJrAn34Jo2V88dZ6tPFPqgYcSysOXxhXPMOEwg7xAr4L3p1J6fulw==", + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@demox-labs/miden-wallet-adapter-reactui/-/miden-wallet-adapter-reactui-0.10.0.tgz", + "integrity": "sha512-SdHq7ic6S4GXFcuIg8mtSSS/iFQeLOeBqJYlXh3LrHMGfKVQll9nRhGT1ZvJlXfQdC3/aX3fCNDqsgNzfosTjg==", "license": "MIT", "dependencies": { - "@demox-labs/miden-wallet-adapter-base": "^0.8.0", - "@demox-labs/miden-wallet-adapter-react": "^0.8.0" + "@demox-labs/miden-wallet-adapter-base": "^0.10.0", + "@demox-labs/miden-wallet-adapter-react": "^0.10.0" }, "peerDependencies": { "@types/react": "^19.0.0", @@ -1623,6 +1621,66 @@ } } }, + "node_modules/@rollup/plugin-typescript": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-12.3.0.tgz", + "integrity": "sha512-7DP0/p7y3t67+NabT9f8oTBFE6gGkto4SA6Np2oudYmZE/m1dt8RB0SjL1msMxFpLo631qjRCcBlAbq1ml/Big==", + "license": "MIT", + "dependencies": { + "@rollup/pluginutils": "^5.1.0", + "resolve": "^1.22.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^2.14.0||^3.0.0||^4.0.0", + "tslib": "*", + "typescript": ">=3.7.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + }, + "tslib": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, + "node_modules/@rollup/pluginutils/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/@rtsao/scc": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", @@ -1697,7 +1755,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, "license": "MIT" }, "node_modules/@types/json-schema": { @@ -2919,6 +2976,16 @@ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "license": "MIT" }, + "node_modules/baseline-browser-mapping": { + "version": "2.8.32", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.32.tgz", + "integrity": "sha512-OPz5aBThlyLFgxyhdwf/s2+8ab3OvT7AdTNvKHBwpXomIYeXqpUUuT8LrdtxZSsWJ4R4CU1un4XGh5Ez3nlTpw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" + } + }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -2955,9 +3022,9 @@ } }, "node_modules/browserslist": { - "version": "4.25.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", - "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz", + "integrity": "sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==", "dev": true, "funding": [ { @@ -2975,10 +3042,11 @@ ], "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001726", - "electron-to-chromium": "^1.5.173", - "node-releases": "^2.0.19", - "update-browserslist-db": "^1.1.3" + "baseline-browser-mapping": "^2.8.25", + "caniuse-lite": "^1.0.30001754", + "electron-to-chromium": "^1.5.249", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.1.4" }, "bin": { "browserslist": "cli.js" @@ -3065,9 +3133,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001731", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz", - "integrity": "sha512-lDdp2/wrOmTRWuoB5DpfNkC0rJDU8DqRa6nYL6HK6sytw70QMopt/NIc/9SM7ylItlBWfACXk0tEn37UWM/+mg==", + "version": "1.0.30001757", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001757.tgz", + "integrity": "sha512-r0nnL/I28Zi/yjk1el6ilj27tKcdjLsNqAOZr0yVjWPrSQyHgKI2INaEWw21bAQSv2LXRt1XuCS/GomNpWOxsQ==", "funding": [ { "type": "opencollective", @@ -3084,28 +3152,6 @@ ], "license": "CC-BY-4.0" }, - "node_modules/chai": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-6.0.1.tgz", - "integrity": "sha512-/JOoU2//6p5vCXh00FpNgtlw0LjvhGttaWc+y7wpW9yjBm3ys0dI8tSKZxIOgNruz5J0RleccatSIC3uxEZP0g==", - "license": "MIT", - "peer": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/chai-as-promised": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-8.0.2.tgz", - "integrity": "sha512-1GadL+sEJVLzDjcawPM4kjfnL+p/9vrxiEUonowKOAzvVg0PixJUdtuDzdkDeQhK3zfOE76GqGkZIQ7/Adcrqw==", - "license": "MIT", - "dependencies": { - "check-error": "^2.1.1" - }, - "peerDependencies": { - "chai": ">= 2.1.2 < 7" - } - }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -3123,15 +3169,6 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/check-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", - "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", - "license": "MIT", - "engines": { - "node": ">= 16" - } - }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -3485,9 +3522,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { - "version": "1.5.192", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.192.tgz", - "integrity": "sha512-rP8Ez0w7UNw/9j5eSXCe10o1g/8B1P5SM90PCCMVkIRQn2R0LEHWz4Eh9RnxkniuDe1W0cTSOB3MLlkTGDcuCg==", + "version": "1.5.262", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.262.tgz", + "integrity": "sha512-NlAsMteRHek05jRUxUR0a5jpjYq9ykk6+kO0yRaMi5moe7u0fVIOeQ3Y30A8dIiWFBNUoQGi1ljb1i5VtS9WQQ==", "dev": true, "license": "ISC" }, @@ -4177,6 +4214,12 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", + "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", + "license": "MIT" + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -5463,14 +5506,18 @@ "license": "MIT" }, "node_modules/loader-runner": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", - "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", + "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=6.11.5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/locate-path": { @@ -5775,9 +5822,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.19", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", - "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true, "license": "MIT" }, @@ -6578,9 +6625,9 @@ "license": "MIT" }, "node_modules/schema-utils": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", - "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", + "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "dev": true, "license": "MIT", "dependencies": { @@ -7345,26 +7392,30 @@ } }, "node_modules/tapable": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", - "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", + "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", "dev": true, "license": "MIT", "peer": true, "engines": { "node": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" } }, "node_modules/terser": { - "version": "5.43.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", - "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", + "version": "5.44.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.44.1.tgz", + "integrity": "sha512-t/R3R/n0MSwnnazuPpPNVO60LX0SKL45pyl9YlvxIdkH0Of7D5qM2EVe+yASRIlY5pZ73nclYJfNANGWPwFDZw==", "dev": true, "license": "BSD-2-Clause", "peer": true, "dependencies": { "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.14.0", + "acorn": "^8.15.0", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -7701,9 +7752,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", - "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.4.tgz", + "integrity": "sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==", "dev": true, "funding": [ { @@ -7772,9 +7823,9 @@ } }, "node_modules/webpack": { - "version": "5.101.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.101.1.tgz", - "integrity": "sha512-rHY3vHXRbkSfhG6fH8zYQdth/BtDgXXuR2pHF++1f/EBkI8zkgM5XWfsC3BvOoW9pr1CvZ1qQCxhCEsbNgT50g==", + "version": "5.103.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.103.0.tgz", + "integrity": "sha512-HU1JOuV1OavsZ+mfigY0j8d1TgQgbZ6M+J75zDkpEAwYeXjWSqrGJtgnPblJjd/mAyTNQ7ygw0MiKOn6etz8yw==", "dev": true, "license": "MIT", "peer": true, @@ -7787,7 +7838,7 @@ "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.15.0", "acorn-import-phases": "^1.0.3", - "browserslist": "^4.24.0", + "browserslist": "^4.26.3", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.17.3", "es-module-lexer": "^1.2.1", @@ -7796,13 +7847,13 @@ "glob-to-regexp": "^0.4.1", "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", + "loader-runner": "^4.3.1", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^4.3.2", - "tapable": "^2.1.1", + "schema-utils": "^4.3.3", + "tapable": "^2.3.0", "terser-webpack-plugin": "^5.3.11", - "watchpack": "^2.4.1", + "watchpack": "^2.4.4", "webpack-sources": "^3.3.3" }, "bin": { diff --git a/bin/coordinator-frontend/package.json b/bin/coordinator-frontend/package.json index 429d771..c122cb5 100644 --- a/bin/coordinator-frontend/package.json +++ b/bin/coordinator-frontend/package.json @@ -9,12 +9,10 @@ "lint": "next lint" }, "dependencies": { - "@demox-labs/miden-sdk": "^0.11.11", - "@demox-labs/miden-wallet-adapter": "^0.8.0", - "@demox-labs/miden-wallet-adapter-base": "^0.8.0", - "@demox-labs/miden-wallet-adapter-miden": "^0.8.0", - "@demox-labs/miden-wallet-adapter-react": "^0.8.0", - "@demox-labs/miden-wallet-adapter-reactui": "^0.8.0", + "@demox-labs/miden-sdk": "^0.12.3", + "@demox-labs/miden-wallet-adapter": "^0.10.0", + "@demox-labs/miden-wallet-adapter-base": "^0.10.0", + "@demox-labs/miden-wallet-adapter-miden": "^0.10.0", "@reduxjs/toolkit": "^2.8.2", "framer-motion": "^12.23.12", "next": "15.4.5", @@ -36,4 +34,4 @@ "tailwindcss": "^3.4.0", "typescript": "^5" } -} +} \ No newline at end of file diff --git a/bin/coordinator-frontend/src/app/dashboard/components/PendingActions.tsx b/bin/coordinator-frontend/src/app/dashboard/components/PendingActions.tsx index 930949b..e546b14 100644 --- a/bin/coordinator-frontend/src/app/dashboard/components/PendingActions.tsx +++ b/bin/coordinator-frontend/src/app/dashboard/components/PendingActions.tsx @@ -6,9 +6,9 @@ import media from "../../../../public/media"; import { useAppSelector, useAppDispatch } from "@/store/hooks"; import PendingTransactionDetails from "@/interactions/PendingTransactionDetails"; import { AnimatePresence, motion } from "framer-motion"; -import { TransactionRequest, TransactionSummary, SigningInputs } from "@demox-labs/miden-sdk"; +import { TransactionRequest, TransactionSummary, SigningInputs, NoteFile } from "@demox-labs/miden-sdk"; import { useMidenClient } from "../../../contexts/MidenClientContext"; -import { fetchPendingTransactions, fetchConfirmedTransactions} from "../../../services/transactionApi"; +import { fetchPendingTransactions, fetchConfirmedTransactions } from "../../../services/transactionApi"; import { addSignatureThunk } from "../../../services/signatureApi"; import { useWallet } from "@demox-labs/miden-wallet-adapter"; import { PendingActionsProps, DecodedTransaction, WebClient } from "@/types"; @@ -64,7 +64,8 @@ const getReceiveTransactionAmount = async (noteId: string, noteIdFileBytes: stri if (!inputNoteRecord) { if (noteIdFileBytes) { const noteBytes = Uint8Array.fromBase64(noteIdFileBytes); - await webClient.importNoteFile(noteBytes); + const noteFile = NoteFile.deserialize(noteBytes); + await webClient.importNoteFile(noteFile); inputNoteRecord = await webClient.getInputNote(noteId); } else { console.error("No note file bytes to import"); @@ -92,7 +93,7 @@ const getReceiveTransactionAmount = async (noteId: string, noteIdFileBytes: stri const PendingActions: React.FC = ({ threshold, fixedHeight = false }) => { const router = useRouter(); - const { wallet, accountId, connected, signBytes } = useWallet(); + const { wallet, address, connected, signBytes } = useWallet(); const { handle, isInitialized } = useMidenClient(); const dispatch = useAppDispatch(); const { pendingTransactions, loading: transactionsLoading } = useAppSelector( @@ -114,7 +115,7 @@ const PendingActions: React.FC = ({ threshold, fixedHeight }, [transactionsLoading, hasLoadedOnce]); const handleSign = async (txReqFromApi: string, txId: string) => { - if (!wallet || !accountId || !connected) { + if (!wallet || !address || !connected) { setShowWalletErrorModal(true); setTimeout(() => { setShowWalletErrorModal(false); @@ -157,7 +158,7 @@ const PendingActions: React.FC = ({ threshold, fixedHeight try { const signatureData = { tx_id: txId, - approver: accountId, + approver: address, signature: signatureBase64, }; diff --git a/bin/coordinator-frontend/src/app/dashboard/components/RecentTransactions.tsx b/bin/coordinator-frontend/src/app/dashboard/components/RecentTransactions.tsx index 30a1366..3ccaa50 100644 --- a/bin/coordinator-frontend/src/app/dashboard/components/RecentTransactions.tsx +++ b/bin/coordinator-frontend/src/app/dashboard/components/RecentTransactions.tsx @@ -5,7 +5,7 @@ import { useRouter } from "next/navigation"; import media from "../../../../public/media"; import { useAppSelector } from "@/store/hooks"; import { DecodedTransaction, RecentTransactionsProps } from "@/types"; -import { TransactionRequest } from "@demox-labs/miden-sdk"; +import { TransactionRequest, NoteFile } from "@demox-labs/miden-sdk"; import { useMidenClient } from "../../../contexts/MidenClientContext"; const getTransactionType = ( @@ -79,7 +79,8 @@ const getReceiveTransactionAmount = async (noteId: string, noteIdFileBytes: stri if (!inputNoteRecord) { if (noteIdFileBytes) { const noteBytes = Uint8Array.fromBase64(noteIdFileBytes); - await webClient.importNoteFile(noteBytes); + const noteFile = NoteFile.deserialize(noteBytes); + await webClient.importNoteFile(noteFile); // Retry getting the note inputNoteRecord = await webClient.getInputNote(noteId); diff --git a/bin/coordinator-frontend/src/app/dashboard/components/Taskbar.tsx b/bin/coordinator-frontend/src/app/dashboard/components/Taskbar.tsx index bcf96d5..ce8322a 100644 --- a/bin/coordinator-frontend/src/app/dashboard/components/Taskbar.tsx +++ b/bin/coordinator-frontend/src/app/dashboard/components/Taskbar.tsx @@ -70,7 +70,7 @@ const TaskBar: React.FC = () => { const walletAddress = Address.fromBech32(currentWalletId); const walletAccountId = walletAddress.accountId(); - const convertedWalletId = walletAccountId.toBech32(NetworkId.Testnet, AccountInterface.Unspecified); + const convertedWalletId = walletAccountId.toBech32(NetworkId.Testnet, AccountInterface.BasicWallet); return convertedWalletId; diff --git a/bin/coordinator-frontend/src/app/dashboard/settings/components/General.tsx b/bin/coordinator-frontend/src/app/dashboard/settings/components/General.tsx index 1efcf38..4be61c7 100644 --- a/bin/coordinator-frontend/src/app/dashboard/settings/components/General.tsx +++ b/bin/coordinator-frontend/src/app/dashboard/settings/components/General.tsx @@ -17,7 +17,7 @@ const General = () => { const walletAccountId = walletAddress.accountId(); const convertedWalletId = walletAccountId.toBech32( NetworkId.Testnet, - AccountInterface.Unspecified + AccountInterface.BasicWallet ); return convertedWalletId; } catch (error) { diff --git a/bin/coordinator-frontend/src/components/DynamicWalletButton.tsx b/bin/coordinator-frontend/src/components/DynamicWalletButton.tsx index b584ebe..7ed6820 100644 --- a/bin/coordinator-frontend/src/components/DynamicWalletButton.tsx +++ b/bin/coordinator-frontend/src/components/DynamicWalletButton.tsx @@ -1,9 +1,10 @@ 'use client'; import React, { useState, useEffect } from 'react'; +import { WalletAdapterNetwork } from '@demox-labs/miden-wallet-adapter-base'; const DynamicWalletButton: React.FC = () => { - const [WalletMultiButton, setWalletMultiButton] = useState | null>(null); + const [WalletMultiButton, setWalletMultiButton] = useState | null>(null); const [isLoading, setIsLoading] = useState(true); useEffect(() => { @@ -40,7 +41,7 @@ const DynamicWalletButton: React.FC = () => { } return ( - + ); }; diff --git a/bin/coordinator-frontend/src/components/Providers.tsx b/bin/coordinator-frontend/src/components/Providers.tsx index f4c0b08..180abe1 100644 --- a/bin/coordinator-frontend/src/components/Providers.tsx +++ b/bin/coordinator-frontend/src/components/Providers.tsx @@ -9,6 +9,7 @@ import { MidenWalletAdapter, PrivateDataPermission, } from '@demox-labs/miden-wallet-adapter'; +import { WalletAdapterNetwork } from '@demox-labs/miden-wallet-adapter-base'; import { MidenSdkProvider } from '../hooks/useMidenSdk'; import { MidenClientProvider } from '../contexts/MidenClientContext'; @@ -48,9 +49,10 @@ export function Providers({ children }: { children: React.ReactNode }) { - + {children} diff --git a/bin/coordinator-frontend/src/components/SimpleWalletButton.tsx b/bin/coordinator-frontend/src/components/SimpleWalletButton.tsx index aae957f..2dc0002 100644 --- a/bin/coordinator-frontend/src/components/SimpleWalletButton.tsx +++ b/bin/coordinator-frontend/src/components/SimpleWalletButton.tsx @@ -2,6 +2,7 @@ import React from 'react'; import { WalletMultiButton } from '@demox-labs/miden-wallet-adapter'; +import { WalletAdapterNetwork } from '@demox-labs/miden-wallet-adapter-base'; const SimpleWalletButton: React.FC = () => { return ( @@ -12,7 +13,7 @@ const SimpleWalletButton: React.FC = () => {

Click the button below to connect your Miden wallet

- + ); }; diff --git a/bin/coordinator-frontend/src/components/WalletConnection.tsx b/bin/coordinator-frontend/src/components/WalletConnection.tsx index 6ad4949..f0f30e4 100644 --- a/bin/coordinator-frontend/src/components/WalletConnection.tsx +++ b/bin/coordinator-frontend/src/components/WalletConnection.tsx @@ -4,6 +4,7 @@ import React from 'react'; import { motion } from 'framer-motion'; import { WalletMultiButton } from '@demox-labs/miden-wallet-adapter'; import { useWallet } from '@demox-labs/miden-wallet-adapter'; +import { WalletAdapterNetwork } from '@demox-labs/miden-wallet-adapter-base'; import { WalletConnectionProps } from '@/types'; export const WalletConnection: React.FC = ({ className = '' }) => { @@ -27,6 +28,7 @@ export const WalletConnection: React.FC = ({ className =
diff --git a/bin/coordinator-frontend/src/components/WalletStatus.tsx b/bin/coordinator-frontend/src/components/WalletStatus.tsx index cc97b02..c8cab04 100644 --- a/bin/coordinator-frontend/src/components/WalletStatus.tsx +++ b/bin/coordinator-frontend/src/components/WalletStatus.tsx @@ -4,6 +4,7 @@ import React from 'react'; import { motion } from 'framer-motion'; import { useWallet } from '@demox-labs/miden-wallet-adapter'; import { WalletMultiButton } from '@demox-labs/miden-wallet-adapter'; +import { WalletAdapterNetwork } from '@demox-labs/miden-wallet-adapter-base'; interface WalletStatusProps { className?: string; @@ -60,6 +61,7 @@ export const WalletStatus: React.FC = ({ {showButton && ( )} diff --git a/bin/coordinator-frontend/src/hooks/useFungibleAssets.ts b/bin/coordinator-frontend/src/hooks/useFungibleAssets.ts index 45acf54..c97e99d 100644 --- a/bin/coordinator-frontend/src/hooks/useFungibleAssets.ts +++ b/bin/coordinator-frontend/src/hooks/useFungibleAssets.ts @@ -45,7 +45,7 @@ export const useFungibleAssets = () => { const assets = assetVault.fungibleAssets(); const assetsWithBalance = assets.map(asset => { - const faucetId = asset.faucetId().toBech32(NetworkId.Testnet, AccountInterface.Unspecified); + const faucetId = asset.faucetId().toBech32(NetworkId.Testnet, AccountInterface.BasicWallet); const balance = assetVault.getBalance(asset.faucetId()).toString(); return { faucetId, balance }; }); diff --git a/bin/coordinator-frontend/src/hooks/useMidenSdk.tsx b/bin/coordinator-frontend/src/hooks/useMidenSdk.tsx index e66fd19..6cedf6d 100644 --- a/bin/coordinator-frontend/src/hooks/useMidenSdk.tsx +++ b/bin/coordinator-frontend/src/hooks/useMidenSdk.tsx @@ -46,59 +46,13 @@ export const MidenSdkProvider: FC = ({ children }) => { return await Miden.WebClient.createClient('https://rpc.testnet.miden.io'); }, [Miden]); - const createFaucet = useCallback( - async ( - client: unknown, - storageMode: unknown, - nonFungible: boolean, - assetSymbol: string, - decimals: number, - totalSupply: bigint - ): Promise => { - if (!Miden || !client) - throw new Error('Miden SDK or client not initialized'); - - try { - // Cast client to any to use dynamic SDK methods - const webClient = client as any; - - // First sync the client state to ensure we're up to date - await webClient.syncState(); - - // Create the faucet with provided configuration - const faucet = await webClient.newFaucet( - storageMode, - nonFungible, - assetSymbol, - decimals, - totalSupply - ); - - // Get the faucet ID before any other operations - const newFaucetId = faucet.id(); - - // Add a delay to ensure proper initialization - await new Promise((resolve) => setTimeout(resolve, 2000)); - - // Sync state again after faucet creation - await webClient.syncState(); - - return newFaucetId; - } catch (error) { - console.error('Error creating faucet:', error); - throw error; - } - }, - [Miden] - ); - useEffect(() => { loadSdk(); }, [loadSdk]); return ( {children} diff --git a/bin/coordinator-frontend/src/interactions/ReceiveFundTransfer.tsx b/bin/coordinator-frontend/src/interactions/ReceiveFundTransfer.tsx index cd507fd..485cc14 100644 --- a/bin/coordinator-frontend/src/interactions/ReceiveFundTransfer.tsx +++ b/bin/coordinator-frontend/src/interactions/ReceiveFundTransfer.tsx @@ -3,6 +3,7 @@ import { useState, useEffect } from "react"; import { useMidenClient } from "@/contexts/MidenClientContext"; import { useDispatch, useSelector } from "react-redux"; import { AppDispatch } from "@/store"; +import { NoteFile } from "@demox-labs/miden-sdk"; import { proposeTransactionWithTxBzThunk, fetchPendingTransactions, fetchConfirmedTransactions, getConsumableNotesThunk } from "../services/transactionApi"; const getReceiveTransactionAmount = async (noteId: string, noteIdFileBytes: string, webClient: any): Promise => { @@ -20,7 +21,8 @@ const getReceiveTransactionAmount = async (noteId: string, noteIdFileBytes: stri if (!inputNoteRecord) { if (noteIdFileBytes) { const noteBytes = Uint8Array.fromBase64(noteIdFileBytes); - await webClient.importNoteFile(noteBytes); + const noteFile = NoteFile.deserialize(noteBytes); + await webClient.importNoteFile(noteFile); inputNoteRecord = await webClient.getInputNote(noteId); } else { console.error("No note file bytes to import"); diff --git a/bin/coordinator-frontend/src/types/hooks.ts b/bin/coordinator-frontend/src/types/hooks.ts index d5564c6..9a100f5 100644 --- a/bin/coordinator-frontend/src/types/hooks.ts +++ b/bin/coordinator-frontend/src/types/hooks.ts @@ -92,14 +92,6 @@ export interface MidenSdkContextState { isLoading: boolean; Miden: typeof MidenSDK | null; createClient: () => Promise; - createFaucet: ( - client: MidenClient, - storageMode: StorageMode, - nonFungible: boolean, - assetSymbol: string, - decimals: number, - totalSupply: bigint - ) => Promise; } // Miden SDK class type diff --git a/bin/coordinator-server/src/routes.rs b/bin/coordinator-server/src/routes.rs index 9fda75e..ad692ad 100644 --- a/bin/coordinator-server/src/routes.rs +++ b/bin/coordinator-server/src/routes.rs @@ -3,7 +3,8 @@ use itertools::Itertools; use miden_client::{ Word, account::AccountId, - address::{Address, AddressId}, + address::{Address, AddressId, NetworkId}, + auth::Signature, utils::{Deserializable, Serializable}, }; use miden_multisig_coordinator_engine::{ @@ -66,22 +67,14 @@ pub async fn create_multisig_account( let approvers = approvers .iter() .map(AsRef::as_ref) - .map(Address::decode) - .map(|res| { - res.map_err(|e| AppError::other(format!("failed to decode address: {e}"))) - }) - .map_ok(|(network_id, address)| { + .map(decode_account_address) + .map_ok(|(network_id, account_id)| { engine_network_id .eq(&network_id) - .then_some(address) + .then_some(account_id) .ok_or(AppError::InvalidNetworkId) }) .map(Result::flatten) - .map_ok(|a| match a.id() { - AddressId::AccountId(id) => Ok(id), - _ => Err(AppError::other("approver address must be account id")), - }) - .map(Result::flatten) .try_collect() .inspect_err(|e| tracing::error!("failed to decode approvers: {e}"))?; @@ -125,13 +118,11 @@ pub async fn propose_multisig_tx( ) -> Result, AppError> { let AppDissolved { engine } = app.dissolve(); - let ProposeMultisigTxRequestPayloadDissolved { - multisig_account_address: address, - tx_request, - } = payload.dissolve(); + let ProposeMultisigTxRequestPayloadDissolved { multisig_account_address, tx_request } = + payload.dissolve(); let request = { - let account_id_address = AccountId::from_bech32(&address) + let account_id = decode_account_address(&multisig_account_address) .map(|(network_id, account_id)| { engine.network_id().eq(&network_id).then_some(account_id) })? @@ -141,7 +132,7 @@ pub async fn propose_multisig_tx( .map_err(|_| AppError::InvalidTransactionRequest)?; ProposeMultisigTxRequest::builder() - .multisig_account_id(account_id_address) + .multisig_account_id(account_id) .tx_request(tx_request) .build() }; @@ -167,14 +158,17 @@ pub async fn add_signature( let AddSignatureRequestPayloadDissolved { tx_id, approver, signature } = payload.dissolve(); let request = { - let approver = AccountId::from_bech32(&approver) + let approver = decode_account_address(&approver) .map(|(network_id, account_id)| { engine.network_id().eq(&network_id).then_some(account_id) })? .ok_or(AppError::InvalidNetworkId)?; - let signature = - Deserializable::read_from_bytes(&signature).map_err(|_| AppError::InvalidSignature)?; + let Signature::RpoFalcon512(signature) = + Signature::read_from_bytes(&signature).map_err(|_| AppError::InvalidSignature)? + else { + return Err(AppError::InvalidSignature); + }; AddSignatureRequest::builder() .tx_id(tx_id.into()) @@ -201,7 +195,7 @@ pub async fn list_consumable_notes( let account_id = address .as_deref() - .map(AccountId::from_bech32) + .map(decode_account_address) .transpose()? .map(|(network_id, account_id)| { engine @@ -236,7 +230,7 @@ pub async fn get_multisig_account_details( let GetMultisigAccountDetailsRequestPayloadDissolved { multisig_account_address } = payload.dissolve(); - let multisig_account_id = AccountId::from_bech32(&multisig_account_address) + let multisig_account_id = decode_account_address(&multisig_account_address) .map(|(network_id, account_id)| engine.network_id().eq(&network_id).then_some(account_id))? .ok_or(AppError::InvalidNetworkId)?; @@ -266,7 +260,7 @@ pub async fn list_multisig_approvers( let ListMultisigApproverRequestPayloadDissolved { multisig_account_address } = payload.dissolve(); - let multisig_account_id = AccountId::from_bech32(&multisig_account_address) + let multisig_account_id = decode_account_address(&multisig_account_address) .map(|(network_id, account_id)| engine.network_id().eq(&network_id).then_some(account_id))? .ok_or(AppError::InvalidNetworkId)?; @@ -292,7 +286,7 @@ pub async fn get_multisig_tx_stats( let GetMultisigTxStatsRequestPayloadDissolved { multisig_account_address } = payload.dissolve(); - let multisig_account_id = AccountId::from_bech32(&multisig_account_address) + let multisig_account_id = decode_account_address(&multisig_account_address) .map(|(network_id, account_id)| engine.network_id().eq(&network_id).then_some(account_id))? .ok_or(AppError::InvalidNetworkId)?; @@ -320,7 +314,7 @@ pub async fn list_multisig_tx( tx_status_filter, } = payload.dissolve(); - let multisig_account_id = AccountId::from_bech32(&multisig_account_address) + let multisig_account_id = decode_account_address(&multisig_account_address) .map(|(network_id, account_id)| engine.network_id().eq(&network_id).then_some(account_id))? .ok_or(AppError::InvalidNetworkId)?; @@ -344,3 +338,13 @@ pub async fn list_multisig_tx( Ok(Json(response)) } + +fn decode_account_address(address: &str) -> Result<(NetworkId, AccountId), AppError> { + let (network_id, address) = Address::decode(address) + .map_err(|e| AppError::other(format!("failed to decode address: {e}")))?; + + match address.id() { + AddressId::AccountId(account_id) => Ok((network_id, account_id)), + _ => Err(AppError::other("address must be account id")), + } +} From dbb56c5f9108bded93a949c5628343606c24f6fa Mon Sep 17 00:00:00 2001 From: hubcycle Date: Sat, 29 Nov 2025 10:53:46 +0000 Subject: [PATCH 6/8] fix: delete miden client web store index db when initialization fails --- bin/coordinator-frontend/lib/miden-client.ts | 57 ++++++++++++++++++- .../src/contexts/MidenClientContext.tsx | 11 +++- 2 files changed, 64 insertions(+), 4 deletions(-) diff --git a/bin/coordinator-frontend/lib/miden-client.ts b/bin/coordinator-frontend/lib/miden-client.ts index c81fb53..2a78960 100644 --- a/bin/coordinator-frontend/lib/miden-client.ts +++ b/bin/coordinator-frontend/lib/miden-client.ts @@ -21,7 +21,62 @@ export class MidenWebClientHandle { console.log("Initializing Miden Web Client..."); const nodeEndpoint = process.env.NEXT_PUBLIC_MIDEN_NODE_ENDPOINT || "https://rpc.testnet.miden.io:443"; console.log(`Using Miden node endpoint: ${nodeEndpoint}`); - this.webClient = await WebClient.createClient(nodeEndpoint); + + try { + this.webClient = await WebClient.createClient(nodeEndpoint); + } catch (error: any) { + console.error("Error creating Miden client:", error); + + // Check for specific IndexedDB upgrade error or generic WebStore initialization failure + // The SDK might wrap the underlying DB error into "Failed to initialize WebStore" + if (error?.message?.includes("UpgradeError") || + error?.message?.includes("Not yet support for changing primary key") || + error?.message?.includes("Failed to initialize WebStore") || + error?.toString().includes("Failed to initialize WebStore")) { + console.warn("Database schema mismatch or init failure detected. Attempting to clear database..."); + + const DB_NAME = "MidenClientDB"; + + try { + await new Promise((resolve, reject) => { + const req = indexedDB.deleteDatabase(DB_NAME); + + // Add a timeout to prevent hanging + const timeoutId = setTimeout(() => { + reject(new Error("Database deletion timed out. Please close other tabs and reload.")); + }, 5000); + + req.onsuccess = () => { + clearTimeout(timeoutId); + console.log(`Successfully deleted database: ${DB_NAME}`); + resolve(); + }; + + req.onerror = () => { + clearTimeout(timeoutId); + console.error(`Failed to delete database: ${DB_NAME}`); + reject(req.error); + }; + + req.onblocked = () => { + console.warn(`Database deletion blocked: ${DB_NAME}. Please close other tabs using this app.`); + // We don't reject immediately on blocked, as it might unblock if user closes tabs, + // but the timeout will catch it if it takes too long. + }; + }); + + // Retry initialization + console.log("Retrying initialization after database cleanup..."); + this.webClient = await WebClient.createClient(nodeEndpoint); + } catch (cleanupError) { + console.error("Failed to recover from database error:", cleanupError); + throw cleanupError; // Re-throw to be caught by outer catch + } + } else { + throw error; + } + } + console.log("Miden Web Client initialized successfully!"); return true; diff --git a/bin/coordinator-frontend/src/contexts/MidenClientContext.tsx b/bin/coordinator-frontend/src/contexts/MidenClientContext.tsx index ce869e7..49ac9c1 100644 --- a/bin/coordinator-frontend/src/contexts/MidenClientContext.tsx +++ b/bin/coordinator-frontend/src/contexts/MidenClientContext.tsx @@ -21,21 +21,24 @@ export function MidenClientProvider({ children }: { children: ReactNode }) { const [isInitialized, setIsInitialized] = useState(false); const [error, setError] = useState(null); + const initializationRef = React.useRef(false); + const reinitialize = async () => { - if (isRunning || isInitialized) { + if (initializationRef.current || isRunning || isInitialized) { console.info('MidenClient: Initialization skipped (already running or complete)'); return; } console.info('MidenClient: Starting initialization'); + initializationRef.current = true; setIsRunning(true); setStatus('Initializing Miden client...'); setError(null); - + try { const newHandle = new MidenWebClientHandle(); setHandle(newHandle); - + const success = await newHandle.initialize(); if (success) { console.info('MidenClient: Initialized successfully'); @@ -46,6 +49,7 @@ export function MidenClientProvider({ children }: { children: ReactNode }) { setStatus('Failed to initialize Miden client'); setIsInitialized(false); setError('Initialization failed'); + initializationRef.current = false; // Allow retry on failure } } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Unknown error'; @@ -53,6 +57,7 @@ export function MidenClientProvider({ children }: { children: ReactNode }) { setStatus(`Error: ${errorMessage}`); setIsInitialized(false); setError(errorMessage); + initializationRef.current = false; // Allow retry on error } finally { setIsRunning(false); } From 8bbb581bd17c8df23eaccf528aedf8d3513f82be Mon Sep 17 00:00:00 2001 From: hubcycle Date: Sat, 29 Nov 2025 11:07:31 +0000 Subject: [PATCH 7/8] test: remove ruduntant block proving calls --- crates/test-utils/src/lib.rs | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/crates/test-utils/src/lib.rs b/crates/test-utils/src/lib.rs index 9925b95..35f07ac 100644 --- a/crates/test-utils/src/lib.rs +++ b/crates/test-utils/src/lib.rs @@ -105,15 +105,6 @@ async fn create_prebuilt_mock_chain() -> MockChain { // Block 1 mock_chain.prove_next_block().unwrap(); - // Block 2 - mock_chain.prove_next_block().unwrap(); - - // Block 3 - mock_chain.prove_next_block().unwrap(); - - // Block 4 - mock_chain.prove_next_block().unwrap(); - let transaction = Box::pin( mock_chain .build_tx_context(mock_account, &[note_second.id()], &[]) @@ -125,7 +116,7 @@ async fn create_prebuilt_mock_chain() -> MockChain { .await .unwrap(); - // Block 5: Consume (nullify) second note + // Block 2: Consume (nullify) second note mock_chain.add_pending_executed_transaction(&transaction).unwrap(); mock_chain.prove_next_block().unwrap(); From d5913a6989ebf77c2d89c8d13a2239ce16727d9c Mon Sep 17 00:00:00 2001 From: rotorship Date: Tue, 2 Dec 2025 05:34:33 +0000 Subject: [PATCH 8/8] chore: add rust-toolchain --- Cargo.lock | 104 ++++++++++++++++++++++---------------------- rust-toolchain.toml | 4 ++ 2 files changed, 56 insertions(+), 52 deletions(-) create mode 100644 rust-toolchain.toml diff --git a/Cargo.lock b/Cargo.lock index eea22c7..c308da5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -482,9 +482,9 @@ checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "cc" -version = "1.2.47" +version = "1.2.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07" +checksum = "c481bdbf0ed3b892f6f806287d72acd515b352a4ec27a208489b8c1bc839633a" dependencies = [ "find-msvc-tools", "jobserver", @@ -1852,9 +1852,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.82" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", @@ -2148,9 +2148,9 @@ dependencies = [ [[package]] name = "miden-block-prover" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abd33a60630977df766a901e9c89342e1632673071e13fb5711410a25610aa3e" +checksum = "ec766587e838664ded55fa926d0611244cac2fe23b7cec202d8db0a85d9e536e" dependencies = [ "miden-lib", "miden-objects", @@ -2302,9 +2302,9 @@ dependencies = [ [[package]] name = "miden-lib" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "015992e9a31a4a2667adf2ee795d5f02927a6e9f4e21490ce02fb6395eb6bd41" +checksum = "598582071e5b0ec835d06288857d4ddc0090a98bd4c17e408fa56b2c43f45d73" dependencies = [ "Inflector", "fs-err", @@ -2486,9 +2486,9 @@ dependencies = [ [[package]] name = "miden-node-proto-build" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f083bf3a275076f207fa36d4e247c1554e7310c9b85c245b2fc5fbb69934f437" +checksum = "ec8059a6beaabf87cc58c24a9c51d01fbd6d9b46edc2522125442962ce279ec2" dependencies = [ "fs-err", "miette", @@ -2510,9 +2510,9 @@ dependencies = [ [[package]] name = "miden-objects" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57ea15ca33d7735e08e81afd9c9f4f02fc0259ec019fcb4ec44192c205743553" +checksum = "ace4018bb2d6cdbcff4d86d8af5ade8efca9f0479f7e5775c7f09cfab5f91ebe" dependencies = [ "bech32", "getrandom 0.3.4", @@ -2570,9 +2570,9 @@ dependencies = [ [[package]] name = "miden-remote-prover-client" -version = "0.12.3" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23a02c8c0a548982dc7871df53df6c703119d47c6a3c746604de2979bcff4b42" +checksum = "b319ea63a16a95c04ed16b1626fb9eae581acc79c46050ba231e4d8cb9b06aae" dependencies = [ "getrandom 0.3.4", "miden-node-proto-build", @@ -2606,9 +2606,9 @@ dependencies = [ [[package]] name = "miden-testing" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8107f897f415813a85677f49a9b4470d0562b13ada3d0bbaaa161e53a4a665d0" +checksum = "cda0d572d7415682ed168f616becf006825aa04b89692f9907cbb3e3586bf46a" dependencies = [ "anyhow", "itertools", @@ -2626,9 +2626,9 @@ dependencies = [ [[package]] name = "miden-tx" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94f5295f8646bc84829ebda923448aebffa2a36f88ef2112b7b4538901e1b34b" +checksum = "2d959064f99ce09fc38e9b6b4dc24c3fa80a63072bf5840a1074ca4ed5e9c911" dependencies = [ "miden-lib", "miden-objects", @@ -2642,9 +2642,9 @@ dependencies = [ [[package]] name = "miden-tx-batch-prover" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b4a7e1a2a2fd9224f5048b69181c1aaaad796b671efa4fdda2bae5c76ad83e6" +checksum = "f5029810b106654a1ec5d7d7123945db91b96bc4f4187715d0c2cfe0b0a53af4" dependencies = [ "miden-objects", "miden-tx", @@ -3358,9 +3358,9 @@ dependencies = [ [[package]] name = "prost-reflect" -version = "0.16.2" +version = "0.16.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89a3ac73ec9a9118131a4594c9d336631a07852220a1d0ae03ee36b04503a063" +checksum = "b89455ef41ed200cafc47c76c552ee7792370ac420497e551f16123a9135f76e" dependencies = [ "logos 0.15.1", "miette", @@ -3410,7 +3410,7 @@ dependencies = [ "bytes", "miette", "prost 0.14.1", - "prost-reflect 0.16.2", + "prost-reflect 0.16.3", "prost-types 0.14.1", "protox-parse 0.9.0", "thiserror 2.0.17", @@ -3774,9 +3774,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94182ad936a0c91c324cd46c6511b9510ed16af436d7b5bab34beab0afd55f7a" +checksum = "708c0f9d5f54ba0272468c1d306a52c495b31fa155e91bc25371e6df7996908c" dependencies = [ "zeroize", ] @@ -4017,9 +4017,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.16.0" +version = "3.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10574371d41b0d9b2cff89418eda27da52bcaff2cc8741db26382a77c29131f1" +checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" dependencies = [ "base64 0.22.1", "chrono", @@ -4036,9 +4036,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.16.0" +version = "3.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08a72d8216842fdd57820dc78d840bef99248e35fb2554ff923319e60f2d686b" +checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" dependencies = [ "darling", "proc-macro2", @@ -4828,9 +4828,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.41" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" dependencies = [ "log", "pin-project-lite", @@ -4872,9 +4872,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.20" +version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ "matchers", "nu-ansi-term", @@ -5071,13 +5071,13 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.18.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ "getrandom 0.3.4", "js-sys", - "serde", + "serde_core", "wasm-bindgen", ] @@ -5150,9 +5150,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", @@ -5163,9 +5163,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.55" +version = "0.4.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0" +checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" dependencies = [ "cfg-if", "js-sys", @@ -5176,9 +5176,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5186,9 +5186,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ "bumpalo", "proc-macro2", @@ -5199,9 +5199,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.105" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] @@ -5221,9 +5221,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.82" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" +checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" dependencies = [ "js-sys", "wasm-bindgen", @@ -5860,18 +5860,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.30" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea879c944afe8a2b25fef16bb4ba234f47c694565e97383b36f3a878219065c" +checksum = "fd74ec98b9250adb3ca554bdde269adf631549f51d8a8f8f0a10b50f1cb298c3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.30" +version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf955aa904d6040f70dc8e9384444cb1030aed272ba3cb09bbc4ab9e7c1f34f5" +checksum = "d8a8d209fdf45cf5138cbb5a506f6b52522a25afccc534d1475dad8e31105c6a" dependencies = [ "proc-macro2", "quote", diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..3ce6eaf --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,4 @@ +[toolchain] +channel = "1.90" +components = ["clippy", "rust-src", "rustfmt"] +profile = "minimal"