From a84c659736266126902d66fe0113cb0090857ad5 Mon Sep 17 00:00:00 2001 From: kilianglas Date: Tue, 14 Apr 2026 17:20:26 +0200 Subject: [PATCH 1/8] refactor: adapt to upstream world-id-core API changes from PR #641 --- Cargo.lock | 352 ++++++++++++++++++++---- Cargo.toml | 2 +- walletkit-core/src/authenticator/mod.rs | 159 ++++------- 3 files changed, 358 insertions(+), 155 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c83bc25e..4fa04ab4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,10 +23,35 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "generic-array", ] +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures 0.2.17", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + [[package]] name = "ahash" version = "0.8.12" @@ -262,7 +287,7 @@ dependencies = [ "either", "serde", "serde_with", - "sha2", + "sha2 0.10.9", "thiserror 2.0.18", ] @@ -827,7 +852,7 @@ dependencies = [ "fnv", "merlin", "rayon", - "sha2", + "sha2 0.10.9", ] [[package]] @@ -1430,6 +1455,15 @@ dependencies = [ "serde", ] +[[package]] +name = "bhttp" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d305a54bcb99974213b4c78a486c34091e83c5d6d6572f7f4331c904ea9d127" +dependencies = [ + "thiserror 2.0.18", +] + [[package]] name = "bincode" version = "1.3.3" @@ -1514,7 +1548,7 @@ dependencies = [ "cc", "cfg-if", "constant_time_eq", - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -1526,6 +1560,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", +] + [[package]] name = "blst" version = "0.3.16" @@ -1694,7 +1737,7 @@ checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", "cipher", - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -1757,7 +1800,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "inout", "zeroize", ] @@ -1928,7 +1971,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3bb320cac8a0750d7f25280aa97b09c26edfe161164238ecbbb31092b079e735" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "proptest", "serde_core", ] @@ -1939,6 +1982,12 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "const_format" version = "0.2.35" @@ -1989,6 +2038,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crc" version = "3.4.0" @@ -2073,6 +2131,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +dependencies = [ + "hybrid-array", +] + [[package]] name = "ctor" version = "0.2.9" @@ -2083,6 +2150,40 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "curve25519-dalek-derive", + "fiat-crypto", + "rustc_version 0.4.1", + "subtle", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "cxx-build" version = "1.0.194" @@ -2160,7 +2261,7 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ - "const-oid", + "const-oid 0.9.6", "zeroize", ] @@ -2245,12 +2346,23 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "const-oid", - "crypto-common", + "block-buffer 0.10.4", + "const-oid 0.9.6", + "crypto-common 0.1.7", "subtle", ] +[[package]] +name = "digest" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" +dependencies = [ + "block-buffer 0.12.0", + "const-oid 0.10.2", + "crypto-common 0.2.1", +] + [[package]] name = "dirs" version = "6.0.0" @@ -2477,6 +2589,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + [[package]] name = "filetime" version = "0.2.27" @@ -2710,6 +2828,16 @@ dependencies = [ "wasip3", ] +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + [[package]] name = "gimli" version = "0.32.3" @@ -2925,6 +3053,26 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "hpke" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f65d16b699dd1a1fa2d851c970b0c971b388eeeb40f744252b8de48860980c8f" +dependencies = [ + "aead", + "aes-gcm", + "chacha20poly1305", + "digest 0.10.7", + "generic-array", + "hkdf", + "hmac", + "rand_core 0.9.5", + "sha2 0.10.9", + "subtle", + "x25519-dalek", + "zeroize", +] + [[package]] name = "http" version = "1.4.0" @@ -2970,6 +3118,15 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" +[[package]] +name = "hybrid-array" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3944cf8cf766b40e2a1a333ee5e9b563f854d5fa49d6a8ca2764e97c6eddb214" +dependencies = [ + "typenum", +] + [[package]] name = "hyper" version = "1.8.1" @@ -3315,7 +3472,7 @@ dependencies = [ "elliptic-curve", "once_cell", "serdect", - "sha2", + "sha2 0.10.9", "signature", ] @@ -3325,7 +3482,7 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -3671,6 +3828,28 @@ dependencies = [ "memchr", ] +[[package]] +name = "ohttp" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41a03aaaf57495c75ce66aee6a7c3b21abf046c9d4cca3d45b22cdbf0de1bfba" +dependencies = [ + "aead", + "aes-gcm", + "byteorder", + "chacha20poly1305", + "hex", + "hkdf", + "hpke", + "log", + "rand 0.9.2", + "serde", + "serde_derive", + "sha2 0.10.9", + "thiserror 2.0.18", + "toml", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -3834,7 +4013,19 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", "opaque-debug", "universal-hash", ] @@ -4604,7 +4795,7 @@ dependencies = [ "semaphore-rs-utils", "semaphore-rs-witness", "serde", - "sha2", + "sha2 0.10.9", "thiserror 1.0.69", "tiny-keccak", "zeroize", @@ -4934,7 +5125,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.10.7", ] @@ -4945,10 +5136,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.10.7", ] +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.2", +] + [[package]] name = "sha3" version = "0.10.8" @@ -5204,6 +5406,20 @@ name = "taceo-ark-serde-compat" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07528b4dd1a0c9e49ef352f96219c611af0aa2f7cbd97ddb7276dcf3c2cf8dd0" +dependencies = [ + "ark-ec", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "num-bigint", + "serde", + "taceo-ark-babyjubjub", +] + +[[package]] +name = "taceo-ark-serde-compat" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fcd6f55fec9dd131019bdc0319db2271915056607b75bf8b8bc0a6ec496347" dependencies = [ "ark-bn254", "ark-ec", @@ -5216,9 +5432,9 @@ dependencies = [ [[package]] name = "taceo-circom-types" -version = "0.2.2" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677eb3ed8275b2f179d4b1a93126a51c5b4f409c5ea9d7bc50398b13e517e30b" +checksum = "a4ae56552ed9a44722d293640d5aedd90b9940284bf1f1bf4df727b3ce5bc34b" dependencies = [ "ark-bn254", "ark-ec", @@ -5229,20 +5445,18 @@ dependencies = [ "ark-serialize 0.5.0", "ark-std 0.5.0", "byteorder", - "num-traits", - "rayon", "serde", "serde_json", - "taceo-ark-serde-compat", + "taceo-ark-serde-compat 0.5.0", "thiserror 2.0.18", "tracing", ] [[package]] name = "taceo-eddsa-babyjubjub" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75dbec63f7a89093b4116a7164e6a92d3cda33dec248da8c8a5922a80a06e7dd" +checksum = "10becbd559ee21d8376a4c2e18f0e38257ec1b5bfff3dcb2cb2945ca1db38906" dependencies = [ "ark-ec", "ark-ff 0.5.0", @@ -5253,16 +5467,16 @@ dependencies = [ "rand 0.8.5", "serde", "taceo-ark-babyjubjub", - "taceo-ark-serde-compat", + "taceo-ark-serde-compat 0.5.0", "taceo-poseidon2", "zeroize", ] [[package]] name = "taceo-groth16" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4983857c95d20ca2dc0400a3a116e6931c012ecc4b78ccede8238cfb0c298e3" +checksum = "56b4c2cb727c5e3312f88e0ae5785d4d5c28ccb3afa4ebe297cf9ea32b358262" dependencies = [ "ark-ec", "ark-ff 0.5.0", @@ -5270,22 +5484,19 @@ dependencies = [ "ark-poly", "ark-relations", "eyre", - "num-traits", "rayon", "tracing", ] [[package]] name = "taceo-groth16-material" -version = "0.2.3" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "936b1e6b8a77f931796917501fe13a2ae93304e7eb384ed29d80ddc370b011bd" +checksum = "e3231b9df1847b843a1178e5dfdc6fd4b35b6571adb017408b073db885960f71" dependencies = [ "ark-bn254", - "ark-ec", "ark-ff 0.5.0", "ark-groth16", - "ark-relations", "ark-serialize 0.5.0", "circom-witness-rs", "eyre", @@ -5293,11 +5504,10 @@ dependencies = [ "postcard", "rand 0.8.5", "ruint", - "sha2", + "sha2 0.11.0", "taceo-circom-types", "taceo-groth16", "thiserror 2.0.18", - "tracing", ] [[package]] @@ -5305,6 +5515,21 @@ name = "taceo-groth16-sol" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c6a7b90f2ecb6db1212557550890d9d9d114447688f6146d726024ec7a3410b" +dependencies = [ + "alloy-primitives", + "ark-bn254", + "ark-ec", + "ark-ff 0.5.0", + "ark-groth16", + "eyre", + "ruint", +] + +[[package]] +name = "taceo-groth16-sol" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d590d9ef92eee2cf8930ba4732bfbbd56d98b42545b0611b7c4ec7f112adc908" dependencies = [ "alloy-primitives", "ark-bn254", @@ -5321,6 +5546,15 @@ name = "taceo-oprf" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91e2b4f0c8650d5b66f01966d0bdabafcfb25cbd84b1bff46c9665368ba0a9d5" +dependencies = [ + "taceo-oprf-types", +] + +[[package]] +name = "taceo-oprf" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cdb5bdabfe916822e6a7def8b8538c24d9582daf050e924a15263b68563b766" dependencies = [ "taceo-oprf-client", "taceo-oprf-core", @@ -5367,7 +5601,7 @@ dependencies = [ "serde", "subtle", "taceo-ark-babyjubjub", - "taceo-ark-serde-compat", + "taceo-ark-serde-compat 0.4.1", "taceo-poseidon2", "uuid", "zeroize", @@ -5387,9 +5621,9 @@ dependencies = [ "http", "serde", "taceo-ark-babyjubjub", - "taceo-ark-serde-compat", + "taceo-ark-serde-compat 0.4.1", "taceo-circom-types", - "taceo-groth16-sol", + "taceo-groth16-sol 0.2.2", "taceo-oprf-core", "uuid", ] @@ -6062,7 +6296,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "subtle", ] @@ -6206,10 +6440,10 @@ dependencies = [ "semaphore-rs", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "strum", "subtle", - "taceo-oprf", + "taceo-oprf 0.11.0", "thiserror 2.0.18", "tokio", "tokio-test", @@ -6230,7 +6464,7 @@ dependencies = [ "cc", "hex", "secrecy", - "sha2", + "sha2 0.10.9", "sqlite-wasm-rs", "tempfile", "zeroize", @@ -6820,14 +7054,17 @@ dependencies = [ [[package]] name = "world-id-authenticator" version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c38b4f4ccbfee4b7585b15b0843255a6f0db9045bcafbd9cf96835f27df012" +source = "git+https://github.com/worldcoin/world-id-protocol?branch=main#3abdfa8d726926a08114bf47927f33e7aa8d142b" dependencies = [ "alloy", "anyhow", "ark-serialize 0.5.0", "backon", + "base64 0.22.1", + "bhttp", "eyre", + "hex", + "ohttp", "rand 0.8.5", "reqwest", "ruint", @@ -6838,7 +7075,7 @@ dependencies = [ "taceo-ark-babyjubjub", "taceo-eddsa-babyjubjub", "taceo-groth16-material", - "taceo-oprf", + "taceo-oprf 0.12.1", "taceo-poseidon2", "thiserror 2.0.18", "tokio", @@ -6850,8 +7087,7 @@ dependencies = [ [[package]] name = "world-id-core" version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8974ca9cb27313d5164d5b9c40cceb5abb95d3a1a5436c76a4bb9218514e582" +source = "git+https://github.com/worldcoin/world-id-protocol?branch=main#3abdfa8d726926a08114bf47927f33e7aa8d142b" dependencies = [ "taceo-eddsa-babyjubjub", "world-id-authenticator", @@ -6862,8 +7098,7 @@ dependencies = [ [[package]] name = "world-id-primitives" version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c95e6f02b30c93e30674c3b19aed3228afe866df8a9ca750f6284a4c2e7b480a" +source = "git+https://github.com/worldcoin/world-id-protocol?branch=main#3abdfa8d726926a08114bf47927f33e7aa8d142b" dependencies = [ "alloy", "alloy-primitives", @@ -6884,12 +7119,12 @@ dependencies = [ "sha3", "strum", "taceo-ark-babyjubjub", - "taceo-ark-serde-compat", + "taceo-ark-serde-compat 0.5.0", "taceo-circom-types", "taceo-eddsa-babyjubjub", "taceo-groth16-material", - "taceo-groth16-sol", - "taceo-oprf", + "taceo-groth16-sol 0.3.1", + "taceo-oprf 0.12.1", "taceo-poseidon2", "thiserror 2.0.18", "url", @@ -6899,8 +7134,7 @@ dependencies = [ [[package]] name = "world-id-proof" version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49cd28f6adadba3043f10c7c286330ad23d66da1f9e9b2646e5d5c866aea50b3" +source = "git+https://github.com/worldcoin/world-id-protocol?branch=main#3abdfa8d726926a08114bf47927f33e7aa8d142b" dependencies = [ "ark-bn254", "ark-ec", @@ -6916,7 +7150,7 @@ dependencies = [ "taceo-circom-types", "taceo-eddsa-babyjubjub", "taceo-groth16-material", - "taceo-oprf", + "taceo-oprf 0.12.1", "taceo-poseidon2", "tar", "thiserror 2.0.18", @@ -6941,6 +7175,16 @@ dependencies = [ "tap", ] +[[package]] +name = "x25519-dalek" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +dependencies = [ + "curve25519-dalek", + "rand_core 0.6.4", +] + [[package]] name = "xattr" version = "1.6.1" diff --git a/Cargo.toml b/Cargo.toml index 8d9d45aa..337b983a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ alloy-core = { version = "1", default-features = false, features = [ ] } alloy-primitives = { version = "1", default-features = false } uniffi = { version = "0.31.0", features = ["tokio"] } -world-id-core = { version = "0.8.2", default-features = false } +world-id-core = { git = "https://github.com/worldcoin/world-id-protocol", branch = "main", default-features = false } # internal walletkit-core = { version = "0.13.0", path = "walletkit-core", default-features = false } diff --git a/walletkit-core/src/authenticator/mod.rs b/walletkit-core/src/authenticator/mod.rs index 5cc5b64f..a7207928 100644 --- a/walletkit-core/src/authenticator/mod.rs +++ b/walletkit-core/src/authenticator/mod.rs @@ -17,10 +17,7 @@ use world_id_core::{ }; #[cfg(feature = "storage")] -use world_id_core::{ - requests::{ProofResponse as CoreProofResponse, ResponseItem}, - FieldElement as CoreFieldElement, -}; +use world_id_core::CredentialInput; #[cfg(feature = "storage")] use crate::storage::{CredentialStore, StoragePaths}; @@ -99,25 +96,23 @@ fn load_query_material_from_cache( } #[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. +/// Returns an error if the cached nullifier material cannot be loaded or verified. 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, - )) + world_id_core::proof::load_nullifier_material_from_paths(nullifier_zkey, nullifier_graph) + .map_err(|error| WalletKitError::Groth16MaterialCacheInvalid { + path: format!( + "{} and {}", + nullifier_zkey.to_string_lossy(), + nullifier_graph.to_string_lossy() + ), + error: error.to_string(), + }) } /// The Authenticator is the main component with which users interact with the World ID Protocol. @@ -168,14 +163,7 @@ impl Authenticator { pub async fn get_packed_account_data_remote( &self, ) -> Result { - let client = reqwest::Client::new(); // TODO: reuse client - let packed_account_data = CoreAuthenticator::get_packed_account_data( - self.inner.onchain_address(), - self.inner.registry().as_deref(), - &self.inner.config, - &client, - ) - .await?; + let packed_account_data = self.inner.refresh_packed_account_data().await?; Ok(packed_account_data.into()) } @@ -406,7 +394,7 @@ impl Authenticator { store: Arc, ) -> Result { let config = Config::from_environment(environment, rpc_url, region)?; - let authenticator = CoreAuthenticator::init(seed, config).await?; + let authenticator = CoreAuthenticator::init(seed, config.into()).await?; let (query_material, nullifier_material) = load_cached_materials(paths)?; let authenticator = authenticator.with_proof_materials(query_material, nullifier_material); @@ -436,7 +424,7 @@ impl Authenticator { attribute: "config".to_string(), reason: "Invalid config".to_string(), })?; - let authenticator = CoreAuthenticator::init(seed, config).await?; + let authenticator = CoreAuthenticator::init(seed, config.into()).await?; let (query_material, nullifier_material) = load_cached_materials(paths)?; let authenticator = authenticator.with_proof_materials(query_material, nullifier_material); @@ -467,24 +455,27 @@ impl Authenticator { .as_secs() }; - // TODO: If request is to initiate a session, call `self.inner.generate_session_id` and cache seed - - // First check if the request can be fulfilled and which credentials should be used + // Build CredentialInput list from storage let credential_list = self.store.list_credentials(None, now)?; - let credential_list = credential_list - .into_iter() + let credentials: Vec = credential_list + .iter() .filter(|cred| !cred.is_expired) - .map(|cred| cred.issuer_schema_id) - .collect::>(); - let credentials_to_prove = proof_request - .0 - .credentials_to_prove(&credential_list) - .ok_or(WalletKitError::UnfulfillableRequest)?; + .filter_map(|cred| { + self.store + .get_credential(cred.issuer_schema_id, now) + .ok() + .flatten() + .map(|(credential, blinding_factor)| CredentialInput { + credential: credential.into(), + blinding_factor: blinding_factor.into(), + }) + }) + .collect(); let account_inclusion_proof = self.fetch_inclusion_proof_with_cache(now).await?; - // Next, generate the nullifier and check the replay guard + // Generate the nullifier and check the replay guard let nullifier = self .inner .generate_nullifier(&proof_request.0, Some(account_inclusion_proof.clone())) @@ -497,78 +488,46 @@ impl Authenticator { return Err(WalletKitError::NullifierReplay); } - // If the request is for a Session Proof, get the correct `session_id_r_seed`, either - // from the cache or compute it again - let session_id_r_seed = if let Some(session_id) = proof_request.0.session_id { - let cached_r_seed = - self.store.get_session_seed(session_id.oprf_seed, now)?; - - if cached_r_seed.is_some() { - cached_r_seed - } else { - let (expected_session_id, seed) = self - .inner - .generate_session_id( - &proof_request.0, - None, - Some(account_inclusion_proof), - ) - .await?; - - if expected_session_id != session_id { - return Err(WalletKitError::SessionIdMismatch); - } + // Get cached session seed if available + let session_id_r_seed = proof_request + .0 + .session_id + .and_then(|sid| { + self.store + .get_session_seed(sid.oprf_seed, now) + .ok() + .flatten() + }); + + // Delegate to upstream — handles credential selection, session resolution, + // per-credential proofs, response assembly, and validation + let result = self + .inner + .generate_proof( + &proof_request.0, + nullifier.clone(), + &credentials, + Some(account_inclusion_proof), + session_id_r_seed.map(Into::into), + ) + .await?; + // Cache session seed if returned + if let Some(seed) = result.session_id_r_seed { + if let Some(session_id) = proof_request.0.session_id { if let Err(err) = self.store - .store_session_seed(session_id.oprf_seed, seed, now) + .store_session_seed(session_id.oprf_seed, seed.into(), now) { tracing::error!("error caching session_id_r_seed: {}", err); } - - Some(seed) } - } else { - None - }; - - let mut responses: Vec = vec![]; - - for request_item in credentials_to_prove { - let (credential, blinding_factor) = self - .store - .get_credential(request_item.issuer_schema_id, now)? - .ok_or(WalletKitError::CredentialNotIssued)?; - - let response_item = self.inner.generate_single_proof( - nullifier.clone(), - request_item, - &credential, - blinding_factor.0, - session_id_r_seed.unwrap_or(CoreFieldElement::ZERO), // TODO: upstream update coming accepting Option - proof_request.0.session_id, - proof_request.0.created_at, - )?; - responses.push(response_item); } - let response = CoreProofResponse { - id: proof_request.0.id.clone(), - version: world_id_core::requests::RequestVersion::V1, - responses, - error: None, - session_id: proof_request.0.session_id, - }; - - proof_request - .0 - .validate_response(&response) - .map_err(|err| WalletKitError::ResponseValidation(err.to_string()))?; - self.store .replay_guard_set(nullifier.verifiable_oprf_output.output.into(), now)?; - Ok(response.into()) + Ok(result.proof_response.into()) } } @@ -642,7 +601,7 @@ impl InitializingAuthenticator { let config = Config::from_environment(environment, rpc_url, region)?; let initializing_authenticator = - CoreAuthenticator::register(seed, config, recovery_address).await?; + CoreAuthenticator::register(seed, config.into(), recovery_address).await?; Ok(Self(initializing_authenticator)) } @@ -675,7 +634,7 @@ impl InitializingAuthenticator { })?; let initializing_authenticator = - CoreAuthenticator::register(seed, config, recovery_address).await?; + CoreAuthenticator::register(seed, config.into(), recovery_address).await?; Ok(Self(initializing_authenticator)) } From 6d528acb26ec17e8c94720278a8dda7c1bca8e00 Mon Sep 17 00:00:00 2001 From: kilianglas Date: Tue, 14 Apr 2026 17:36:02 +0200 Subject: [PATCH 2/8] fix: add explicit error mappings for new upstream AuthenticatorError variants --- walletkit-core/src/error.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/walletkit-core/src/error.rs b/walletkit-core/src/error.rs index 56ad331a..e32c412c 100644 --- a/walletkit-core/src/error.rs +++ b/walletkit-core/src/error.rs @@ -216,6 +216,17 @@ impl From for WalletKitError { error: error.to_string(), }, + AuthenticatorError::IndexerError { status, body } => Self::NetworkError { + url: "indexer".to_string(), + error: body, + status: Some(status.as_u16()), + }, + AuthenticatorError::UnfullfilableRequest => Self::UnfulfillableRequest, + AuthenticatorError::ResponseValidationError(err) => { + Self::ResponseValidation(err.to_string()) + } + AuthenticatorError::SessionIdMismatch => Self::SessionIdMismatch, + _ => Self::AuthenticatorError { error: error.to_string(), }, From 0f85e802a786f8f10f91b8767040ea87a30caf58 Mon Sep 17 00:00:00 2001 From: kilianglas Date: Tue, 14 Apr 2026 17:57:31 +0200 Subject: [PATCH 3/8] test: fix integration tests for upstream API renames --- walletkit-core/tests/proof_generation_integration.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/walletkit-core/tests/proof_generation_integration.rs b/walletkit-core/tests/proof_generation_integration.rs index 6539b3ae..4e49b7f9 100644 --- a/walletkit-core/tests/proof_generation_integration.rs +++ b/walletkit-core/tests/proof_generation_integration.rs @@ -131,7 +131,7 @@ async fn e2e_authenticator_generate_proof() -> Result<()> { ); let core_authenticator = - CoreAuthenticator::init_or_register(&seed, config, Some(recovery_address)) + CoreAuthenticator::init_or_register(&seed, config.into(), Some(recovery_address)) .await .wrap_err("account creation/init failed")? .with_proof_materials(query_material, nullifier_material); @@ -350,7 +350,7 @@ async fn e2e_session_proof() -> Result<()> { ); let core_authenticator = - CoreAuthenticator::init_or_register(&seed, config, Some(recovery_address)) + CoreAuthenticator::init_or_register(&seed, config.into(), Some(recovery_address)) .await .wrap_err("account creation/init failed")? .with_proof_materials(query_material, nullifier_material); @@ -466,7 +466,7 @@ async fn e2e_session_proof() -> Result<()> { // Use the core authenticator to generate a session ID (calls OPRF) let (session_id, session_id_r_seed) = core_authenticator - .generate_session_id(&init_request, None, None) + .build_session_id(&init_request, None, None) .await .wrap_err("generate_session_id failed")?; From b8534ace1aa75ecca1424da6ea9128f21f28d37a Mon Sep 17 00:00:00 2001 From: kilianglas Date: Wed, 15 Apr 2026 11:57:41 +0200 Subject: [PATCH 4/8] chore: switch world-id-core from git dep to crates.io 0.9.0 --- Cargo.lock | 20 ++++++++++++-------- Cargo.toml | 2 +- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4fa04ab4..a99ebfc1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7053,8 +7053,9 @@ dependencies = [ [[package]] name = "world-id-authenticator" -version = "0.8.2" -source = "git+https://github.com/worldcoin/world-id-protocol?branch=main#3abdfa8d726926a08114bf47927f33e7aa8d142b" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9672e179672a81578323123026e4af8ce07201a58ac74360d7a668d22f31cbc5" dependencies = [ "alloy", "anyhow", @@ -7086,8 +7087,9 @@ dependencies = [ [[package]] name = "world-id-core" -version = "0.8.2" -source = "git+https://github.com/worldcoin/world-id-protocol?branch=main#3abdfa8d726926a08114bf47927f33e7aa8d142b" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd133bb577f3159873e0c988f352134265f89127477f191d97e6e37cc8c42424" dependencies = [ "taceo-eddsa-babyjubjub", "world-id-authenticator", @@ -7097,8 +7099,9 @@ dependencies = [ [[package]] name = "world-id-primitives" -version = "0.8.2" -source = "git+https://github.com/worldcoin/world-id-protocol?branch=main#3abdfa8d726926a08114bf47927f33e7aa8d142b" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39642d8335d4474132d39f2c1ad777645b3b7f973e0699461d80007a696a0922" dependencies = [ "alloy", "alloy-primitives", @@ -7133,8 +7136,9 @@ dependencies = [ [[package]] name = "world-id-proof" -version = "0.8.2" -source = "git+https://github.com/worldcoin/world-id-protocol?branch=main#3abdfa8d726926a08114bf47927f33e7aa8d142b" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4693f94b3d16470de5c7a30f705f2d486e5c4100bc7f4fec5880c6121e242b0f" dependencies = [ "ark-bn254", "ark-ec", diff --git a/Cargo.toml b/Cargo.toml index 337b983a..b88163db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ alloy-core = { version = "1", default-features = false, features = [ ] } alloy-primitives = { version = "1", default-features = false } uniffi = { version = "0.31.0", features = ["tokio"] } -world-id-core = { git = "https://github.com/worldcoin/world-id-protocol", branch = "main", default-features = false } +world-id-core = { version = "0.9.0", default-features = false } # internal walletkit-core = { version = "0.13.0", path = "walletkit-core", default-features = false } From 92dbbf5918736cff8de10e6729910c61a6f98127 Mon Sep 17 00:00:00 2001 From: kilianglas Date: Wed, 15 Apr 2026 16:04:14 +0200 Subject: [PATCH 5/8] refactor: credential loading and error handling --- walletkit-core/src/authenticator/mod.rs | 85 +++++++++++++++---------- 1 file changed, 50 insertions(+), 35 deletions(-) diff --git a/walletkit-core/src/authenticator/mod.rs b/walletkit-core/src/authenticator/mod.rs index a7207928..af26ab91 100644 --- a/walletkit-core/src/authenticator/mod.rs +++ b/walletkit-core/src/authenticator/mod.rs @@ -104,15 +104,18 @@ fn load_nullifier_material_from_cache( nullifier_zkey: &std::path::Path, nullifier_graph: &std::path::Path, ) -> Result { - world_id_core::proof::load_nullifier_material_from_paths(nullifier_zkey, nullifier_graph) - .map_err(|error| WalletKitError::Groth16MaterialCacheInvalid { - path: format!( - "{} and {}", - nullifier_zkey.to_string_lossy(), - nullifier_graph.to_string_lossy() - ), - error: error.to_string(), - }) + world_id_core::proof::load_nullifier_material_from_paths( + nullifier_zkey, + nullifier_graph, + ) + .map_err(|error| WalletKitError::Groth16MaterialCacheInvalid { + path: format!( + "{} and {}", + nullifier_zkey.to_string_lossy(), + nullifier_graph.to_string_lossy() + ), + error: error.to_string(), + }) } /// The Authenticator is the main component with which users interact with the World ID Protocol. @@ -456,19 +459,29 @@ impl Authenticator { }; // Build CredentialInput list from storage - let credential_list = self.store.list_credentials(None, now)?; - let credentials: Vec = credential_list + // Note: We simply load all non-expired credentials. Filtering for the requested schema IDs is done in `generate_proof`. + // We could avoid unnecessary loading by filtering via `world_id_primitives::ProofRequest::credentials_to_prove`. We consider this an + // unnecessary optimization for now. + let credentials: Vec<_> = self + .store + .list_credentials(None, now)? .iter() - .filter(|cred| !cred.is_expired) + .filter(|c| !c.is_expired) .filter_map(|cred| { - self.store - .get_credential(cred.issuer_schema_id, now) - .ok() - .flatten() - .map(|(credential, blinding_factor)| CredentialInput { + match self.store.get_credential(cred.issuer_schema_id, now) { + Ok(Some((credential, blinding_factor))) => Some(CredentialInput { credential: credential.into(), blinding_factor: blinding_factor.into(), - }) + }), + Ok(None) | Err(_) => { + tracing::warn!( + issuer_schema_id = %cred.issuer_schema_id, + credential_id = %cred.credential_id, + "credential listed but not loadable, skipping" + ); + None + } + } }) .collect(); @@ -488,19 +501,20 @@ impl Authenticator { return Err(WalletKitError::NullifierReplay); } - // Get cached session seed if available - let session_id_r_seed = proof_request - .0 - .session_id - .and_then(|sid| { - self.store - .get_session_seed(sid.oprf_seed, now) - .ok() - .flatten() - }); - - // Delegate to upstream — handles credential selection, session resolution, - // per-credential proofs, response assembly, and validation + // Get cached `session_id_r_seed` if session ID is provided in the proof request + let session_id_r_seed = if let Some(session_id) = proof_request.0.session_id { + match self.store.get_session_seed(session_id.oprf_seed, now) { + Ok(seed) => seed, + Err(err) => { + tracing::warn!(error = %err, "failed to load cached session seed, continuing without"); + None + } + } + } else { + None + }; + + // Handles credential selection, session resolution, per-credential proofs, response assembly, and validation let result = self .inner .generate_proof( @@ -515,10 +529,11 @@ impl Authenticator { // Cache session seed if returned if let Some(seed) = result.session_id_r_seed { if let Some(session_id) = proof_request.0.session_id { - if let Err(err) = - self.store - .store_session_seed(session_id.oprf_seed, seed.into(), now) - { + if let Err(err) = self.store.store_session_seed( + session_id.oprf_seed, + seed.into(), + now, + ) { tracing::error!("error caching session_id_r_seed: {}", err); } } From 27693ec7d6c3dc0eb0c05b3d05ba56c79c8597b7 Mon Sep 17 00:00:00 2001 From: kilianglas Date: Wed, 15 Apr 2026 16:21:16 +0200 Subject: [PATCH 6/8] style: fix rustfmt in integration tests --- .../tests/proof_generation_integration.rs | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/walletkit-core/tests/proof_generation_integration.rs b/walletkit-core/tests/proof_generation_integration.rs index 4e49b7f9..d8fd2eee 100644 --- a/walletkit-core/tests/proof_generation_integration.rs +++ b/walletkit-core/tests/proof_generation_integration.rs @@ -130,11 +130,14 @@ async fn e2e_authenticator_generate_proof() -> Result<()> { .wrap_err("failed to load embedded nullifier material")?, ); - let core_authenticator = - CoreAuthenticator::init_or_register(&seed, config.into(), Some(recovery_address)) - .await - .wrap_err("account creation/init failed")? - .with_proof_materials(query_material, nullifier_material); + let core_authenticator = CoreAuthenticator::init_or_register( + &seed, + config.into(), + Some(recovery_address), + ) + .await + .wrap_err("account creation/init failed")? + .with_proof_materials(query_material, nullifier_material); let leaf_index = core_authenticator.leaf_index(); eprintln!("Phase 1 complete: account ready (leaf_index={leaf_index})"); @@ -349,11 +352,14 @@ async fn e2e_session_proof() -> Result<()> { .wrap_err("failed to load embedded nullifier material")?, ); - let core_authenticator = - CoreAuthenticator::init_or_register(&seed, config.into(), Some(recovery_address)) - .await - .wrap_err("account creation/init failed")? - .with_proof_materials(query_material, nullifier_material); + let core_authenticator = CoreAuthenticator::init_or_register( + &seed, + config.into(), + Some(recovery_address), + ) + .await + .wrap_err("account creation/init failed")? + .with_proof_materials(query_material, nullifier_material); let leaf_index = core_authenticator.leaf_index(); eprintln!("Phase 1 complete: account ready (leaf_index={leaf_index})"); From 0b48c312f572d10b838abfb123342ad9129c2434 Mon Sep 17 00:00:00 2001 From: kilianglas Date: Wed, 15 Apr 2026 17:44:02 +0200 Subject: [PATCH 7/8] chore: clippy --- walletkit-core/src/authenticator/mod.rs | 77 +++++++++++++------------ 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/walletkit-core/src/authenticator/mod.rs b/walletkit-core/src/authenticator/mod.rs index af26ab91..eb1efc0f 100644 --- a/walletkit-core/src/authenticator/mod.rs +++ b/walletkit-core/src/authenticator/mod.rs @@ -468,19 +468,20 @@ impl Authenticator { .iter() .filter(|c| !c.is_expired) .filter_map(|cred| { - match self.store.get_credential(cred.issuer_schema_id, now) { - Ok(Some((credential, blinding_factor))) => Some(CredentialInput { + if let Ok(Some((credential, blinding_factor))) = + self.store.get_credential(cred.issuer_schema_id, now) + { + Some(CredentialInput { credential: credential.into(), blinding_factor: blinding_factor.into(), - }), - Ok(None) | Err(_) => { - tracing::warn!( - issuer_schema_id = %cred.issuer_schema_id, - credential_id = %cred.credential_id, - "credential listed but not loadable, skipping" - ); - None - } + }) + } else { + tracing::warn!( + issuer_schema_id = %cred.issuer_schema_id, + credential_id = %cred.credential_id, + "credential listed but not loadable, skipping" + ); + None } }) .collect(); @@ -489,10 +490,12 @@ impl Authenticator { self.fetch_inclusion_proof_with_cache(now).await?; // Generate the nullifier and check the replay guard - let nullifier = self - .inner - .generate_nullifier(&proof_request.0, Some(account_inclusion_proof.clone())) - .await?; + // Box::pin to heap-allocate the large upstream futures and keep this future below clippy::large_futures threshold + let nullifier = Box::pin( + self.inner + .generate_nullifier(&proof_request.0, Some(account_inclusion_proof.clone())), + ) + .await?; if self .store @@ -502,36 +505,36 @@ impl Authenticator { } // Get cached `session_id_r_seed` if session ID is provided in the proof request - let session_id_r_seed = if let Some(session_id) = proof_request.0.session_id { - match self.store.get_session_seed(session_id.oprf_seed, now) { - Ok(seed) => seed, - Err(err) => { - tracing::warn!(error = %err, "failed to load cached session seed, continuing without"); - None - } - } - } else { - None - }; + let session_id_r_seed = + proof_request + .0 + .session_id + .and_then(|session_id| { + match self.store.get_session_seed(session_id.oprf_seed, now) { + Ok(seed) => seed, + Err(err) => { + tracing::warn!(error = %err, "failed to load cached session seed, continuing without"); + None + } + } + }); // Handles credential selection, session resolution, per-credential proofs, response assembly, and validation - let result = self - .inner - .generate_proof( - &proof_request.0, - nullifier.clone(), - &credentials, - Some(account_inclusion_proof), - session_id_r_seed.map(Into::into), - ) - .await?; + let result = Box::pin(self.inner.generate_proof( + &proof_request.0, + nullifier.clone(), + &credentials, + Some(account_inclusion_proof), + session_id_r_seed, + )) + .await?; // Cache session seed if returned if let Some(seed) = result.session_id_r_seed { if let Some(session_id) = proof_request.0.session_id { if let Err(err) = self.store.store_session_seed( session_id.oprf_seed, - seed.into(), + seed, now, ) { tracing::error!("error caching session_id_r_seed: {}", err); From f0f106e909c61f445de99cb36e1f89909235e04b Mon Sep 17 00:00:00 2001 From: kilianglas Date: Wed, 15 Apr 2026 17:46:37 +0200 Subject: [PATCH 8/8] style: fix rustfmt formatting --- walletkit-core/src/authenticator/mod.rs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/walletkit-core/src/authenticator/mod.rs b/walletkit-core/src/authenticator/mod.rs index eb1efc0f..0e2a6ae7 100644 --- a/walletkit-core/src/authenticator/mod.rs +++ b/walletkit-core/src/authenticator/mod.rs @@ -491,10 +491,10 @@ impl Authenticator { // Generate the nullifier and check the replay guard // Box::pin to heap-allocate the large upstream futures and keep this future below clippy::large_futures threshold - let nullifier = Box::pin( - self.inner - .generate_nullifier(&proof_request.0, Some(account_inclusion_proof.clone())), - ) + let nullifier = Box::pin(self.inner.generate_nullifier( + &proof_request.0, + Some(account_inclusion_proof.clone()), + )) .await?; if self @@ -532,11 +532,10 @@ impl Authenticator { // Cache session seed if returned if let Some(seed) = result.session_id_r_seed { if let Some(session_id) = proof_request.0.session_id { - if let Err(err) = self.store.store_session_seed( - session_id.oprf_seed, - seed, - now, - ) { + if let Err(err) = + self.store + .store_session_seed(session_id.oprf_seed, seed, now) + { tracing::error!("error caching session_id_r_seed: {}", err); } }