diff --git a/Cargo.lock b/Cargo.lock index 23e554f25..ca7c4c005 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,9 +4,9 @@ version = 4 [[package]] name = "ab_glyph" -version = "0.2.31" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e074464580a518d16a7126262fffaaa47af89d4099d4cb403f8ed938ba12ee7d" +checksum = "01c0457472c38ea5bd1c3b5ada5e368271cb550be7a4ca4a0b4634e9913f6cc2" dependencies = [ "ab_glyph_rasterizer", "owned_ttf_parser", @@ -94,8 +94,8 @@ dependencies = [ "accesskit_consumer", "hashbrown 0.15.5", "static_assertions", - "windows", - "windows-core", + "windows 0.61.3", + "windows-core 0.61.2", ] [[package]] @@ -112,15 +112,6 @@ dependencies = [ "winit", ] -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - [[package]] name = "adler2" version = "2.0.1" @@ -134,7 +125,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ "crypto-common", - "generic-array 0.14.7", + "generic-array 0.14.9", ] [[package]] @@ -169,7 +160,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" dependencies = [ "cfg-if", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", "serde", "version_check", @@ -198,7 +189,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef6978589202a00cd7e118380c448a08b6ed394c3a8df3a430d0898e3a42d046" dependencies = [ "android-properties", - "bitflags 2.9.1", + "bitflags 2.10.0", "cc", "cesu8", "jni", @@ -207,8 +198,8 @@ dependencies = [ "log", "ndk", "ndk-context", - "ndk-sys", - "num_enum 0.7.4", + "ndk-sys 0.6.0+11769913", + "num_enum 0.7.5", "thiserror 1.0.69", ] @@ -218,12 +209,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -235,9 +220,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.20" +version = "0.6.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" +checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a" dependencies = [ "anstyle", "anstyle-parse", @@ -250,9 +235,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.11" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" +checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" [[package]] name = "anstyle-parse" @@ -285,36 +270,36 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.99" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" dependencies = [ "derive_arbitrary", ] [[package]] name = "arboard" -version = "3.6.0" +version = "3.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55f533f8e0af236ffe5eb979b99381df3258853f00ba2e44b6e1955292c75227" +checksum = "0348a1c054491f4bfe6ab86a7b6ab1e44e45d899005de92f58b3df180b36ddaf" dependencies = [ "clipboard-win", "image", "log", - "objc2 0.6.1", - "objc2-app-kit 0.3.1", + "objc2 0.6.3", + "objc2-app-kit 0.3.2", "objc2-core-foundation", "objc2-core-graphics", - "objc2-foundation 0.3.1", + "objc2-foundation 0.3.2", "parking_lot", "percent-encoding", - "windows-sys 0.59.0", + "windows-sys 0.60.2", "x11rb", ] @@ -360,6 +345,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16" +[[package]] +name = "ash" +version = "0.38.0+1.3.281" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" +dependencies = [ + "libloading", +] + [[package]] name = "ashpd" version = "0.10.3" @@ -437,9 +431,9 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.13.2" +version = "1.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb812ffb58524bdd10860d7d974e2f01cc0950c2438a74ee5ec2e2280c6c4ffa" +checksum = "497c00e0fd83a72a79a39fcbd8e3e2f055d6f6c7e025f3b3d91f4f8e76527fb8" dependencies = [ "async-task", "concurrent-queue", @@ -451,9 +445,9 @@ dependencies = [ [[package]] name = "async-fs" -version = "2.1.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f7e37c0ed80b2a977691c47dae8625cfb21e205827106c64f7c588766b2e50" +checksum = "8034a681df4aed8b8edbd7fbe472401ecf009251c8b40556b304567052e294c5" dependencies = [ "async-lock", "blocking", @@ -477,20 +471,20 @@ dependencies = [ [[package]] name = "async-io" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19634d6336019ef220f09fd31168ce5c184b295cbf80345437cc36094ef223ca" +checksum = "456b8a8feb6f42d237746d4b3e9a178494627745c3c56c6ea55d92ba50d026fc" dependencies = [ - "async-lock", + "autocfg", "cfg-if", "concurrent-queue", "futures-io", "futures-lite", "parking", "polling", - "rustix 1.0.8", + "rustix 1.1.2", "slab", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -517,9 +511,9 @@ dependencies = [ [[package]] name = "async-process" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65daa13722ad51e6ab1a1b9c01299142bc75135b337923cfa10e79bbbd669f00" +checksum = "fc50921ec0055cdd8a16de48773bfeec5c972598674347252c0399676be7da75" dependencies = [ "async-channel 2.5.0", "async-io", @@ -530,7 +524,7 @@ dependencies = [ "cfg-if", "event-listener 5.4.1", "futures-lite", - "rustix 1.0.8", + "rustix 1.1.2", ] [[package]] @@ -541,14 +535,14 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] name = "async-signal" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f567af260ef69e1d52c2b560ce0ea230763e6fbb9214a85d768760a920e3e3c1" +checksum = "43c070bbf59cd3570b6b2dd54cd772527c7c3620fce8be898406dd3ed6adc64c" dependencies = [ "async-io", "async-lock", @@ -556,17 +550,17 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 1.0.8", + "rustix 1.1.2", "signal-hook-registry", "slab", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "async-std" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "730294c1c08c2e0f85759590518f6333f0d5a0a766a27d519c1b244c3dfd8a24" +checksum = "2c8e079a4ab67ae52b7403632e4618815d6db36d2a010cfe41b02c1b1578f93b" dependencies = [ "async-channel 1.9.0", "async-global-executor", @@ -596,13 +590,13 @@ checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.88" +version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -682,29 +676,14 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "backon" -version = "1.5.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "592277618714fbcecda9a02ba7a8781f319d26532a88553bbacc77ba5d2b3a8d" +checksum = "cffb0e931875b666fc4fcb20fee52e9bbd1ef836fd9e9e04ec21555f9f85f7ef" dependencies = [ "fastrand", "tokio", ] -[[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - [[package]] name = "base16ct" version = "0.2.0" @@ -754,6 +733,15 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bincode" version = "2.0.0-rc.3" @@ -773,6 +761,29 @@ dependencies = [ "virtue 0.0.13", ] +[[package]] +name = "bindgen" +version = "0.65.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5" +dependencies = [ + "bitflags 1.3.2", + "cexpr", + "clang-sys", + "lazy_static", + "lazycell", + "log", + "peeking_take_while", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash 1.1.0", + "shlex", + "syn 2.0.108", + "which 4.4.2", +] + [[package]] name = "bip37-bloom-filter" version = "0.1.0" @@ -873,11 +884,11 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.1" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -914,13 +925,19 @@ dependencies = [ "constant_time_eq", ] +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + [[package]] name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.7", + "generic-array 0.14.9", ] [[package]] @@ -934,11 +951,11 @@ dependencies = [ [[package]] name = "block2" -version = "0.6.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "340d2f0bdb2a43c1d3cd40513185b2bd7def0aa1052f956455114bc98f82dcf2" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" dependencies = [ - "objc2 0.6.1", + "objc2 0.6.3", ] [[package]] @@ -956,8 +973,8 @@ dependencies = [ [[package]] name = "blsful" -version = "3.0.0-pre8" -source = "git+https://github.com/dashpay/agora-blsful?rev=be108b2cf6ac64eedbe04f91c63731533c8956bc#be108b2cf6ac64eedbe04f91c63731533c8956bc" +version = "3.0.0" +source = "git+https://github.com/dashpay/agora-blsful?rev=0c34a7a488a0bd1c9a9a2196e793b303ad35c900#0c34a7a488a0bd1c9a9a2196e793b303ad35c900" dependencies = [ "anyhow", "blstrs_plus", @@ -973,7 +990,7 @@ dependencies = [ "sha2", "sha3", "subtle", - "thiserror 2.0.14", + "thiserror 2.0.17", "uint-zigzag", "vsss-rs", "zeroize", @@ -1026,22 +1043,22 @@ checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "bytemuck" -version = "1.23.2" +version = "1.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3995eaeebcdf32f91f980d360f78732ddc061097ab4e39991ae7a6ace9194677" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" dependencies = [ "bytemuck_derive", ] [[package]] name = "bytemuck_derive" -version = "1.10.1" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f154e572231cb6ba2bd1176980827e3d5dc04cc183a75dea38109fbdd672d29" +checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -1071,7 +1088,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b99da2f8558ca23c71f4fd15dc57c906239752dd27ff3c00a1d56b685b7cbfec" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "log", "polling", "rustix 0.38.44", @@ -1093,10 +1110,11 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.32" +version = "1.2.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2352e5597e9c544d5e6d9c95190d5d27738ade584fa8db0a16e130e5c2b5296e" +checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" dependencies = [ + "find-msvc-tools", "jobserver", "libc", "shlex", @@ -1108,6 +1126,15 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom 7.1.3", +] + [[package]] name = "cfg-expr" version = "0.15.8" @@ -1120,9 +1147,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.1" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -1141,17 +1168,16 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-link", + "windows-link 0.2.1", ] [[package]] @@ -1222,6 +1248,57 @@ dependencies = [ "inout", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + +[[package]] +name = "clap" +version = "4.5.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c2cfd7bf8a6017ddaa4e32ffe7403d547790db06bd171c1c53926faab501623" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4c05b9e80c5ccd3a7ef080ad7b6ba7d6fc00a985b8b157197075677c82c7a0" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0b5487afeab2deb2ff4e03a807ad1a03ac532ff5a2cee5d86884440c7f7671" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.108", +] + +[[package]] +name = "clap_lex" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" + [[package]] name = "clipboard-win" version = "5.4.1" @@ -1356,6 +1433,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + [[package]] name = "crossbeam" version = "0.8.4" @@ -1412,6 +1495,31 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" +[[package]] +name = "crossterm" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" +dependencies = [ + "bitflags 2.10.0", + "crossterm_winapi", + "libc", + "mio 0.8.11", + "parking_lot", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + [[package]] name = "crunchy" version = "0.2.4" @@ -1424,7 +1532,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ - "generic-array 0.14.7", + "generic-array 0.14.9", "rand_core 0.6.4", "serdect", "subtle", @@ -1437,7 +1545,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.7", + "generic-array 0.14.9", "rand_core 0.6.4", "typenum", ] @@ -1481,13 +1589,13 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] name = "dapi-grpc" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "dapi-grpc-macros", "futures-core", @@ -1505,12 +1613,12 @@ dependencies = [ [[package]] name = "dapi-grpc-macros" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "heck", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -1524,7 +1632,7 @@ dependencies = [ "objc2 0.5.2", "objc2-foundation 0.2.2", "web-sys", - "winreg", + "winreg 0.52.0", ] [[package]] @@ -1548,7 +1656,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -1559,13 +1667,13 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] name = "dash-context-provider" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "dpp", "drive", @@ -1583,9 +1691,9 @@ dependencies = [ "arboard", "argon2", "base64 0.22.1", - "bincode", + "bincode 2.0.0-rc.3", "bip39", - "bitflags 2.9.1", + "bitflags 2.10.0", "chrono", "chrono-humanize", "crossbeam-channel", @@ -1621,7 +1729,7 @@ dependencies = [ "serde_yaml", "sha2", "tempfile", - "thiserror 2.0.14", + "thiserror 2.0.17", "tokio", "tokio-util", "tracing", @@ -1637,9 +1745,9 @@ dependencies = [ [[package]] name = "dash-network" version = "0.40.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=befd0356bebfcd0d06d1028d8a03bfa4c78bd219#befd0356bebfcd0d06d1028d8a03bfa4c78bd219" +source = "git+https://github.com/dashpay/rust-dashcore?tag=v0.40.0#c877c1a74d145e2003d549619698511513db925c" dependencies = [ - "bincode", + "bincode 2.0.0-rc.3", "bincode_derive", "hex", "serde", @@ -1647,8 +1755,8 @@ dependencies = [ [[package]] name = "dash-sdk" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "arc-swap", "async-trait", @@ -1674,22 +1782,50 @@ dependencies = [ "rustls-pemfile", "serde", "serde_json", - "thiserror 2.0.14", + "thiserror 2.0.17", "tokio", "tokio-util", "tracing", "zeroize", ] +[[package]] +name = "dash-spv" +version = "0.40.0" +source = "git+https://github.com/dashpay/rust-dashcore?tag=v0.40.0#c877c1a74d145e2003d549619698511513db925c" +dependencies = [ + "anyhow", + "async-trait", + "bincode 1.3.3", + "blsful", + "clap", + "crossterm", + "dashcore", + "dashcore_hashes", + "hex", + "hickory-resolver", + "indexmap 2.12.0", + "key-wallet", + "key-wallet-manager", + "log", + "rand 0.8.5", + "serde", + "serde_json", + "thiserror 1.0.69", + "tokio", + "tracing", + "tracing-subscriber", +] + [[package]] name = "dashcore" version = "0.40.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=befd0356bebfcd0d06d1028d8a03bfa4c78bd219#befd0356bebfcd0d06d1028d8a03bfa4c78bd219" +source = "git+https://github.com/dashpay/rust-dashcore?tag=v0.40.0#c877c1a74d145e2003d549619698511513db925c" dependencies = [ "anyhow", "base64-compat", "bech32", - "bincode", + "bincode 2.0.0-rc.3", "bincode_derive", "bitvec", "blake3", @@ -1704,18 +1840,18 @@ dependencies = [ "rustversion", "secp256k1", "serde", - "thiserror 2.0.14", + "thiserror 2.0.17", ] [[package]] name = "dashcore-private" version = "0.40.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=befd0356bebfcd0d06d1028d8a03bfa4c78bd219#befd0356bebfcd0d06d1028d8a03bfa4c78bd219" +source = "git+https://github.com/dashpay/rust-dashcore?tag=v0.40.0#c877c1a74d145e2003d549619698511513db925c" [[package]] name = "dashcore-rpc" version = "0.40.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=befd0356bebfcd0d06d1028d8a03bfa4c78bd219#befd0356bebfcd0d06d1028d8a03bfa4c78bd219" +source = "git+https://github.com/dashpay/rust-dashcore?tag=v0.40.0#c877c1a74d145e2003d549619698511513db925c" dependencies = [ "dashcore-rpc-json", "hex", @@ -1728,9 +1864,9 @@ dependencies = [ [[package]] name = "dashcore-rpc-json" version = "0.40.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=befd0356bebfcd0d06d1028d8a03bfa4c78bd219#befd0356bebfcd0d06d1028d8a03bfa4c78bd219" +source = "git+https://github.com/dashpay/rust-dashcore?tag=v0.40.0#c877c1a74d145e2003d549619698511513db925c" dependencies = [ - "bincode", + "bincode 2.0.0-rc.3", "dashcore", "hex", "key-wallet", @@ -1743,10 +1879,11 @@ dependencies = [ [[package]] name = "dashcore_hashes" version = "0.40.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=befd0356bebfcd0d06d1028d8a03bfa4c78bd219#befd0356bebfcd0d06d1028d8a03bfa4c78bd219" +source = "git+https://github.com/dashpay/rust-dashcore?tag=v0.40.0#c877c1a74d145e2003d549619698511513db925c" dependencies = [ - "bincode", + "bincode 2.0.0-rc.3", "dashcore-private", + "rs-x11-hash", "secp256k1", "serde", ] @@ -1766,19 +1903,19 @@ dependencies = [ [[package]] name = "dashpay-contract" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "platform-value", "platform-version", "serde_json", - "thiserror 2.0.14", + "thiserror 2.0.17", ] [[package]] name = "data-contracts" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "dashpay-contract", "dpns-contract", @@ -1788,12 +1925,18 @@ dependencies = [ "platform-value", "platform-version", "serde_json", - "thiserror 2.0.14", + "thiserror 2.0.17", "token-history-contract", "wallet-utils-contract", "withdrawals-contract", ] +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + [[package]] name = "der" version = "0.7.10" @@ -1806,23 +1949,23 @@ dependencies = [ [[package]] name = "deranged" -version = "0.4.0" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" +checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" dependencies = [ "powerfmt", - "serde", + "serde_core", ] [[package]] name = "derive_arbitrary" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" +checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -1843,7 +1986,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -1853,7 +1996,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -1882,7 +2025,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", "unicode-xid", ] @@ -1894,7 +2037,7 @@ checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -1946,7 +2089,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -1961,10 +2104,10 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" dependencies = [ - "bitflags 2.9.1", - "block2 0.6.1", + "bitflags 2.10.0", + "block2 0.6.2", "libc", - "objc2 0.6.1", + "objc2 0.6.3", ] [[package]] @@ -1975,7 +2118,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -2016,30 +2159,31 @@ checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" [[package]] name = "dpns-contract" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "platform-value", "platform-version", "serde_json", - "thiserror 2.0.14", + "thiserror 2.0.17", ] [[package]] name = "dpp" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "anyhow", "async-trait", "base64 0.22.1", - "bincode", + "bincode 2.0.0-rc.3", "bincode_derive", "bs58", "byteorder", "chrono", "chrono-tz", "ciborium", + "dash-spv", "dashcore", "dashcore-rpc", "data-contracts", @@ -2047,13 +2191,14 @@ dependencies = [ "env_logger", "getrandom 0.2.16", "hex", - "indexmap 2.10.0", + "indexmap 2.12.0", "integer-encoding", "itertools 0.13.0", "key-wallet", + "key-wallet-manager", "lazy_static", "nohash-hasher", - "num_enum 0.7.4", + "num_enum 0.7.5", "once_cell", "platform-serialization", "platform-serialization-derive", @@ -2067,16 +2212,16 @@ dependencies = [ "serde_repr", "sha2", "strum", - "thiserror 2.0.14", + "thiserror 2.0.17", "tracing", ] [[package]] name = "drive" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ - "bincode", + "bincode 2.0.0-rc.3", "byteorder", "derive_more 1.0.0", "dpp", @@ -2086,43 +2231,43 @@ dependencies = [ "grovedb-path", "grovedb-version", "hex", - "indexmap 2.10.0", + "indexmap 2.12.0", "integer-encoding", "nohash-hasher", "platform-version", "serde", "sqlparser", - "thiserror 2.0.14", + "thiserror 2.0.17", "tracing", ] [[package]] name = "drive-proof-verifier" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ - "bincode", + "bincode 2.0.0-rc.3", "dapi-grpc", "dash-context-provider", "derive_more 1.0.0", "dpp", "drive", "hex", - "indexmap 2.10.0", + "indexmap 2.12.0", "platform-serialization", "platform-serialization-derive", "serde", "serde_json", "tenderdash-abci", - "thiserror 2.0.14", + "thiserror 2.0.17", "tracing", ] [[package]] name = "ecolor" -version = "0.32.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a631732d995184114016fab22fc7e3faf73d6841c2d7650395fe251fbcd9285" +checksum = "94bdf37f8d5bd9aa7f753573fdda9cf7343afa73dd28d7bfe9593bd9798fc07e" dependencies = [ "bytemuck", "emath", @@ -2177,9 +2322,9 @@ dependencies = [ [[package]] name = "eframe" -version = "0.32.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c790ccfbb3dd556588342463454b2b2b13909e5fdce5bc2a1432a8aa69c8b7a" +checksum = "14d1c15e7bd136b309bd3487e6ffe5f668b354cd9768636a836dd738ac90eb0b" dependencies = [ "ahash", "bytemuck", @@ -2216,13 +2361,13 @@ dependencies = [ [[package]] name = "egui" -version = "0.32.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8470210c95a42cc985d9ffebfd5067eea55bdb1c3f7611484907db9639675e28" +checksum = "5d5d0306cd61ca75e29682926d71f2390160247f135965242e904a636f51c0dc" dependencies = [ "accesskit", "ahash", - "bitflags 2.9.1", + "bitflags 2.10.0", "emath", "epaint", "log", @@ -2236,9 +2381,9 @@ dependencies = [ [[package]] name = "egui-wgpu" -version = "0.32.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14de9942d8b9e99e2d830403c208ab1a6e052e925a7456a4f6f66d567d90de1d" +checksum = "c12eca13293f8eba27a32aaaa1c765bfbf31acd43e8d30d5881dcbe5e99ca0c7" dependencies = [ "ahash", "bytemuck", @@ -2256,9 +2401,9 @@ dependencies = [ [[package]] name = "egui-winit" -version = "0.32.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c490804a035cec9c826082894a3e1ecf4198accd3817deb10f7919108ebafab0" +checksum = "f95d0a91f9cb0dc2e732d49c2d521ac8948e1f0b758f306fb7b14d6f5db3927f" dependencies = [ "accesskit_winit", "ahash", @@ -2300,9 +2445,9 @@ dependencies = [ [[package]] name = "egui_extras" -version = "0.32.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f791a5937f518249016b276b3639ad2aa3824048b6f2161ec2b431ab325880a" +checksum = "dddbceddf39805fc6c62b1f7f9c05e23590b40844dc9ed89c6dc6dbc886e3e3b" dependencies = [ "ahash", "egui", @@ -2315,9 +2460,9 @@ dependencies = [ [[package]] name = "egui_glow" -version = "0.32.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d44f3fd4fdc5f960c9e9ef7327c26647edc3141abf96102980647129d49358e6" +checksum = "cc7037813341727937f9e22f78d912f3e29bc3c46e2f40a9e82bb51cbf5e4cfb" dependencies = [ "ahash", "bytemuck", @@ -2333,9 +2478,9 @@ dependencies = [ [[package]] name = "egui_kittest" -version = "0.32.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dacd0e777f0557aebde97346a8c534e76607ce1e4f4a6e10a82d95ec5d5bca8" +checksum = "5bb00f16e00af09092c117515246732adba4ca4649463bdbc2ab6114a2944765" dependencies = [ "eframe", "egui", @@ -2358,7 +2503,7 @@ dependencies = [ "crypto-bigint", "digest", "ff", - "generic-array 0.14.7", + "generic-array 0.14.9", "group", "hkdf", "pkcs8", @@ -2371,9 +2516,9 @@ dependencies = [ [[package]] name = "elliptic-curve-tools" -version = "0.1.2" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e48843edfbd0a370b3dd14cdbb4e446e9a8855311e6b2b57bf9a1fd1367bc317" +checksum = "1de2b6fae800f08032a6ea32995b52925b1d451bff9d445c8ab2932323277faf" dependencies = [ "elliptic-curve", "heapless", @@ -2385,9 +2530,9 @@ dependencies = [ [[package]] name = "emath" -version = "0.32.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45f057b141e7e46340c321400be74b793543b1b213036f0f989c35d35957c32e" +checksum = "45fd7bc25f769a3c198fe1cf183124bf4de3bd62ef7b4f1eaf6b08711a3af8db" dependencies = [ "bytemuck", "serde", @@ -2408,24 +2553,36 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" +[[package]] +name = "enum-as-inner" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.108", +] + [[package]] name = "enum-iterator" -version = "2.1.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c280b9e6b3ae19e152d8e31cf47f18389781e119d4013a2a2bb0180e5facc635" +checksum = "a4549325971814bda7a44061bf3fe7e487d447cba01e4220a4b454d630d7a016" dependencies = [ "enum-iterator-derive", ] [[package]] name = "enum-iterator-derive" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" +checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -2445,7 +2602,7 @@ checksum = "f282cfdfe92516eb26c2af8589c274c7c17681f5ecc03c18255fe741c6aa64eb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -2466,7 +2623,7 @@ checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -2477,14 +2634,14 @@ checksum = "2f9ed6b3789237c8a0c1c505af1c7eb2c560df6186f01b098c3a1064ea532f38" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] name = "env_filter" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" dependencies = [ "log", "regex", @@ -2520,9 +2677,9 @@ dependencies = [ [[package]] name = "epaint" -version = "0.32.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94cca02195f0552c17cabdc02f39aa9ab6fbd815dac60ab1cd3d5b0aa6f9551c" +checksum = "63adcea970b7a13094fe97a36ab9307c35a750f9e24bf00bb7ef3de573e0fddb" dependencies = [ "ab_glyph", "ahash", @@ -2539,9 +2696,9 @@ dependencies = [ [[package]] name = "epaint_default_fonts" -version = "0.32.0" +version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8495e11ed527dff39663b8c36b6c2b2799d7e4287fb90556e455d72eca0b4d3" +checksum = "1537accc50c9cab5a272c39300bdd0dd5dca210f6e5e8d70be048df9596e7ca2" [[package]] name = "equivalent" @@ -2551,12 +2708,12 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.13" +version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -2611,8 +2768,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "531e46835a22af56d1e3b66f04844bed63158bc094a628bec1d321d9b4c44bf2" dependencies = [ "bit-set 0.5.3", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", + "regex-automata", + "regex-syntax", ] [[package]] @@ -2621,6 +2778,26 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "fax" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05de7d48f37cd6730705cbca900770cab77a89f413d23e100ad7fad7795a0ab" +dependencies = [ + "fax_derive", +] + +[[package]] +name = "fax_derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0aca10fb742cb43f9e7bb8467c91aa9bcb8e3ffbc6a6f7389bb93ffc920577d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.108", +] + [[package]] name = "fdeflate" version = "0.3.7" @@ -2632,13 +2809,13 @@ dependencies = [ [[package]] name = "feature-flags-contract" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "platform-value", "platform-version", "serde_json", - "thiserror 2.0.14", + "thiserror 2.0.17", ] [[package]] @@ -2658,6 +2835,12 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" +[[package]] +name = "find-msvc-tools" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" + [[package]] name = "fixedbitset" version = "0.5.7" @@ -2666,9 +2849,9 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9" dependencies = [ "crc32fast", "libz-rs-sys", @@ -2687,6 +2870,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 = "foreign-types" version = "0.3.2" @@ -2714,7 +2903,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -2731,9 +2920,9 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -2825,7 +3014,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -2860,9 +3049,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -2871,22 +3060,23 @@ dependencies = [ [[package]] name = "generic-array" -version = "1.2.0" +version = "1.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c8444bc9d71b935156cc0ccab7f622180808af7867b1daae6547d773591703" +checksum = "985a5578ebdb02351d484a77fb27e7cb79272f1ba9bc24692d8243c3cfe40660" dependencies = [ - "serde", + "rustversion", + "serde_core", "typenum", ] [[package]] name = "gethostname" -version = "0.4.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8" dependencies = [ - "libc", - "windows-targets 0.48.5", + "rustix 1.1.2", + "windows-link 0.2.1", ] [[package]] @@ -2898,20 +3088,20 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.1+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasip2", ] [[package]] @@ -2924,12 +3114,6 @@ dependencies = [ "polyval", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - [[package]] name = "gl_generator" version = "0.14.0" @@ -2977,7 +3161,7 @@ version = "0.32.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "12124de845cacfebedff80e877bb37b5b75c34c5a4c89e47e1cdd67fb6041325" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "cfg_aliases", "cgl", "dispatch2", @@ -2985,10 +3169,10 @@ dependencies = [ "glutin_glx_sys", "glutin_wgl_sys", "libloading", - "objc2 0.6.1", - "objc2-app-kit 0.3.1", + "objc2 0.6.3", + "objc2-app-kit 0.3.2", "objc2-core-foundation", - "objc2-foundation 0.3.1", + "objc2-foundation 0.3.2", "once_cell", "raw-window-handle", "wayland-sys", @@ -3038,67 +3222,122 @@ dependencies = [ ] [[package]] -name = "group" -version = "0.13.0" +name = "gpu-alloc" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +checksum = "fbcd2dba93594b227a1f57ee09b8b9da8892c34d55aa332e034a228d0fe6a171" dependencies = [ - "ff", - "rand 0.8.5", - "rand_core 0.6.4", - "rand_xorshift", - "subtle", + "bitflags 2.10.0", + "gpu-alloc-types", ] [[package]] -name = "grovedb" -version = "3.0.0" -source = "git+https://github.com/dashpay/grovedb?rev=1ecedf530fbc5b5e12edf1bc607bd288c187ddde#1ecedf530fbc5b5e12edf1bc607bd288c187ddde" +name = "gpu-alloc-types" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98ff03b468aa837d70984d55f5d3f846f6ec31fe34bbb97c4f85219caeee1ca4" dependencies = [ - "bincode", - "bincode_derive", - "blake3", - "grovedb-costs", - "grovedb-merk", - "grovedb-path", - "grovedb-version", - "hex", - "hex-literal", - "indexmap 2.10.0", - "integer-encoding", - "reqwest", - "sha2", - "thiserror 2.0.14", + "bitflags 2.10.0", ] [[package]] -name = "grovedb-costs" -version = "3.0.0" -source = "git+https://github.com/dashpay/grovedb?rev=1ecedf530fbc5b5e12edf1bc607bd288c187ddde#1ecedf530fbc5b5e12edf1bc607bd288c187ddde" +name = "gpu-allocator" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c151a2a5ef800297b4e79efa4f4bec035c5f51d5ae587287c9b952bdf734cacd" dependencies = [ - "integer-encoding", + "log", + "presser", + "thiserror 1.0.69", + "windows 0.58.0", +] + +[[package]] +name = "gpu-descriptor" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" +dependencies = [ + "bitflags 2.10.0", + "gpu-descriptor-types", + "hashbrown 0.15.5", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdf242682df893b86f33a73828fb09ca4b2d3bb6cc95249707fc684d27484b91" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand 0.8.5", + "rand_core 0.6.4", + "rand_xorshift", + "subtle", +] + +[[package]] +name = "grovedb" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12b2378c5eda5b7cadceb34fc6e0a8fd87fe03fc04841a7d32a74ff73ccef71" +dependencies = [ + "bincode 2.0.0-rc.3", + "bincode_derive", + "blake3", + "grovedb-costs", + "grovedb-merk", + "grovedb-path", + "grovedb-version", + "hex", + "hex-literal", + "indexmap 2.12.0", + "integer-encoding", + "reqwest", + "sha2", + "thiserror 2.0.17", +] + +[[package]] +name = "grovedb-costs" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e74fafe53bf5ae27128799856e557ef5cb2d7109f1f7bc7f4440bbd0f97c7072" +dependencies = [ + "integer-encoding", "intmap", - "thiserror 2.0.14", + "thiserror 2.0.17", ] [[package]] name = "grovedb-epoch-based-storage-flags" -version = "3.0.0" -source = "git+https://github.com/dashpay/grovedb?rev=1ecedf530fbc5b5e12edf1bc607bd288c187ddde#1ecedf530fbc5b5e12edf1bc607bd288c187ddde" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6bdc033cc229b17cd02ee9d5c5a5a344788ed0e69ad7468b0d34d94b021fc4" dependencies = [ "grovedb-costs", "hex", "integer-encoding", "intmap", - "thiserror 2.0.14", + "thiserror 2.0.17", ] [[package]] name = "grovedb-merk" -version = "3.0.0" -source = "git+https://github.com/dashpay/grovedb?rev=1ecedf530fbc5b5e12edf1bc607bd288c187ddde#1ecedf530fbc5b5e12edf1bc607bd288c187ddde" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6dd6f733e9d5c15c98e05b68a2028e00b7f177baa51e8d8c1541102942a72b7" dependencies = [ - "bincode", + "bincode 2.0.0-rc.3", "bincode_derive", "blake3", "byteorder", @@ -3108,32 +3347,35 @@ dependencies = [ "grovedb-version", "grovedb-visualize", "hex", - "indexmap 2.10.0", + "indexmap 2.12.0", "integer-encoding", - "thiserror 2.0.14", + "thiserror 2.0.17", ] [[package]] name = "grovedb-path" -version = "3.0.0" -source = "git+https://github.com/dashpay/grovedb?rev=1ecedf530fbc5b5e12edf1bc607bd288c187ddde#1ecedf530fbc5b5e12edf1bc607bd288c187ddde" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01f716520d6c6b0f25dc4a68bc7dded645826ed57d38a06a80716a487c09d23c" dependencies = [ "hex", ] [[package]] name = "grovedb-version" -version = "3.0.0" -source = "git+https://github.com/dashpay/grovedb?rev=1ecedf530fbc5b5e12edf1bc607bd288c187ddde#1ecedf530fbc5b5e12edf1bc607bd288c187ddde" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc855662f05f41b10dd022226cb78e345a33f35c390e25338d21dedd45966ae" dependencies = [ - "thiserror 2.0.14", + "thiserror 2.0.17", "versioned-feature-core 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "grovedb-visualize" -version = "3.0.0" -source = "git+https://github.com/dashpay/grovedb?rev=1ecedf530fbc5b5e12edf1bc607bd288c187ddde#1ecedf530fbc5b5e12edf1bc607bd288c187ddde" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34fa6f41c110d1d141bf912175f187ef51ac5d2a8f163dfd229be007461a548f" dependencies = [ "hex", "itertools 0.14.0", @@ -3151,7 +3393,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.10.0", + "indexmap 2.12.0", "slab", "tokio", "tokio-util", @@ -3160,13 +3402,14 @@ dependencies = [ [[package]] name = "half" -version = "2.6.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b" dependencies = [ "cfg-if", "crunchy", "num-traits", + "zerocopy", ] [[package]] @@ -3189,10 +3432,6 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", -] [[package]] name = "hashbrown" @@ -3202,7 +3441,16 @@ checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ "allocator-api2", "equivalent", - "foldhash", + "foldhash 0.1.5", +] + +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +dependencies = [ + "foldhash 0.2.0", ] [[package]] @@ -3278,6 +3526,52 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" +[[package]] +name = "hickory-proto" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna", + "ipnet", + "once_cell", + "rand 0.9.2", + "ring", + "thiserror 2.0.17", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "moka", + "once_cell", + "parking_lot", + "rand 0.9.2", + "resolv-conf", + "smallvec", + "thiserror 2.0.17", + "tokio", + "tracing", +] + [[package]] name = "hkdf" version = "0.12.4" @@ -3363,19 +3657,20 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "humantime" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b112acc8b3adf4b107a8ec20977da0273a8c386765a3ec0229bd500a1443f9f" +checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" [[package]] name = "hyper" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", + "futures-core", "h2", "http", "http-body", @@ -3383,6 +3678,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", + "pin-utils", "smallvec", "tokio", "want", @@ -3435,9 +3731,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" dependencies = [ "base64 0.22.1", "bytes", @@ -3451,7 +3747,7 @@ dependencies = [ "libc", "percent-encoding", "pin-project-lite", - "socket2", + "socket2 0.6.1", "system-configuration", "tokio", "tower-service", @@ -3461,9 +3757,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.63" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -3471,7 +3767,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core", + "windows-core 0.62.2", ] [[package]] @@ -3577,9 +3873,9 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -3598,12 +3894,13 @@ dependencies = [ [[package]] name = "image" -version = "0.25.6" +version = "0.25.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a" +checksum = "529feb3e6769d234375c4cf1ee2ce713682b8e76538cb13f9fc23e1400a591e7" dependencies = [ "bytemuck", "byteorder-lite", + "moxcms", "num-traits", "png", "tiff", @@ -3622,13 +3919,14 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.10.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" dependencies = [ "equivalent", - "hashbrown 0.15.5", + "hashbrown 0.16.0", "serde", + "serde_core", ] [[package]] @@ -3637,7 +3935,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" dependencies = [ - "generic-array 0.14.7", + "generic-array 0.14.9", ] [[package]] @@ -3656,14 +3954,15 @@ dependencies = [ ] [[package]] -name = "io-uring" -version = "0.7.9" +name = "ipconfig" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "bitflags 2.9.1", - "cfg-if", - "libc", + "socket2 0.5.10", + "widestring", + "windows-sys 0.48.0", + "winreg 0.50.0", ] [[package]] @@ -3684,9 +3983,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" @@ -3733,7 +4032,7 @@ checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -3760,25 +4059,19 @@ checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "libc", ] -[[package]] -name = "jpeg-decoder" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07" - [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" dependencies = [ "once_cell", "wasm-bindgen", @@ -3817,11 +4110,13 @@ dependencies = [ [[package]] name = "key-wallet" version = "0.40.0" -source = "git+https://github.com/dashpay/rust-dashcore?rev=befd0356bebfcd0d06d1028d8a03bfa4c78bd219#befd0356bebfcd0d06d1028d8a03bfa4c78bd219" +source = "git+https://github.com/dashpay/rust-dashcore?tag=v0.40.0#c877c1a74d145e2003d549619698511513db925c" dependencies = [ "base58ck", + "bincode 2.0.0-rc.3", + "bincode_derive", "bip39", - "bitflags 2.9.1", + "bitflags 2.10.0", "dash-network", "dashcore", "dashcore-private", @@ -3834,18 +4129,44 @@ dependencies = [ "serde", "serde_json", "sha2", + "tracing", + "zeroize", +] + +[[package]] +name = "key-wallet-manager" +version = "0.40.0" +source = "git+https://github.com/dashpay/rust-dashcore?tag=v0.40.0#c877c1a74d145e2003d549619698511513db925c" +dependencies = [ + "async-trait", + "bincode 2.0.0-rc.3", + "dashcore", + "dashcore_hashes", + "key-wallet", + "secp256k1", "zeroize", ] [[package]] name = "keyword-search-contract" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "platform-value", "platform-version", "serde_json", - "thiserror 2.0.14", + "thiserror 2.0.17", +] + +[[package]] +name = "khronos-egl" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aae1df220ece3c0ada96b8153459b67eebe9ae9212258bb0134ae60416fdf76" +dependencies = [ + "libc", + "libloading", + "pkg-config", ] [[package]] @@ -3880,6 +4201,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "lazycell" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" + [[package]] name = "lhash" version = "1.1.0" @@ -3888,18 +4215,18 @@ checksum = "744a4c881f502e98c2241d2e5f50040ac73b30194d64452bb6260393b53f0dc9" [[package]] name = "libc" -version = "0.2.175" +version = "0.2.177" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" +checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" [[package]] name = "libloading" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-targets 0.53.3", + "windows-link 0.2.1", ] [[package]] @@ -3910,13 +4237,13 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" [[package]] name = "libredox" -version = "0.1.9" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" +checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "libc", - "redox_syscall 0.5.17", + "redox_syscall 0.5.18", ] [[package]] @@ -3947,9 +4274,9 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "linux-raw-sys" -version = "0.9.4" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "litemap" @@ -3965,19 +4292,18 @@ checksum = "f5e54036fe321fd421e10d732f155734c4e4afd610dd556d9a82833ab3ee0bed" [[package]] name = "lock_api" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" dependencies = [ - "autocfg", "scopeguard", ] [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" dependencies = [ "value-bag", ] @@ -3991,37 +4317,46 @@ dependencies = [ "hashbrown 0.15.5", ] +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + [[package]] name = "masternode-reward-shares-contract" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "platform-value", "platform-version", "serde_json", - "thiserror 2.0.14", + "thiserror 2.0.17", ] [[package]] name = "matchers" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" dependencies = [ - "regex-automata 0.1.10", + "regex-automata", ] [[package]] name = "memchr" -version = "2.7.5" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "memmap2" -version = "0.9.7" +version = "0.9.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "483758ad303d734cec05e5c12b41d7e93e6a6390c5e9dae6bdeb7c1259012d28" +checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" dependencies = [ "libc", ] @@ -4047,6 +4382,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "metal" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f569fb946490b5743ad69813cb19629130ce9374034abe31614a36402d18f99e" +dependencies = [ + "bitflags 2.10.0", + "block", + "core-graphics-types", + "foreign-types 0.5.0", + "log", + "objc", + "paste", +] + [[package]] name = "mime" version = "0.3.17" @@ -4065,6 +4415,12 @@ dependencies = [ "unicase", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.9" @@ -4077,23 +4433,64 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.4" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "log", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "mio" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d83b0086dc8ecf3ce9ae2874b2d1290252e2a30720bea58a5c6639b0092873" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.61.2", +] + +[[package]] +name = "moka" +version = "0.12.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8261cd88c312e0004c1d51baad2980c66528dfdb2bee62003e643a4d8f86b077" +dependencies = [ + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "equivalent", + "parking_lot", + "portable-atomic", + "rustc_version", + "smallvec", + "tagptr", + "uuid", +] + +[[package]] +name = "moxcms" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c588e11a3082784af229e23e8e4ecf5bcc6fbe4f69101e0421ce8d79da7f0b40" +dependencies = [ + "num-traits", + "pxfm", ] [[package]] name = "multiexp" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a383da1ae933078ddb1e4141f1dd617b512b4183779d6977e6451b0e644806" +checksum = "7ec2ce93a6f06ac6cae04c1da3f2a6a24fcfc1f0eb0b4e0f3d302f0df45326cb" dependencies = [ "ff", "group", + "rand_core 0.6.4", "rustversion", "std-shims", "zeroize", @@ -4119,40 +4516,41 @@ checksum = "2b977c445f26e49757f9aca3631c3b8b836942cb278d69a92e7b80d3b24da632" dependencies = [ "arrayvec", "bit-set 0.8.0", - "bitflags 2.9.1", + "bitflags 2.10.0", "cfg_aliases", "codespan-reporting", "half", "hashbrown 0.15.5", "hexf-parse", - "indexmap 2.10.0", + "indexmap 2.12.0", "log", "num-traits", "once_cell", "rustc-hash 1.1.0", + "spirv", "strum", - "thiserror 2.0.14", + "thiserror 2.0.17", "unicode-ident", ] [[package]] name = "native-dialog" -version = "0.9.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f006431cea71a83e6668378cb5abc2d52af299cbac6dca1780c6eeca90822df" +checksum = "1657b63bf0e60ee0eca886b5df70269240b6197b6ee46ec37da9a7d28d8e8e24" dependencies = [ "ascii", - "block2 0.6.1", + "block2 0.6.2", "dirs", "dispatch2", "formatx", - "objc2 0.6.1", - "objc2-app-kit 0.3.1", + "objc2 0.6.3", + "objc2-app-kit 0.3.2", "objc2-core-foundation", "objc2-core-graphics", - "objc2-foundation 0.3.1", + "objc2-foundation 0.3.2", "raw-window-handle", - "thiserror 2.0.14", + "thiserror 2.0.17", "versions", "wfd", "which 7.0.3", @@ -4182,11 +4580,11 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "jni-sys", "log", - "ndk-sys", - "num_enum 0.7.4", + "ndk-sys 0.6.0+11769913", + "num_enum 0.7.5", "raw-window-handle", "thiserror 1.0.69", ] @@ -4197,6 +4595,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + [[package]] name = "ndk-sys" version = "0.6.0+11769913" @@ -4212,7 +4619,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "cfg-if", "cfg_aliases", "libc", @@ -4225,6 +4632,16 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "nom" version = "8.0.0" @@ -4236,12 +4653,11 @@ dependencies = [ [[package]] name = "nu-ansi-term" -version = "0.46.0" +version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "overload", - "winapi", + "windows-sys 0.61.2", ] [[package]] @@ -4295,7 +4711,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -4361,11 +4777,11 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" dependencies = [ - "num_enum_derive 0.7.4", + "num_enum_derive 0.7.5", "rustversion", ] @@ -4383,14 +4799,23 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ - "proc-macro-crate 3.3.0", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", ] [[package]] @@ -4411,9 +4836,9 @@ dependencies = [ [[package]] name = "objc2" -version = "0.6.1" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88c6597e14493ab2e44ce58f2fdecf095a51f12ca57bec060a11c57332520551" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" dependencies = [ "objc2-encode", ] @@ -4424,33 +4849,28 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "block2 0.5.1", "libc", "objc2 0.5.2", - "objc2-core-data 0.2.2", - "objc2-core-image 0.2.2", + "objc2-core-data", + "objc2-core-image", "objc2-foundation 0.2.2", - "objc2-quartz-core 0.2.2", + "objc2-quartz-core", ] [[package]] name = "objc2-app-kit" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" dependencies = [ - "bitflags 2.9.1", - "block2 0.6.1", - "libc", - "objc2 0.6.1", - "objc2-cloud-kit 0.3.1", - "objc2-core-data 0.3.1", + "bitflags 2.10.0", + "block2 0.6.2", + "objc2 0.6.3", "objc2-core-foundation", "objc2-core-graphics", - "objc2-core-image 0.3.1", - "objc2-foundation 0.3.1", - "objc2-quartz-core 0.3.1", + "objc2-foundation 0.3.2", ] [[package]] @@ -4459,24 +4879,13 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74dd3b56391c7a0596a295029734d3c1c5e7e510a4cb30245f8221ccea96b009" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", "objc2-foundation 0.2.2", ] -[[package]] -name = "objc2-cloud-kit" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17614fdcd9b411e6ff1117dfb1d0150f908ba83a7df81b1f118005fe0a8ea15d" -dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", - "objc2-foundation 0.3.1", -] - [[package]] name = "objc2-contacts" version = "0.2.2" @@ -4494,50 +4903,34 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", ] -[[package]] -name = "objc2-core-data" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291fbbf7d29287518e8686417cf7239c74700fd4b607623140a7d4a3c834329d" -dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", - "objc2-foundation 0.3.1", -] - [[package]] name = "objc2-core-foundation" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" dependencies = [ - "bitflags 2.9.1", - "block2 0.6.1", + "bitflags 2.10.0", "dispatch2", - "libc", - "objc2 0.6.1", + "objc2 0.6.3", ] [[package]] name = "objc2-core-graphics" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" dependencies = [ - "bitflags 2.9.1", - "block2 0.6.1", + "bitflags 2.10.0", "dispatch2", - "libc", - "objc2 0.6.1", + "objc2 0.6.3", "objc2-core-foundation", "objc2-io-surface", - "objc2-metal 0.3.1", ] [[package]] @@ -4549,17 +4942,7 @@ dependencies = [ "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", - "objc2-metal 0.2.2", -] - -[[package]] -name = "objc2-core-image" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79b3dc0cc4386b6ccf21c157591b34a7f44c8e75b064f85502901ab2188c007e" -dependencies = [ - "objc2 0.6.1", - "objc2-foundation 0.3.1", + "objc2-metal", ] [[package]] @@ -4586,7 +4969,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "block2 0.5.1", "dispatch", "libc", @@ -4595,25 +4978,23 @@ dependencies = [ [[package]] name = "objc2-foundation" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" dependencies = [ - "bitflags 2.9.1", - "block2 0.6.1", - "libc", - "objc2 0.6.1", + "bitflags 2.10.0", + "objc2 0.6.3", "objc2-core-foundation", ] [[package]] name = "objc2-io-surface" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7282e9ac92529fa3457ce90ebb15f4ecbc383e8338060960760fa2cf75420c3c" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", + "bitflags 2.10.0", + "objc2 0.6.3", "objc2-core-foundation", ] @@ -4635,45 +5016,23 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", ] -[[package]] -name = "objc2-metal" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f246c183239540aab1782457b35ab2040d4259175bd1d0c58e46ada7b47a874" -dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", - "objc2-foundation 0.3.1", -] - [[package]] name = "objc2-quartz-core" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "block2 0.5.1", "objc2 0.5.2", "objc2-foundation 0.2.2", - "objc2-metal 0.2.2", -] - -[[package]] -name = "objc2-quartz-core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ffb6a0cd5f182dc964334388560b12a57f7b74b3e2dec5e2722aa2dfb2ccd5" -dependencies = [ - "bitflags 2.9.1", - "objc2 0.6.1", - "objc2-foundation 0.3.1", + "objc2-metal", ] [[package]] @@ -4692,16 +5051,16 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8bb46798b20cd6b91cbd113524c490f1686f4c4e8f49502431415f3512e2b6f" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "block2 0.5.1", "objc2 0.5.2", - "objc2-cloud-kit 0.2.2", - "objc2-core-data 0.2.2", - "objc2-core-image 0.2.2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-image", "objc2-core-location", "objc2-foundation 0.2.2", "objc2-link-presentation", - "objc2-quartz-core 0.2.2", + "objc2-quartz-core", "objc2-symbols", "objc2-uniform-type-identifiers", "objc2-user-notifications", @@ -4724,33 +5083,28 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76cfcbf642358e8689af64cee815d139339f3ed8ad05103ed5eaf73db8d84cb3" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "block2 0.5.1", "objc2 0.5.2", "objc2-core-location", "objc2-foundation 0.2.2", ] -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +dependencies = [ + "critical-section", + "portable-atomic", +] [[package]] name = "once_cell_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "opaque-debug" @@ -4760,11 +5114,11 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.73" +version = "0.10.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "cfg-if", "foreign-types 0.3.2", "libc", @@ -4781,7 +5135,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -4792,9 +5146,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.109" +version = "0.9.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" dependencies = [ "cc", "libc", @@ -4817,6 +5171,15 @@ dependencies = [ "libredox", ] +[[package]] +name = "ordered-float" +version = "4.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb71e1b3fa6ca1c61f383464aaf2bb0e2f8e772a1f01d486832464de363b951" +dependencies = [ + "num-traits", +] + [[package]] name = "ordered-stream" version = "0.2.0" @@ -4827,12 +5190,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "overload" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" - [[package]] name = "owned_ttf_parser" version = "0.25.1" @@ -4859,9 +5216,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.4" +version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" dependencies = [ "lock_api", "parking_lot_core", @@ -4869,15 +5226,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.11" +version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.5.17", + "redox_syscall 0.5.18", "smallvec", - "windows-targets 0.52.6", + "windows-link 0.2.1", ] [[package]] @@ -4900,11 +5257,23 @@ dependencies = [ "subtle", ] +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "peeking_take_while" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099" + [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "petgraph" @@ -4913,7 +5282,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772" dependencies = [ "fixedbitset", - "indexmap 2.10.0", + "indexmap 2.12.0", ] [[package]] @@ -4956,7 +5325,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", "unicase", ] @@ -4987,7 +5356,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -5031,73 +5400,73 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "platform-serialization" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ - "bincode", + "bincode 2.0.0-rc.3", "platform-version", ] [[package]] name = "platform-serialization-derive" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", "virtue 0.0.17", ] [[package]] name = "platform-value" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "base64 0.22.1", - "bincode", + "bincode 2.0.0-rc.3", "bs58", "ciborium", "hex", - "indexmap 2.10.0", + "indexmap 2.12.0", "platform-serialization", "platform-version", "rand 0.8.5", "serde", "serde_json", - "thiserror 2.0.14", + "thiserror 2.0.17", "treediff", ] [[package]] name = "platform-version" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ - "bincode", + "bincode 2.0.0-rc.3", "grovedb-version", "once_cell", - "thiserror 2.0.14", + "thiserror 2.0.17", "versioned-feature-core 1.0.0 (git+https://github.com/dashpay/versioned-feature-core)", ] [[package]] name = "platform-versioning" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] name = "png" -version = "0.17.16" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.10.0", "crc32fast", "fdeflate", "flate2", @@ -5106,16 +5475,16 @@ dependencies = [ [[package]] name = "polling" -version = "3.10.0" +version = "3.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5bd19146350fe804f7cb2669c851c03d69da628803dab0d98018142aaa5d829" +checksum = "5d0e4f59085d47d8241c88ead0f274e8a0cb551f3625263c05eb8dd897c34218" dependencies = [ "cfg-if", "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix 1.0.8", - "windows-sys 0.60.2", + "rustix 1.1.2", + "windows-sys 0.61.2", ] [[package]] @@ -5153,9 +5522,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" dependencies = [ "zerovec", ] @@ -5175,14 +5544,20 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "presser" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa" + [[package]] name = "prettyplease" -version = "0.2.36" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -5197,18 +5572,18 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.3.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "toml_edit 0.22.27", + "toml_edit 0.23.7", ] [[package]] name = "proc-macro2" -version = "1.0.97" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d61789d7719defeb74ea5fe81f2fdfdbd28a803847077cecce2ff14e1472f6f1" +checksum = "8e0f6df8eaa422d97d72edcd152e1451618fed47fabbdbd5a8864167b1d4aff7" dependencies = [ "unicode-ident", ] @@ -5236,7 +5611,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac6c3320f9abac597dcbc668774ef006702672474aad53c6d596b62e487b40b1" dependencies = [ "heck", - "itertools 0.13.0", + "itertools 0.14.0", "log", "multimap", "once_cell", @@ -5247,7 +5622,7 @@ dependencies = [ "pulldown-cmark", "pulldown-cmark-to-cmark", "regex", - "syn 2.0.104", + "syn 2.0.108", "tempfile", ] @@ -5258,10 +5633,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9120690fafc389a67ba3803df527d0ec9cbbc9cc45e4cc20b332996dfb672425" dependencies = [ "anyhow", - "itertools 0.13.0", + "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -5279,7 +5654,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "memchr", "unicase", ] @@ -5293,6 +5668,15 @@ dependencies = [ "pulldown-cmark", ] +[[package]] +name = "pxfm" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3cbdf373972bf78df4d3b518d07003938e2c7d1fb5891e55f9cb6df57009d84" +dependencies = [ + "num-traits", +] + [[package]] name = "qrcode" version = "0.14.1" @@ -5302,6 +5686,12 @@ dependencies = [ "image", ] +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + [[package]] name = "quick-xml" version = "0.36.2" @@ -5323,9 +5713,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" dependencies = [ "proc-macro2", ] @@ -5398,7 +5788,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", ] [[package]] @@ -5410,13 +5800,19 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "range-alloc" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde" + [[package]] name = "raw-cpuid" -version = "11.5.0" +version = "11.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6df7ab838ed27997ba19a4664507e6f82b41fe6e20be42929332156e5e85146" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", ] [[package]] @@ -5427,9 +5823,9 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "rayon" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f" dependencies = [ "either", "rayon-core", @@ -5437,9 +5833,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.1" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -5456,11 +5852,11 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.17" +version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", ] [[package]] @@ -5471,52 +5867,37 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.16", "libredox", - "thiserror 2.0.14", + "thiserror 2.0.17", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.9", - "regex-syntax 0.8.5", + "regex-automata", + "regex-syntax", ] [[package]] name = "regex-automata" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" -dependencies = [ - "regex-syntax 0.6.29", -] - -[[package]] -name = "regex-automata" -version = "0.4.9" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.5", + "regex-syntax", ] [[package]] name = "regex-syntax" -version = "0.6.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" - -[[package]] -name = "regex-syntax" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "renderdoc-sys" @@ -5526,9 +5907,9 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" [[package]] name = "reqwest" -version = "0.12.23" +version = "0.12.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" dependencies = [ "base64 0.22.1", "bytes", @@ -5566,6 +5947,12 @@ dependencies = [ "web-sys", ] +[[package]] +name = "resolv-conf" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3789b30bd25ba102de4beabd95d21ac45b69b1be7d14522bab988c526d6799" + [[package]] name = "rfd" version = "0.15.4" @@ -5573,14 +5960,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ef2bee61e6cffa4635c72d7d81a84294e28f0930db0ddcb0f66d10244674ebed" dependencies = [ "ashpd 0.11.0", - "block2 0.6.1", + "block2 0.6.2", "dispatch2", "js-sys", "log", - "objc2 0.6.1", - "objc2-app-kit 0.3.1", + "objc2 0.6.3", + "objc2-app-kit 0.3.2", "objc2-core-foundation", - "objc2-foundation 0.3.1", + "objc2-foundation 0.3.2", "pollster", "raw-window-handle", "urlencoding", @@ -5611,7 +5998,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "beceb6f7bf81c73e73aeef6dd1356d9a1b2b4909e1f0fc3e59b034f9572d7b7f" dependencies = [ "base64 0.22.1", - "bitflags 2.9.1", + "bitflags 2.10.0", "serde", "serde_derive", "unicode-ident", @@ -5619,8 +6006,8 @@ dependencies = [ [[package]] name = "rs-dapi-client" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "backon", "chrono", @@ -5637,7 +6024,7 @@ dependencies = [ "serde", "serde_json", "sha2", - "thiserror 2.0.14", + "thiserror 2.0.17", "tokio", "tonic-web-wasm-client", "tower-service", @@ -5645,13 +6032,24 @@ dependencies = [ "wasm-bindgen-futures", ] +[[package]] +name = "rs-x11-hash" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94ea852806513d6f5fd7750423300375bc8481a18ed033756c1a836257893a30" +dependencies = [ + "bindgen", + "cc", + "libc", +] + [[package]] name = "rusqlite" version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -5661,9 +6059,9 @@ dependencies = [ [[package]] name = "rust-embed" -version = "8.7.2" +version = "8.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "025908b8682a26ba8d12f6f2d66b987584a4a87bc024abc5bbc12553a8cd178a" +checksum = "fb44e1917075637ee8c7bcb865cf8830e3a92b5b1189e44e3a0ab5a0d5be314b" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -5672,33 +6070,27 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "8.7.2" +version = "8.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6065f1a4392b71819ec1ea1df1120673418bf386f50de1d6f54204d836d4349c" +checksum = "382499b49db77a7c19abd2a574f85ada7e9dbe125d5d1160fa5cad7c4cf71fc9" dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.104", + "syn 2.0.108", "walkdir", ] [[package]] name = "rust-embed-utils" -version = "8.7.2" +version = "8.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6cc0c81648b20b70c491ff8cce00c1c3b223bb8ed2b5d41f0e54c6c4c0a3594" +checksum = "21fcbee55c2458836bcdbfffb6ec9ba74bbc23ca7aa6816015a3dd2c4d8fc185" dependencies = [ "sha2", "walkdir", ] -[[package]] -name = "rustc-demangle" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" - [[package]] name = "rustc-hash" version = "1.1.0" @@ -5726,7 +6118,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "errno", "libc", "linux-raw-sys 0.4.15", @@ -5735,22 +6127,22 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.8" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "errno", "libc", - "linux-raw-sys 0.9.4", - "windows-sys 0.60.2", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.23.31" +version = "0.23.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" +checksum = "6a9586e9ee2b4f8fab52a0048ca7334d7024eef48e2cb9407e3497bb7cab7fa7" dependencies = [ "log", "once_cell", @@ -5763,14 +6155,14 @@ dependencies = [ [[package]] name = "rustls-native-certs" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +checksum = "9980d917ebb0c0536119ba501e90834767bffc3d60641457fd84a1f3fd337923" dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", - "security-framework 3.3.0", + "security-framework 3.5.1", ] [[package]] @@ -5793,9 +6185,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.103.4" +version = "0.103.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" dependencies = [ "ring", "rustls-pki-types", @@ -5825,11 +6217,11 @@ dependencies = [ [[package]] name = "schannel" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -5865,7 +6257,7 @@ checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", - "generic-array 0.14.7", + "generic-array 0.14.9", "pkcs8", "subtle", "zeroize", @@ -5898,7 +6290,7 @@ version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "core-foundation 0.9.4", "core-foundation-sys", "libc", @@ -5907,11 +6299,11 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.3.0" +version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80fb1d92c5028aa318b4b8bd7302a5bfcf48be96a37fc6fc790f806b0004ee0c" +checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -5920,9 +6312,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.14.0" +version = "2.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" dependencies = [ "core-foundation-sys", "libc", @@ -5930,16 +6322,17 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.26" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] @@ -5954,35 +6347,46 @@ dependencies = [ [[package]] name = "serde_bytes" -version = "0.11.17" +version = "0.11.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" +checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8" dependencies = [ "serde", + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] name = "serde_json" -version = "1.0.142" +version = "1.0.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" dependencies = [ - "indexmap 2.10.0", + "indexmap 2.12.0", "itoa", "memchr", "ryu", "serde", + "serde_core", ] [[package]] @@ -5993,7 +6397,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -6042,7 +6446,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -6051,7 +6455,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.10.0", + "indexmap 2.12.0", "itoa", "ryu", "serde", @@ -6104,6 +6508,27 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +dependencies = [ + "libc", + "mio 0.8.11", + "signal-hook", +] + [[package]] name = "signal-hook-registry" version = "1.4.6" @@ -6161,7 +6586,7 @@ version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3457dea1f0eb631b4034d61d4d8c32074caa6cd1ab2d59f2327bd8461e2c0016" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "calloop", "calloop-wayland-source", "cursor-icon", @@ -6202,21 +6627,37 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.0" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", ] [[package]] name = "spin" -version = "0.9.8" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" + +[[package]] +name = "spirv" +version = "0.3.0+sdk-1.3.268.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +checksum = "eda41003dc44290527a59b13432d4a0379379fa074b70174882adfbdfd917844" dependencies = [ - "lock_api", + "bitflags 2.10.0", ] [[package]] @@ -6240,9 +6681,9 @@ dependencies = [ [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "static_assertions" @@ -6252,11 +6693,12 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "std-shims" -version = "0.1.1" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90e49360f31b0b75a6a82a5205c6103ea07a79a60808d44f5cc879d303337926" +checksum = "227c4f8561598188d0df96dbe749824576174bba278b5b6bb2eacff1066067d0" dependencies = [ - "hashbrown 0.14.5", + "hashbrown 0.16.0", + "rustversion", "spin", ] @@ -6291,7 +6733,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -6322,9 +6764,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.104" +version = "2.0.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" dependencies = [ "proc-macro2", "quote", @@ -6348,7 +6790,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -6357,7 +6799,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -6385,6 +6827,12 @@ dependencies = [ "version-compare", ] +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + [[package]] name = "tap" version = "1.0.1" @@ -6399,15 +6847,15 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.20.0" +version = "3.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.3.4", "once_cell", - "rustix 1.0.8", - "windows-sys 0.59.0", + "rustix 1.1.2", + "windows-sys 0.61.2", ] [[package]] @@ -6420,7 +6868,7 @@ dependencies = [ "lhash", "semver", "tenderdash-proto", - "thiserror 2.0.14", + "thiserror 2.0.17", "tracing", "url", ] @@ -6439,7 +6887,7 @@ dependencies = [ "serde", "subtle-encoding", "tenderdash-proto-compiler", - "thiserror 2.0.14", + "thiserror 2.0.17", "time", ] @@ -6477,11 +6925,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.14" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b0949c3a6c842cbde3f1686d6eea5a010516deb7085f79db747562d4102f41e" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" dependencies = [ - "thiserror-impl 2.0.14", + "thiserror-impl 2.0.17", ] [[package]] @@ -6492,18 +6940,18 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] name = "thiserror-impl" -version = "2.0.14" +version = "2.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc5b44b4ab9c2fdd0e0512e6bece8388e214c0749f5862b114cc5b7a25daf227" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -6526,20 +6974,23 @@ dependencies = [ [[package]] name = "tiff" -version = "0.9.1" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" +checksum = "af9605de7fee8d9551863fd692cce7637f548dbd9db9180fcc07ccc6d26c336f" dependencies = [ + "fax", "flate2", - "jpeg-decoder", + "half", + "quick-error", "weezl", + "zune-jpeg", ] [[package]] name = "time" -version = "0.3.41" +version = "0.3.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" dependencies = [ "deranged", "itoa", @@ -6552,15 +7003,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" +checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" [[package]] name = "time-macros" -version = "0.2.22" +version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" dependencies = [ "num-conv", "time-core", @@ -6603,9 +7054,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" dependencies = [ "tinyvec_macros", ] @@ -6618,44 +7069,41 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "token-history-contract" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "platform-value", "platform-version", "serde_json", - "thiserror 2.0.14", + "thiserror 2.0.17", ] [[package]] name = "tokio" -version = "1.47.1" +version = "1.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", - "mio", + "mio 1.1.0", "parking_lot", "pin-project-lite", "signal-hook-registry", - "slab", - "socket2", + "socket2 0.6.1", "tokio-macros", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -6670,9 +7118,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.2" +version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" dependencies = [ "rustls", "tokio", @@ -6711,7 +7159,7 @@ checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" dependencies = [ "serde", "serde_spanned", - "toml_datetime", + "toml_datetime 0.6.11", "toml_edit 0.22.27", ] @@ -6724,14 +7172,23 @@ dependencies = [ "serde", ] +[[package]] +name = "toml_datetime" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.10.0", - "toml_datetime", + "indexmap 2.12.0", + "toml_datetime 0.6.11", "winnow 0.5.40", ] @@ -6741,11 +7198,32 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.10.0", + "indexmap 2.12.0", "serde", "serde_spanned", - "toml_datetime", - "winnow 0.7.12", + "toml_datetime 0.6.11", + "winnow 0.7.13", +] + +[[package]] +name = "toml_edit" +version = "0.23.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d" +dependencies = [ + "indexmap 2.12.0", + "toml_datetime 0.7.3", + "toml_parser", + "winnow 0.7.13", +] + +[[package]] +name = "toml_parser" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +dependencies = [ + "winnow 0.7.13", ] [[package]] @@ -6767,7 +7245,7 @@ dependencies = [ "percent-encoding", "pin-project", "rustls-native-certs", - "socket2", + "socket2 0.6.1", "sync_wrapper", "tokio", "tokio-rustls", @@ -6776,7 +7254,7 @@ dependencies = [ "tower-layer", "tower-service", "tracing", - "webpki-roots 1.0.2", + "webpki-roots", ] [[package]] @@ -6788,7 +7266,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -6813,7 +7291,7 @@ dependencies = [ "prost-build", "prost-types", "quote", - "syn 2.0.104", + "syn 2.0.108", "tempfile", "tonic-build", ] @@ -6834,7 +7312,7 @@ dependencies = [ "httparse", "js-sys", "pin-project", - "thiserror 2.0.14", + "thiserror 2.0.17", "tonic", "tower-service", "wasm-bindgen", @@ -6851,7 +7329,7 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ "futures-core", "futures-util", - "indexmap 2.10.0", + "indexmap 2.12.0", "pin-project-lite", "slab", "sync_wrapper", @@ -6868,7 +7346,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "bytes", "futures-util", "http", @@ -6911,7 +7389,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -6937,14 +7415,14 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.19" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" dependencies = [ "matchers", "nu-ansi-term", "once_cell", - "regex", + "regex-automata", "sharded-slab", "smallvec", "thread_local", @@ -6982,15 +7460,15 @@ dependencies = [ [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "tz-rs" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1450bf2b99397e72070e7935c89facaa80092ac812502200375f1f7d33c71a1" +checksum = "14eff19b8dc1ace5bf7e4d920b2628ae3837f422ff42210cb1567cbf68b5accf" [[package]] name = "uds_windows" @@ -7020,9 +7498,9 @@ checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" +checksum = "462eeb75aeb73aea900253ce739c8e18a67423fadf006037cd3ff27e82748a06" [[package]] name = "unicode-normalization" @@ -7041,9 +7519,9 @@ checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unicode-xid" @@ -7075,9 +7553,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "3.0.12" +version = "3.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f0fde9bc91026e381155f8c67cb354bcd35260b2f4a29bcc84639f762760c39" +checksum = "99ba1025f18a4a3fc3e9b48c868e9beb4f24f4b4b1a325bada26bd4119f46537" dependencies = [ "base64 0.22.1", "flate2", @@ -7088,14 +7566,14 @@ dependencies = [ "rustls-pki-types", "ureq-proto", "utf-8", - "webpki-roots 0.26.11", + "webpki-roots", ] [[package]] name = "ureq-proto" -version = "0.4.2" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59db78ad1923f2b1be62b6da81fe80b173605ca0d57f85da2e005382adf693f7" +checksum = "60b4531c118335662134346048ddb0e54cc86bd7e81866757873055f0e38f5d2" dependencies = [ "base64 0.22.1", "http", @@ -7105,9 +7583,9 @@ dependencies = [ [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", @@ -7141,12 +7619,13 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.18.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be" +checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" dependencies = [ - "getrandom 0.3.3", + "getrandom 0.3.4", "js-sys", + "serde", "wasm-bindgen", ] @@ -7198,7 +7677,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80a7e511ce1795821207a837b7b1c8d8aca0c648810966ad200446ae58f6667f" dependencies = [ "itertools 0.14.0", - "nom", + "nom 8.0.0", ] [[package]] @@ -7216,13 +7695,12 @@ checksum = "7302ac74a033bf17b6e609ceec0f891ca9200d502d31f02dc7908d3d98767c9d" [[package]] name = "vsss-rs" version = "5.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fec4ebcc5594130c31b49594d55c0583fe80621f252f570b222ca4845cafd3cf" +source = "git+https://github.com/dashpay/vsss-rs?branch=main#668f1406bf25a4b9a95cd97c9069f7a1632897c3" dependencies = [ "crypto-bigint", "elliptic-curve", "elliptic-curve-tools", - "generic-array 1.2.0", + "generic-array 1.3.4", "hex", "num", "rand_core 0.6.4", @@ -7244,13 +7722,13 @@ dependencies = [ [[package]] name = "wallet-utils-contract" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "platform-value", "platform-version", "serde_json", - "thiserror 2.0.14", + "thiserror 2.0.17", ] [[package]] @@ -7269,45 +7747,46 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] -name = "wasi" -version = "0.14.2+wasi-0.2.4" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", + "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" dependencies = [ "bumpalo", "log", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.50" +version = "0.4.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" dependencies = [ "cfg-if", "js-sys", @@ -7318,9 +7797,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -7328,22 +7807,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" dependencies = [ "unicode-ident", ] @@ -7369,7 +7848,7 @@ checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35" dependencies = [ "cc", "downcast-rs", - "rustix 1.0.8", + "rustix 1.1.2", "scoped-tls", "smallvec", "wayland-sys", @@ -7381,8 +7860,8 @@ version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d" dependencies = [ - "bitflags 2.9.1", - "rustix 1.0.8", + "bitflags 2.10.0", + "rustix 1.1.2", "wayland-backend", "wayland-scanner", ] @@ -7393,7 +7872,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "cursor-icon", "wayland-backend", ] @@ -7404,7 +7883,7 @@ version = "0.31.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "447ccc440a881271b19e9989f75726d60faa09b95b0200a9b7eb5cc47c3eeb29" dependencies = [ - "rustix 1.0.8", + "rustix 1.1.2", "wayland-client", "xcursor", ] @@ -7415,7 +7894,7 @@ version = "0.32.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -7427,7 +7906,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a07a14257c077ab3279987c4f8bb987851bf57081b93710381daea94f2c2c032" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -7440,7 +7919,7 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "efd94963ed43cf9938a090ca4f7da58eb55325ec8200c3848963e98dc25b78ec" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -7472,9 +7951,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.77" +version = "0.3.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" dependencies = [ "js-sys", "wasm-bindgen", @@ -7492,34 +7971,25 @@ dependencies = [ [[package]] name = "webbrowser" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf4f3c0ba838e82b4e5ccc4157003fb8c324ee24c058470ffb82820becbde98" +checksum = "00f1243ef785213e3a32fa0396093424a3a6ea566f9948497e5a2309261a4c97" dependencies = [ "core-foundation 0.10.1", "jni", "log", "ndk-context", - "objc2 0.6.1", - "objc2-foundation 0.3.1", + "objc2 0.6.3", + "objc2-foundation 0.3.2", "url", "web-sys", ] [[package]] name = "webpki-roots" -version = "0.26.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" -dependencies = [ - "webpki-roots 1.0.2", -] - -[[package]] -name = "webpki-roots" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" dependencies = [ "rustls-pki-types", ] @@ -7532,9 +8002,9 @@ checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" [[package]] name = "wfd" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e713040b67aae5bf1a0ae3e1ebba8cc29ab2b90da9aa1bff6e09031a8a41d7a8" +checksum = "0c17bbfb155305bcb79144f568c3b796275ba4db5d5856597bc85acefe29b819" dependencies = [ "libc", "winapi", @@ -7547,12 +8017,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec8fb398f119472be4d80bc3647339f56eb63b2a331f6a3d16e25d8144197dd9" dependencies = [ "arrayvec", - "bitflags 2.9.1", + "bitflags 2.10.0", "cfg_aliases", "document-features", "hashbrown 0.15.5", "js-sys", "log", + "naga", "parking_lot", "portable-atomic", "profiling", @@ -7560,6 +8031,7 @@ dependencies = [ "smallvec", "static_assertions", "wasm-bindgen", + "wasm-bindgen-futures", "web-sys", "wgpu-core", "wgpu-hal", @@ -7575,11 +8047,11 @@ dependencies = [ "arrayvec", "bit-set 0.8.0", "bit-vec 0.8.0", - "bitflags 2.9.1", + "bitflags 2.10.0", "cfg_aliases", "document-features", "hashbrown 0.15.5", - "indexmap 2.10.0", + "indexmap 2.12.0", "log", "naga", "once_cell", @@ -7589,12 +8061,32 @@ dependencies = [ "raw-window-handle", "rustc-hash 1.1.0", "smallvec", - "thiserror 2.0.14", + "thiserror 2.0.17", + "wgpu-core-deps-apple", + "wgpu-core-deps-emscripten", "wgpu-core-deps-windows-linux-android", "wgpu-hal", "wgpu-types", ] +[[package]] +name = "wgpu-core-deps-apple" +version = "25.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfd488b3239b6b7b185c3b045c39ca6bf8af34467a4c5de4e0b1a564135d093d" +dependencies = [ + "wgpu-hal", +] + +[[package]] +name = "wgpu-core-deps-emscripten" +version = "25.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f09ad7aceb3818e52539acc679f049d3475775586f3f4e311c30165cf2c00445" +dependencies = [ + "wgpu-hal", +] + [[package]] name = "wgpu-core-deps-windows-linux-android" version = "25.0.0" @@ -7610,17 +8102,45 @@ version = "25.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f968767fe4d3d33747bbd1473ccd55bf0f6451f55d733b5597e67b5deab4ad17" dependencies = [ - "bitflags 2.9.1", + "android_system_properties", + "arrayvec", + "ash", + "bit-set 0.8.0", + "bitflags 2.10.0", + "block", + "bytemuck", + "cfg-if", "cfg_aliases", + "core-graphics-types", + "glow", + "glutin_wgl_sys", + "gpu-alloc", + "gpu-allocator", + "gpu-descriptor", + "hashbrown 0.15.5", + "js-sys", + "khronos-egl", + "libc", "libloading", "log", + "metal", "naga", + "ndk-sys 0.5.0+25.2.9519653", + "objc", + "ordered-float", "parking_lot", "portable-atomic", + "profiling", + "range-alloc", "raw-window-handle", "renderdoc-sys", - "thiserror 2.0.14", + "smallvec", + "thiserror 2.0.17", + "wasm-bindgen", + "web-sys", "wgpu-types", + "windows 0.58.0", + "windows-core 0.58.0", ] [[package]] @@ -7629,14 +8149,26 @@ version = "25.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2aa49460c2a8ee8edba3fca54325540d904dd85b2e086ada762767e17d06e8bc" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "bytemuck", "js-sys", "log", - "thiserror 2.0.14", + "thiserror 2.0.17", "web-sys", ] +[[package]] +name = "which" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7" +dependencies = [ + "either", + "home", + "once_cell", + "rustix 0.38.44", +] + [[package]] name = "which" version = "7.0.3" @@ -7645,7 +8177,7 @@ checksum = "24d643ce3fd3e5b54854602a080f34fb10ab75e0b813ee32d00ca2b44fa74762" dependencies = [ "either", "env_home", - "rustix 1.0.8", + "rustix 1.1.2", "winsafe", ] @@ -7656,10 +8188,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fabb953106c3c8eea8306e4393700d7657561cb43122571b172bbfb7c7ba1d" dependencies = [ "env_home", - "rustix 1.0.8", + "rustix 1.1.2", "winsafe", ] +[[package]] +name = "widestring" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" + [[package]] name = "winapi" version = "0.3.9" @@ -7678,11 +8216,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -7691,6 +8229,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows" version = "0.61.3" @@ -7698,9 +8246,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ "windows-collections", - "windows-core", + "windows-core 0.61.2", "windows-future", - "windows-link", + "windows-link 0.1.3", "windows-numerics", ] @@ -7710,7 +8258,20 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" dependencies = [ - "windows-core", + "windows-core 0.61.2", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets 0.52.6", ] [[package]] @@ -7719,11 +8280,24 @@ version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement 0.60.2", + "windows-interface 0.59.3", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", ] [[package]] @@ -7732,31 +8306,53 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ - "windows-core", - "windows-link", + "windows-core 0.61.2", + "windows-link 0.1.3", "windows-threading", ] [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.108", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.108", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -7765,14 +8361,20 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + [[package]] name = "windows-numerics" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ - "windows-core", - "windows-link", + "windows-core 0.61.2", + "windows-link 0.1.3", ] [[package]] @@ -7781,9 +8383,18 @@ version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" dependencies = [ - "windows-link", - "windows-result", - "windows-strings", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -7792,7 +8403,26 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", ] [[package]] @@ -7801,7 +8431,16 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ - "windows-link", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link 0.2.1", ] [[package]] @@ -7846,7 +8485,16 @@ version = "0.60.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" dependencies = [ - "windows-targets 0.53.3", + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", ] [[package]] @@ -7897,19 +8545,19 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.53.3" +version = "0.53.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows-link 0.2.1", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -7918,7 +8566,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" dependencies = [ - "windows-link", + "windows-link 0.1.3", ] [[package]] @@ -7941,9 +8589,9 @@ checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" [[package]] name = "windows_aarch64_msvc" @@ -7965,9 +8613,9 @@ checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_aarch64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" [[package]] name = "windows_i686_gnu" @@ -7989,9 +8637,9 @@ checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" [[package]] name = "windows_i686_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" [[package]] name = "windows_i686_gnullvm" @@ -8001,9 +8649,9 @@ checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" [[package]] name = "windows_i686_msvc" @@ -8025,9 +8673,9 @@ checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_i686_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" [[package]] name = "windows_x86_64_gnu" @@ -8049,9 +8697,9 @@ checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnu" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" [[package]] name = "windows_x86_64_gnullvm" @@ -8073,9 +8721,9 @@ checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_gnullvm" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" [[package]] name = "windows_x86_64_msvc" @@ -8097,9 +8745,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "windows_x86_64_msvc" -version = "0.53.0" +version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winit" @@ -8110,7 +8758,7 @@ dependencies = [ "ahash", "android-activity", "atomic-waker", - "bitflags 2.9.1", + "bitflags 2.10.0", "block2 0.5.1", "bytemuck", "calloop", @@ -8164,13 +8812,23 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.12" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" dependencies = [ "memchr", ] +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "winreg" version = "0.52.0" @@ -8188,18 +8846,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "wit-bindgen" +version = "0.46.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.1", -] +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" [[package]] name = "withdrawals-contract" -version = "2.1.0-dev.8" -source = "git+https://github.com/dashpay/platform?rev=d6f9d9e74b885fbac27948bce6bae60b0cbd7135#d6f9d9e74b885fbac27948bce6bae60b0cbd7135" +version = "2.1.0-rc.1" +source = "git+https://github.com/dashpay/platform?rev=2c681e3713e86452ef061b757dc0af9350ed6b05#2c681e3713e86452ef061b757dc0af9350ed6b05" dependencies = [ "num_enum 0.5.11", "platform-value", @@ -8207,7 +8862,7 @@ dependencies = [ "serde", "serde_json", "serde_repr", - "thiserror 2.0.14", + "thiserror 2.0.17", ] [[package]] @@ -8238,24 +8893,24 @@ dependencies = [ [[package]] name = "x11rb" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" +checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414" dependencies = [ "as-raw-xcb-connection", "gethostname", "libc", "libloading", "once_cell", - "rustix 0.38.44", + "rustix 1.1.2", "x11rb-protocol", ] [[package]] name = "x11rb-protocol" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" +checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd" [[package]] name = "xcursor" @@ -8269,7 +8924,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.9.1", + "bitflags 2.10.0", "dlib", "log", "once_cell", @@ -8308,15 +8963,15 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", "synstructure", ] [[package]] name = "zbus" -version = "5.9.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb4f9a464286d42851d18a605f7193b8febaf5b0919d71c6399b7b26e5b0aad" +checksum = "b622b18155f7a93d1cd2dc8c01d2d6a44e08fb9ebb7b3f9e6ed101488bad6c91" dependencies = [ "async-broadcast", "async-executor", @@ -8338,8 +8993,9 @@ dependencies = [ "serde_repr", "tracing", "uds_windows", - "windows-sys 0.59.0", - "winnow 0.7.12", + "uuid", + "windows-sys 0.61.2", + "winnow 0.7.13", "zbus_macros", "zbus_names", "zvariant", @@ -8363,7 +9019,7 @@ checksum = "dc6821851fa840b708b4cbbaf6241868cabc85a2dc22f426361b0292bfc0b836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", "zbus-lockstep", "zbus_xml", "zvariant", @@ -8371,14 +9027,14 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "5.9.0" +version = "5.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef9859f68ee0c4ee2e8cde84737c78e3f4c54f946f2a38645d0d4c7a95327659" +checksum = "1cdb94821ca8a87ca9c298b5d1cbd80e2a8b67115d99f6e4551ac49e42b6a314" dependencies = [ - "proc-macro-crate 3.3.0", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", "zbus_names", "zvariant", "zvariant_utils", @@ -8392,7 +9048,7 @@ checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" dependencies = [ "serde", "static_assertions", - "winnow 0.7.12", + "winnow 0.7.13", "zvariant", ] @@ -8411,22 +9067,22 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.26" +version = "0.8.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -8446,15 +9102,15 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", "synstructure", ] [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" dependencies = [ "serde", "zeroize_derive", @@ -8468,7 +9124,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -8538,7 +9194,7 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", ] [[package]] @@ -8550,7 +9206,7 @@ dependencies = [ "arbitrary", "crc32fast", "flate2", - "indexmap 2.10.0", + "indexmap 2.12.0", "memchr", "zopfli", ] @@ -8595,46 +9251,60 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "zune-core" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a" + +[[package]] +name = "zune-jpeg" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713" +dependencies = [ + "zune-core", +] + [[package]] name = "zvariant" -version = "5.6.0" +version = "5.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91b3680bb339216abd84714172b5138a4edac677e641ef17e1d8cb1b3ca6e6f" +checksum = "2be61892e4f2b1772727be11630a62664a1826b62efa43a6fe7449521cb8744c" dependencies = [ "endi", "enumflags2", "serde", "url", - "winnow 0.7.12", + "winnow 0.7.13", "zvariant_derive", "zvariant_utils", ] [[package]] name = "zvariant_derive" -version = "5.6.0" +version = "5.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a8c68501be459a8dbfffbe5d792acdd23b4959940fc87785fb013b32edbc208" +checksum = "da58575a1b2b20766513b1ec59d8e2e68db2745379f961f86650655e862d2006" dependencies = [ - "proc-macro-crate 3.3.0", + "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.104", + "syn 2.0.108", "zvariant_utils", ] [[package]] name = "zvariant_utils" -version = "3.2.0" +version = "3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16edfee43e5d7b553b77872d99bc36afdda75c223ca7ad5e3fbecd82ca5fc34" +checksum = "c6949d142f89f6916deca2232cf26a8afacf2b9fdc35ce766105e104478be599" dependencies = [ "proc-macro2", "quote", "serde", - "static_assertions", - "syn 2.0.104", - "winnow 0.7.12", + "syn 2.0.108", + "winnow 0.7.13", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index cb80ea5b6..8f805bacd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,7 +18,7 @@ qrcode = "0.14.1" nix = { version = "0.30.1", features = ["signal"] } eframe = { version = "0.32.0", features = ["persistence"] } base64 = "0.22.1" -dash-sdk = { git = "https://github.com/dashpay/platform", features = ["core_key_wallet", "core_bincode", "core_quorum-validation", "core_verification", "core_rpc_client"], rev = "d6f9d9e74b885fbac27948bce6bae60b0cbd7135" } +dash-sdk = { git = "https://github.com/dashpay/platform", features = ["core_key_wallet", "core_key_wallet_manager", "core_spv", "core_bincode", "core_quorum-validation", "core_verification", "core_rpc_client"], rev = "2c681e3713e86452ef061b757dc0af9350ed6b05" } thiserror = "2.0.12" serde = "1.0.219" serde_json = "1.0.140" diff --git a/src/app.rs b/src/app.rs index 0608c3fb0..10bebc359 100644 --- a/src/app.rs +++ b/src/app.rs @@ -67,13 +67,13 @@ pub struct AppState { pub devnet_app_context: Option>, pub local_app_context: Option>, #[allow(dead_code)] // Kept alive for the lifetime of the app - pub mainnet_core_zmq_listener: CoreZMQListener, + pub mainnet_core_zmq_listener: Option, #[allow(dead_code)] // Kept alive for the lifetime of the app - pub testnet_core_zmq_listener: CoreZMQListener, + pub testnet_core_zmq_listener: Option, #[allow(dead_code)] // Kept alive for the lifetime of the app - pub devnet_core_zmq_listener: CoreZMQListener, + pub devnet_core_zmq_listener: Option, #[allow(dead_code)] // Kept alive for the lifetime of the app - pub local_core_zmq_listener: CoreZMQListener, + pub local_core_zmq_listener: Option, pub core_message_receiver: mpsc::Receiver<(ZMQMessage, Network)>, pub task_result_sender: egui_mpsc::SenderAsync, // Channel sender for sending task results pub task_result_receiver: tokiompsc::Receiver, // Channel receiver for receiving task results @@ -339,13 +339,25 @@ impl AppState { .core_zmq_endpoint .clone() .unwrap_or_else(|| "tcp://127.0.0.1:23708".to_string()); - let mainnet_core_zmq_listener = CoreZMQListener::spawn_listener( - Network::Dash, - &mainnet_core_zmq_endpoint, - core_message_sender.clone(), // Clone the sender for each listener - Some(mainnet_app_context.sx_zmq_status.clone()), - ) - .expect("Failed to create mainnet InstantSend listener"); + let mainnet_disable_zmq = mainnet_app_context + .get_settings() + .ok() + .flatten() + .map(|s| s.disable_zmq) + .unwrap_or(false); + let mainnet_core_zmq_listener = if !mainnet_disable_zmq { + Some( + CoreZMQListener::spawn_listener( + Network::Dash, + &mainnet_core_zmq_endpoint, + core_message_sender.clone(), // Clone the sender for each listener + Some(mainnet_app_context.sx_zmq_status.clone()), + ) + .expect("Failed to create mainnet InstantSend listener"), + ) + } else { + None + }; let testnet_tx_zmq_status_option = testnet_app_context .as_ref() @@ -355,13 +367,24 @@ impl AppState { .as_ref() .and_then(|ctx| ctx.config.read().unwrap().core_zmq_endpoint.clone()) .unwrap_or_else(|| "tcp://127.0.0.1:23709".to_string()); - let testnet_core_zmq_listener = CoreZMQListener::spawn_listener( - Network::Testnet, - &testnet_core_zmq_endpoint, - core_message_sender.clone(), // Use the original sender or create a new one if needed - testnet_tx_zmq_status_option, - ) - .expect("Failed to create testnet InstantSend listener"); + let testnet_disable_zmq = testnet_app_context + .as_ref() + .and_then(|ctx| ctx.get_settings().ok().flatten()) + .map(|s| s.disable_zmq) + .unwrap_or(false); + let testnet_core_zmq_listener = if !testnet_disable_zmq { + Some( + CoreZMQListener::spawn_listener( + Network::Testnet, + &testnet_core_zmq_endpoint, + core_message_sender.clone(), // Use the original sender or create a new one if needed + testnet_tx_zmq_status_option, + ) + .expect("Failed to create testnet InstantSend listener"), + ) + } else { + None + }; let devnet_tx_zmq_status_option = devnet_app_context .as_ref() @@ -371,13 +394,24 @@ impl AppState { .as_ref() .and_then(|ctx| ctx.config.read().unwrap().core_zmq_endpoint.clone()) .unwrap_or_else(|| "tcp://127.0.0.1:23710".to_string()); - let devnet_core_zmq_listener = CoreZMQListener::spawn_listener( - Network::Devnet, - &devnet_core_zmq_endpoint, - core_message_sender.clone(), - devnet_tx_zmq_status_option, - ) - .expect("Failed to create devnet InstantSend listener"); + let devnet_disable_zmq = devnet_app_context + .as_ref() + .and_then(|ctx| ctx.get_settings().ok().flatten()) + .map(|s| s.disable_zmq) + .unwrap_or(false); + let devnet_core_zmq_listener = if !devnet_disable_zmq { + Some( + CoreZMQListener::spawn_listener( + Network::Devnet, + &devnet_core_zmq_endpoint, + core_message_sender.clone(), + devnet_tx_zmq_status_option, + ) + .expect("Failed to create devnet InstantSend listener"), + ) + } else { + None + }; let local_tx_zmq_status_option = local_app_context .as_ref() @@ -387,13 +421,24 @@ impl AppState { .as_ref() .and_then(|ctx| ctx.config.read().unwrap().core_zmq_endpoint.clone()) .unwrap_or_else(|| "tcp://127.0.0.1:20302".to_string()); - let local_core_zmq_listener = CoreZMQListener::spawn_listener( - Network::Regtest, - &local_core_zmq_endpoint, - core_message_sender, - local_tx_zmq_status_option, - ) - .expect("Failed to create local InstantSend listener"); + let local_disable_zmq = local_app_context + .as_ref() + .and_then(|ctx| ctx.get_settings().ok().flatten()) + .map(|s| s.disable_zmq) + .unwrap_or(false); + let local_core_zmq_listener = if !local_disable_zmq { + Some( + CoreZMQListener::spawn_listener( + Network::Regtest, + &local_core_zmq_endpoint, + core_message_sender, + local_tx_zmq_status_option, + ) + .expect("Failed to create local InstantSend listener"), + ) + } else { + None + }; Self { main_screens: [ diff --git a/src/context.rs b/src/context.rs index e8132edac..8474d8f96 100644 --- a/src/context.rs +++ b/src/context.rs @@ -2,7 +2,8 @@ use crate::app_dir::core_cookie_path; use crate::backend_task::contested_names::ScheduledDPNSVote; use crate::components::core_zmq_listener::ZMQConnectionEvent; use crate::config::{Config, NetworkConfig}; -use crate::context_provider::Provider; +use crate::context_provider::Provider as RpcProvider; +use crate::context_provider_spv::SpvProvider; use crate::database::Database; use crate::model::contested_name::ContestedName; use crate::model::password_info::PasswordInfo; @@ -11,6 +12,8 @@ use crate::model::qualified_identity::{DPNSNameInfo, QualifiedIdentity}; use crate::model::settings::Settings; use crate::model::wallet::{Wallet, WalletSeedHash}; use crate::sdk_wrapper::initialize_sdk; +use crate::spv::WatchOnlyWalletAttachment; +use crate::spv::{CoreBackendMode, SpvManager}; use crate::ui::RootScreenType; use crate::ui::tokens::tokens_screen::{IdentityTokenBalance, IdentityTokenIdentifier}; use crate::utils::tasks::TaskManager; @@ -26,6 +29,7 @@ use dash_sdk::dpp::data_contract::TokenConfiguration; use dash_sdk::dpp::identity::accessors::IdentityGettersV0; use dash_sdk::dpp::identity::state_transition::asset_lock_proof::InstantAssetLockProof; use dash_sdk::dpp::identity::state_transition::asset_lock_proof::chain::ChainAssetLockProof; +use dash_sdk::dpp::key_wallet::wallet::managed_wallet_info::wallet_info_interface::WalletInfoInterface; use dash_sdk::dpp::prelude::{AssetLockProof, CoreBlockHeight}; use dash_sdk::dpp::state_transition::StateTransitionSigningOptions; use dash_sdk::dpp::state_transition::batch_transition::methods::StateTransitionCreationOptions; @@ -37,7 +41,7 @@ use dash_sdk::query_types::IndexMap; use egui::Context; use rusqlite::Result; use std::collections::{BTreeMap, HashMap}; -use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::atomic::{AtomicBool, AtomicU8, Ordering}; use std::sync::{Arc, Mutex, RwLock, RwLockWriteGuard}; const ANIMATION_REFRESH_TIME: std::time::Duration = std::time::Duration::from_millis(100); @@ -56,7 +60,10 @@ pub struct AppContext { pub(crate) devnet_name: Option, pub(crate) db: Arc, pub(crate) sdk: RwLock, - pub(crate) config: RwLock, + // Context providers for SDK, so we can switch when backend mode changes + spv_context_provider: RwLock, + rpc_context_provider: RwLock, + pub(crate) config: Arc>, pub(crate) rx_zmq_status: Receiver, pub(crate) sx_zmq_status: Sender, pub(crate) zmq_connection_status: Mutex, @@ -80,6 +87,8 @@ pub struct AppContext { cached_settings: RwLock>, // subtasks started by the app context, used for graceful shutdown pub(crate) subtasks: Arc, + pub(crate) spv_manager: Arc, + core_backend_mode: AtomicU8, } impl AppContext { @@ -98,13 +107,17 @@ impl AppContext { }; let network_config = config.config_for_network(network).clone()?; + let config_lock = Arc::new(RwLock::new(network_config.clone())); let (sx_zmq_status, rx_zmq_status) = crossbeam_channel::unbounded(); - // we create provider, but we need to set app context to it later, as we have a circular dependency - let provider = - Provider::new(db.clone(), network, &network_config).expect("Failed to initialize SDK"); + // Create both providers; bind to app context later (post construction) due to circularity + let spv_provider = + SpvProvider::new(db.clone(), network).expect("Failed to initialize SPV provider"); + let rpc_provider = RpcProvider::new(db.clone(), network, &network_config) + .expect("Failed to initialize RPC provider"); - let sdk = initialize_sdk(&network_config, network, provider.clone()); + // Default to SPV provider initially; UI can switch backend after + let sdk = initialize_sdk(&network_config, network, spv_provider.clone()); let platform_version = sdk.version(); let dpns_contract = load_system_data_contract(SystemDataContract::DPNS, platform_version) @@ -164,13 +177,24 @@ impl AppContext { false => AtomicBool::new(true), // Animations are enabled by default }; + let spv_manager = match SpvManager::new(network, Arc::clone(&config_lock), subtasks.clone()) + { + Ok(manager) => manager, + Err(err) => { + tracing::error!(?err, ?network, "Failed to initialize SPV manager"); + return None; + } + }; + let app_context = AppContext { network, developer_mode: AtomicBool::new(config.developer_mode.unwrap_or(false)), devnet_name: None, db, sdk: sdk.into(), - config: network_config.into(), + spv_context_provider: spv_provider.into(), + rpc_context_provider: rpc_provider.into(), + config: config_lock, sx_zmq_status, rx_zmq_status, dpns_contract: Arc::new(dpns_contract), @@ -186,10 +210,32 @@ impl AppContext { animate, cached_settings: RwLock::new(None), subtasks, + spv_manager, + core_backend_mode: AtomicU8::new(CoreBackendMode::Spv.as_u8()), }; let app_context = Arc::new(app_context); - provider.bind_app_context(app_context.clone()); + // Bind providers to the newly created app_context. + // Only the active provider is registered with the SDK here (SPV by default). + app_context + .spv_context_provider + .read() + .unwrap() + .bind_app_context(app_context.clone()); + + // If defaulting to RPC is desired, swap provider after binding. + if app_context.core_backend_mode() == CoreBackendMode::Rpc { + app_context + .rpc_context_provider + .read() + .unwrap() + .bind_app_context(app_context.clone()); + } else { + // Ensure SDK uses the SPV provider + let sdk_lock = app_context.sdk.write().expect("SDK lock poisoned"); + let provider = app_context.spv_context_provider.read().unwrap().clone(); + sdk_lock.set_context_provider(provider); + } Some(app_context) } @@ -207,6 +253,257 @@ impl AppContext { self.enable_animations(!enable); } + pub fn core_backend_mode(&self) -> CoreBackendMode { + self.core_backend_mode.load(Ordering::Relaxed).into() + } + + pub fn set_core_backend_mode(self: &Arc, mode: CoreBackendMode) { + self.core_backend_mode + .store(mode.as_u8(), Ordering::Relaxed); + + // Switch SDK context provider to match the selected backend + match mode { + CoreBackendMode::Spv => { + // Make sure SPV provider knows about the app context + self.spv_context_provider + .read() + .unwrap() + .bind_app_context(Arc::clone(self)); + let sdk = self.sdk.write().expect("SDK lock poisoned"); + let provider = self.spv_context_provider.read().unwrap().clone(); + sdk.set_context_provider(provider); + } + CoreBackendMode::Rpc => { + // RPC provider binding also sets itself on the SDK + self.rpc_context_provider + .read() + .unwrap() + .bind_app_context(Arc::clone(self)); + } + } + } + + pub fn spv_manager(&self) -> &Arc { + &self.spv_manager + } + + pub fn start_spv(self: &Arc) -> Result<(), String> { + self.spv_manager.start()?; + self.spv_attach_current_wallets(); + self.spv_setup_reconcile_listener(); + Ok(()) + } + + pub fn spv_attach_current_wallets(&self) { + // Build attachment from current wallets and schedule attach. + let spv = Arc::clone(&self.spv_manager); + let network = self.network; + let wallets_snapshot = { + let wallets = self.wallets.read().unwrap(); + wallets.clone() + }; + let attachment = WatchOnlyWalletAttachment::from_wallets(network, &wallets_snapshot); + let subtasks = self.subtasks.clone(); + subtasks.spawn_sync(async move { + if let Err(e) = spv.attach_watch_only_accounts(attachment).await { + tracing::warn!("Failed to attach watch-only wallets to SPV: {}", e); + } + }); + } + + /// Subscribe to SPV reconcile signals and debounce updates. + pub fn spv_setup_reconcile_listener(self: &Arc) { + use tokio::time::{Duration, Instant, sleep}; + let rx = self.spv_manager.register_reconcile_channel(); + let ctx = Arc::clone(self); + self.subtasks.spawn_sync(async move { + tokio::pin!(rx); + let mut last = Instant::now(); + loop { + tokio::select! { + maybe = rx.recv() => { + if maybe.is_none() { break; } + // simple debounce window + if last.elapsed() > Duration::from_millis(300) { + if let Err(e) = ctx.reconcile_spv_wallets().await { tracing::debug!("SPV reconcile error: {}", e); } + last = Instant::now(); + } else { + sleep(Duration::from_millis(300)).await; + if let Err(e) = ctx.reconcile_spv_wallets().await { tracing::debug!("SPV reconcile error: {}", e); } + last = Instant::now(); + } + } + } + } + }); + } + + /// Reconcile SPV wallet state into DET. + pub async fn reconcile_spv_wallets(&self) -> Result<(), String> { + let wm_arc = self.spv_manager.wallet(); + let wm = wm_arc.read().await; + let mapping = self.spv_manager.det_wallets_snapshot(); + + // Take a snapshot of known addresses per wallet so we can scope DB updates + let wallets_guard = self.wallets.read().unwrap(); + + for (seed_hash, wallet_id) in mapping.iter() { + // Log total balance for visibility + let balance = wm + .get_wallet_balance(wallet_id) + .map_err(|e| format!("get_wallet_balance failed: {e}"))?; + tracing::debug!(wallet = %hex::encode(seed_hash), confirmed = balance.confirmed, unconfirmed = balance.unconfirmed, total = balance.total, "SPV balance snapshot"); + + // Get the wallet's known addresses (only update those to avoid cross-wallet churn) + let mut known_addresses: std::collections::BTreeSet = + if let Some(wref) = wallets_guard.get(seed_hash) { + let w = wref.read().unwrap(); + w.known_addresses.keys().cloned().collect() + } else { + continue; + }; + + // Clear existing UTXOs for these addresses in this network + for addr in &known_addresses { + let _ = self.db.execute( + "DELETE FROM utxos WHERE address = ? AND network = ?", + rusqlite::params![addr.to_string(), self.network.to_string()], + ); + } + + // Read current UTXOs from SPV and re-insert, registering unknown addresses if derivation metadata is available + let utxos = wm + .wallet_utxos(wallet_id) + .map_err(|e| format!("wallet_utxos failed: {e}"))?; + + use dash_sdk::dpp::dashcore::Address as CoreAddress; + // no-op + + let mut per_address_sum: std::collections::BTreeMap = + Default::default(); + + for u in utxos { + // Best-effort accessors for outpoint/txout; adjust if API differs + // Try field access (common struct layout): `outpoint` + `txout` + let outpoint = u.outpoint; + let tx_out = u.txout.clone(); + + // Derive address from script + let address = match CoreAddress::from_script(&tx_out.script_pubkey, self.network) { + Ok(a) => a, + Err(_) => continue, + }; + + // If address unknown to DET, try to register using SPV metadata + if !known_addresses.contains(&address) { + if let Some(info) = wm.get_wallet_info(wallet_id) { + // Map network for accounts lookup if required by API + let net = match self.network { + dash_sdk::dpp::dashcore::Network::Dash => { + dash_sdk::dpp::key_wallet::Network::Dash + } + dash_sdk::dpp::dashcore::Network::Testnet => { + dash_sdk::dpp::key_wallet::Network::Testnet + } + dash_sdk::dpp::dashcore::Network::Devnet => { + dash_sdk::dpp::key_wallet::Network::Devnet + } + dash_sdk::dpp::dashcore::Network::Regtest => { + dash_sdk::dpp::key_wallet::Network::Regtest + } + _ => dash_sdk::dpp::key_wallet::Network::Dash, + }; + if let Some(collection) = info.accounts(net) { + let mut registered = false; + for acc in collection.all_accounts() { + if let Some(ai) = acc.get_address_info(&address) { + use crate::model::wallet::{ + DerivationPathReference, DerivationPathType, + }; + + let path_reference = DerivationPathReference::BIP44; + let path_type = DerivationPathType::CLEAR_FUNDS; // minimal classification + + // Insert into DB (idempotent) and update in-memory wallet model + if let Some(wref) = wallets_guard.get(seed_hash) + && let Ok(mut w) = wref.write() + { + let _ = self.db.add_address_if_not_exists( + seed_hash, + &address, + &self.network, + &ai.path, + path_reference, + path_type, + None, + ); + // Update in-memory maps + use crate::model::wallet::AddressInfo as WalletAddressInfo; + w.known_addresses.insert(address.clone(), ai.path.clone()); + w.watched_addresses.insert( + ai.path.clone(), + WalletAddressInfo { + address: address.clone(), + path_type, + path_reference, + }, + ); + known_addresses.insert(address.clone()); + registered = true; + } + if registered { + break; + } + } + } + if !registered { + // SPV has no derivation metadata for this address under this wallet; skip it. + continue; + } + } else { + // No accounts collection; skip registration + continue; + } + } else { + // No wallet info available; skip registration + continue; + } + } + + // Insert UTXO row + self.db + .insert_utxo( + outpoint.txid.as_ref(), + outpoint.vout, + &address, + tx_out.value, + &tx_out.script_pubkey.to_bytes(), + self.network, + ) + .map_err(|e| e.to_string())?; + + // Sum per address for balance update + *per_address_sum.entry(address).or_default() += tx_out.value; + } + + // Write per-address balances into DB and wallet model + if let Some(wref) = wallets_guard.get(seed_hash) + && let Ok(mut w) = wref.write() + { + for (addr, sum) in per_address_sum.into_iter() { + // Update wallet and DB through model helper + let _ = w.update_address_balance(&addr, sum, self); + } + } + } + + Ok(()) + } + + pub fn stop_spv(&self) { + self.spv_manager.stop(); + } + pub fn is_developer_mode(&self) -> bool { self.developer_mode.load(Ordering::Relaxed) } @@ -260,10 +557,25 @@ impl AppContext { ) .map_err(|e| format!("Failed to create new Core RPC client: {e}"))?; - // 3. Rebuild the Sdk with the updated config - let provider = Provider::new(self.db.clone(), self.network, &cfg) - .map_err(|e| format!("Failed to init provider: {e}"))?; - let new_sdk = initialize_sdk(&cfg, self.network, provider.clone()); + // 3. Rebuild the Sdk with the updated config and current backend mode + let new_sdk = match self.core_backend_mode() { + CoreBackendMode::Spv => { + // Reuse existing SPV provider (rebinding below to ensure context is set) + let provider = self.spv_context_provider.read().unwrap().clone(); + initialize_sdk(&cfg, self.network, provider) + } + CoreBackendMode::Rpc => { + // Create a fresh RPC provider with the new config + let rpc_provider = RpcProvider::new(self.db.clone(), self.network, &cfg) + .map_err(|e| format!("Failed to init RPC provider: {e}"))?; + // Swap in the updated RPC provider for future switches + { + let mut guard = self.rpc_context_provider.write().unwrap(); + *guard = rpc_provider.clone(); + } + initialize_sdk(&cfg, self.network, rpc_provider) + } + }; // 4. Swap them in { @@ -278,8 +590,21 @@ impl AppContext { *sdk_lock = new_sdk; } - // Rebind the provider to the new app context - provider.bind_app_context(self.clone()); + // Rebind providers to ensure they hold the new AppContext reference + self.spv_context_provider + .read() + .unwrap() + .bind_app_context(self.clone()); + if self.core_backend_mode() == CoreBackendMode::Rpc { + self.rpc_context_provider + .read() + .unwrap() + .bind_app_context(self.clone()); + } else { + let sdk_lock = self.sdk.write().expect("SDK lock poisoned"); + let provider = self.spv_context_provider.read().unwrap().clone(); + sdk_lock.set_context_provider(provider); + } Ok(()) } @@ -511,6 +836,12 @@ impl AppContext { .update_dash_core_execution_settings(custom_dash_qt_path, overwrite_dash_conf) } + /// Updates the disable_zmq flag in settings + pub fn update_disable_zmq(&self, disable: bool) -> Result<()> { + let _guard = self.invalidate_settings_cache(); + self.db.update_disable_zmq(disable) + } + /// Invalidates the settings cache and returns a guard /// /// The cache is invalidated immediately and the guard prevents concurrent access diff --git a/src/context_provider.rs b/src/context_provider.rs index c100a6424..8671bdfc0 100644 --- a/src/context_provider.rs +++ b/src/context_provider.rs @@ -145,3 +145,9 @@ impl Clone for Provider { } } } + +impl std::fmt::Debug for Provider { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Provider").finish() + } +} diff --git a/src/context_provider_spv.rs b/src/context_provider_spv.rs new file mode 100644 index 000000000..f04effa38 --- /dev/null +++ b/src/context_provider_spv.rs @@ -0,0 +1,125 @@ +use crate::context::AppContext; +use crate::database::Database; +use dash_sdk::dpp::dashcore::Network; +use dash_sdk::dpp::data_contract::accessors::v0::DataContractV0Getters; +use dash_sdk::dpp::version::PlatformVersion; +use dash_sdk::error::ContextProviderError; +use dash_sdk::platform::{ContextProvider, DataContract}; +use std::sync::{Arc, Mutex}; + +/// SPV-based ContextProvider for the Dash SDK. +/// +/// - DataContract and TokenConfiguration are served from the local DB (same as RPC provider) +/// - Quorum public keys are resolved via dash-spv (through SpvManager) when in SPV mode +#[derive(Debug)] +pub(crate) struct SpvProvider { + db: Arc, + app_context: Mutex>>, + _network: Network, +} + +impl SpvProvider { + pub fn new(db: Arc, network: Network) -> Result { + Ok(Self { + db, + app_context: Default::default(), + _network: network, + }) + } + + /// Attach the `AppContext` so we can access SpvManager and settings. + pub fn bind_app_context(&self, app_context: Arc) { + let mut ac = self.app_context.lock().expect("lock poisoned"); + ac.replace(app_context); + } +} + +impl ContextProvider for SpvProvider { + fn get_data_contract( + &self, + data_contract_id: &dash_sdk::platform::Identifier, + _platform_version: &PlatformVersion, + ) -> Result>, ContextProviderError> { + let app_ctx_guard = self.app_context.lock().expect("lock poisoned"); + let app_ctx = app_ctx_guard + .as_ref() + .ok_or(ContextProviderError::Config("no app context".to_string()))?; + + if data_contract_id == &app_ctx.dpns_contract.id() { + Ok(Some(app_ctx.dpns_contract.clone())) + } else if data_contract_id == &app_ctx.token_history_contract.id() { + Ok(Some(app_ctx.token_history_contract.clone())) + } else if data_contract_id == &app_ctx.withdraws_contract.id() { + Ok(Some(app_ctx.withdraws_contract.clone())) + } else if data_contract_id == &app_ctx.keyword_search_contract.id() { + Ok(Some(app_ctx.keyword_search_contract.clone())) + } else { + let dc = self + .db + .get_contract_by_id(*data_contract_id, app_ctx.as_ref()) + .map_err(|e| ContextProviderError::Generic(e.to_string()))?; + + drop(app_ctx_guard); + + Ok(dc.map(|qc| Arc::new(qc.contract))) + } + } + + fn get_token_configuration( + &self, + token_id: &dash_sdk::platform::Identifier, + ) -> Result, ContextProviderError> + { + let app_ctx_guard = self.app_context.lock().expect("lock poisoned"); + let app_ctx = app_ctx_guard + .as_ref() + .ok_or(ContextProviderError::Config("no app context".to_string()))?; + + self.db + .get_token_config_for_id(token_id, app_ctx) + .map_err(|e| ContextProviderError::Generic(e.to_string())) + } + + fn get_quorum_public_key( + &self, + quorum_type: u32, + quorum_hash: [u8; 32], + core_chain_locked_height: u32, + ) -> Result<[u8; 48], ContextProviderError> { + let app_ctx_guard = self.app_context.lock().expect("lock poisoned"); + let app_ctx = app_ctx_guard + .as_ref() + .ok_or(ContextProviderError::Config("no app context".to_string()))?; + + // Ask SPV manager for the public key corresponding to (type, hash) + match app_ctx.spv_manager().get_quorum_public_key( + quorum_type, + quorum_hash, + core_chain_locked_height, + ) { + Ok(key) => Ok(key), + Err(e) => Err(ContextProviderError::Generic(format!( + "SPV quorum key lookup failed: {}", + e + ))), + } + } + + fn get_platform_activation_height( + &self, + ) -> Result { + // TODO: wire actual activation height if needed + Ok(1) + } +} + +impl Clone for SpvProvider { + fn clone(&self) -> Self { + let app_guard = self.app_context.lock().expect("lock poisoned"); + Self { + db: self.db.clone(), + app_context: Mutex::new(app_guard.clone()), + _network: self._network, + } + } +} diff --git a/src/database/initialization.rs b/src/database/initialization.rs index 68b285cc8..036b3eced 100644 --- a/src/database/initialization.rs +++ b/src/database/initialization.rs @@ -4,7 +4,7 @@ use rusqlite::{Connection, params}; use std::fs; use std::path::Path; -pub const DEFAULT_DB_VERSION: u16 = 11; +pub const DEFAULT_DB_VERSION: u16 = 12; pub const DEFAULT_NETWORK: &str = "dash"; @@ -34,6 +34,7 @@ impl Database { fn apply_version_changes(&self, version: u16, tx: &Connection) -> rusqlite::Result<()> { match version { + 12 => self.add_disable_zmq_column(tx)?, 11 => self.rename_identity_column_is_in_creation_to_status(tx)?, 10 => { self.add_theme_preference_column(tx)?; @@ -215,6 +216,7 @@ impl Database { start_root_screen INTEGER NOT NULL, custom_dash_qt_path TEXT, overwrite_dash_conf INTEGER, + disable_zmq INTEGER DEFAULT 0, theme_preference TEXT DEFAULT 'System', database_version INTEGER NOT NULL )", diff --git a/src/database/settings.rs b/src/database/settings.rs index eaa47bad2..be5fb54f0 100644 --- a/src/database/settings.rs +++ b/src/database/settings.rs @@ -119,6 +119,24 @@ impl Database { Ok(()) } + + pub fn add_disable_zmq_column(&self, conn: &rusqlite::Connection) -> Result<()> { + // Check if disable_zmq column exists + let disable_zmq_exists: bool = conn.query_row( + "SELECT COUNT(*) FROM pragma_table_info('settings') WHERE name='disable_zmq'", + [], + |row| row.get::<_, i32>(0).map(|count| count > 0), + )?; + + if !disable_zmq_exists { + conn.execute( + "ALTER TABLE settings ADD COLUMN disable_zmq INTEGER DEFAULT 0;", + (), + )?; + } + + Ok(()) + } /// Updates the theme preference in the settings table. /// /// Don't call this method directly, use `AppContext` methods instead to ensure proper caching behavior. @@ -139,6 +157,15 @@ impl Database { Ok(()) } + /// Updates the disable_zmq flag in the settings table. + pub fn update_disable_zmq(&self, disable: bool) -> Result<()> { + self.execute( + "UPDATE settings SET disable_zmq = ? WHERE id = 1", + rusqlite::params![disable], + )?; + Ok(()) + } + /// Updates the database version in the settings table. pub fn update_database_version(&self, new_version: u16, conn: &Connection) -> Result<()> { // Ensure the database version is updated @@ -165,13 +192,15 @@ impl Database { Option, Option, bool, + bool, ThemeMode, )>, > { // Query the settings row let conn = self.conn.lock().unwrap(); - let mut stmt = - conn.prepare("SELECT network, start_root_screen, password_check, main_password_salt, main_password_nonce, custom_dash_qt_path, overwrite_dash_conf, theme_preference FROM settings WHERE id = 1")?; + let mut stmt = conn.prepare( + "SELECT network, start_root_screen, password_check, main_password_salt, main_password_nonce, custom_dash_qt_path, overwrite_dash_conf, disable_zmq, theme_preference FROM settings WHERE id = 1", + )?; let result = stmt.query_row([], |row| { let network: String = row.get(0)?; @@ -181,7 +210,8 @@ impl Database { let main_password_nonce: Option> = row.get(4)?; let custom_dash_qt_path: Option = row.get(5)?; let overwrite_dash_conf: Option = row.get(6)?; - let theme_preference: Option = row.get(7)?; + let disable_zmq: Option = row.get(7)?; + let theme_preference: Option = row.get(8)?; // Combine the password-related fields if all are present, otherwise set to None let password_data = match (password_check, main_password_salt, main_password_nonce) { @@ -215,6 +245,7 @@ impl Database { password_data, custom_dash_qt_path.map(PathBuf::from), overwrite_dash_conf.unwrap_or(true), + disable_zmq.unwrap_or(false), theme_mode, )) }); diff --git a/src/lib.rs b/src/lib.rs index 2206c1812..3ff4f42c8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,11 +6,13 @@ pub mod components; pub mod config; pub mod context; pub mod context_provider; +pub mod context_provider_spv; pub mod cpu_compatibility; pub mod database; pub mod logging; pub mod model; pub mod sdk_wrapper; +pub mod spv; pub mod ui; pub mod utils; diff --git a/src/main.rs b/src/main.rs index 1ae6c3f09..73df296e1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,7 +16,7 @@ fn main() -> eframe::Result<()> { check_cpu_compatibility(); // Initialize the Tokio runtime let runtime = tokio::runtime::Builder::new_multi_thread() - .worker_threads(40) + .worker_threads(12) .enable_all() .build() .expect("multi-threading runtime cannot be initialized"); diff --git a/src/model/settings.rs b/src/model/settings.rs index 37b203bc7..aeab6b64c 100644 --- a/src/model/settings.rs +++ b/src/model/settings.rs @@ -14,6 +14,7 @@ pub struct Settings { /// Empty value (`""`) means path deliberately not set, autodetect will not be performed. pub dash_qt_path: Option, pub overwrite_dash_conf: bool, + pub disable_zmq: bool, pub theme_mode: ThemeMode, } @@ -24,6 +25,7 @@ impl Option, Option, bool, + bool, ThemeMode, )> for Settings { @@ -37,10 +39,13 @@ impl Option, Option, bool, + bool, ThemeMode, ), ) -> Self { - Self::new(tuple.0, tuple.1, tuple.2, tuple.3, tuple.4, tuple.5) + Self::new( + tuple.0, tuple.1, tuple.2, tuple.3, tuple.4, tuple.5, tuple.6, + ) } } @@ -53,6 +58,7 @@ impl Default for Settings { None, None, // autodetect true, + false, ThemeMode::System, ) } @@ -66,6 +72,7 @@ impl Settings { password_info: Option, dash_qt_path: Option, overwrite_dash_conf: bool, + disable_zmq: bool, theme_mode: ThemeMode, ) -> Self { Self { @@ -74,6 +81,7 @@ impl Settings { password_info, dash_qt_path: dash_qt_path.or_else(detect_dash_qt_path), overwrite_dash_conf, + disable_zmq, theme_mode, } } diff --git a/src/model/wallet/encryption.rs b/src/model/wallet/encryption.rs index 0630945be..9e2009ca1 100644 --- a/src/model/wallet/encryption.rs +++ b/src/model/wallet/encryption.rs @@ -30,6 +30,7 @@ pub fn derive_password_key(password: &str, salt: &[u8]) -> Result, Strin /// Encrypt the seed using AES-256-GCM. #[allow(clippy::type_complexity)] +#[allow(deprecated)] pub fn encrypt_message( message: &[u8], password: &str, @@ -49,8 +50,9 @@ pub fn encrypt_message( let cipher = Aes256Gcm::new_from_slice(&key).map_err(|e| e.to_string())?; // Encrypt the seed + let nonce_arr = Nonce::from_slice(&nonce); let encrypted_seed = cipher - .encrypt(Nonce::from_slice(&nonce), message) + .encrypt(nonce_arr, message) .map_err(|e| e.to_string())?; Ok((encrypted_seed, salt, nonce)) @@ -76,6 +78,7 @@ impl ClosedKeyItem { } /// Decrypt the seed using AES-256-GCM. + #[allow(deprecated)] pub fn decrypt_seed(&self, password: &str) -> Result<[u8; 64], String> { // Derive the key let key = derive_password_key(password, &self.salt)?; @@ -84,11 +87,9 @@ impl ClosedKeyItem { let cipher = Aes256Gcm::new_from_slice(&key).map_err(|e| e.to_string())?; // Decrypt the seed + let nonce_arr = Nonce::from_slice(&self.nonce); let seed = cipher - .decrypt( - Nonce::from_slice(&self.nonce), - self.encrypted_seed.as_slice(), - ) + .decrypt(nonce_arr, self.encrypted_seed.as_slice()) .map_err(|e| e.to_string())?; let sized_seed = seed.try_into().map_err(|e: Vec| { diff --git a/src/spv/manager.rs b/src/spv/manager.rs new file mode 100644 index 000000000..7b192b54f --- /dev/null +++ b/src/spv/manager.rs @@ -0,0 +1,719 @@ +use crate::app_dir::app_user_data_dir_path; +use crate::config::NetworkConfig; +use crate::utils::tasks::TaskManager; +use dash_sdk::dash_spv::network::MultiPeerNetworkManager; +use dash_sdk::dash_spv::storage::DiskStorageManager; +use dash_sdk::dash_spv::types::{DetailedSyncProgress, SpvEvent, SyncProgress, ValidationMode}; +use dash_sdk::dash_spv::{ClientConfig, DashSpvClient}; +use dash_sdk::dpp::dashcore::Network; +use dash_sdk::dpp::key_wallet::wallet::managed_wallet_info::ManagedWalletInfo; +use dash_sdk::dpp::key_wallet::wallet::managed_wallet_info::managed_account_operations::ManagedAccountOperations; +use dash_sdk::dpp::key_wallet_manager::wallet_manager::{WalletError, WalletId, WalletManager}; +// use dash_sdk::dpp::key_wallet::bip32::ExtendedPubKey; // not needed directly here +use crate::spv::wallet_bridge::{WatchOnlyAccount, WatchOnlyWalletAttachment}; +use dash_sdk::dpp::key_wallet; +use dash_sdk::dpp::key_wallet::account::{AccountType, StandardAccountType}; +use std::fmt; +use std::fs; +use std::net::ToSocketAddrs; +use std::path::PathBuf; +use std::sync::{Arc, Mutex, RwLock}; +use std::time::SystemTime; +use tokio::sync::RwLock as AsyncRwLock; +use tokio::sync::mpsc; +use tokio_util::sync::CancellationToken; + +/// Preferred backend for Core-level operations. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub enum CoreBackendMode { + #[default] + Rpc = 0, + Spv = 1, +} + +impl CoreBackendMode { + pub fn as_u8(self) -> u8 { + self as u8 + } +} + +impl From for CoreBackendMode { + fn from(value: u8) -> Self { + match value { + 1 => CoreBackendMode::Spv, + _ => CoreBackendMode::Rpc, + } + } +} + +/// High-level status of the SPV client runtime. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] +pub enum SpvStatus { + #[default] + Idle, + Starting, + Syncing, + Running, + Stopping, + Stopped, + Error, +} + +impl SpvStatus { + pub fn is_active(self) -> bool { + matches!( + self, + SpvStatus::Starting | SpvStatus::Syncing | SpvStatus::Running | SpvStatus::Stopping + ) + } +} + +/// Snapshot of the SPV runtime state for UI consumption. +/// Uses dash-spv's built-in progress types directly instead of duplicating. +#[derive(Debug, Clone, Default)] +pub struct SpvStatusSnapshot { + pub status: SpvStatus, + pub sync_progress: Option, + pub detailed_progress: Option, + pub last_error: Option, + pub started_at: Option, + pub last_updated: Option, +} + +/// Manages SPV client lifecycle and exposes status updates. +/// Uses dash-spv's built-in state management while maintaining a dedicated runtime for performance. +pub struct SpvManager { + network: Network, + data_dir: PathBuf, + config: Arc>, + subtasks: Arc, + wallet: Arc>>, + #[allow(clippy::type_complexity)] + client: Arc< + AsyncRwLock< + Option< + DashSpvClient< + WalletManager, + MultiPeerNetworkManager, + DiskStorageManager, + >, + >, + >, + >, + status: Arc>, + last_error: Arc>>, + started_at: Arc>>, + // mapping DET wallet seed_hash -> SPV wallet identifier (if created) + det_wallets: Arc>>, + // signal channel to trigger external reconcile on wallet-related events + reconcile_tx: Mutex>>, + // Cancellation token for clean shutdown + stop_token: Mutex>, +} + +impl SpvManager { + pub fn new( + network: Network, + config: Arc>, + subtasks: Arc, + ) -> Result, String> { + let cfg = config.read().map_err(|e| e.to_string())?; + let data_dir = build_spv_data_dir(network, &cfg)?; + drop(cfg); + fs::create_dir_all(&data_dir).map_err(|e| format!("Failed to create SPV data dir: {e}"))?; + + let manager = Arc::new(Self { + network, + data_dir, + config, + subtasks, + wallet: Arc::new(AsyncRwLock::new(WalletManager::::new())), + client: Arc::new(AsyncRwLock::new(None)), + status: Arc::new(RwLock::new(SpvStatus::Idle)), + last_error: Arc::new(RwLock::new(None)), + started_at: Arc::new(RwLock::new(None)), + det_wallets: Arc::new(RwLock::new(std::collections::BTreeMap::new())), + reconcile_tx: Mutex::new(None), + stop_token: Mutex::new(None), + }); + + Ok(manager) + } + + /// Async status method for getting full details including progress + pub async fn status_async(&self) -> SpvStatusSnapshot { + let client_guard = self.client.read().await; + let status = *self.status.read().expect("SPV status lock poisoned"); + let last_error = self + .last_error + .read() + .expect("SPV last_error lock poisoned") + .clone(); + let started_at = *self + .started_at + .read() + .expect("SPV started_at lock poisoned"); + + // Get progress directly from the client if available + let (sync_progress, detailed_progress) = if let Some(_client) = client_guard.as_ref() { + // Note: These would need to be exposed by dash-spv's DashSpvClient + // For now, we'll track them separately until dash-spv exposes them + (None, None) + } else { + (None, None) + }; + + SpvStatusSnapshot { + status, + sync_progress, + detailed_progress, + last_error, + started_at, + last_updated: Some(SystemTime::now()), + } + } + + /// Sync status method for UI updates (doesn't fetch detailed progress) + pub fn status(&self) -> SpvStatusSnapshot { + let status = *self.status.read().expect("SPV status lock poisoned"); + let last_error = self + .last_error + .read() + .expect("SPV last_error lock poisoned") + .clone(); + let started_at = *self + .started_at + .read() + .expect("SPV started_at lock poisoned"); + + SpvStatusSnapshot { + status, + sync_progress: None, + detailed_progress: None, + last_error, + started_at, + last_updated: Some(SystemTime::now()), + } + } + + pub fn start(self: &Arc) -> Result<(), String> { + // Check if already running + { + let stop_token_guard = self + .stop_token + .lock() + .expect("SPV stop_token lock poisoned"); + if stop_token_guard.is_some() { + return Ok(()); + } + } + + *self.status.write().expect("SPV status lock poisoned") = SpvStatus::Starting; + *self + .last_error + .write() + .expect("SPV last_error lock poisoned") = None; + *self + .started_at + .write() + .expect("SPV started_at lock poisoned") = Some(SystemTime::now()); + + let stop_token = CancellationToken::new(); + *self + .stop_token + .lock() + .expect("SPV stop_token lock poisoned") = Some(stop_token.clone()); + + let manager = Arc::clone(self); + let global_cancel = self.subtasks.cancellation_token.clone(); + + // Spawn a dedicated OS thread with a multi-thread Tokio runtime for SPV operations + // This ensures SPV sync doesn't compete with UI thread resources + std::thread::Builder::new() + .name("spv".to_string()) + .spawn(move || { + let rt = tokio::runtime::Builder::new_multi_thread() + .worker_threads(4) + .enable_all() + .thread_name("spv-rt") + .build() + .expect("Failed to create SPV runtime"); + + rt.block_on(async move { + let manager_for_loop = Arc::clone(&manager); + if let Err(err) = manager_for_loop.run_spv_loop(stop_token, global_cancel).await { + tracing::error!(error = %err, network = ?manager.network, "SPV runtime failed"); + *manager.last_error.write().expect("SPV last_error lock poisoned") = Some(err.clone()); + *manager.status.write().expect("SPV status lock poisoned") = SpvStatus::Error; + } + + // Clean up on exit + *manager.stop_token.lock().expect("SPV stop_token lock poisoned") = None; + }); + }) + .map_err(|e| format!("Failed to spawn SPV thread: {e}"))?; + + Ok(()) + } + + pub fn stop(&self) { + *self.status.write().expect("SPV status lock poisoned") = SpvStatus::Stopping; + + // Signal the runtime to stop + if let Some(token) = self + .stop_token + .lock() + .expect("SPV stop_token lock poisoned") + .as_ref() + { + token.cancel(); + } + } + + pub fn wallet(&self) -> Arc>> { + Arc::clone(&self.wallet) + } + + pub fn det_wallets_snapshot(&self) -> std::collections::BTreeMap<[u8; 32], WalletId> { + self.det_wallets + .read() + .map(|m| m.clone()) + .unwrap_or_default() + } + + /// Create a reconciliation signal channel for external listeners. + /// Returns a receiver that will get a signal when SPV wallet state likely changed. + pub fn register_reconcile_channel(&self) -> mpsc::Receiver<()> { + let (tx, rx) = mpsc::channel(64); + let mut guard = self.reconcile_tx.lock().expect("reconcile_tx poisoned"); + *guard = Some(tx); + rx + } + + /// Attempt to resolve a quorum public key via the SPV client's masternode/quorum state. + /// + /// Note: This is a blocking, best-effort lookup. If SPV state is unavailable, + /// or the key is not known yet, an error is returned for the caller to handle. + pub fn get_quorum_public_key( + &self, + quorum_type: u32, + quorum_hash: [u8; 32], + core_chain_locked_height: u32, + ) -> Result<[u8; 48], String> { + // Try repeatedly to grab a non-blocking read guard. + // We avoid blocking_read to prevent panicking inside Tokio runtime threads. + let mut attempts = 0u32; + loop { + if let Ok(guard) = self.client.try_read() { + if let Some(client) = guard.as_ref() { + if let Some(q) = client.get_quorum_at_height( + core_chain_locked_height, + quorum_type as u8, + &quorum_hash, + ) { + let pk48: [u8; 48] = *q.quorum_entry.quorum_public_key.as_ref(); + return Ok(pk48); + } else { + return Err(format!( + "Quorum not found at height {} for llmq_type={} hash=0x{}", + core_chain_locked_height, + quorum_type, + hex::encode(quorum_hash) + )); + } + } else { + return Err("SPV client not initialized".to_string()); + } + } + + attempts = attempts.saturating_add(1); + if attempts > 500 { + return Err("SPV client busy; try again".to_string()); + } + // Short backoff to yield to the writer; keep small to avoid stalling proof verification. + std::thread::sleep(std::time::Duration::from_millis(4)); + } + } + + /// Attach watch-only accounts (e.g., BIP44 account 0 xpubs) from DET into the SPV wallet manager. + /// This stores a mapping locally and attempts to prepare the SPV wallet manager state when possible. + pub async fn attach_watch_only_accounts( + &self, + attachment: WatchOnlyWalletAttachment, + ) -> Result<(), String> { + // Map dashcore::Network to key_wallet::Network (they are identical variants). + fn to_wallet_network(n: Network) -> key_wallet::Network { + match n { + Network::Dash => key_wallet::Network::Dash, + Network::Testnet => key_wallet::Network::Testnet, + Network::Devnet => key_wallet::Network::Devnet, + Network::Regtest => key_wallet::Network::Regtest, + other => { + // Fallback: treat unknown as Dash (shouldn't happen for standard nets) + tracing::warn!( + ?other, + "Unknown dashcore::Network; defaulting to Dash for wallet network mapping" + ); + key_wallet::Network::Dash + } + } + } + + let net_wallet = to_wallet_network(attachment.network); + + let mut wm = self.wallet.write().await; + let mut map = self.det_wallets.write().map_err(|e| e.to_string())?; + + for WatchOnlyAccount { + seed_hash, + xpub, + account_index, + } in attachment.accounts + { + let xpub_str = xpub.to_string(); + + // 1) Ensure a watch-only wallet exists for this xpub + let wallet_id = match wm.import_wallet_from_xpub(&xpub_str, net_wallet, false) { + Ok(id) => id, + Err(WalletError::WalletExists(id)) => id, + Err(e) => { + tracing::error!(?e, seed = %hex::encode(seed_hash), "import_wallet_from_xpub failed"); + return Err(format!("import_wallet_from_xpub failed: {e}")); + } + }; + + // 2) Ensure BIP44 account exists on the Wallet (backed by xpub) + let acct_type = AccountType::Standard { + index: account_index, + standard_account_type: StandardAccountType::BIP44Account, + }; + if let Err(e) = wm.create_account(&wallet_id, acct_type, net_wallet, Some(xpub)) { + match e { + WalletError::AccountCreation(msg) if msg.contains("already exists") => { + // Ignore duplicates + } + other => { + tracing::error!(?other, seed = %hex::encode(seed_hash), "create_account failed"); + return Err(format!("create_account failed: {other}")); + } + } + } + + // 3) Add ManagedAccount so filters have monitored addresses (idempotent) + if let Some(info) = wm.get_wallet_info_mut(&wallet_id) { + let _ = info.add_managed_account_from_xpub(acct_type, net_wallet, xpub); + } else { + return Err(format!("wallet_info not found for wallet_id {wallet_id:?}")); + } + + // Store mapping of DET seed_hash to WalletId + map.insert(seed_hash, wallet_id); + } + + // Optional: log monitored addresses count for debugging + let addr_count = wm.monitored_addresses(attachment.network).len(); + tracing::info!(addresses = addr_count, network = ?attachment.network, "SPV now watching addresses"); + + Ok(()) + } + + async fn run_spv_loop( + self: Arc, + stop_token: CancellationToken, + global_cancel: CancellationToken, + ) -> Result<(), String> { + // Build and start the client + let mut client = self.build_client().await?; + client + .start() + .await + .map_err(|e| format!("SPV start failed: {e}"))?; + + // Set up progress handler + if let Some(progress_rx) = client.take_progress_receiver() { + self.spawn_progress_handler(progress_rx); + } + + // Set up event handler + if let Some(event_rx) = client.take_event_receiver() { + self.spawn_event_handler(event_rx); + } + + *self.client.write().await = Some(client); + *self.status.write().expect("SPV status lock poisoned") = SpvStatus::Syncing; + + // Run sync and monitor + self.run_sync_and_monitor(stop_token, global_cancel).await + } + + async fn run_sync_and_monitor( + self: Arc, + stop_token: CancellationToken, + global_cancel: CancellationToken, + ) -> Result<(), String> { + let client_guard = self.client.read().await; + if let Some(client) = client_guard.as_ref() { + // Wait for at least one peer to connect + let mut waited_ms: u64 = 0; + loop { + // Check for cancellation + if stop_token.is_cancelled() || global_cancel.is_cancelled() { + drop(client_guard); + let mut client_guard = self.client.write().await; + if let Some(mut client) = client_guard.take() { + let _ = client.stop().await; + } + *self.status.write().expect("SPV status lock poisoned") = SpvStatus::Stopped; + return Ok(()); + } + + let peers = client.get_peer_count().await; + if peers > 0 { + break; + } + tokio::time::sleep(std::time::Duration::from_millis(200)).await; + waited_ms = waited_ms.saturating_add(200); + if waited_ms % 5000 == 0 { + tracing::info!("SPV waiting for peers... {}s elapsed", waited_ms / 1000); + } + } + + // Need to get a mutable reference for sync_to_tip + drop(client_guard); + let mut client_guard = self.client.write().await; + if let Some(client) = client_guard.as_mut() { + // Sync to tip + match client.sync_to_tip().await { + Ok(progress) => { + tracing::info!("Initial sync complete: {:?}", progress); + *self.status.write().expect("SPV status lock poisoned") = + SpvStatus::Running; + } + Err(err) => { + tracing::error!("Initial sync failed: {}", err); + let _ = client.stop().await; + *self + .last_error + .write() + .expect("SPV last_error lock poisoned") = + Some(format!("Initial sync failed: {err}")); + *self.status.write().expect("SPV status lock poisoned") = SpvStatus::Error; + return Err(format!("Initial sync failed: {err}")); + } + } + + // Monitor network (this blocks until stopped or error) + enum MonitorOutcome { + Completed(Result<(), dash_sdk::dash_spv::SpvError>), + StopRequested, + GlobalCancelled, + } + + let outcome = { + let monitor_future = client.monitor_network(); + tokio::pin!(monitor_future); + + tokio::select! { + result = &mut monitor_future => MonitorOutcome::Completed(result), + _ = stop_token.cancelled() => MonitorOutcome::StopRequested, + _ = global_cancel.cancelled() => MonitorOutcome::GlobalCancelled, + } + }; + + match outcome { + MonitorOutcome::Completed(Ok(())) => { + let _ = client.stop().await; + *self.status.write().expect("SPV status lock poisoned") = + SpvStatus::Stopped; + Ok(()) + } + MonitorOutcome::Completed(Err(err)) => { + let _ = client.stop().await; + let message = format!("monitor_network failed: {err}"); + *self + .last_error + .write() + .expect("SPV last_error lock poisoned") = Some(message.clone()); + *self.status.write().expect("SPV status lock poisoned") = SpvStatus::Error; + Err(message) + } + MonitorOutcome::StopRequested | MonitorOutcome::GlobalCancelled => { + let _ = client.stop().await; + *self.status.write().expect("SPV status lock poisoned") = + SpvStatus::Stopped; + Ok(()) + } + } + } else { + Err("Client not available".to_string()) + } + } else { + Err("Client not initialized".to_string()) + } + } + + fn spawn_progress_handler( + &self, + mut progress_rx: tokio::sync::mpsc::UnboundedReceiver, + ) { + let status = Arc::clone(&self.status); + let cancel = self.subtasks.cancellation_token.clone(); + + self.subtasks.spawn_sync(async move { + let mut last_update = std::time::Instant::now(); + let min_interval = std::time::Duration::from_millis(500); + + loop { + tokio::select! { + _ = cancel.cancelled() => break, + msg = progress_rx.recv() => { + match msg { + Some(detailed) => { + if last_update.elapsed() >= min_interval { + // Update status based on progress + if detailed.percentage >= 100.0 || detailed.sync_progress.header_height >= detailed.peer_best_height { + *status.write().expect("SPV status lock poisoned") = SpvStatus::Running; + } else { + let current = *status.read().expect("SPV status lock poisoned"); + if matches!(current, SpvStatus::Starting | SpvStatus::Idle | SpvStatus::Stopped) { + *status.write().expect("SPV status lock poisoned") = SpvStatus::Syncing; + } + } + last_update = std::time::Instant::now(); + } + } + None => break, + } + } + } + } + }); + } + + fn spawn_event_handler(&self, mut event_rx: tokio::sync::mpsc::UnboundedReceiver) { + let reconcile_tx = self + .reconcile_tx + .lock() + .expect("reconcile_tx poisoned") + .clone(); + let cancel = self.subtasks.cancellation_token.clone(); + + self.subtasks.spawn_sync(async move { + loop { + tokio::select! { + _ = cancel.cancelled() => break, + evt = event_rx.recv() => { + match evt { + Some(event) => { + // Push reconcile signal for wallet-related updates + let should_signal = matches!(event, + SpvEvent::TransactionDetected { .. } | + SpvEvent::BalanceUpdate { .. } | + SpvEvent::BlockProcessed { .. } + ); + if should_signal + && let Some(ref tx) = reconcile_tx { + let _ = tx.try_send(()); + } + } + None => break, + } + } + } + } + }); + } + + async fn build_client( + &self, + ) -> Result< + DashSpvClient< + WalletManager, + MultiPeerNetworkManager, + DiskStorageManager, + >, + String, + > { + let mut config = ClientConfig::new(self.network) + .with_storage_path(self.data_dir.clone()) + .with_validation_mode(ValidationMode::Full) + // Start from the latest built-in checkpoint instead of genesis + // (effective only when storage is empty / first initialization) + .with_start_height(u32::MAX); + + // Pin peers when running against local nodes to avoid random peers. + if self.network == Network::Devnet || self.network == Network::Regtest { + if let Some(peer) = self.primary_peer_socket() { + config.add_peer(peer); + } + } else if self.network == Network::Testnet { + // For testnet testing, connect only to local Dash Core at 127.0.0.1:19999 + if let Ok(mut it) = "127.0.0.1:19999".to_socket_addrs() + && let Some(peer) = it.next() + { + config.add_peer(peer); + } + } + + let network_manager = MultiPeerNetworkManager::new(&config) + .await + .map_err(|e| format!("Failed to initialize SPV network manager: {e}"))?; + + let storage_manager = DiskStorageManager::new(self.data_dir.clone()) + .await + .map_err(|e| format!("Failed to initialize SPV storage: {e}"))?; + + DashSpvClient::new( + config, + network_manager, + storage_manager, + Arc::clone(&self.wallet), + ) + .await + .map_err(|e| format!("Failed to create SPV client: {e}")) + } + + fn primary_peer_socket(&self) -> Option { + let config = self.config.read().ok()?; + + let host = config.core_host.as_str(); + let port = match self.network { + Network::Dash => 9999, + Network::Testnet => 19999, + Network::Devnet => 20001, + Network::Regtest => 19899, + _ => 9999, + }; + + let addr = format!("{}:{}", host, port); + addr.to_socket_addrs().ok()?.next() + } +} + +fn build_spv_data_dir(network: Network, config: &NetworkConfig) -> Result { + let mut base = app_user_data_dir_path().map_err(|e| e.to_string())?; + base.push("spv"); + fs::create_dir_all(&base).map_err(|e| format!("Failed to create SPV base dir: {e}"))?; + + let network_dir = match network { + Network::Dash => "mainnet".to_string(), + Network::Testnet => "testnet".to_string(), + Network::Devnet => config + .devnet_name + .clone() + .unwrap_or_else(|| "devnet".to_string()), + Network::Regtest => "regtest".to_string(), + other => format!("{other:?}"), + }; + + Ok(base.join(network_dir)) +} + +impl fmt::Debug for SpvManager { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("SpvManager") + .field("network", &self.network) + .field("data_dir", &self.data_dir) + .finish() + } +} diff --git a/src/spv/mod.rs b/src/spv/mod.rs new file mode 100644 index 000000000..da6626ad9 --- /dev/null +++ b/src/spv/mod.rs @@ -0,0 +1,5 @@ +mod manager; +mod wallet_bridge; + +pub use manager::{CoreBackendMode, SpvManager, SpvStatus, SpvStatusSnapshot}; +pub use wallet_bridge::{WatchOnlyAccount, WatchOnlyWalletAttachment}; diff --git a/src/spv/wallet_bridge.rs b/src/spv/wallet_bridge.rs new file mode 100644 index 000000000..1271606f3 --- /dev/null +++ b/src/spv/wallet_bridge.rs @@ -0,0 +1,37 @@ +use crate::model::wallet::{Wallet, WalletSeedHash}; +use dash_sdk::dpp::dashcore::Network; +use dash_sdk::dpp::key_wallet::bip32::ExtendedPubKey; +use std::collections::BTreeMap; +use std::sync::{Arc, RwLock}; + +#[derive(Debug, Clone)] +pub struct WatchOnlyAccount { + pub seed_hash: WalletSeedHash, + pub account_index: u32, + pub xpub: ExtendedPubKey, +} + +#[derive(Debug, Clone)] +pub struct WatchOnlyWalletAttachment { + pub network: Network, + pub accounts: Vec, +} + +impl WatchOnlyWalletAttachment { + pub fn from_wallets( + network: Network, + wallets: &BTreeMap>>, + ) -> Self { + let mut accounts = Vec::new(); + for (seed_hash, wallet_arc) in wallets.iter() { + let w = wallet_arc.read().expect("wallet lock poisoned"); + let xpub = w.master_bip44_ecdsa_extended_public_key; + accounts.push(WatchOnlyAccount { + seed_hash: *seed_hash, + account_index: 0, + xpub, + }); + } + Self { network, accounts } + } +} diff --git a/src/ui/network_chooser_screen.rs b/src/ui/network_chooser_screen.rs index 309a72abf..ddef52944 100644 --- a/src/ui/network_chooser_screen.rs +++ b/src/ui/network_chooser_screen.rs @@ -4,15 +4,18 @@ use crate::backend_task::system_task::SystemTask; use crate::backend_task::{BackendTask, BackendTaskSuccessResult}; use crate::config::Config; use crate::context::AppContext; +use crate::spv::{CoreBackendMode, SpvStatus, SpvStatusSnapshot}; use crate::ui::components::left_panel::add_left_panel; use crate::ui::components::styled::{StyledCard, StyledCheckbox, island_central_panel}; use crate::ui::components::top_panel::add_top_panel; -use crate::ui::theme::{DashColors, ThemeMode}; +use crate::ui::theme::{DashColors, Shape, ThemeMode}; use crate::ui::{RootScreenType, ScreenLike}; use crate::utils::path::format_path_for_display; +use dash_sdk::dash_spv::types::{DetailedSyncProgress, SyncStage}; use dash_sdk::dpp::dashcore::Network; use dash_sdk::dpp::identity::TimestampMillis; use eframe::egui::{self, Context, Ui}; +use std::collections::HashMap; use std::path::PathBuf; use std::sync::Arc; use std::time::{Duration, SystemTime, UNIX_EPOCH}; @@ -32,9 +35,11 @@ pub struct NetworkChooserScreen { custom_dash_qt_path: Option, custom_dash_qt_error_message: Option, overwrite_dash_conf: bool, + disable_zmq: bool, developer_mode: bool, theme_preference: ThemeMode, should_reset_collapsing_states: bool, + backend_modes: HashMap, } impl NetworkChooserScreen { @@ -72,8 +77,30 @@ impl NetworkChooserScreen { .flatten() .unwrap_or_default(); let theme_preference = settings.theme_mode; + let disable_zmq = settings.disable_zmq; let custom_dash_qt_path = settings.dash_qt_path; + let mut backend_modes = HashMap::new(); + backend_modes.insert(Network::Dash, mainnet_app_context.core_backend_mode()); + backend_modes.insert( + Network::Testnet, + testnet_app_context + .map(|ctx| ctx.core_backend_mode()) + .unwrap_or_default(), + ); + backend_modes.insert( + Network::Devnet, + devnet_app_context + .map(|ctx| ctx.core_backend_mode()) + .unwrap_or_default(), + ); + backend_modes.insert( + Network::Regtest, + local_app_context + .map(|ctx| ctx.core_backend_mode()) + .unwrap_or_default(), + ); + Self { mainnet_app_context: mainnet_app_context.clone(), testnet_app_context: testnet_app_context.cloned(), @@ -89,9 +116,11 @@ impl NetworkChooserScreen { custom_dash_qt_path, custom_dash_qt_error_message: None, overwrite_dash_conf, + disable_zmq, developer_mode, theme_preference, should_reset_collapsing_states: true, // Start with collapsed state + backend_modes, } } @@ -126,530 +155,825 @@ impl NetworkChooserScreen { ) .map_err(|e| e.to_string()) } - /// Render the network selection table + /// Render the simplified settings interface fn render_network_table(&mut self, ui: &mut Ui) -> AppAction { let mut app_action = AppAction::None; let dark_mode = ui.ctx().style().visuals.dark_mode; - egui::Grid::new("network_grid") - .striped(false) - .spacing([20.0, 10.0]) - .show(ui, |ui| { - // Header row - ui.label( - egui::RichText::new("Network") - .strong() - .underline() - .color(DashColors::text_primary(dark_mode)), - ); + // Connection Settings Card + StyledCard::new().padding(24.0).show(ui, |ui| { + ui.heading("Connection Settings"); + ui.add_space(20.0); + + // Create a table with rows and 2 columns + egui::Grid::new("connection_settings_grid") + .num_columns(2) + .spacing([40.0, 12.0]) + .striped(false) + .show(ui, |ui| { + // Row 1: Connection Type + ui.label( + egui::RichText::new("Connection Type:") + .color(DashColors::text_primary(dark_mode)), + ); + + let current_backend_mode = *self + .backend_modes + .entry(self.current_network) + .or_insert(CoreBackendMode::Rpc); + + let connection_text = match current_backend_mode { + CoreBackendMode::Spv => "SPV Client", + CoreBackendMode::Rpc => "Dash Core RPC", + }; + + let mut connection_mode = current_backend_mode; + egui::ComboBox::from_id_salt("connection_mode_selector") + .selected_text(connection_text) + .width(200.0) + .show_ui(ui, |ui| { + if ui + .selectable_value( + &mut connection_mode, + CoreBackendMode::Spv, + "SPV Client", + ) + .changed() + { + self.backend_modes + .insert(self.current_network, CoreBackendMode::Spv); + let ctx = self.current_app_context(); + ctx.set_core_backend_mode(CoreBackendMode::Spv); + } + if ui + .selectable_value( + &mut connection_mode, + CoreBackendMode::Rpc, + "Dash Core RPC", + ) + .changed() + { + self.backend_modes + .insert(self.current_network, CoreBackendMode::Rpc); + let ctx = self.current_app_context(); + ctx.set_core_backend_mode(CoreBackendMode::Rpc); + ctx.stop_spv(); + } + }); + + ui.end_row(); + + // Row 2: Network + ui.label( + egui::RichText::new("Network:").color(DashColors::text_primary(dark_mode)), + ); + + // Check if currently connected via SPV (only SPV restricts network switching) + let is_spv_connected = if current_backend_mode == CoreBackendMode::Spv { + let ctx = self.current_app_context(); + let snapshot = ctx.spv_manager().status(); + snapshot.status.is_active() + } else { + false // Core mode doesn't restrict network switching + }; + + let network_text = match self.current_network { + Network::Dash => "Mainnet", + Network::Testnet => "Testnet", + Network::Devnet => "Devnet", + Network::Regtest => "Local", + _ => "Unknown", + }; + + let network_combo = egui::ComboBox::from_id_salt("network_selector") + .selected_text(network_text) + .width(200.0); + + let response = ui.add_enabled_ui(!is_spv_connected, |ui| { + network_combo.show_ui(ui, |ui| { + if ui + .selectable_value( + &mut self.current_network, + Network::Dash, + "Mainnet", + ) + .clicked() + { + app_action = AppAction::SwitchNetwork(Network::Dash); + } + if self.testnet_app_context.is_some() + && ui + .selectable_value( + &mut self.current_network, + Network::Testnet, + "Testnet", + ) + .clicked() + { + app_action = AppAction::SwitchNetwork(Network::Testnet); + } + if self.devnet_app_context.is_some() + && ui + .selectable_value( + &mut self.current_network, + Network::Devnet, + "Devnet", + ) + .clicked() + { + app_action = AppAction::SwitchNetwork(Network::Devnet); + } + if self.local_app_context.is_some() + && ui + .selectable_value( + &mut self.current_network, + Network::Regtest, + "Local", + ) + .clicked() + { + app_action = AppAction::SwitchNetwork(Network::Regtest); + } + }); + }); + + if is_spv_connected { + response.response.on_hover_text("Disconnect from SPV first"); + } + + ui.end_row(); + }); + + // Password input for Local network + let current_backend_mode = *self + .backend_modes + .entry(self.current_network) + .or_insert(CoreBackendMode::Rpc); + if self.current_network == Network::Regtest + && current_backend_mode == CoreBackendMode::Rpc + { + ui.add_space(20.0); + ui.separator(); + ui.add_space(12.0); + ui.label( - egui::RichText::new("Status") + egui::RichText::new("Local Network Password") .strong() - .underline() .color(DashColors::text_primary(dark_mode)), ); - // ui.label(egui::RichText::new("Wallet Count").strong().underline()); - // ui.label(egui::RichText::new("Add New Wallet").strong().underline()); - ui.label( - egui::RichText::new("Select") - .strong() - .underline() - .color(DashColors::text_primary(dark_mode)), + ui.add_space(8.0); + + ui.horizontal(|ui| { + ui.text_edit_singleline(&mut self.local_network_dashmate_password); + + if ui.button("Save").clicked() + && let Ok(mut config) = Config::load() + && let Some(local_cfg) = config.config_for_network(Network::Regtest).clone() + { + let updated_local_config = local_cfg + .update_core_rpc_password(self.local_network_dashmate_password.clone()); + config.update_config_for_network( + Network::Regtest, + updated_local_config.clone(), + ); + if let Err(e) = config.save() { + eprintln!("Failed to save config to .env: {e}"); + } + + // Update our local AppContext in memory + if let Some(local_app_context) = &self.local_app_context { + { + // Overwrite the config field with the new password + let mut cfg_lock = local_app_context.config.write().unwrap(); + *cfg_lock = updated_local_config; + } + + // Re-init the client & sdk from the updated config + if let Err(e) = + Arc::clone(local_app_context).reinit_core_client_and_sdk() + { + eprintln!("Failed to re-init local RPC client and sdk: {}", e); + } else { + // Trigger SwitchNetworks + app_action = AppAction::SwitchNetwork(Network::Regtest); + } + } + } + }); + } + }); + + // Connection Status Card + ui.add_space(16.0); + + StyledCard::new().padding(24.0).show(ui, |ui| { + ui.heading("Connection Status"); + ui.add_space(20.0); + + let current_backend_mode = *self + .backend_modes + .entry(self.current_network) + .or_insert(CoreBackendMode::Rpc); + + // Check connection status + let (is_connected, snapshot) = match current_backend_mode { + CoreBackendMode::Rpc => (self.check_network_status(self.current_network), None), + CoreBackendMode::Spv => { + let ctx = self.current_app_context(); + let snap = ctx.spv_manager().status(); + let connected = snap.status.is_active() || snap.status == SpvStatus::Running; + (connected, Some(snap)) + } + }; + + // Button on the left with status + ui.horizontal(|ui| { + if is_connected { + if current_backend_mode == CoreBackendMode::Spv { + let disconnect_button = egui::Button::new( + egui::RichText::new("Disconnect").color(DashColors::WHITE), + ) + .fill(DashColors::ERROR) + .stroke(egui::Stroke::NONE) + .corner_radius(Shape::RADIUS_MD) + .min_size(egui::vec2(120.0, 36.0)); + + if ui.add(disconnect_button).clicked() { + self.current_app_context().stop_spv(); + } + + // Show sync status next to button + ui.add_space(12.0); + + if let Some(snap) = &snapshot { + match snap.status { + SpvStatus::Running => { + ui.colored_label(DashColors::SUCCESS, "Fully Synced - The SPV client can now be used for transacting and querying."); + } + SpvStatus::Syncing | SpvStatus::Starting => { + ui.style_mut().visuals.widgets.inactive.fg_stroke.color = + DashColors::DASH_BLUE; + ui.style_mut().visuals.widgets.hovered.fg_stroke.color = + DashColors::DASH_BLUE; + ui.style_mut().visuals.widgets.active.fg_stroke.color = + DashColors::DASH_BLUE; + ui.spinner(); + ui.label(egui::RichText::new("Syncing...")); + } + SpvStatus::Stopping => { + ui.style_mut().visuals.widgets.inactive.fg_stroke.color = + DashColors::DASH_BLUE; + ui.style_mut().visuals.widgets.hovered.fg_stroke.color = + DashColors::DASH_BLUE; + ui.style_mut().visuals.widgets.active.fg_stroke.color = + DashColors::DASH_BLUE; + ui.spinner(); + ui.label(egui::RichText::new("Disconnecting...")); + } + _ => {} + } + } + } else { + // For Core mode, just show status since it can switch networks freely + ui.colored_label(DashColors::DASH_BLUE, "✓ Connected"); + } + } else { + let connect_button = + egui::Button::new(egui::RichText::new("Connect").color(DashColors::WHITE)) + .fill(DashColors::DASH_BLUE) + .stroke(egui::Stroke::NONE) + .corner_radius(Shape::RADIUS_MD) + .min_size(egui::vec2(120.0, 36.0)); + + if ui.add(connect_button).clicked() { + if current_backend_mode == CoreBackendMode::Spv { + if let Err(err) = self.current_app_context().start_spv() { + app_action = + AppAction::Custom(format!("Failed to start SPV: {}", err)); + } + } else { + // Core mode connect + let settings = + self.current_app_context().get_settings().ok().flatten(); + let dash_qt_path = settings + .and_then(|s| s.dash_qt_path) + .or_else(|| self.custom_dash_qt_path.clone()); + if let Some(path) = dash_qt_path { + app_action = AppAction::BackendTask(BackendTask::CoreTask( + CoreTask::StartDashQT( + self.current_network, + path, + self.overwrite_dash_conf, + ), + )); + } + } + } + } + }); + + // SPV sync progress (only show when SPV is selected and syncing) + if current_backend_mode == CoreBackendMode::Spv + && let Some(snap) = snapshot + && (snap.status == SpvStatus::Syncing || snap.status == SpvStatus::Starting) { + ui.add_space(10.0); + ui.separator(); + ui.add_space(10.0); + + self.render_spv_sync_progress(ui, &snap); + } + }); + + // Advanced Settings section with clean dropdown + ui.add_space(16.0); + + StyledCard::new().padding(20.0).show(ui, |ui| { + // Custom collapsing header + let id = ui.make_persistent_id("advanced_settings_header"); + let mut state = egui::collapsing_header::CollapsingState::load_with_default_open( + ui.ctx(), + id, + false, + ); + + // Custom expand/collapse icon + let icon = if state.is_open() { + "−" // Minus sign when open + } else { + "+" // Plus sign when closed + }; + + let response = ui.horizontal(|ui| { + // Make the content area clickable + let response = ui.allocate_response( + egui::vec2(ui.available_width(), 30.0), + egui::Sense::click(), ); - ui.label( - egui::RichText::new("Start") - .strong() - .underline() - .color(DashColors::text_primary(dark_mode)), + + // Draw the content on top of the response area + let painter = ui.painter_at(response.rect); + let mut cursor = response.rect.min; + + // Icon with background + let icon_size = egui::vec2(24.0, 24.0); + let icon_rect = egui::Rect::from_min_size(cursor, icon_size); + painter.rect_filled( + icon_rect, + egui::CornerRadius::from(4.0), + DashColors::glass_white(dark_mode), ); - ui.label( - egui::RichText::new("Dashmate Password") - .strong() - .underline() - .color(DashColors::text_primary(dark_mode)), + + let icon_text = painter.layout_no_wrap( + icon.to_string(), + egui::FontId::proportional(16.0), + DashColors::DASH_BLUE, ); - ui.label( - egui::RichText::new("Actions") - .strong() - .underline() - .color(DashColors::text_primary(dark_mode)), + painter.galley( + icon_rect.center() - icon_text.size() / 2.0, + icon_text, + DashColors::DASH_BLUE, ); - ui.end_row(); - - // Render Mainnet Row - app_action |= self.render_network_row(ui, Network::Dash, "Mainnet"); - // Render Testnet Row - app_action |= self.render_network_row(ui, Network::Testnet, "Testnet"); + cursor.x += icon_size.x + 8.0; - // Render Devnet Row - app_action |= self.render_network_row(ui, Network::Devnet, "Devnet"); + // Advanced Settings text + let text = painter.layout_no_wrap( + "Advanced Settings".to_string(), + egui::FontId::proportional(16.0), + DashColors::text_primary(dark_mode), + ); + painter.galley( + cursor + egui::vec2(0.0, (icon_size.y - text.size().y) / 2.0), + text, + DashColors::text_primary(dark_mode), + ); - // Render Local Row - app_action |= self.render_network_row(ui, Network::Regtest, "Local"); + response }); - ui.add_space(20.0); + if response.inner.clicked() { + state.toggle(ui); + } - // Advanced Settings - Collapsible - let mut collapsing_state = egui::collapsing_header::CollapsingState::load_with_default_open( - ui.ctx(), - ui.make_persistent_id("advanced_settings_header"), - false, - ); + if response.inner.hovered() { + ui.ctx().set_cursor_icon(egui::CursorIcon::PointingHand); + }; + state.show_body_unindented(ui, |ui| { + ui.add_space(12.0); + + // Theme Selection + ui.horizontal(|ui| { + ui.label(egui::RichText::new("🎨").size(16.0)); + ui.label("Theme:"); + + egui::ComboBox::from_id_salt("theme_selection") + .selected_text(match self.theme_preference { + ThemeMode::Light => "☀ Light", + ThemeMode::Dark => "🌙 Dark", + ThemeMode::System => "🖥 System", + }) + .width(100.0) + .show_ui(ui, |ui| { + if ui + .selectable_value( + &mut self.theme_preference, + ThemeMode::System, + "🖥 System", + ) + .clicked() + { + app_action |= AppAction::BackendTask(BackendTask::SystemTask( + SystemTask::UpdateThemePreference(ThemeMode::System), + )); + } + if ui + .selectable_value( + &mut self.theme_preference, + ThemeMode::Light, + "☀ Light", + ) + .clicked() + { + app_action |= AppAction::BackendTask(BackendTask::SystemTask( + SystemTask::UpdateThemePreference(ThemeMode::Light), + )); + } + if ui + .selectable_value( + &mut self.theme_preference, + ThemeMode::Dark, + "🌙 Dark", + ) + .clicked() + { + app_action |= AppAction::BackendTask(BackendTask::SystemTask( + SystemTask::UpdateThemePreference(ThemeMode::Dark), + )); + } + }); + }); - // Force close if we need to reset - if self.should_reset_collapsing_states { - collapsing_state.set_open(false); - self.should_reset_collapsing_states = false; - } + // Dash-QT Path + ui.add_space(10.0); + ui.separator(); + ui.add_space(10.0); - collapsing_state - .show_header(ui, |ui| { - ui.label("Advanced Settings"); - }) - .body(|ui| { - // Advanced Settings Card Content - StyledCard::new().padding(20.0).show(ui, |ui| { - ui.vertical(|ui| { - // Dash-QT Path Section - ui.group(|ui| { - ui.vertical(|ui| { - ui.label( - egui::RichText::new("Custom Dash-QT Path") - .strong() - .color(DashColors::text_primary(dark_mode)), - ); - ui.add_space(8.0); - - ui.horizontal(|ui| { - if ui - .add( - egui::Button::new("Select File") - .fill(DashColors::DASH_BLUE) - .stroke(egui::Stroke::NONE) - .corner_radius(egui::CornerRadius::same(6)) - .min_size(egui::vec2(120.0, 32.0)), - ) - .clicked() - && let Some(path) = rfd::FileDialog::new().pick_file() { - let file_name = - path.file_name().and_then(|f| f.to_str()); - if let Some(file_name) = file_name { - self.custom_dash_qt_path = None; - self.custom_dash_qt_error_message = None; - - // Handle macOS .app bundles - let resolved_path = if cfg!(target_os = "macos") && path.extension().and_then(|s| s.to_str()) == Some("app") { - // For .app bundles, resolve to the actual executable inside - path.join("Contents").join("MacOS").join("Dash-Qt") - } else { - path.clone() - }; - - // Check if the resolved path exists and is valid - let is_valid = if cfg!(target_os = "windows") { - file_name.to_ascii_lowercase().ends_with("dash-qt.exe") - } else if cfg!(target_os = "macos") { - // Accept both direct executable and .app bundle - file_name.eq_ignore_ascii_case("dash-qt") || - (file_name.to_ascii_lowercase().ends_with(".app") && resolved_path.exists()) - } else { - // Linux - file_name.eq_ignore_ascii_case("dash-qt") - }; - - if is_valid { - self.custom_dash_qt_path = Some(resolved_path); - self.custom_dash_qt_error_message = None; - self.save() - .expect("Expected to save db settings"); - } else { - let required_file_name = if cfg!(target_os = "windows") { - "dash-qt.exe" - } else if cfg!(target_os = "macos") { - "Dash-Qt or Dash-Qt.app" - } else { - "dash-qt" - }; - self.custom_dash_qt_error_message = Some(format!( - "Invalid file: Please select a valid '{}'.", - required_file_name - )); - } - } - } - - if (self.custom_dash_qt_path.is_some() - || self.custom_dash_qt_error_message.is_some()) - && ui - .add( - egui::Button::new("Clear") - .fill(DashColors::ERROR.linear_multiply(0.8)) - .stroke(egui::Stroke::NONE) - .corner_radius(egui::CornerRadius::same(6)) - .min_size(egui::vec2(80.0, 32.0)), - ) - .clicked() - { - self.custom_dash_qt_path = Some(PathBuf::new()); // Reset to empty to avoid auto-detection - self.custom_dash_qt_error_message = None; - self.save().expect("Expected to save db settings"); - } - }); - - ui.add_space(8.0); - - if let Some(ref file) = self.custom_dash_qt_path { - ui.horizontal(|ui| { - ui.label("Selected:"); - ui.label( - egui::RichText::new(format_path_for_display(file)).color(DashColors::SUCCESS), - ) - .on_hover_text(format!("Full path: {}", file.display())); - }); - } else if let Some(ref error) = self.custom_dash_qt_error_message { - ui.horizontal(|ui| { - ui.label("Error:"); - ui.colored_label(DashColors::ERROR, error); - }); + ui.label( + egui::RichText::new("Dash Core Executable Path") + .strong() + .color(DashColors::text_primary(dark_mode)), + ); + ui.add_space(8.0); + + ui.horizontal(|ui| { + if ui.button("Select File").clicked() + && let Some(path) = rfd::FileDialog::new().pick_file() + { + let file_name = path.file_name().and_then(|f| f.to_str()); + if let Some(file_name) = file_name { + self.custom_dash_qt_path = None; + self.custom_dash_qt_error_message = None; + + // Handle macOS .app bundles + let resolved_path = if cfg!(target_os = "macos") + && path.extension().and_then(|s| s.to_str()) == Some("app") + { + path.join("Contents").join("MacOS").join("Dash-Qt") + } else { + path.clone() + }; + + // Check if the resolved path exists and is valid + let is_valid = if cfg!(target_os = "windows") { + file_name.to_ascii_lowercase().ends_with("dash-qt.exe") + } else if cfg!(target_os = "macos") { + file_name.eq_ignore_ascii_case("dash-qt") + || (file_name.to_ascii_lowercase().ends_with(".app") + && resolved_path.exists()) + } else { + file_name.eq_ignore_ascii_case("dash-qt") + }; + + if is_valid { + self.custom_dash_qt_path = Some(resolved_path); + self.custom_dash_qt_error_message = None; + self.save().expect("Expected to save db settings"); + } else { + let required_file_name = if cfg!(target_os = "windows") { + "dash-qt.exe" + } else if cfg!(target_os = "macos") { + "Dash-Qt or Dash-Qt.app" } else { - ui.label( - egui::RichText::new( - "dash-qt not found, click 'Select File' to choose.", - ) - .color(DashColors::TEXT_SECONDARY) - .italics(), - ); - } - }); - }); - - ui.add_space(16.0); + "dash-qt" + }; + self.custom_dash_qt_error_message = Some(format!( + "Invalid file: Please select a valid '{}'.", + required_file_name + )); + } + } + } - // Configuration Options Section - ui.group(|ui| { - ui.vertical(|ui| { - ui.label( - egui::RichText::new("Configuration Options") - .strong() - .color(DashColors::text_primary(dark_mode)), - ); - ui.add_space(8.0); + if self.custom_dash_qt_path.is_some() && ui.button("Clear").clicked() { + self.custom_dash_qt_path = Some(PathBuf::new()); + self.custom_dash_qt_error_message = None; + self.save().expect("Expected to save db settings"); + } + }); - // Overwrite dash.conf checkbox - ui.horizontal(|ui| { - if StyledCheckbox::new( - &mut self.overwrite_dash_conf, - "Overwrite dash.conf", - ) - .show(ui) - .clicked() - { - self.save().expect("Expected to save db settings"); - } - ui.label( - egui::RichText::new( - "Automatically configure dash.conf with required settings", - ) - .color(DashColors::TEXT_SECONDARY), - ); - }); + if let Some(ref file) = self.custom_dash_qt_path { + if !file.as_os_str().is_empty() { + ui.horizontal(|ui| { + ui.label("Path:"); + ui.label( + egui::RichText::new(format_path_for_display(file)) + .color(DashColors::SUCCESS) + .italics(), + ); + }); + } + } else if let Some(ref error) = self.custom_dash_qt_error_message { + ui.colored_label(DashColors::ERROR, error); + } - ui.add_space(8.0); + // Configuration Options + ui.add_space(10.0); + ui.separator(); + ui.add_space(10.0); + ui.label( + egui::RichText::new("Configuration Options") + .strong() + .color(DashColors::text_primary(dark_mode)), + ); + ui.add_space(8.0); + + ui.horizontal(|ui| { + if StyledCheckbox::new(&mut self.overwrite_dash_conf, "Overwrite dash.conf") + .show(ui) + .clicked() + { + self.save().expect("Expected to save db settings"); + } + ui.label( + egui::RichText::new("Auto-configure required settings") + .color(DashColors::TEXT_SECONDARY) + .italics(), + ); + }); - // Developer mode checkbox - ui.horizontal(|ui| { - if StyledCheckbox::new( - &mut self.developer_mode, - "Enable developer mode", - ) - .show(ui) - .clicked() - { - // Update the global developer mode in config - if let Ok(mut config) = Config::load() { - config.developer_mode = Some(self.developer_mode); - if let Err(e) = config.save() { - eprintln!("Failed to save config to .env: {e}"); - } - - // Update developer mode for all contexts - self.mainnet_app_context - .enable_developer_mode(self.developer_mode); - - if let Some(ref testnet_ctx) = self.testnet_app_context - { - testnet_ctx - .enable_developer_mode(self.developer_mode); - } - - if let Some(ref devnet_ctx) = self.devnet_app_context { - devnet_ctx - .enable_developer_mode(self.developer_mode); - } - - if let Some(ref local_ctx) = self.local_app_context { - local_ctx - .enable_developer_mode(self.developer_mode); - } - } - } - ui.label( - egui::RichText::new( - "Enables advanced features and less strict validation", - ) - .color(DashColors::TEXT_SECONDARY), - ); - }); - }); - }); + // Disable ZMQ toggle (requires restart) + ui.add_space(6.0); + ui.horizontal(|ui| { + if StyledCheckbox::new(&mut self.disable_zmq, "Disable ZMQ (requires restart)") + .show(ui) + .clicked() + { + // Persist immediately via context + let _ = self + .current_app_context() + .update_disable_zmq(self.disable_zmq); + } + }); - // Theme Selection Section - ui.add_space(16.0); - ui.group(|ui| { - ui.vertical(|ui| { - ui.horizontal(|ui| { - ui.label( - egui::RichText::new("Theme:") - .strong() - .color(DashColors::text_primary(dark_mode)), - ); - - egui::ComboBox::from_id_salt("theme_selection") - .selected_text(match self.theme_preference { - ThemeMode::Light => "Light", - ThemeMode::Dark => "Dark", - ThemeMode::System => "System", - }) - .show_ui(ui, |ui| { - if ui.selectable_value(&mut self.theme_preference, ThemeMode::System, "System").clicked() { - app_action |= AppAction::BackendTask(BackendTask::SystemTask( - SystemTask::UpdateThemePreference(ThemeMode::System) - )); - } - if ui.selectable_value(&mut self.theme_preference, ThemeMode::Light, "Light").clicked() { - app_action |= AppAction::BackendTask(BackendTask::SystemTask( - SystemTask::UpdateThemePreference(ThemeMode::Light) - )); - } - if ui.selectable_value(&mut self.theme_preference, ThemeMode::Dark, "Dark").clicked() { - app_action |= AppAction::BackendTask(BackendTask::SystemTask( - SystemTask::UpdateThemePreference(ThemeMode::Dark) - )); - } - }); - }); - ui.label( - egui::RichText::new( - "System: follows your OS theme • Light/Dark: force specific theme", - ) - .color(DashColors::TEXT_SECONDARY), - ); - }); - }); + ui.add_space(8.0); + + ui.horizontal(|ui| { + if StyledCheckbox::new(&mut self.developer_mode, "Developer mode") + .show(ui) + .clicked() + && let Ok(mut config) = Config::load() + { + config.developer_mode = Some(self.developer_mode); + if let Err(e) = config.save() { + eprintln!("Failed to save config: {e}"); + } - // Configuration Requirements Section (only show if not overwriting dash.conf) - if !self.overwrite_dash_conf { - ui.add_space(16.0); - - ui.group(|ui| { - ui.vertical(|ui| { - ui.label( - egui::RichText::new("Manual Configuration Required") - .strong() - .color(DashColors::WARNING), - ); - ui.add_space(8.0); - - let (network_name, zmq_ports) = match self.current_network { - Network::Dash => ("Mainnet", ("23708", "23708")), - Network::Testnet => ("Testnet", ("23709", "23709")), - Network::Devnet => ("Devnet", ("23710", "23710")), - Network::Regtest => ("Regtest", ("20302", "20302")), - _ => ("Unknown", ("0", "0")), - }; - - ui.label( - egui::RichText::new(format!( - "Add these lines to your {} dash.conf:", - network_name - )) - .color(DashColors::TEXT_PRIMARY), - ); - - ui.add_space(8.0); - - // Configuration code block - egui::Frame::new() - .fill(DashColors::INPUT_BACKGROUND) - .stroke(egui::Stroke::new(1.0, DashColors::BORDER)) - .corner_radius(egui::CornerRadius::same(6)) - .inner_margin(egui::Margin::same(12)) - .show(ui, |ui| { - ui.vertical(|ui| { - ui.label( - egui::RichText::new(format!( - "zmqpubrawtxlocksig=tcp://0.0.0.0:{}", - zmq_ports.0 - )) - .monospace() - .color(DashColors::TEXT_PRIMARY), - ); - if self.current_network != Network::Regtest { - ui.label( - egui::RichText::new(format!( - "zmqpubrawchainlock=tcp://0.0.0.0:{}", - zmq_ports.1 - )) - .monospace() - .color(DashColors::TEXT_PRIMARY), - ); - } - }); - }); - }); - }); + // Update all contexts + self.mainnet_app_context + .enable_developer_mode(self.developer_mode); + if let Some(ref ctx) = self.testnet_app_context { + ctx.enable_developer_mode(self.developer_mode); } - }); + if let Some(ref ctx) = self.devnet_app_context { + ctx.enable_developer_mode(self.developer_mode); + } + if let Some(ref ctx) = self.local_app_context { + ctx.enable_developer_mode(self.developer_mode); + } + } + ui.label( + egui::RichText::new("Enable advanced features") + .color(DashColors::TEXT_SECONDARY) + .italics(), + ); }); }); + }); app_action } - /// Render a single row for the network table - fn render_network_row(&mut self, ui: &mut Ui, network: Network, name: &str) -> AppAction { - let mut app_action = AppAction::None; + fn render_spv_sync_progress(&self, ui: &mut Ui, snapshot: &SpvStatusSnapshot) { let dark_mode = ui.ctx().style().visuals.dark_mode; - ui.label(name); - - // Check network status - let is_working = self.check_network_status(network); - let status_color = if is_working { - DashColors::success_color(dark_mode) // Theme-aware green - } else { - DashColors::error_color(dark_mode) // Theme-aware red - }; - - // Display status indicator - ui.colored_label(status_color, if is_working { "Online" } else { "Offline" }); - - if network == Network::Testnet && self.testnet_app_context.is_none() { - ui.label("(No configs for testnet loaded)"); - ui.end_row(); - return AppAction::None; - } - if network == Network::Devnet && self.devnet_app_context.is_none() { - ui.label("(No configs for devnet loaded)"); - ui.end_row(); - return AppAction::None; - } - if network == Network::Regtest && self.local_app_context.is_none() { - ui.label("(No configs for local loaded)"); - ui.end_row(); - return AppAction::None; - } - // Network selection - let mut is_selected = self.current_network == network; - if StyledCheckbox::new(&mut is_selected, "").show(ui).clicked() && is_selected { - self.current_network = network; - app_action = AppAction::SwitchNetwork(network); - // Recheck in 1 second - self.recheck_time = Some( - (SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("Time went backwards") - + Duration::from_secs(1)) - .as_millis() as u64, - ); - } - - // Add a button to start the network - let start_enabled = if let Some(path) = self.custom_dash_qt_path.as_ref() { - !path.as_os_str().is_empty() && path.is_file() - } else { - false - }; - - if network != Network::Regtest { - ui.add_enabled_ui(start_enabled, |ui| { - if ui - .button("Start") - .on_disabled_hover_text( - "Please select path to dash-qt binary in Advanced Settings", - ) - .clicked() - { - app_action = - AppAction::BackendTask(BackendTask::CoreTask(CoreTask::StartDashQT( - network, - self.custom_dash_qt_path - .clone() - .expect("Some() checked above"), - self.overwrite_dash_conf, - ))); - } - }); - } - - // Add a text field for the dashmate password - if network == Network::Regtest { - ui.spacing_mut().item_spacing.x = 5.0; - let dark_mode = ui.ctx().style().visuals.dark_mode; - ui.add( - egui::TextEdit::singleline(&mut self.local_network_dashmate_password) - .desired_width(100.0) - .text_color(crate::ui::theme::DashColors::text_primary(dark_mode)) - .background_color(crate::ui::theme::DashColors::input_background(dark_mode)), - ); - if ui.button("Save Password").clicked() { - // 1) Reload the config - if let Ok(mut config) = Config::load() - && let Some(local_cfg) = config.config_for_network(Network::Regtest).clone() - { - let updated_local_config = local_cfg - .update_core_rpc_password(self.local_network_dashmate_password.clone()); - config - .update_config_for_network(Network::Regtest, updated_local_config.clone()); - if let Err(e) = config.save() { - eprintln!("Failed to save config to .env: {e}"); - } + // Raw sync status display + egui::Frame::new() + .fill(DashColors::glass_white(dark_mode)) + .corner_radius(Shape::RADIUS_SM) + .inner_margin(12.0) + .show(ui, |ui| { + ui.label( + egui::RichText::new("SPV Sync Status") + .strong() + .color(DashColors::text_primary(dark_mode)), + ); - // 5) Update our local AppContext in memory - if let Some(local_app_context) = &self.local_app_context { - { - // Overwrite the config field with the new password - let mut cfg_lock = local_app_context.config.write().unwrap(); - *cfg_lock = updated_local_config; + ui.add_space(8.0); + + // Display sync information in a grid + egui::Grid::new("spv_sync_info") + .num_columns(2) + .spacing([16.0, 4.0]) + .show(ui, |ui| { + // Show current status detail + if let Some(detail) = self.spv_status_detail(snapshot) { + ui.label( + egui::RichText::new("Status:") + .color(DashColors::text_secondary(dark_mode)), + ); + ui.label(detail); + ui.end_row(); } - // 6) Re-init the client & sdk from the updated config - if let Err(e) = Arc::clone(local_app_context).reinit_core_client_and_sdk() { - eprintln!("Failed to re-init local RPC client and sdk: {}", e); - } else { - // Trigger SwitchNetworks - app_action = AppAction::SwitchNetwork(Network::Regtest); + // Prefer detailed header progress when available + if let Some(detailed) = &snapshot.detailed_progress { + // Add separator between status and progress bars + ui.separator(); + ui.separator(); + ui.end_row(); + + // Use detailed percentage for headers bar + ui.label( + egui::RichText::new("Headers:") + .color(DashColors::text_secondary(dark_mode)), + ); + let overall_progress = (detailed.calculate_percentage() / 100.0) as f32; + ui.add(egui::ProgressBar::new(overall_progress).show_percentage()); + ui.end_row(); + + // Masternode Lists progress bar (estimate based on sync stage) + ui.label( + egui::RichText::new("Masternode Lists:") + .color(DashColors::text_secondary(dark_mode)), + ); + let mn_progress = self.calculate_mn_progress(snapshot); + ui.add(egui::ProgressBar::new(mn_progress).show_percentage()); + ui.end_row(); + + // Blocks/Filters progress bar + ui.label( + egui::RichText::new("Blocks:") + .color(DashColors::text_secondary(dark_mode)), + ); + let blocks_progress = self.calculate_blocks_progress(snapshot); + ui.add(egui::ProgressBar::new(blocks_progress).show_percentage()); + ui.end_row(); + + // Peers (if we have a snapshot with counts) + if let Some(progress) = &snapshot.sync_progress + && progress.peer_count > 0 + { + ui.label( + egui::RichText::new("Peers:") + .color(DashColors::text_secondary(dark_mode)), + ); + ui.label(format!("{}", progress.peer_count)); + ui.end_row(); + } + } else if let Some(ev) = &snapshot.sync_progress { + // Event-driven progress (updates most frequently) + ui.label( + egui::RichText::new("Synced:") + .color(DashColors::text_secondary(dark_mode)), + ); + ui.label(format!( + "Headers: {} / {}", + ev.header_height, ev.filter_header_height + )); + ui.end_row(); + + // Add separator between stats and progress bars + ui.separator(); + ui.separator(); + ui.end_row(); + + // Progress bars for different components + // Headers progress bar (from events) + ui.label( + egui::RichText::new("Headers:") + .color(DashColors::text_secondary(dark_mode)), + ); + let headers_progress = self.calculate_headers_progress(snapshot); + ui.add(egui::ProgressBar::new(headers_progress).show_percentage()); + ui.end_row(); + + // Masternode Lists progress bar (estimate based on sync stage) + ui.label( + egui::RichText::new("Masternode Lists:") + .color(DashColors::text_secondary(dark_mode)), + ); + let mn_progress = self.calculate_mn_progress(snapshot); + ui.add(egui::ProgressBar::new(mn_progress).show_percentage()); + ui.end_row(); + + // Blocks/Filters progress bar + ui.label( + egui::RichText::new("Blocks:") + .color(DashColors::text_secondary(dark_mode)), + ); + let blocks_progress = self.calculate_blocks_progress(snapshot); + ui.add(egui::ProgressBar::new(blocks_progress).show_percentage()); + ui.end_row(); + + // Peers (if we also have a snapshot with counts) + if let Some(progress) = &snapshot.sync_progress + && progress.peer_count > 0 + { + ui.label( + egui::RichText::new("Peers:") + .color(DashColors::text_secondary(dark_mode)), + ); + ui.label(format!("{}", progress.peer_count)); + ui.end_row(); + } } + }); + }); + } + + fn calculate_headers_progress(&self, snapshot: &SpvStatusSnapshot) -> f32 { + if let Some(detailed) = &snapshot.detailed_progress { + // If we have detailed progress, use it + match &detailed.sync_stage { + SyncStage::DownloadingHeaders { start, end } => { + if end > start { + ((detailed.sync_progress.header_height - start) as f32 + / (end - start) as f32) + .min(1.0) + } else { + 0.0 } } + SyncStage::ValidatingHeaders { .. } | SyncStage::StoringHeaders { .. } => 0.8, // Headers mostly done + SyncStage::Complete => 1.0, + _ => 0.0, + } + } else if let Some(ev) = &snapshot.sync_progress { + // Estimate based on filter progress + if ev.filter_header_height > 0 && ev.header_height > 0 { + (ev.filter_header_height as f32 / ev.header_height as f32).clamp(0.0, 1.0) + } else { + 0.0 } } else { - ui.label(""); + 0.0 } + } - if network == Network::Devnet { - if ui.button("Clear local Platform data").clicked() { - app_action = - AppAction::BackendTask(BackendTask::SystemTask(SystemTask::WipePlatformData)); + fn calculate_mn_progress(&self, snapshot: &SpvStatusSnapshot) -> f32 { + // Since the current SPV doesn't directly report MN list progress, + // we estimate based on the sync stage + if snapshot.status == SpvStatus::Running { + 1.0 // Fully synced means MN lists are done + } else if let Some(progress) = &snapshot.sync_progress { + if progress.filter_header_height > 0 && progress.header_height > 0 { + // If we have both headers and filters, MN lists are likely in progress or done + if progress.filter_header_height >= progress.header_height { + 1.0 + } else { + (progress.filter_header_height as f32 / progress.header_height as f32).min(1.0) + } + } else { + 0.0 } } else { - ui.label(""); + 0.0 } + } - ui.end_row(); - app_action + fn calculate_blocks_progress(&self, snapshot: &SpvStatusSnapshot) -> f32 { + if snapshot.status == SpvStatus::Running { + 1.0 // Fully synced + } else if let Some(progress) = &snapshot.sync_progress { + // Blocks progress is roughly filters progress + if progress.header_height > 0 && progress.filter_header_height > 0 { + (progress.filter_header_height as f32 / progress.header_height as f32).min(1.0) + } else { + 0.0 + } + } else { + 0.0 + } } /// Check if the network is working @@ -662,6 +986,91 @@ impl NetworkChooserScreen { _ => false, } } + + fn any_rpc_backend(&self) -> bool { + self.backend_modes + .iter() + .any(|(network, mode)| *mode == CoreBackendMode::Rpc && self.has_context_for(*network)) + } + + fn has_context_for(&self, network: Network) -> bool { + match network { + Network::Dash => true, + Network::Testnet => self.testnet_app_context.is_some(), + Network::Devnet => self.devnet_app_context.is_some(), + Network::Regtest => self.local_app_context.is_some(), + _ => false, + } + } + + fn spv_status_detail(&self, snapshot: &SpvStatusSnapshot) -> Option { + if let SpvStatus::Error = snapshot.status + && let Some(err) = &snapshot.last_error + { + return Some(err.clone()); + } + + if let Some(progress) = snapshot.detailed_progress.as_ref() { + return Some(Self::format_detailed_progress(progress)); + } + + if let Some(ev) = snapshot.sync_progress.as_ref() { + return Some(format!( + "Sync: {} / {} ({:.1}%)", + ev.header_height, + ev.filter_header_height, + (ev.filter_header_height as f32 / ev.header_height.max(1) as f32 * 100.0) + )); + } + + if let Some(progress) = snapshot.sync_progress.as_ref() { + return Some(format!( + "Headers: {} | Filters: {} | Peers: {}", + progress.header_height, progress.filter_header_height, progress.peer_count + )); + } + + snapshot.last_error.clone() + } + + fn format_detailed_progress(progress: &DetailedSyncProgress) -> String { + let mut message = match &progress.sync_stage { + SyncStage::Connecting => "Connecting to peers".to_string(), + SyncStage::QueryingPeerHeight => "Querying peer heights".to_string(), + SyncStage::DownloadingHeaders { start, end } => { + format!("Headers: {start} / {end}") + } + SyncStage::ValidatingHeaders { batch_size } => { + format!("Validating headers (batch {batch_size})") + } + SyncStage::StoringHeaders { batch_size } => { + format!("Storing headers (batch {batch_size})") + } + SyncStage::Complete => "Sync complete".to_string(), + SyncStage::Failed(reason) => format!("Failed: {reason}"), + SyncStage::DownloadingFilterHeaders { current, target } => { + format!("FilterHeaders: {current} / {target}") + } + SyncStage::DownloadingFilters { completed, total } => { + format!("Filters: {completed} / {total}") + } + SyncStage::DownloadingBlocks { pending } => { + format!("Blocks: {pending}") + } + }; + + if progress.sync_progress.peer_count > 0 { + message = format!("{message} | Peers: {}", progress.sync_progress.peer_count); + } + + if let Some(eta) = progress.calculate_eta() + && eta.as_secs() > 0 + { + message = format!("{message} | ETA: {}s", eta.as_secs()); + } + + message + } } impl ScreenLike for NetworkChooserScreen { @@ -676,6 +1085,21 @@ impl ScreenLike for NetworkChooserScreen { self.overwrite_dash_conf = settings.overwrite_dash_conf; self.theme_preference = settings.theme_mode; } + + self.backend_modes + .insert(Network::Dash, self.mainnet_app_context.core_backend_mode()); + if let Some(ctx) = &self.testnet_app_context { + self.backend_modes + .insert(Network::Testnet, ctx.core_backend_mode()); + } + if let Some(ctx) = &self.devnet_app_context { + self.backend_modes + .insert(Network::Devnet, ctx.core_backend_mode()); + } + if let Some(ctx) = &self.local_app_context { + self.backend_modes + .insert(Network::Regtest, ctx.core_backend_mode()); + } } fn display_message(&mut self, message: &str, _message_type: super::MessageType) { @@ -739,17 +1163,22 @@ impl ScreenLike for NetworkChooserScreen { // Recheck both network status every 3 seconds let recheck_time = Duration::from_secs(3); if action == AppAction::None { - let current_time = SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("Time went backwards"); - if let Some(time) = self.recheck_time { - if current_time.as_millis() as u64 >= time { - action = - AppAction::BackendTask(BackendTask::CoreTask(CoreTask::GetBestChainLocks)); + if self.any_rpc_backend() { + let current_time = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards"); + if let Some(time) = self.recheck_time { + if current_time.as_millis() as u64 >= time { + action = AppAction::BackendTask(BackendTask::CoreTask( + CoreTask::GetBestChainLocks, + )); + self.recheck_time = Some((current_time + recheck_time).as_millis() as u64); + } + } else { self.recheck_time = Some((current_time + recheck_time).as_millis() as u64); } } else { - self.recheck_time = Some((current_time + recheck_time).as_millis() as u64); + self.recheck_time = None; } } diff --git a/src/ui/wallets/add_new_wallet_screen.rs b/src/ui/wallets/add_new_wallet_screen.rs index 6ce596402..6f3d4562d 100644 --- a/src/ui/wallets/add_new_wallet_screen.rs +++ b/src/ui/wallets/add_new_wallet_screen.rs @@ -153,13 +153,23 @@ impl AddNewWalletScreen { .map_err(|e| e.to_string())?; // Acquire a write lock and add the new wallet + let mut should_attach_spv = false; if let Ok(mut wallets) = self.app_context.wallets.write() { wallets.insert(wallet.seed_hash(), Arc::new(RwLock::new(wallet))); self.app_context.has_wallet.store(true, Ordering::Relaxed); + // Mark for SPV attach outside of the lock to avoid re-entrancy deadlocks + if self.app_context.core_backend_mode() == crate::spv::CoreBackendMode::Spv { + should_attach_spv = true; + } } else { eprintln!("Failed to acquire write lock on wallets"); } + // Perform SPV attachment after releasing the wallets lock + if should_attach_spv { + self.app_context.spv_attach_current_wallets(); + } + Ok(AppAction::GoToMainScreen) // Navigate back to the main screen after saving } else { Ok(AppAction::None) // No action if no seed phrase exists diff --git a/src/ui/wallets/import_wallet_screen.rs b/src/ui/wallets/import_wallet_screen.rs index d2f37f169..79107202b 100644 --- a/src/ui/wallets/import_wallet_screen.rs +++ b/src/ui/wallets/import_wallet_screen.rs @@ -123,13 +123,23 @@ impl ImportWalletScreen { })?; // Acquire a write lock and add the new wallet + let mut should_attach_spv = false; if let Ok(mut wallets) = self.app_context.wallets.write() { wallets.insert(wallet.seed_hash(), Arc::new(RwLock::new(wallet))); self.app_context.has_wallet.store(true, Ordering::Relaxed); + // Mark for SPV attach outside the lock to avoid re-entrancy deadlocks + if self.app_context.core_backend_mode() == crate::spv::CoreBackendMode::Spv { + should_attach_spv = true; + } } else { eprintln!("Failed to acquire write lock on wallets"); } + // Perform SPV attachment after releasing the wallets lock + if should_attach_spv { + self.app_context.spv_attach_current_wallets(); + } + Ok(AppAction::GoToMainScreen) // Navigate back to the main screen after saving } else { Ok(AppAction::None) // No action if no seed phrase exists