Conversation
Map close_v2 wrapper to sqlite3_close on wasm and use SQLITE_TRANSIENT() for bind blob/text destructor arguments to match sqlite-wasm-rs 0.5 signatures. Co-authored-by: otto@toolsforhumanity.com
Add a dedicated CI job that installs wasm32 target, selects a wasm-capable clang, and runs cargo check for walletkit-db on wasm32-unknown-unknown. Co-authored-by: otto@toolsforhumanity.com
Detect available llvm-ar variants (or fallback to ar) instead of assuming llvm-ar is on PATH when using system clang for wasm builds. Co-authored-by: otto@toolsforhumanity.com
Co-authored-by: otto@toolsforhumanity.com
Make the SQLite-backed credential storage an always-compiled part of walletkit-core instead of an optional feature. This unifies the code path for native and future WASM builds. Changes: - Make ciborium, hkdf, rand, sha2, uuid, walletkit-db non-optional deps - Remove `storage` feature definition from walletkit-core and walletkit - Remove all `#[cfg(feature = "storage")]" gates from source and tests - Remove non-storage Authenticator constructors (the ones without paths/store params); only storage-aware constructors remain BREAKING CHANGE: Authenticator::init and Authenticator::init_with_defaults now always require Arc<StoragePaths> and Arc<CredentialStore> parameters. Co-authored-by: otto@toolsforhumanity.com
Replace the `paths: Arc<StoragePaths>` parameter in Authenticator constructors with `materials: Arc<Groth16Materials>`, decoupling Groth16 material loading from authenticator initialization. Groth16Materials provides two constructors: - `from_embedded()`: loads compiled-in zkeys/graphs (all platforms) - `from_cache(paths)`: loads from filesystem cache (native only) This enables WASM builds where no filesystem is available — callers use `from_embedded()` directly instead of caching to disk first. Also gates `groth16_cache` module behind `cfg(not(wasm32))` since it depends on `std::fs`. BREAKING CHANGE: Authenticator::init and init_with_defaults now take `Arc<Groth16Materials>` instead of `Arc<StoragePaths>`. Co-authored-by: otto@toolsforhumanity.com
Platform-gate all native-only dependencies and uniffi attributes for WASM compatibility. Both `walletkit-core` and `walletkit` now compile cleanly for `wasm32-unknown-unknown`. Key changes: - Gate `uniffi::` derives/attributes with `cfg_attr(not(wasm32), ...)` across all public types (~17 source files). uniffi requires Send which is unavailable on WASM's single-threaded model. - Move `ctor`, `reqwest[rustls-tls,brotli]`, `rustls` to native-only deps. Base `reqwest` kept with just `json` feature (WASM-compatible). - Gate `groth16_cache` module (uses std::fs), `generate_proof` (uses SystemTime), `fetch_inclusion_proof_with_cache` for non-WASM. - Gate `is_connect()` check in http_request.rs (requires hyper, native only). - Add WASM no-op doc comments on storage lock methods. Depends on upstream WASM-compat PRs: - worldcoin/world-id-protocol#512 (authenticator + proof crate gating) - TaceoLabs/oprf-service#488 (gloo-net WebSocket transport for OPRF) - worldcoin/semaphore-rs#131 (mmap-rs + lazy tree gating) Uses `[patch.crates-io]` git refs pointing to those PR branches until they are merged and released. Co-authored-by: otto@toolsforhumanity.com
- Introduce `embed-zkeys` Cargo feature in walletkit-core and walletkit
that activates world-id-core/embed-zkeys and world-id-core/zstd-compress-zkeys;
previously these were always enabled, preventing downstream consumers from
opting out (e.g. to reduce binary size on WASM).
- Feature-gate `Groth16Materials::from_embedded` behind `embed-zkeys`.
`Groth16Materials::from_cache` (native filesystem) is unaffected.
- Feature-gate `storage::groth16_cache` (and the exported
`cache_embedded_groth16_material`) behind `all(not(wasm32), embed-zkeys)`.
- Fix WASM compilation error: split the single `#[uniffi::export] impl
Groth16Materials` block into two (one per feature/target gate) so the
uniffi proc-macro no longer generates FFI shims that reference
`from_cache`/`StoragePaths` on wasm32 targets.
- Fix dead-code / unused-import warnings on wasm32:
- logger.rs: gate `struct LogEvent`, `LOG_CHANNEL`, and the
`mpsc`/`Mutex` imports behind `#[cfg(not(target_arch = "wasm32"))]`.
- storage/lock.rs: gate `StorageError` import behind non-wasm.
- Add `required-features = ["embed-zkeys"]` to the integration test
targets that call `from_embedded` / `load_embedded_*` so cargo skips
them when the feature is off.
- Fix pre-existing missing-docs error in authenticator_integration.rs and
credential_storage_integration.rs (clippy --all-targets -D warnings).
- Update crate-level doc example to use the correct API and mark it
`ignore` since it requires the `embed-zkeys` feature.
Co-authored-by: otto@toolsforhumanity.com
Co-authored-by: otto@toolsforhumanity.com
UniFFI constructors require owned Arc arguments across the FFI boundary, so clippy::needless_pass_by_value cannot be acted on here. Document this with #[expect(..., reason = ...)] so the suppression is self-explanatory and will become a compile error if the lint ever stops firing. Co-authored-by: otto@toolsforhumanity.com
sqlite3mc registers its cipher implementations during the very first sqlite3_open_v2 call. When the test binary runs all 8 tests as parallel threads, two threads can race inside that one-time initialization window and one sees 'unknown cipher chacha20' even though chacha20 is compiled in (CODEC_TYPE_CHACHA20). Add init_sqlite() using std::sync::OnceLock so that exactly one thread performs the first open; all other threads block until codec initialization is complete before running their own test-specific code. Called as the first statement of every test in the file. Co-authored-by: otto@toolsforhumanity.com
docs.rs builds run without network access; world-id-core/embed-zkeys downloads circuit files (zkeys) during the build script, so including it in [package.metadata.docs.rs] features would cause every docs.rs build to fail with a network error. The crate-level example is already marked `ignore` precisely because it calls from_embedded() which requires embed-zkeys, so removing the feature from the docs.rs config is safe and complete. Co-authored-by: otto@toolsforhumanity.com
from_embedded is gated behind #[cfg(feature = "embed-zkeys")] and embed-zkeys is excluded from [package.metadata.docs.rs] features (docs.rs has no network access for the circuit download). rustdoc resolves intra-doc links against the features active at doc-build time, so the backtick link produced an unresolved-link error under RUSTDOCFLAGS=-Dwarnings. Replace with a plain code-span so the reference remains readable in the rendered docs without creating a dead link. Co-authored-by: otto@toolsforhumanity.com
Replace the single init_logging function that contained scattered inline #[cfg] blocks with three self-contained functions: - init_logging_native (#[cfg(not(wasm32))]): mpsc channel + background delivery thread. Documents *why* the channel is needed: calling a UniFFI foreign callback synchronously from inside UniFFI's future-poll machinery (rust_call_with_out_status) causes EXC_BAD_ACCESS due to nested FFI frame corruption. - init_logging_wasm (#[cfg(wasm32)]): stores the logger in LOGGER_INSTANCE for direct synchronous dispatch. Safe on WASM because the single-threaded cooperative runtime cannot have a UniFFI poll frame on the stack when a tracing event fires. - init_logging (ungated, #[uniffi::export]): handles the LOGGING_INITIALIZED idempotency guard and the shared subscriber setup, then dispatches to the appropriate platform impl via a single #[cfg]-gated call site. Each platform's code path is now fully self-contained; the public dispatcher contains no inline cfg blocks at all. Co-authored-by: otto@toolsforhumanity.com
…vent circuit download
Both world-id-authenticator v0.5.2 and world-id-proof v0.5.2 ship with
default = ["embed-zkeys"], which means any package that activates them
without explicit default-features = false ends up triggering world-id-proof's
build script to download ~100 MB of circuit files from raw.githubusercontent.com.
The two paths that activated world-id-proof/embed-zkeys without our knowledge:
1. walletkit-core -> world-id-core/authenticator
-> dep:world-id-authenticator (default-features = true)
-> world-id-authenticator/embed-zkeys
-> world-id-proof/embed-zkeys ← download
2. walletkit-core -> world-id-core/authenticator
-> dep:world-id-proof (default-features = true)
-> world-id-proof/default = ["embed-zkeys"] ← download
Neither path is controllable from our Cargo.toml without patching upstream
crates, since both are inside the published world-id-core v0.5.2.
Fix: vendor both crates with a single change each (default = []) and add
[patch.crates-io] entries pointing to the vendor copies. The embed-zkeys
feature still activates correctly when our own feature is
explicitly enabled (verified: world-id-proof resolves to [embed-zkeys,
zstd-compress-zkeys] when walletkit-core/embed-zkeys is active).
The vendor copies are verbatim source from crates.io v0.5.2 with only the
[features] default line changed. They should be updated whenever either
crate is bumped.
Co-authored-by: otto@toolsforhumanity.com
Remove the [patch.crates-io] overrides for world-id-authenticator and world-id-proof that set default=[] to prevent circuit downloads. The upstream crates on crates.io are used directly now. Also fix duplicate uniffi workspace dependency in walletkit-core/Cargo.toml introduced during rebase conflict resolution.
…lock The UniFFI proc macro processes all methods in the impl block before `#[cfg]` attributes are evaluated, so `VaultChangedListener` was being resolved even on wasm32 where the cfg-gated import is absent. Move the method into the non-uniffi impl block where the `#[cfg]` gate works as expected.
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
Supersedes #253 after rebasing onto the latest
mainand resolving the conflict set there.Summary
Enables
wasm32-unknown-unknowncompilation for bothwalletkit-coreandwalletkitcrates. This is the foundation for running World ID authentication flows in the browser.What works on WASM
cargo check --target wasm32-unknown-unknown)Authenticator::initgenerate_nullifier/generate_credential_blinding_factor(via WASM-compatible OPRF transport upstream)What's native-only (correctly gated)
Groth16Materials::from_cache(filesystem-based, usesstd::fs)Major changes
walletkit-db WASM FFI fixes
Fixes sqlite-wasm-rs FFI compatibility and supports the WASM compile path.
Remove
storagefeature flagUnifies the storage code path so the SQLite credential store is always compiled in.
Introduce
Groth16MaterialsDecouples Groth16 material loading from authenticator construction with:
from_cachefor nativefrom_embeddedfor embedded-zkeys buildsEnable WASM compilation
Upstream dependencies
This PR currently relies on git patches for upstream compatibility:
worldcoin/world-id-protocol(main)TaceoLabs/oprf-service(main)Verification
cargo fmt --allcargo check --workspacecargo clippy --workspace --all-targets