diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 439dbc731..1eb2ef264 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -45,6 +45,45 @@ jobs: - name: Run clippy (no default features) run: cargo clippy --workspace --all-targets --no-default-features -- -D warnings + wasm-check: + name: WASM walletkit compile check + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout code + uses: actions/checkout@v6 + + - name: Set up Rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: 1.92.0 + targets: wasm32-unknown-unknown + + # clang-18 (LLVM 18) is the minimum version that supports the C23 + # [[noreturn]] attribute syntax used in sqlite-wasm-rs's wasm-shim.h. + # The system clang on Ubuntu (clang-14) predates C23 attribute support + # and fails to compile the shim, so we must install a newer toolchain explicitly. + - name: Install LLVM toolchain for WASM C build + shell: bash + run: | + set -euo pipefail + sudo apt-get update + sudo apt-get install -y clang-18 llvm-18 + + - name: Configure C toolchain for wasm32 + shell: bash + run: | + set -euo pipefail + echo "CC_wasm32_unknown_unknown=clang-18" >> "$GITHUB_ENV" + echo "AR_wasm32_unknown_unknown=llvm-ar-18" >> "$GITHUB_ENV" + clang-18 --version | head -n1 + llvm-ar-18 --version | head -n1 + + - name: Run WASM compile check + run: cargo check -p walletkit --target wasm32-unknown-unknown + swift-build-and-test: name: Swift Build & Foreign Binding Tests runs-on: macos-14 diff --git a/Cargo.lock b/Cargo.lock index f11b572ac..6d1c0c151 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -91,9 +91,9 @@ dependencies = [ [[package]] name = "alloy-chains" -version = "0.2.30" +version = "0.2.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f374d3c6d729268bbe2d0e0ff992bb97898b2df756691a62ee1d5f0506bc39" +checksum = "9247f0a399ef71aeb68f497b2b8fb348014f742b50d3b83b1e00dfe1b7d64b3d" dependencies = [ "alloy-primitives", "num_enum", @@ -189,7 +189,7 @@ dependencies = [ "itoa", "serde", "serde_json", - "winnow", + "winnow 0.7.15", ] [[package]] @@ -232,9 +232,9 @@ dependencies = [ [[package]] name = "alloy-eip7928" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3231de68d5d6e75332b7489cfcc7f4dfabeba94d990a10e4b923af0e6623540" +checksum = "f8222b1d88f9a6d03be84b0f5e76bb60cd83991b43ad8ab6477f0e4a7809b98d" dependencies = [ "alloy-primitives", "alloy-rlp", @@ -392,7 +392,7 @@ dependencies = [ "const-hex", "derive_more", "foldhash 0.2.0", - "getrandom 0.4.1", + "getrandom 0.4.2", "hashbrown 0.16.1", "indexmap 2.13.0", "itoa", @@ -468,7 +468,7 @@ checksum = "ce8849c74c9ca0f5a03da1c865e3eb6f768df816e67dd3721a398a8a7e398011" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -591,7 +591,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -609,7 +609,7 @@ dependencies = [ "proc-macro2", "quote", "sha3", - "syn 2.0.114", + "syn 2.0.117", "syn-solidity", ] @@ -627,7 +627,7 @@ dependencies = [ "proc-macro2", "quote", "serde_json", - "syn 2.0.114", + "syn 2.0.117", "syn-solidity", ] @@ -638,7 +638,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6df77fea9d6a2a75c0ef8d2acbdfd92286cc599983d3175ccdc170d3433d249" dependencies = [ "serde", - "winnow", + "winnow 0.7.15", ] [[package]] @@ -694,13 +694,12 @@ dependencies = [ [[package]] name = "alloy-trie" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d7fd448ab0a017de542de1dcca7a58e7019fe0e7a34ed3f9543ebddf6aceffa" +checksum = "3f14b5d9b2c2173980202c6ff470d96e7c5e202c65a9f67884ad565226df7fbb" dependencies = [ "alloy-primitives", "alloy-rlp", - "arrayvec", "derive_more", "nybbles", "serde", @@ -715,10 +714,10 @@ version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fa0c53e8c1e1ef4d01066b01c737fb62fc9397ab52c6e7bb5669f97d281b9bc" dependencies = [ - "darling", + "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -732,15 +731,15 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78" +checksum = "940b3a0ca603d1eade50a4846a2afffd5ef57a9feac2c0e2ec2e14f9ead76000" [[package]] name = "anyhow" -version = "1.0.101" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e0fee31ef5ed1ba1316088939cea399010ed7731dba877ed44aeb407a75ea" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "arbitrary" @@ -794,7 +793,7 @@ checksum = "e7e89fe77d1f0f4fe5b96dfc940923d88d17b6a773808124f21e764dfb063c6a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -905,7 +904,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -943,7 +942,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1050,7 +1049,7 @@ checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1126,9 +1125,9 @@ dependencies = [ [[package]] name = "askama" -version = "0.15.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08e1676b346cadfec169374f949d7490fd80a24193d37d2afce0c047cf695e57" +checksum = "33b7e89247085c4bb89576c3116140bac3999c81d74db52afe11b36c7e11a97d" dependencies = [ "askama_macros", "itoa", @@ -1151,16 +1150,16 @@ dependencies = [ "rustc-hash", "serde", "serde_derive", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "askama_derive" -version = "0.15.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7661ff56517787343f376f75db037426facd7c8d3049cef8911f1e75016f3a37" +checksum = "adf18857bd6189696f6e44ab992acbb731cc12bc1661959cd9f1d56342708cee" dependencies = [ - "askama_parser 0.15.4", + "askama_parser 0.15.5", "basic-toml", "memchr", "proc-macro2", @@ -1168,16 +1167,16 @@ dependencies = [ "rustc-hash", "serde", "serde_derive", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "askama_macros" -version = "0.15.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "713ee4dbfd1eb719c2dab859465b01fa1d21cb566684614a713a6b7a99a4e47b" +checksum = "78a8dcefb2a4763c7957ad5b1a16df6d81cff6227aae161b95af322d52c02005" dependencies = [ - "askama_derive 0.15.4", + "askama_derive 0.15.5", ] [[package]] @@ -1189,20 +1188,20 @@ dependencies = [ "memchr", "serde", "serde_derive", - "winnow", + "winnow 0.7.15", ] [[package]] name = "askama_parser" -version = "0.15.4" +version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d62d674238a526418b30c0def480d5beadb9d8964e7f38d635b03bf639c704c" +checksum = "e7ef9905e0280528d0c2271ff66cab68ec4a550e745e3a365ded353f6e30faac" dependencies = [ "rustc-hash", "serde", "serde_derive", "unicode-ident", - "winnow", + "winnow 0.7.15", ] [[package]] @@ -1230,9 +1229,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.39" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68650b7df54f0293fd061972a0fb05aaf4fc0879d3b3d21a638a182c5c543b9f" +checksum = "d0f9ee0f6e02ffd7ad5816e9464499fba7b3effd01123b515c41d1697c43dad1" dependencies = [ "compression-codecs", "compression-core", @@ -1259,7 +1258,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1270,7 +1269,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1296,7 +1295,7 @@ checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1434,9 +1433,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.10.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af" [[package]] name = "bitvec" @@ -1496,25 +1495,26 @@ dependencies = [ [[package]] name = "borsh" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" +checksum = "cfd1e3f8955a5d7de9fab72fc8373fade9fb8a703968cb200ae3dc6cf08e185a" dependencies = [ "borsh-derive", + "bytes", "cfg_aliases", ] [[package]] name = "borsh-derive" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" +checksum = "bfcfdc083699101d5a7965e49925975f2f55060f94f9a05e7187be95d530ca59" dependencies = [ "once_cell", "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -1540,9 +1540,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.19.1" +version = "3.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" [[package]] name = "byte-slice-cast" @@ -1573,9 +1573,9 @@ dependencies = [ [[package]] name = "c-kzg" -version = "2.1.5" +version = "2.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e00bf4b112b07b505472dbefd19e37e53307e2bfed5a79e0cc161d58ccd0e687" +checksum = "6648ed1e4ea8e8a1a4a2c78e1cda29a3fd500bc622899c340d8525ea9a76b24a" dependencies = [ "blst", "cc", @@ -1620,9 +1620,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.55" +version = "1.2.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47b26a0954ae34af09b50f0de26458fa95369a0d478d8236d3f93082b219bd29" +checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" dependencies = [ "find-msvc-tools", "jobserver", @@ -1742,9 +1742,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.59" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5caf74d17c3aec5495110c34cc3f78644bfa89af6c8993ed4de2790e49b6499" +checksum = "b193af5b67834b676abd72466a96c1024e6a6ad978a1f484bd90b85c94041351" dependencies = [ "clap_builder", "clap_derive", @@ -1752,9 +1752,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.59" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "370daa45065b80218950227371916a1633217ae42b2715b2287b606dcd618e24" +checksum = "714a53001bf66416adb0e2ef5ac857140e7dc3a0c48fb28b2f10762fc4b5069f" dependencies = [ "anstyle", "clap_lex", @@ -1763,21 +1763,21 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.55" +version = "4.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5" +checksum = "1110bd8a634a1ab8cb04345d8d878267d57c3cf1b38d91b71af6686408bbca6a" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "clap_lex" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831" +checksum = "c8d4a3bb8b1e0c1050499d1815f5ab16d04f0959b233085fb31653fbfc9d98f9" [[package]] name = "cmake" @@ -1856,9 +1856,9 @@ dependencies = [ [[package]] name = "compression-codecs" -version = "0.4.36" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00828ba6fd27b45a448e57dbfe84f1029d4c9f26b368157e9a448a5f49a2ec2a" +checksum = "eb7b51a7d9c967fc26773061ba86150f19c50c0d65c887cb1fbe295fd16619b7" dependencies = [ "brotli", "compression-core", @@ -1872,9 +1872,9 @@ checksum = "75984efb6ed102a0d42db99afb6c1948f0380d1d91808d5529916e6c08b49d8d" [[package]] name = "const-hex" -version = "1.17.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3bb320cac8a0750d7f25280aa97b09c26edfe161164238ecbbb31092b079e735" +checksum = "531185e432bb31db1ecda541e9e7ab21468d4d844ad7505e0546a49b4945d49b" dependencies = [ "cfg-if", "cpufeatures", @@ -2029,7 +2029,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2044,7 +2044,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2053,8 +2053,18 @@ version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ - "darling_core", - "darling_macro", + "darling_core 0.21.3", + "darling_macro 0.21.3", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core 0.23.0", + "darling_macro 0.23.0", ] [[package]] @@ -2069,7 +2079,20 @@ dependencies = [ "quote", "serde", "strsim", - "syn 2.0.114", + "syn 2.0.117", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.117", ] [[package]] @@ -2078,9 +2101,20 @@ version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ - "darling_core", + "darling_core 0.21.3", "quote", - "syn 2.0.114", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core 0.23.0", + "quote", + "syn 2.0.117", ] [[package]] @@ -2115,9 +2149,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.5.6" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc3dc5ad92c2e2d1c193bbbbdf2ea477cb81331de4f3103f267ca18368b988c4" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" dependencies = [ "powerfmt", "serde_core", @@ -2136,13 +2170,13 @@ dependencies = [ [[package]] name = "derive-where" -version = "1.6.0" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef941ded77d15ca19b40374869ac6000af1c9f2a4c0f3d4c70926287e6364a8f" +checksum = "d08b3a0bcc0d079199cd476b2cae8435016ec11d1c0986c6901c5ac223041534" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2153,7 +2187,7 @@ checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2175,7 +2209,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version 0.4.1", - "syn 2.0.114", + "syn 2.0.117", "unicode-xid", ] @@ -2208,7 +2242,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2253,7 +2287,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2318,7 +2352,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2338,7 +2372,7 @@ checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -2494,9 +2528,9 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" [[package]] name = "futures" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", @@ -2509,9 +2543,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -2519,15 +2553,15 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +checksum = "baf29c38818342a3b26b5b923639e7b1f4a61fc5e76102d4b1981c6dc7a7579d" dependencies = [ "futures-core", "futures-task", @@ -2536,38 +2570,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-channel", "futures-core", @@ -2577,7 +2611,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -2620,20 +2653,20 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", "wasm-bindgen", ] [[package]] name = "getrandom" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 6.0.0", "wasip2", "wasip3", ] @@ -3116,7 +3149,7 @@ checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -3159,15 +3192,15 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.11.0" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iri-string" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +checksum = "d8e7418f59cc01c88316161279a7f665217ae316b388e58a0d10e29f54f1e5eb" dependencies = [ "memchr", "serde", @@ -3202,9 +3235,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jobserver" @@ -3218,9 +3251,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.85" +version = "0.3.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" dependencies = [ "once_cell", "wasm-bindgen", @@ -3274,9 +3307,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.181" +version = "0.2.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" [[package]] name = "libm" @@ -3286,20 +3319,21 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.12" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "libc", - "redox_syscall 0.7.1", + "plain", + "redox_syscall 0.7.3", ] [[package]] name = "linux-raw-sys" -version = "0.11.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" @@ -3354,7 +3388,7 @@ checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -3374,9 +3408,9 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" [[package]] name = "memmap2" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "744133e4a0e0a658e1374cf3bf8e415c4052a15a111acd372764c55b4177d490" +checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" dependencies = [ "libc", ] @@ -3551,9 +3585,9 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" +checksum = "5d0bca838442ec211fa11de3a8b0e0e8f3a4522575b5c4c06ed722e005036f26" dependencies = [ "num_enum_derive", "rustversion", @@ -3561,13 +3595,13 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.7.5" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +checksum = "680998035259dcfcafe653688bf2aa6d3e2dc05e98be6ab46afb089dc84f1df8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -3595,9 +3629,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.21.3" +version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" [[package]] name = "opaque-debug" @@ -3607,9 +3641,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "owo-colors" -version = "4.2.3" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c6901729fa79e91a0913333229e9ca5dc725089d1c363b2f4b4760709dc4a52" +checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" [[package]] name = "parity-scale-codec" @@ -3636,7 +3670,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -3686,29 +3720,29 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +checksum = "f1749c7ed4bcaf4c3d0a3efc28538844fb29bcdd7d2b67b2be7e20ba861ff517" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.10" +version = "1.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +checksum = "d9b20ed30f105399776b9c883e68e536ef602a16ae6f596d2c473591d6ad64c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] name = "pin-project-lite" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" [[package]] name = "pin-utils" @@ -3793,7 +3827,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -3809,9 +3843,9 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "3.4.0" +version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ "toml_edit", ] @@ -3835,7 +3869,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -3855,7 +3889,7 @@ checksum = "37566cb3fdacef14c0737f9546df7cfeadbfbc9fef10991038bf5015d0c80532" dependencies = [ "bit-set", "bit-vec", - "bitflags 2.10.0", + "bitflags 2.11.0", "num-traits", "rand 0.9.2", "rand_chacha 0.9.0", @@ -3929,9 +3963,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.44" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -3942,6 +3976,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "radium" version = "0.7.0" @@ -4021,9 +4061,9 @@ dependencies = [ [[package]] name = "rapidhash" -version = "4.3.0" +version = "4.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84816e4c99c467e92cf984ee6328caa976dfecd33a673544489d79ca2caaefe5" +checksum = "b5e48930979c155e2f33aa36ab3119b5ee81332beb6482199a8ecd6029b80b59" dependencies = [ "rustversion", ] @@ -4054,16 +4094,16 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", ] [[package]] name = "redox_syscall" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35985aa610addc02e24fc232012c86fd11f14111180f902b67e2d5331f8ebf2b" +checksum = "6ce70a74e890531977d37e532c34d45e9055d2409ed08ddba14529471ed0be16" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", ] [[package]] @@ -4083,7 +4123,7 @@ checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -4111,9 +4151,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.9" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a96887878f22d7bad8a3b6dc5b7440e0ada9a245242924394987b21cf2210a4c" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" [[package]] name = "reqwest" @@ -4282,11 +4322,11 @@ dependencies = [ [[package]] name = "rustix" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "errno", "libc", "linux-raw-sys", @@ -4417,7 +4457,7 @@ checksum = "1783eabc414609e28a5ba76aee5ddd52199f7107a0b24c2e9746a1ecc34a683d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -4564,7 +4604,7 @@ dependencies = [ "proc-macro2", "quote", "semaphore-rs-depth-config", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -4748,7 +4788,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -4787,9 +4827,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.16.1" +version = "3.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" +checksum = "dd5414fad8e6907dbdd5bc441a50ae8d6e26151a03b1de04d89a5576de61d01f" dependencies = [ "base64 0.22.1", "chrono", @@ -4806,14 +4846,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.16.1" +version = "3.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" +checksum = "d3db8978e608f1fe7357e211969fd9abdcae80bac1ba7a3369bb7eb6b404eb65" dependencies = [ - "darling", + "darling 0.23.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -4934,12 +4974,12 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" [[package]] name = "socket2" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -5009,7 +5049,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -5031,9 +5071,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.114" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -5049,7 +5089,7 @@ dependencies = [ "paste", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -5069,7 +5109,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -5078,7 +5118,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec7dddc5f0fee506baf8b9fdb989e242f17e4b11c61dfbb0635b705217199eea" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "byteorder", "enum-as-inner", "libc", @@ -5100,9 +5140,9 @@ dependencies = [ [[package]] name = "taceo-ark-serde-compat" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07528b4dd1a0c9e49ef352f96219c611af0aa2f7cbd97ddb7276dcf3c2cf8dd0" +checksum = "0a9a63a8ccb028bc47205f82ef207be4950c3f8afc39a6515d4c2b530bf41e3e" dependencies = [ "ark-bn254", "ark-ec", @@ -5115,9 +5155,9 @@ dependencies = [ [[package]] name = "taceo-circom-types" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677eb3ed8275b2f179d4b1a93126a51c5b4f409c5ea9d7bc50398b13e517e30b" +checksum = "0ad03e9d126fb248cc8f8bfecd5f1220195e0a6694b4d605f051cc3ac78f36ad" dependencies = [ "ark-bn254", "ark-ec", @@ -5176,9 +5216,9 @@ dependencies = [ [[package]] name = "taceo-groth16-material" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936b1e6b8a77f931796917501fe13a2ae93304e7eb384ed29d80ddc370b011bd" +checksum = "124a8757ed58c5772a0b8e06ad431e7f1a2af1cbfe1f92c7428c2e1e8925ce8c" dependencies = [ "ark-bn254", "ark-ec", @@ -5201,29 +5241,62 @@ dependencies = [ [[package]] name = "taceo-groth16-sol" -version = "0.2.2" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c6a7b90f2ecb6db1212557550890d9d9d114447688f6146d726024ec7a3410b" +checksum = "1f2c005a2303bfcd0cf47dc0e2320c80418d685c00d84c322194e7f47320eae8" dependencies = [ "alloy-primitives", "ark-bn254", "ark-ec", "ark-ff 0.5.0", "ark-groth16", - "askama 0.15.4", + "askama 0.15.5", "eyre", "ruint", ] +[[package]] +name = "taceo-oprf" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "412211d4d43aeb060c369a69213bd7ae941f769cc4361df83195d2a7936f22d5" +dependencies = [ + "taceo-oprf-client 0.8.1", +] + [[package]] name = "taceo-oprf" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be862ba49094098f945f1375f704a2c47b4e267a6e564462a43ad142b4b1469e" dependencies = [ - "taceo-oprf-client", - "taceo-oprf-core", - "taceo-oprf-types", + "taceo-oprf-client 0.9.0", + "taceo-oprf-core 0.5.0", + "taceo-oprf-types 0.10.1", +] + +[[package]] +name = "taceo-oprf-client" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de42daf867ed4d1ed661258a4541d5dcf1ebe3f43f923acc3ec7716b8824670d" +dependencies = [ + "ark-ec", + "ciborium", + "futures", + "getrandom 0.2.17", + "gloo-net", + "http", + "serde", + "taceo-ark-babyjubjub", + "taceo-oprf-core 0.4.3", + "taceo-oprf-types 0.9.2", + "taceo-poseidon2", + "thiserror 2.0.18", + "tokio", + "tokio-tungstenite", + "tracing", + "uuid", ] [[package]] @@ -5240,8 +5313,8 @@ dependencies = [ "http", "serde", "taceo-ark-babyjubjub", - "taceo-oprf-core", - "taceo-oprf-types", + "taceo-oprf-core 0.5.0", + "taceo-oprf-types 0.10.1", "taceo-poseidon2", "thiserror 2.0.18", "tokio", @@ -5250,6 +5323,28 @@ dependencies = [ "uuid", ] +[[package]] +name = "taceo-oprf-core" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d2baf9c72e6687fa8839c3e3368236b36237a905b8c7fcd445250a7a57ab063" +dependencies = [ + "ark-ec", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "blake3", + "itertools 0.14.0", + "num-bigint", + "rand 0.8.5", + "serde", + "subtle", + "taceo-ark-babyjubjub", + "taceo-ark-serde-compat", + "taceo-poseidon2", + "uuid", + "zeroize", +] + [[package]] name = "taceo-oprf-core" version = "0.5.0" @@ -5272,6 +5367,27 @@ dependencies = [ "zeroize", ] +[[package]] +name = "taceo-oprf-types" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447b96ee4bb69a16b05fa1e581501c426338698263cde39fc8fbfdbf5d24b616" +dependencies = [ + "alloy", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "async-trait", + "eyre", + "http", + "serde", + "taceo-ark-babyjubjub", + "taceo-ark-serde-compat", + "taceo-circom-types", + "taceo-groth16-sol", + "taceo-oprf-core 0.4.3", + "uuid", +] + [[package]] name = "taceo-oprf-types" version = "0.10.1" @@ -5289,7 +5405,7 @@ dependencies = [ "taceo-ark-serde-compat", "taceo-circom-types", "taceo-groth16-sol", - "taceo-oprf-core", + "taceo-oprf-core 0.5.0", "uuid", ] @@ -5314,9 +5430,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973" dependencies = [ "filetime", "libc", @@ -5325,12 +5441,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.25.0" +version = "3.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.4.1", + "getrandom 0.4.2", "once_cell", "rustix", "windows-sys 0.61.2", @@ -5380,7 +5496,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -5391,7 +5507,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -5464,9 +5580,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3" dependencies = [ "tinyvec_macros", ] @@ -5479,9 +5595,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.49.0" +version = "1.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" dependencies = [ "bytes", "libc", @@ -5495,13 +5611,13 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -5575,10 +5691,10 @@ dependencies = [ "indexmap 2.13.0", "serde_core", "serde_spanned", - "toml_datetime", + "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", - "winnow", + "winnow 0.7.15", ] [[package]] @@ -5590,32 +5706,41 @@ dependencies = [ "serde_core", ] +[[package]] +name = "toml_datetime" +version = "1.0.1+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b320e741db58cac564e26c607d3cc1fdc4a88fd36c879568c07856ed83ff3e9" +dependencies = [ + "serde_core", +] + [[package]] name = "toml_edit" -version = "0.23.10+spec-1.0.0" +version = "0.25.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +checksum = "8ca1a40644a28bce036923f6a431df0b34236949d111cc07cb6dca830c9ef2e1" dependencies = [ "indexmap 2.13.0", - "toml_datetime", + "toml_datetime 1.0.1+spec-1.1.0", "toml_parser", - "winnow", + "winnow 1.0.0", ] [[package]] name = "toml_parser" -version = "1.0.7+spec-1.1.0" +version = "1.0.10+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "247eaa3197818b831697600aadf81514e577e0cba5eab10f7e064e78ae154df1" +checksum = "7df25b4befd31c4816df190124375d5a20c6b6921e2cad937316de3fccd63420" dependencies = [ - "winnow", + "winnow 1.0.0", ] [[package]] name = "toml_writer" -version = "1.0.6+spec-1.1.0" +version = "1.0.7+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" +checksum = "f17aaa1c6e3dc22b1da4b6bba97d066e354c7945cac2f7852d4e4e7ca7a6b56d" [[package]] name = "tower" @@ -5639,7 +5764,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "async-compression", - "bitflags 2.10.0", + "bitflags 2.11.0", "bytes", "futures-core", "futures-util", @@ -5686,7 +5811,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -5706,7 +5831,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db" dependencies = [ "tracing", - "tracing-subscriber 0.3.22", + "tracing-subscriber 0.3.23", ] [[package]] @@ -5731,9 +5856,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.22" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" dependencies = [ "matchers", "nu-ansi-term", @@ -5804,9 +5929,9 @@ checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" [[package]] name = "unicode-ident" -version = "1.0.23" +version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "537dd038a89878be9b64dd4bd1b260315c1bb94f4d784956b81e27a088d9a09e" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" [[package]] name = "unicode-segmentation" @@ -5898,7 +6023,7 @@ dependencies = [ "indexmap 2.13.0", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -5913,7 +6038,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.114", + "syn 2.0.117", "toml", "uniffi_meta", ] @@ -5998,11 +6123,11 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.21.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" +checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" dependencies = [ - "getrandom 0.4.1", + "getrandom 0.4.2", "js-sys", "serde_core", "wasm-bindgen", @@ -6079,13 +6204,14 @@ dependencies = [ "sha2", "strum", "subtle", - "taceo-oprf", + "taceo-oprf 0.7.1", + "taceo-oprf 0.8.0", "thiserror 2.0.18", "tokio", "tokio-test", "tracing", "tracing-log", - "tracing-subscriber 0.3.22", + "tracing-subscriber 0.3.23", "uniffi", "uuid", "walletkit-db", @@ -6141,9 +6267,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" dependencies = [ "cfg-if", "once_cell", @@ -6154,9 +6280,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.58" +version = "0.4.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +checksum = "e9c5522b3a28661442748e09d40924dfb9ca614b21c00d3fd135720e48b67db8" dependencies = [ "cfg-if", "futures-util", @@ -6168,9 +6294,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -6178,22 +6304,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.108" +version = "0.2.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" dependencies = [ "unicode-ident", ] @@ -6226,7 +6352,7 @@ version = "0.244.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ - "bitflags 2.10.0", + "bitflags 2.11.0", "hashbrown 0.15.5", "indexmap 2.13.0", "semver 1.0.27", @@ -6248,9 +6374,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.85" +version = "0.3.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" dependencies = [ "js-sys", "wasm-bindgen", @@ -6338,7 +6464,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -6349,7 +6475,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -6591,9 +6717,18 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +checksum = "df79d97927682d2fd8adb29682d1140b343be4ac0f08fd68b7765d9c059d3945" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8" dependencies = [ "memchr", ] @@ -6628,7 +6763,7 @@ dependencies = [ "heck", "indexmap 2.13.0", "prettyplease", - "syn 2.0.114", + "syn 2.0.117", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -6644,7 +6779,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -6656,7 +6791,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", - "bitflags 2.10.0", + "bitflags 2.11.0", "indexmap 2.13.0", "log", "serde", @@ -6707,7 +6842,7 @@ dependencies = [ "taceo-ark-babyjubjub", "taceo-eddsa-babyjubjub", "taceo-groth16-material", - "taceo-oprf", + "taceo-oprf 0.8.0", "taceo-poseidon2", "thiserror 2.0.18", "tokio", @@ -6758,7 +6893,7 @@ dependencies = [ "taceo-eddsa-babyjubjub", "taceo-groth16-material", "taceo-groth16-sol", - "taceo-oprf", + "taceo-oprf 0.8.0", "taceo-poseidon2", "thiserror 2.0.18", "url", @@ -6785,7 +6920,7 @@ dependencies = [ "taceo-circom-types", "taceo-eddsa-babyjubjub", "taceo-groth16-material", - "taceo-oprf", + "taceo-oprf 0.8.0", "taceo-poseidon2", "tar", "thiserror 2.0.18", @@ -6839,28 +6974,28 @@ checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", "synstructure", ] [[package]] name = "zerocopy" -version = "0.8.39" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a" +checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.39" +version = "0.8.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517" +checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -6880,7 +7015,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", "synstructure", ] @@ -6901,7 +7036,7 @@ checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -6934,7 +7069,7 @@ checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.114", + "syn 2.0.117", ] [[package]] @@ -6956,9 +7091,9 @@ dependencies = [ [[package]] name = "zmij" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de98dfa5d5b7fef4ee834d0073d560c9ca7b6c46a71d058c48db7960f8cfaf7" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" [[package]] name = "zopfli" diff --git a/Cargo.toml b/Cargo.toml index ea2552f46..5db7c3b00 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ alloy-core = { version = "1", default-features = false, features = [ "sol-types", ] } alloy-primitives = { version = "1", default-features = false } -uniffi = { version = "0.31", features = ["tokio"] } +uniffi = { version = "0.31", features = ["tokio", "wasm-unstable-single-threaded"] } world-id-core = { version = "0.6", default-features = false } # internal @@ -42,3 +42,4 @@ opt-level = 'z' # Optimize for size. lto = true # Enable Link Time Optimization. panic = "abort" debug = false + diff --git a/walletkit-core/Cargo.toml b/walletkit-core/Cargo.toml index f48bd83b5..7550a0b8b 100644 --- a/walletkit-core/Cargo.toml +++ b/walletkit-core/Cargo.toml @@ -25,24 +25,19 @@ alloy-core = { workspace = true } alloy-primitives = { workspace = true } backon = "1.6" base64 = { version = "0.22", optional = true } -ctor = "0.2" hex = "0.4" -hkdf = { version = "0.12", optional = true } +hkdf = "0.12" log = "0.4" -rand = { version = "0.8", optional = true } -reqwest = { version = "0.12", default-features = false, features = [ - "json", - "brotli", - "rustls-tls", -] } +rand = "0.8" +reqwest = { version = "0.12", default-features = false, features = ["json"] } ruint = { version = "1.17", default-features = false, features = ["alloc"] } ruint-uniffi = { version = "0.1", features = ["serde"] } -rustls = { version = "0.23", features = ["ring"] } +uniffi = { workspace = true } secrecy = "0.10" -semaphore-rs = { version = "0.5", optional = true } +semaphore-rs = { version = "0.5.1", optional = true } serde = "1" serde_json = "1" -sha2 = { version = "0.10", optional = true } +sha2 = "0.10" strum = { version = "0.27", features = ["derive"] } subtle = "2" thiserror = "2" @@ -51,17 +46,18 @@ tracing = "0.1" tracing-log = "0.2" tracing-subscriber = { version = "0.3", features = ["env-filter"] } zeroize = "1" -uuid = { version = "1.10", features = ["v4"], optional = true } -uniffi = { workspace = true } +uuid = { version = "1.10", features = ["v4"] } +taceo-oprf = { version = "0.7.1", default-features = false, features = ["client"] } +world-id-core = { workspace = true, features = ["authenticator"] } +ciborium = "0.2.2" +walletkit-db = { workspace = true } -world-id-core = { workspace = true, features = [ - "authenticator", - "embed-zkeys", - "zstd-compress-zkeys", -] } -ciborium = { version = "0.2.2", optional = true } -walletkit-db = { workspace = true, optional = true } +# Native-only dependencies (not available on wasm32) +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +ctor = "0.2" +reqwest = { version = "0.12", default-features = false, features = ["brotli", "rustls-tls"] } +rustls = { version = "0.23", features = ["ring"] } [dev-dependencies] alloy = { version = "1", default-features = false, features = [ @@ -85,21 +81,18 @@ rand = "0.8" [features] -default = ["issuers", "storage"] +default = ["issuers"] # Enables point-compression on all verifying keys. This results in ~2x smaller bundle size, but decompression is very expensive, # using it requires proper handling to ensure decompression is done once and cached. By default walletkit-swift and walletkit-android # ship with compressed keys. But this is disabled for tests. compress-zkeys = ["world-id-core/compress-zkeys"] issuers = ["dep:base64"] -storage = [ - "dep:ciborium", - "dep:hkdf", - "dep:rand", - "dep:sha2", - "dep:uuid", - "dep:walletkit-db", -] + +# Embeds compiled zkeys into the binary at compile time, enabling `Groth16Materials::from_embedded`. +# Also activates `cache_embedded_groth16_material` on native targets. +# Disable this feature for environments where binary size matters (e.g. WASM). +embed-zkeys = ["world-id-core/embed-zkeys", "world-id-core/zstd-compress-zkeys"] # SECTION: V3 Feature Flags # Before conventions were introduced for external nullifiers with `app_id` & `action`, raw field elements were used. @@ -108,6 +101,20 @@ legacy-nullifiers = [] semaphore = ["dep:semaphore-rs", "semaphore-rs/depth_30"] v3 = ["semaphore", "legacy-nullifiers", "ruint/ark-ff-04"] +[[test]] +name = "authenticator_integration" +required-features = ["embed-zkeys"] + +[[test]] +name = "proof_generation_integration" +required-features = ["embed-zkeys"] [lints] workspace = true + +[package.metadata.docs.rs] +no-default-features = true +# embed-zkeys is intentionally excluded: docs.rs builds have no network +# access, and world-id-core/embed-zkeys downloads circuit files at compile +# time. The crate-level doc example is marked `ignore` for this reason. +features = ["issuers"] diff --git a/walletkit-core/src/authenticator/mod.rs b/walletkit-core/src/authenticator/mod.rs index 90b03f47e..44f92bdfe 100644 --- a/walletkit-core/src/authenticator/mod.rs +++ b/walletkit-core/src/authenticator/mod.rs @@ -14,81 +14,104 @@ use world_id_core::{ InitializingAuthenticator as CoreInitializingAuthenticator, }; -#[cfg(feature = "storage")] use world_id_core::{ requests::{ProofResponse as CoreProofResponse, ResponseItem}, FieldElement as CoreFieldElement, }; -#[cfg(feature = "storage")] -use crate::storage::{CredentialStore, StoragePaths}; - -#[cfg(feature = "storage")] use crate::requests::{ProofRequest, ProofResponse}; +use crate::storage::CredentialStore; +#[cfg(not(target_arch = "wasm32"))] +use crate::storage::StoragePaths; -#[cfg(feature = "storage")] use rand::rngs::OsRng; -#[cfg(feature = "storage")] mod with_storage; -type Groth16Materials = ( - Arc, - Arc, -); - -#[cfg(not(feature = "storage"))] -/// Loads embedded Groth16 query/nullifier material for authenticator initialization. +/// Pre-loaded Groth16 proving material (query circuit + nullifier circuit). /// -/// # Errors -/// Returns an error if embedded material cannot be loaded or verified. -fn load_embedded_materials() -> Result { - let query_material = - world_id_core::proof::load_embedded_query_material().map_err(|error| { - WalletKitError::Groth16MaterialEmbeddedLoad { - error: error.to_string(), - } - })?; - let nullifier_material = world_id_core::proof::load_embedded_nullifier_material() - .map_err(|error| { - WalletKitError::Groth16MaterialEmbeddedLoad { - error: error.to_string(), - } - })?; +/// Construct via `Groth16Materials::from_embedded` (requires the `embed-zkeys` feature) or +/// [`Groth16Materials::from_cache`] (native only, loads from filesystem). +#[derive(Clone, uniffi::Object)] +pub struct Groth16Materials { + query: Arc, + nullifier: Arc, +} - Ok((Arc::new(query_material), Arc::new(nullifier_material))) +impl std::fmt::Debug for Groth16Materials { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("Groth16Materials").finish_non_exhaustive() + } } -#[cfg(feature = "storage")] -/// Loads cached Groth16 query/nullifier material from the provided storage paths. +/// Constructors that require embedded zkeys compiled into the binary. /// -/// # Errors -/// Returns an error if cached material cannot be loaded or verified. -fn load_cached_materials( - paths: &StoragePaths, -) -> Result { - let query_zkey = paths.query_zkey_path(); - let nullifier_zkey = paths.nullifier_zkey_path(); - let query_graph = paths.query_graph_path(); - let nullifier_graph = paths.nullifier_graph_path(); - - let query_material = load_query_material_from_cache(&query_zkey, &query_graph)?; - let nullifier_material = - load_nullifier_material_from_cache(&nullifier_zkey, &nullifier_graph)?; - - Ok((Arc::new(query_material), Arc::new(nullifier_material))) +/// Enable the `embed-zkeys` Cargo feature to activate these. +#[cfg(feature = "embed-zkeys")] +#[uniffi::export] +impl Groth16Materials { + /// Loads Groth16 material from the embedded (compiled-in) zkeys and graphs. + /// + /// Requires the `embed-zkeys` feature. The material is baked into the binary at + /// compile time so no filesystem access is required, and this works on every + /// platform including WASM. + /// + /// # Errors + /// + /// Returns an error if the embedded material cannot be loaded or verified. + #[uniffi::constructor] + pub fn from_embedded() -> Result { + let query = + world_id_core::proof::load_embedded_query_material().map_err(|error| { + WalletKitError::Groth16MaterialEmbeddedLoad { + error: error.to_string(), + } + })?; + let nullifier = world_id_core::proof::load_embedded_nullifier_material() + .map_err(|error| WalletKitError::Groth16MaterialEmbeddedLoad { + error: error.to_string(), + })?; + Ok(Self { + query: Arc::new(query), + nullifier: Arc::new(nullifier), + }) + } } -#[cfg(feature = "storage")] -/// Loads cached query material from zkey/graph paths. +/// Constructors that load Groth16 material from the native filesystem. /// -/// # Errors -/// Returns an error if the cached query material cannot be loaded or verified. -fn load_query_material_from_cache( - query_zkey: &std::path::Path, - query_graph: &std::path::Path, -) -> Result { - world_id_core::proof::load_query_material_from_paths(query_zkey, query_graph) +/// Not available on WASM targets (no filesystem access). +#[cfg(not(target_arch = "wasm32"))] +#[uniffi::export] +impl Groth16Materials { + /// Loads Groth16 material from cached files on disk. + /// + /// Use `storage::cache_embedded_groth16_material` (requires the `embed-zkeys` feature) + /// to populate the cache before calling this. + /// + /// Not available on WASM (no filesystem). + /// + /// # Errors + /// + /// Returns an error if the cached files cannot be read or verified. + #[uniffi::constructor] + // `Arc` must be taken by value: UniFFI constructors receive + // object arguments as owned `Arc`s across the FFI boundary, so passing by + // reference is not an option here. + #[expect( + clippy::needless_pass_by_value, + reason = "UniFFI constructors require owned Arc arguments" + )] + pub fn from_cache(paths: Arc) -> Result { + let query_zkey = paths.query_zkey_path(); + let nullifier_zkey = paths.nullifier_zkey_path(); + let query_graph = paths.query_graph_path(); + let nullifier_graph = paths.nullifier_graph_path(); + + let query = world_id_core::proof::load_query_material_from_paths( + &query_zkey, + &query_graph, + ) .map_err(|error| WalletKitError::Groth16MaterialCacheInvalid { path: format!( "{} and {}", @@ -96,36 +119,26 @@ fn load_query_material_from_cache( query_graph.to_string_lossy() ), error: error.to_string(), - }) -} + })?; -#[cfg(feature = "storage")] -#[expect( - clippy::unnecessary_wraps, - reason = "Temporary wrapper until world-id-core returns Result for nullifier path loader" -)] -/// Loads cached nullifier material from zkey/graph paths. -/// -/// # Errors -/// This currently mirrors a panicking upstream API and does not return an error path yet. -/// It is intentionally wrapped in `Result` for forward compatibility with upstream. -fn load_nullifier_material_from_cache( - nullifier_zkey: &std::path::Path, - nullifier_graph: &std::path::Path, -) -> Result { - // TODO: Switch to error mapping once world-id-core exposes - // `load_nullifier_material_from_paths` as `Result` instead of panicking. - Ok(world_id_core::proof::load_nullifier_material_from_paths( - nullifier_zkey, - nullifier_graph, - )) + // TODO: Switch to error mapping once world-id-core exposes + // `load_nullifier_material_from_paths` as `Result` instead of panicking. + let nullifier = world_id_core::proof::load_nullifier_material_from_paths( + &nullifier_zkey, + &nullifier_graph, + ); + + Ok(Self { + query: Arc::new(query), + nullifier: Arc::new(nullifier), + }) + } } /// The Authenticator is the main component with which users interact with the World ID Protocol. #[derive(Debug, uniffi::Object)] pub struct Authenticator { inner: CoreAuthenticator, - #[cfg(feature = "storage")] store: Arc, } @@ -222,58 +235,6 @@ impl Authenticator { } } -#[cfg(not(feature = "storage"))] -#[uniffi::export(async_runtime = "tokio")] -impl Authenticator { - /// Initializes a new Authenticator from a seed and with SDK defaults. - /// - /// The user's World ID must already be registered in the `WorldIDRegistry`, - /// otherwise a [`WalletKitError::AccountDoesNotExist`] error will be returned. - /// - /// # Errors - /// See `CoreAuthenticator::init` for potential errors. - #[uniffi::constructor] - pub async fn init_with_defaults( - seed: &[u8], - rpc_url: Option, - environment: &Environment, - region: Option, - ) -> Result { - let config = Config::from_environment(environment, rpc_url, region)?; - let authenticator = CoreAuthenticator::init(seed, config).await?; - let (query_material, nullifier_material) = load_embedded_materials()?; - let authenticator = - authenticator.with_proof_materials(query_material, nullifier_material); - Ok(Self { - inner: authenticator, - }) - } - - /// Initializes a new Authenticator from a seed and config. - /// - /// The user's World ID must already be registered in the `WorldIDRegistry`, - /// otherwise a [`WalletKitError::AccountDoesNotExist`] error will be returned. - /// - /// # Errors - /// Will error if the provided seed is not valid or if the config is not valid. - #[uniffi::constructor] - pub async fn init(seed: &[u8], config: &str) -> Result { - let config = - Config::from_json(config).map_err(|_| WalletKitError::InvalidInput { - attribute: "config".to_string(), - reason: "Invalid config".to_string(), - })?; - let authenticator = CoreAuthenticator::init(seed, config).await?; - let (query_material, nullifier_material) = load_embedded_materials()?; - let authenticator = - authenticator.with_proof_materials(query_material, nullifier_material); - Ok(Self { - inner: authenticator, - }) - } -} - -#[cfg(feature = "storage")] #[uniffi::export(async_runtime = "tokio")] impl Authenticator { /// Initializes a new Authenticator from a seed and with SDK defaults. @@ -289,14 +250,16 @@ impl Authenticator { rpc_url: Option, environment: &Environment, region: Option, - paths: &StoragePaths, + materials: Arc, store: Arc, ) -> Result { let config = Config::from_environment(environment, rpc_url, region)?; - let authenticator = CoreAuthenticator::init(seed, config).await?; - let (query_material, nullifier_material) = load_cached_materials(paths)?; - let authenticator = - authenticator.with_proof_materials(query_material, nullifier_material); + let authenticator = CoreAuthenticator::init(seed, config) + .await? + .with_proof_materials( + Arc::clone(&materials.query), + Arc::clone(&materials.nullifier), + ); Ok(Self { inner: authenticator, store, @@ -314,7 +277,7 @@ impl Authenticator { pub async fn init( seed: &[u8], config: &str, - paths: &StoragePaths, + materials: Arc, store: Arc, ) -> Result { let config = @@ -322,11 +285,12 @@ impl Authenticator { attribute: "config".to_string(), reason: "Invalid config".to_string(), })?; - - let authenticator = CoreAuthenticator::init(seed, config).await?; - let (query_material, nullifier_material) = load_cached_materials(paths)?; - let authenticator = - authenticator.with_proof_materials(query_material, nullifier_material); + let authenticator = CoreAuthenticator::init(seed, config) + .await? + .with_proof_materials( + Arc::clone(&materials.query), + Arc::clone(&materials.nullifier), + ); Ok(Self { inner: authenticator, store, @@ -345,13 +309,24 @@ impl Authenticator { let now = if let Some(n) = now { n } else { - let start = std::time::SystemTime::now(); - start - .duration_since(std::time::UNIX_EPOCH) - .map_err(|e| WalletKitError::Generic { - error: format!("Critical. Unable to determine SystemTime: {e}"), - })? - .as_secs() + #[cfg(target_arch = "wasm32")] + { + return Err(WalletKitError::InvalidInput { + attribute: "now".to_string(), + reason: "`now` must be provided on wasm32 targets".to_string(), + }); + } + + #[cfg(not(target_arch = "wasm32"))] + { + let start = std::time::SystemTime::now(); + start + .duration_since(std::time::UNIX_EPOCH) + .map_err(|e| WalletKitError::Generic { + error: format!("Critical. Unable to determine SystemTime: {e}"), + })? + .as_secs() + } }; // First check if the request can be fulfilled and which credentials should be used @@ -534,17 +509,16 @@ impl InitializingAuthenticator { } } -#[cfg(all(test, feature = "storage"))] +#[cfg(all(test, feature = "embed-zkeys"))] mod tests { use super::*; - use crate::storage::cache_embedded_groth16_material; use crate::storage::tests_utils::{ cleanup_test_storage, temp_root_path, InMemoryStorageProvider, }; use alloy::primitives::address; #[tokio::test] - async fn test_init_with_config_and_storage() { + async fn test_init_with_config_and_materials() { // Install default crypto provider for rustls let _ = rustls::crypto::ring::default_provider().install_default(); @@ -583,11 +557,10 @@ mod tests { let provider = InMemoryStorageProvider::new(&root); let store = CredentialStore::from_provider(&provider).expect("store"); store.init(42, 100).expect("init storage"); - cache_embedded_groth16_material(&store.storage_paths().expect("paths")) - .expect("cache material"); - let paths = store.storage_paths().expect("paths"); - Authenticator::init(&seed, &config, &paths, Arc::new(store)) + let materials = + Arc::new(Groth16Materials::from_embedded().expect("load materials")); + Authenticator::init(&seed, &config, materials, Arc::new(store)) .await .unwrap(); drop(mock_server); diff --git a/walletkit-core/src/authenticator/with_storage.rs b/walletkit-core/src/authenticator/with_storage.rs index 72e30f943..2792588b8 100644 --- a/walletkit-core/src/authenticator/with_storage.rs +++ b/walletkit-core/src/authenticator/with_storage.rs @@ -1,12 +1,12 @@ +use crate::error::WalletKitError; + +use super::Authenticator; + use serde::{Deserialize, Serialize}; use world_id_core::primitives::authenticator::AuthenticatorPublicKeySet; use world_id_core::primitives::merkle::MerkleInclusionProof; use world_id_core::primitives::TREE_DEPTH; -use crate::error::WalletKitError; - -use super::Authenticator; - /// The amount of time a Merkle inclusion proof remains valid in the cache. const MERKLE_PROOF_VALIDITY_SECONDS: u64 = 60 * 15; diff --git a/walletkit-core/src/error.rs b/walletkit-core/src/error.rs index 773b68542..36c24bfc7 100644 --- a/walletkit-core/src/error.rs +++ b/walletkit-core/src/error.rs @@ -1,7 +1,6 @@ use thiserror::Error; use world_id_core::{primitives::PrimitiveError, AuthenticatorError}; -#[cfg(feature = "storage")] use crate::storage::StorageError; /// Error outputs from `WalletKit` @@ -159,7 +158,6 @@ impl From for WalletKitError { } } -#[cfg(feature = "storage")] impl From for WalletKitError { fn from(error: StorageError) -> Self { Self::Generic { diff --git a/walletkit-core/src/http_request.rs b/walletkit-core/src/http_request.rs index 233e22079..5c1d8ac9f 100644 --- a/walletkit-core/src/http_request.rs +++ b/walletkit-core/src/http_request.rs @@ -153,7 +153,11 @@ async fn execute_request_builder( Ok(resp) } Err(err) => { - if err.is_timeout() || err.is_connect() { + #[cfg(not(target_arch = "wasm32"))] + let is_retryable = err.is_timeout() || err.is_connect(); + #[cfg(target_arch = "wasm32")] + let is_retryable = err.is_timeout(); + if is_retryable { return Err(RequestHandleError::retryable( url, None, diff --git a/walletkit-core/src/lib.rs b/walletkit-core/src/lib.rs index 9bbe4c3c8..21f3e90b0 100644 --- a/walletkit-core/src/lib.rs +++ b/walletkit-core/src/lib.rs @@ -3,22 +3,19 @@ //! //! # Example //! -//! ```rust,no_run +//! ```rust,ignore +//! // Note: `Groth16Materials::from_embedded` requires the `embed-zkeys` Cargo feature. +//! // On native targets you can alternatively use `Groth16Materials::from_cache` after +//! // calling `storage::cache_embedded_groth16_material` to populate the on-disk cache. //! use std::sync::Arc; //! use walletkit_core::requests::ProofRequest; -//! use walletkit_core::storage::{ -//! cache_embedded_groth16_material, CredentialStore, StoragePaths, -//! }; -//! use walletkit_core::{Authenticator, Environment}; +//! use walletkit_core::storage::CredentialStore; +//! use walletkit_core::{Authenticator, Environment, Groth16Materials}; //! -//! /// Platform layer provides a [`CredentialStore`] backed by a -//! /// device-specific [`StorageProvider`](walletkit_core::storage::StorageProvider). //! async fn generate_world_id_proof( //! store: Arc, //! ) -> Result<(), Box> { -//! // Cache Groth16 proving material to disk (idempotent). -//! let paths = StoragePaths::from_root("/data/walletkit".into()); -//! cache_embedded_groth16_material(&paths)?; +//! let materials = Arc::new(Groth16Materials::from_embedded()?); //! //! // Initialize an authenticator for an already-registered World ID. //! let seed = b"my_secret_seed_at_length_32_bytes!"; @@ -27,7 +24,7 @@ //! None, // uses default RPC URL //! &Environment::Staging, //! None, // uses default region -//! &paths, +//! materials, //! store, //! ) //! .await?; @@ -50,7 +47,9 @@ use strum::{Display, EnumString}; /// Installs the ring crypto provider as the default for rustls. /// Uses the `ctor` crate to ensure this runs when the dynamic library loads, /// before any user code executes. -#[cfg(not(test))] +/// +/// On WASM targets, rustls is not used (reqwest uses the browser fetch API). +#[cfg(all(not(test), not(target_arch = "wasm32")))] #[ctor::ctor] fn init() { rustls::crypto::ring::default_provider() @@ -88,7 +87,7 @@ impl Environment { /// Region for node selection. #[derive( - Debug, Clone, Copy, PartialEq, Eq, Default, uniffi::Enum, EnumString, Display, + Debug, Clone, Copy, PartialEq, Eq, Default, EnumString, Display, uniffi::Enum, )] #[strum(serialize_all = "lowercase")] pub enum Region { @@ -114,11 +113,12 @@ mod credential; pub use credential::Credential; /// Credential storage primitives for World ID v4. -#[cfg(feature = "storage")] pub mod storage; mod authenticator; -pub use authenticator::{Authenticator, InitializingAuthenticator, RegistrationStatus}; +pub use authenticator::{ + Authenticator, Groth16Materials, InitializingAuthenticator, RegistrationStatus, +}; /// Default configuration values for each [`Environment`]. pub mod defaults; @@ -149,7 +149,7 @@ pub mod v3; // Private modules //////////////////////////////////////////////////////////////////////////////// -#[cfg(any(feature = "issuers", feature = "storage"))] +#[cfg(any(feature = "issuers", feature = "v3"))] mod http_request; pub(crate) mod primitives; diff --git a/walletkit-core/src/logger.rs b/walletkit-core/src/logger.rs index 6603a396d..bfc45ec17 100644 --- a/walletkit-core/src/logger.rs +++ b/walletkit-core/src/logger.rs @@ -1,9 +1,13 @@ +#[cfg(not(target_arch = "wasm32"))] +use std::sync::{mpsc, Mutex}; use std::{ fmt, - sync::{mpsc, Arc, Mutex, OnceLock}, - thread, + sync::{Arc, OnceLock}, }; +#[cfg(not(target_arch = "wasm32"))] +use std::thread; + use tracing::{Event, Level, Subscriber}; use tracing_subscriber::{ layer::{Context, SubscriberExt}, @@ -117,6 +121,10 @@ impl tracing::field::Visit for EventFieldVisitor { /// Forwards walletkit tracing events to the foreign logger. struct ForeignLoggerLayer; +// On native targets, log events flow through a channel to avoid making FFI +// calls from within a UniFFI future-poll context. On WASM the Logger is +// called directly because there is no background thread support. +#[cfg(not(target_arch = "wasm32"))] struct LogEvent { level: LogLevel, message: String, @@ -132,7 +140,10 @@ struct LogEvent { // the tracing layer never makes an FFI call — it only pushes to an in-process // queue — and the dedicated delivery thread calls `Logger::log` from a clean // stack with no active FFI frames. +#[cfg(not(target_arch = "wasm32"))] static LOG_CHANNEL: OnceLock>> = OnceLock::new(); +#[cfg(target_arch = "wasm32")] +static LOGGER_INSTANCE: OnceLock> = OnceLock::new(); static LOGGING_INITIALIZED: OnceLock<()> = OnceLock::new(); impl Layer for ForeignLoggerLayer @@ -140,10 +151,16 @@ where S: Subscriber + for<'span> LookupSpan<'span>, { fn on_event(&self, event: &Event<'_>, _ctx: Context<'_, S>) { + #[cfg(not(target_arch = "wasm32"))] let Some(sender) = LOG_CHANNEL.get() else { return; }; + #[cfg(target_arch = "wasm32")] + if LOGGER_INSTANCE.get().is_none() { + return; + } + let mut visitor = EventFieldVisitor::default(); event.record(&mut visitor); let metadata = event.metadata(); @@ -169,6 +186,12 @@ where let formatted = sanitize_hex_secrets(format!("{} {message}", metadata.target())); + #[cfg(target_arch = "wasm32")] + if let Some(logger) = LOGGER_INSTANCE.get() { + logger.log(log_level(*metadata.level()), formatted.clone()); + } + + #[cfg(not(target_arch = "wasm32"))] if let Ok(sender) = sender.lock() { let _ = sender.send(LogEvent { level: log_level(*metadata.level()), @@ -246,6 +269,44 @@ pub fn emit_log(level: LogLevel, message: String) { } } +/// Native platform initializer: wires the foreign logger to a dedicated +/// delivery thread via an mpsc channel. +/// +/// The channel decouples `ForeignLoggerLayer::on_event` (called from inside +/// `UniFFI`'s future-poll machinery) from the actual FFI call to `Logger::log`. +/// Invoking a `UniFFI` foreign callback synchronously while a `UniFFI` frame is +/// already on the stack causes an `EXC_BAD_ACCESS`; the background thread avoids +/// that by delivering events from a clean, FFI-free call stack. +/// +/// # Panics +/// +/// Panics if the background thread cannot be spawned. +#[cfg(not(target_arch = "wasm32"))] +fn init_logging_native(logger: Arc) { + let (tx, rx) = mpsc::channel::(); + let _ = LOG_CHANNEL.set(Mutex::new(tx)); + + thread::Builder::new() + .name("walletkit-logger".into()) + .spawn(move || { + for event in rx { + logger.log(event.level, event.message); + } + }) + .expect("failed to spawn walletkit logger thread"); +} + +/// WASM platform initializer: stores the logger directly so that +/// `ForeignLoggerLayer::on_event` can call it synchronously. +/// +/// On WASM there is no background-thread risk: the runtime is +/// single-threaded and cooperative, so no UniFFI future-poll frame can be +/// on the stack when a tracing event fires. +#[cfg(target_arch = "wasm32")] +fn init_logging_wasm(logger: Arc) { + let _ = LOGGER_INSTANCE.set(logger); +} + /// Initializes `WalletKit` tracing and registers a foreign logger sink. /// /// `level` controls the minimum severity for `WalletKit` and its direct @@ -257,24 +318,18 @@ pub fn emit_log(level: LogLevel, message: String) { /// /// # Panics /// -/// Panics if the dedicated logger delivery thread cannot be spawned. +/// Panics if the dedicated logger delivery thread cannot be spawned (native only). #[uniffi::export] pub fn init_logging(logger: Arc, level: Option) { if LOGGING_INITIALIZED.get().is_some() { return; } - let (tx, rx) = mpsc::channel::(); - let _ = LOG_CHANNEL.set(Mutex::new(tx)); + #[cfg(not(target_arch = "wasm32"))] + init_logging_native(logger); - thread::Builder::new() - .name("walletkit-logger".into()) - .spawn(move || { - for event in rx { - logger.log(event.level, event.message); - } - }) - .expect("failed to spawn walletkit logger thread"); + #[cfg(target_arch = "wasm32")] + init_logging_wasm(logger); let _ = tracing_log::LogTracer::init(); diff --git a/walletkit-core/src/storage/credential_storage.rs b/walletkit-core/src/storage/credential_storage.rs index 584e77d19..ac221a6d5 100644 --- a/walletkit-core/src/storage/credential_storage.rs +++ b/walletkit-core/src/storage/credential_storage.rs @@ -41,7 +41,7 @@ impl Drop for CleanupFile { } /// Concrete storage implementation backed by `SQLCipher` databases. -#[cfg_attr(not(target_arch = "wasm32"), derive(uniffi::Object))] +#[derive(uniffi::Object)] pub struct CredentialStore { inner: Mutex, /// Channel sender for the vault-changed notification thread. @@ -120,14 +120,14 @@ impl CredentialStoreInner { } } -#[cfg_attr(not(target_arch = "wasm32"), uniffi::export)] +#[uniffi::export] impl CredentialStore { /// Creates a new storage handle from explicit components. /// /// # Errors /// /// Returns an error if the storage lock cannot be opened. - #[cfg_attr(not(target_arch = "wasm32"), uniffi::constructor)] + #[uniffi::constructor] pub fn new_with_components( paths: Arc, keystore: Arc, @@ -147,7 +147,7 @@ impl CredentialStore { /// # Errors /// /// Returns an error if the storage lock cannot be opened. - #[cfg_attr(not(target_arch = "wasm32"), uniffi::constructor)] + #[uniffi::constructor] #[allow(clippy::needless_pass_by_value)] pub fn from_provider_arc( provider: Arc, @@ -259,6 +259,34 @@ impl CredentialStore { .merkle_cache_put(proof_bytes, now, ttl_seconds) } + /// **Development only.** Permanently deletes all stored credentials and their + /// associated blob data from the vault. + /// + /// This is a destructive, unrecoverable operation intended for use in + /// development and testing environments only. Do not call this in production. + /// + /// Preserves storage metadata (leaf index, schema version), so the store + /// remains initialized and ready to accept new credentials after the call. + /// + /// # Returns + /// + /// The number of credentials deleted. + /// + /// # Errors + /// + /// Returns an error if the delete operation fails. + pub fn danger_delete_all_credentials(&self) -> StorageResult { + let result = self.lock_inner()?.danger_delete_all_credentials(); + if result.is_ok() { + self.notify_vault_changed(); + } + result + } +} + +#[cfg(not(target_arch = "wasm32"))] +#[uniffi::export] +impl CredentialStore { /// Exports the current vault as an in-memory plaintext (unencrypted) /// `SQLite` database for backup. /// @@ -268,7 +296,6 @@ impl CredentialStore { /// # Errors /// /// Returns an error if the store is not initialized or the export fails. - #[cfg(not(target_arch = "wasm32"))] #[expect( clippy::significant_drop_tightening, reason = "lock held intentionally for the full operation to prevent concurrent cleanup from deleting in-use temp files" @@ -292,7 +319,6 @@ impl CredentialStore { /// # Errors /// /// Returns an error if the store is not initialized or the import fails. - #[cfg(not(target_arch = "wasm32"))] #[expect( clippy::needless_pass_by_value, reason = "Vec required for UniFFI lifting" @@ -305,31 +331,10 @@ impl CredentialStore { inner.import_vault_from_file(&path) } +} - /// **Development only.** Permanently deletes all stored credentials and their - /// associated blob data from the vault. - /// - /// This is a destructive, unrecoverable operation intended for use in - /// development and testing environments only. Do not call this in production. - /// - /// Preserves storage metadata (leaf index, schema version), so the store - /// remains initialized and ready to accept new credentials after the call. - /// - /// # Returns - /// - /// The number of credentials deleted. - /// - /// # Errors - /// - /// Returns an error if the delete operation fails. - pub fn danger_delete_all_credentials(&self) -> StorageResult { - let result = self.lock_inner()?.danger_delete_all_credentials(); - if result.is_ok() { - self.notify_vault_changed(); - } - result - } - +/// Implementation not exposed to foreign bindings +impl CredentialStore { /// Registers a listener that is called after every successful vault /// mutation (store, delete, purge). /// @@ -363,10 +368,7 @@ impl CredentialStore { } } } -} -/// Implementation not exposed to foreign bindings -impl CredentialStore { /// Best-effort notification to the registered vault-changed listener. /// No-op on wasm32 where the listener cannot be registered. fn notify_vault_changed(&self) { diff --git a/walletkit-core/src/storage/error.rs b/walletkit-core/src/storage/error.rs index 1b97146fb..dd49ef3fb 100644 --- a/walletkit-core/src/storage/error.rs +++ b/walletkit-core/src/storage/error.rs @@ -6,8 +6,7 @@ use thiserror::Error; pub type StorageResult = Result; /// Errors raised by credential storage primitives. -#[derive(Debug, Error)] -#[cfg_attr(not(target_arch = "wasm32"), derive(uniffi::Error))] +#[derive(Debug, Error, uniffi::Error)] pub enum StorageError { /// Errors coming from the device keystore. #[error("keystore error: {0}")] @@ -89,7 +88,6 @@ pub enum StorageError { UnexpectedUniFFICallbackError(String), } -#[cfg(not(target_arch = "wasm32"))] impl From for StorageError { fn from(error: uniffi::UnexpectedUniFFICallbackError) -> Self { Self::UnexpectedUniFFICallbackError(error.reason) diff --git a/walletkit-core/src/storage/lock.rs b/walletkit-core/src/storage/lock.rs index 25fdb7a90..b695ea101 100644 --- a/walletkit-core/src/storage/lock.rs +++ b/walletkit-core/src/storage/lock.rs @@ -9,7 +9,9 @@ use std::path::Path; -use super::error::{StorageError, StorageResult}; +#[cfg(not(target_arch = "wasm32"))] +use super::error::StorageError; +use super::error::StorageResult; // WASM: no-op lock (single-threaded worker, SQLITE_THREADSAFE=0) @@ -26,14 +28,17 @@ mod imp { pub struct StorageLockGuard; impl StorageLock { + /// Opens a no-op lock (WASM is single-threaded). pub fn open(_path: &Path) -> StorageResult { Ok(Self) } + /// Acquires a no-op lock (always succeeds). pub fn lock(&self) -> StorageResult { Ok(StorageLockGuard) } + /// Attempts to acquire a no-op lock (always succeeds). pub fn try_lock(&self) -> StorageResult> { Ok(Some(StorageLockGuard)) } diff --git a/walletkit-core/src/storage/mod.rs b/walletkit-core/src/storage/mod.rs index c24caacab..16c705419 100644 --- a/walletkit-core/src/storage/mod.rs +++ b/walletkit-core/src/storage/mod.rs @@ -4,6 +4,7 @@ pub mod cache; pub mod credential_storage; pub mod envelope; pub mod error; +#[cfg(all(not(target_arch = "wasm32"), feature = "embed-zkeys"))] pub mod groth16_cache; pub mod keys; pub mod lock; @@ -15,6 +16,7 @@ pub mod vault; pub use cache::CacheDb; pub use credential_storage::CredentialStore; pub use error::{StorageError, StorageResult}; +#[cfg(all(not(target_arch = "wasm32"), feature = "embed-zkeys"))] pub use groth16_cache::cache_embedded_groth16_material; pub use keys::StorageKeys; pub use lock::{StorageLock, StorageLockGuard}; diff --git a/walletkit-core/src/storage/paths.rs b/walletkit-core/src/storage/paths.rs index ee37944c4..138803b40 100644 --- a/walletkit-core/src/storage/paths.rs +++ b/walletkit-core/src/storage/paths.rs @@ -12,8 +12,7 @@ const QUERY_GRAPH_FILENAME: &str = "OPRFQueryGraph.bin"; const NULLIFIER_GRAPH_FILENAME: &str = "OPRFNullifierGraph.bin"; /// Paths for credential storage artifacts under `/worldid`. -#[derive(Debug, Clone)] -#[cfg_attr(not(target_arch = "wasm32"), derive(uniffi::Object))] +#[derive(Debug, Clone, uniffi::Object)] pub struct StoragePaths { root: PathBuf, worldid_dir: PathBuf, @@ -89,10 +88,10 @@ impl StoragePaths { } } -#[cfg_attr(not(target_arch = "wasm32"), uniffi::export)] +#[uniffi::export] impl StoragePaths { /// Builds storage paths rooted at `root`. - #[cfg_attr(not(target_arch = "wasm32"), uniffi::constructor)] + #[uniffi::constructor] #[must_use] pub fn from_root(root: String) -> Self { Self::new(PathBuf::from(root)) diff --git a/walletkit-core/src/storage/traits.rs b/walletkit-core/src/storage/traits.rs index 838007197..f5743c210 100644 --- a/walletkit-core/src/storage/traits.rs +++ b/walletkit-core/src/storage/traits.rs @@ -20,7 +20,7 @@ use super::error::StorageResult; use super::paths::StoragePaths; /// Device keystore interface used to seal and open account keys. -#[cfg_attr(not(target_arch = "wasm32"), uniffi::export(with_foreign))] +#[uniffi::export(with_foreign)] pub trait DeviceKeystore: Send + Sync { /// Seals plaintext under the device-bound key, authenticating `associated_data`. /// @@ -52,7 +52,7 @@ pub trait DeviceKeystore: Send + Sync { } /// Atomic blob store for small binary files (e.g., `account_keys.bin`). -#[cfg_attr(not(target_arch = "wasm32"), uniffi::export(with_foreign))] +#[uniffi::export(with_foreign)] pub trait AtomicBlobStore: Send + Sync { /// Reads the blob at `path`, if present. /// @@ -77,7 +77,7 @@ pub trait AtomicBlobStore: Send + Sync { } /// Provider responsible for platform-specific storage components and paths. -#[cfg_attr(not(target_arch = "wasm32"), uniffi::export(with_foreign))] +#[uniffi::export(with_foreign)] pub trait StorageProvider: Send + Sync { /// Returns the device keystore implementation. fn keystore(&self) -> Arc; diff --git a/walletkit-core/src/storage/types.rs b/walletkit-core/src/storage/types.rs index 1ec80939b..edbea91cd 100644 --- a/walletkit-core/src/storage/types.rs +++ b/walletkit-core/src/storage/types.rs @@ -6,8 +6,7 @@ use super::error::{StorageError, StorageResult}; /// /// Blob records (stored in the `blob_objects` table) carry a kind tag that /// distinguishes credential payloads from associated data. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[cfg_attr(not(target_arch = "wasm32"), derive(uniffi::Enum))] +#[derive(Debug, Clone, Copy, PartialEq, Eq, uniffi::Enum)] #[repr(u8)] pub enum BlobKind { /// Credential blob payload. @@ -47,8 +46,7 @@ pub type Nullifier = [u8; 32]; /// /// This is intentionally small and excludes blobs; full credential payloads can /// be fetched separately to avoid heavy list queries. -#[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(not(target_arch = "wasm32"), derive(uniffi::Record))] +#[derive(Debug, Clone, PartialEq, Eq, uniffi::Record)] pub struct CredentialRecord { /// Credential identifier. pub credential_id: u64, @@ -63,8 +61,7 @@ pub struct CredentialRecord { } /// FFI-friendly replay guard result kind. -#[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(not(target_arch = "wasm32"), derive(uniffi::Enum))] +#[derive(Debug, Clone, PartialEq, Eq, uniffi::Enum)] pub enum ReplayGuardKind { /// Stored bytes for the first disclosure of a request. Fresh, @@ -73,8 +70,7 @@ pub enum ReplayGuardKind { } /// Replay guard result. -#[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(not(target_arch = "wasm32"), derive(uniffi::Record))] +#[derive(Debug, Clone, PartialEq, Eq, uniffi::Record)] pub struct ReplayGuardResult { /// Result kind. pub kind: ReplayGuardKind, diff --git a/walletkit-core/tests/authenticator_integration.rs b/walletkit-core/tests/authenticator_integration.rs index 0a77c080a..e5c4c0581 100644 --- a/walletkit-core/tests/authenticator_integration.rs +++ b/walletkit-core/tests/authenticator_integration.rs @@ -1,5 +1,4 @@ -#![allow(missing_docs)] -#![cfg(feature = "storage")] +#![allow(missing_docs, clippy::missing_docs_in_private_items)] mod common; @@ -9,8 +8,7 @@ use alloy::providers::ProviderBuilder; use alloy::signers::local::PrivateKeySigner; use walletkit_core::defaults::STAGING_WORLD_ID_REGISTRY; use walletkit_core::error::WalletKitError; -use walletkit_core::storage::cache_embedded_groth16_material; -use walletkit_core::{Authenticator, Environment}; +use walletkit_core::{Authenticator, Environment, Groth16Materials}; use world_id_core::world_id_registry::WorldIdRegistry; fn setup_anvil() -> AnvilInstance { @@ -36,8 +34,9 @@ async fn test_authenticator_integration() { let authenticator_seeder = PrivateKeySigner::random(); let store = common::create_test_credential_store(); - let paths = store.storage_paths().unwrap(); - cache_embedded_groth16_material(&paths).expect("cache groth16 material"); + let materials = std::sync::Arc::new( + Groth16Materials::from_embedded().expect("load groth16 materials"), + ); // When account doesn't exist, this should fail let authenticator = Authenticator::init_with_defaults( @@ -45,7 +44,7 @@ async fn test_authenticator_integration() { Some(anvil.endpoint()), &Environment::Staging, None, - &paths, + materials.clone(), store.clone(), ) .await @@ -81,7 +80,7 @@ async fn test_authenticator_integration() { Some(anvil.endpoint()), &Environment::Staging, None, - &paths, + materials, store, ) .await diff --git a/walletkit-core/tests/common.rs b/walletkit-core/tests/common.rs index 9ef1e8f19..948afdc39 100644 --- a/walletkit-core/tests/common.rs +++ b/walletkit-core/tests/common.rs @@ -6,7 +6,6 @@ clippy::missing_panics_doc, clippy::must_use_candidate )] -#![cfg(feature = "storage")] //! Common test utilities shared across integration tests. diff --git a/walletkit-core/tests/credential_storage_integration.rs b/walletkit-core/tests/credential_storage_integration.rs index b320d8027..fd272a829 100644 --- a/walletkit-core/tests/credential_storage_integration.rs +++ b/walletkit-core/tests/credential_storage_integration.rs @@ -1,5 +1,4 @@ -#![allow(missing_docs)] -#![cfg(feature = "storage")] +#![allow(missing_docs, clippy::missing_docs_in_private_items)] mod common; diff --git a/walletkit-core/tests/proof_generation_integration.rs b/walletkit-core/tests/proof_generation_integration.rs index def118da1..030c6c37e 100644 --- a/walletkit-core/tests/proof_generation_integration.rs +++ b/walletkit-core/tests/proof_generation_integration.rs @@ -6,7 +6,6 @@ clippy::similar_names, clippy::too_many_lines )] -#![cfg(feature = "storage")] //! End-to-end integration test for `Authenticator::generate_proof` (World ID v4) //! using **staging infrastructure** (real OPRF nodes, indexer, gateway, on-chain registries). @@ -34,8 +33,9 @@ use alloy::sol; use alloy_primitives::U160; use eyre::{Context as _, Result}; use taceo_oprf::types::OprfKeyId; -use walletkit_core::storage::cache_embedded_groth16_material; -use walletkit_core::{defaults::DefaultConfig, Authenticator, Environment}; +use walletkit_core::{ + defaults::DefaultConfig, Authenticator, Environment, Groth16Materials, +}; use world_id_core::primitives::{rp::RpId, FieldElement, Nullifier}; use world_id_core::{ requests::{ProofRequest, RequestItem, RequestVersion}, @@ -144,16 +144,17 @@ async fn e2e_authenticator_generate_proof() -> Result<()> { // Phase 2: Authenticator init with walletkit wrapper // ---------------------------------------------------------------- let store = common::create_test_credential_store(); - let paths = store.storage_paths().wrap_err("storage_paths failed")?; - cache_embedded_groth16_material(&paths) - .wrap_err("cache_embedded_groth16_material failed")?; + let materials = Arc::new( + Groth16Materials::from_embedded() + .wrap_err("failed to load embedded groth16 materials")?, + ); let authenticator = Authenticator::init_with_defaults( &seed, Some(rpc_url.clone()), &Environment::Staging, None, - &paths, + materials, store.clone(), ) .await @@ -266,7 +267,7 @@ async fn e2e_authenticator_generate_proof() -> Result<()> { let nullifier = response_item .nullifier .expect("uniqueness proof should have nullifier"); - assert_ne!(nullifier, Nullifier::new(FieldElement::ZERO)); // TODO: Add `Nullifier::ZERO` + assert_ne!(nullifier, Nullifier::new(FieldElement::ZERO)); eprintln!("Phase 4 complete: proof generated (nullifier={nullifier:?})"); diff --git a/walletkit-db/src/ffi.rs b/walletkit-db/src/ffi.rs index 03f920200..286cd4437 100644 --- a/walletkit-db/src/ffi.rs +++ b/walletkit-db/src/ffi.rs @@ -515,7 +515,7 @@ mod raw { wasm::sqlite3_open_v2(filename.cast(), pp_db.cast(), flags, z_vfs.cast()) } pub unsafe fn sqlite3_close_v2(db: *mut c_void) -> c_int { - wasm::sqlite3_close_v2(db.cast()) + wasm::sqlite3_close(db.cast()) } pub unsafe fn sqlite3_exec( db: *mut c_void, @@ -567,7 +567,12 @@ mod raw { n: c_int, destructor: isize, ) -> c_int { - wasm::sqlite3_bind_blob(stmt.cast(), index, value, n, destructor) + // WASM bindings use typed destructor callbacks instead of SQLite's + // sentinel `isize` values. This shim only supports `SQLITE_TRANSIENT`, + // which matches all current callers and ensures SQLite copies the data + // immediately. + assert_eq!(destructor, super::SQLITE_TRANSIENT); + wasm::sqlite3_bind_blob(stmt.cast(), index, value, n, wasm::SQLITE_TRANSIENT()) } pub unsafe fn sqlite3_bind_text( stmt: *mut c_void, @@ -576,7 +581,18 @@ mod raw { n: c_int, destructor: isize, ) -> c_int { - wasm::sqlite3_bind_text(stmt.cast(), index, value.cast(), n, destructor) + // WASM bindings use typed destructor callbacks instead of SQLite's + // sentinel `isize` values. This shim only supports `SQLITE_TRANSIENT`, + // which matches all current callers and ensures SQLite copies the text + // immediately. + assert_eq!(destructor, super::SQLITE_TRANSIENT); + wasm::sqlite3_bind_text( + stmt.cast(), + index, + value.cast(), + n, + wasm::SQLITE_TRANSIENT(), + ) } pub unsafe fn sqlite3_bind_null(stmt: *mut c_void, index: c_int) -> c_int { wasm::sqlite3_bind_null(stmt.cast(), index) diff --git a/walletkit-db/src/tests.rs b/walletkit-db/src/tests.rs index a2177bf7a..7cd799e08 100644 --- a/walletkit-db/src/tests.rs +++ b/walletkit-db/src/tests.rs @@ -1,10 +1,32 @@ //! Unit tests for the safe `SQLite` db wrapper. +use std::sync::OnceLock; + use super::*; use zeroize::Zeroizing; +/// Ensures sqlite3mc's global codec registration is complete before any test +/// body runs. +/// +/// sqlite3mc registers its cipher implementations the first time +/// `sqlite3_open_v2` is called. When the test binary runs all tests in +/// parallel threads, two threads can race inside that one-time +/// initialization and one of them sees an "unknown cipher 'chacha20'" +/// error even though chacha20 is compiled in. +/// +/// Calling this at the start of every test ensures exactly one thread +/// performs the first open (all others block on the `OnceLock`) so that +/// by the time any test-specific code runs, sqlite3mc is fully initialized. +fn init_sqlite() { + static INIT: OnceLock<()> = OnceLock::new(); + INIT.get_or_init(|| { + drop(Connection::open_in_memory().expect("sqlite3mc pre-init")); + }); +} + #[test] fn test_open_in_memory() { + init_sqlite(); let conn = Connection::open_in_memory().expect("open in-memory db"); conn.execute_batch("CREATE TABLE t (id INTEGER PRIMARY KEY, val TEXT);") .expect("create table"); @@ -23,6 +45,7 @@ fn test_open_in_memory() { #[test] fn test_query_row_optional_none() { + init_sqlite(); let conn = Connection::open_in_memory().expect("open in-memory db"); conn.execute_batch("CREATE TABLE t (id INTEGER PRIMARY KEY);") .expect("create table"); @@ -36,6 +59,7 @@ fn test_query_row_optional_none() { #[test] fn test_transaction_commit() { + init_sqlite(); let conn = Connection::open_in_memory().expect("open in-memory db"); conn.execute_batch("CREATE TABLE t (id INTEGER PRIMARY KEY);") .expect("create table"); @@ -55,6 +79,7 @@ fn test_transaction_commit() { #[test] fn test_transaction_rollback_on_drop() { + init_sqlite(); let conn = Connection::open_in_memory().expect("open in-memory db"); conn.execute_batch("CREATE TABLE t (id INTEGER PRIMARY KEY);") .expect("create table"); @@ -74,6 +99,7 @@ fn test_transaction_rollback_on_drop() { #[test] fn test_blob_round_trip() { + init_sqlite(); let conn = Connection::open_in_memory().expect("open in-memory db"); conn.execute_batch("CREATE TABLE t (id INTEGER PRIMARY KEY, data BLOB);") .expect("create table"); @@ -93,6 +119,7 @@ fn test_blob_round_trip() { #[test] fn test_null_handling() { + init_sqlite(); let conn = Connection::open_in_memory().expect("open in-memory db"); conn.execute_batch("CREATE TABLE t (id INTEGER PRIMARY KEY, val TEXT);") .expect("create table"); @@ -111,6 +138,7 @@ fn test_null_handling() { #[test] fn test_cipher_encrypted_round_trip() { + init_sqlite(); let dir = tempfile::tempdir().expect("create temp dir"); let path = dir.path().join("cipher-test.sqlite"); let key = Zeroizing::new([0xABu8; 32]); @@ -148,6 +176,7 @@ fn test_cipher_encrypted_round_trip() { #[test] fn test_integrity_check() { + init_sqlite(); let conn = Connection::open_in_memory().expect("open in-memory db"); let ok = cipher::integrity_check(&conn).expect("check"); assert!(ok); diff --git a/walletkit/Cargo.toml b/walletkit/Cargo.toml index 21b5660c2..471516bfc 100644 --- a/walletkit/Cargo.toml +++ b/walletkit/Cargo.toml @@ -20,14 +20,17 @@ crate-type = ["lib", "staticlib", "cdylib"] name = "walletkit" [dependencies] -uniffi = { workspace = true } walletkit-core = { workspace = true } +uniffi = { workspace = true } [features] -default = ["issuers", "storage"] +default = ["issuers"] +semaphore = ["walletkit-core/semaphore"] compress-zkeys = ["walletkit-core/compress-zkeys"] issuers = ["walletkit-core/issuers"] -storage = ["walletkit-core/storage"] +# Embeds zkeys into the binary, enabling `Groth16Materials::from_embedded`. +# See walletkit-core's `embed-zkeys` feature for details. +embed-zkeys = ["walletkit-core/embed-zkeys"] # v3 features v3 = ["walletkit-core/v3"]