diff --git a/walletkit-core/src/authenticator/mod.rs b/walletkit-core/src/authenticator/mod.rs index 0e2a6ae7..3a71445c 100644 --- a/walletkit-core/src/authenticator/mod.rs +++ b/walletkit-core/src/authenticator/mod.rs @@ -10,8 +10,9 @@ use ruint_uniffi::Uint256; use std::sync::Arc; use world_id_core::{ api_types::{GatewayErrorCode, GatewayRequestState}, - primitives::{authenticator::AuthenticatorPublicKeySet, Config}, - Authenticator as CoreAuthenticator, Credential as CoreCredential, + primitives::authenticator::AuthenticatorPublicKeySet, + Authenticator as CoreAuthenticator, AuthenticatorConfig, + Credential as CoreCredential, InitializingAuthenticator as CoreInitializingAuthenticator, OnchainKeyRepresentable, Signer, }; @@ -342,7 +343,8 @@ impl Authenticator { environment: &Environment, region: Option, ) -> Result { - let config = Config::from_environment(environment, rpc_url, region)?; + let config = + AuthenticatorConfig::from_environment(environment, rpc_url, region)?; let authenticator = CoreAuthenticator::init(seed, config).await?; let (query_material, nullifier_material) = load_embedded_materials()?; let authenticator = @@ -361,11 +363,12 @@ impl Authenticator { /// 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 { + let config = AuthenticatorConfig::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 = @@ -396,8 +399,9 @@ impl Authenticator { paths: &StoragePaths, store: Arc, ) -> Result { - let config = Config::from_environment(environment, rpc_url, region)?; - let authenticator = CoreAuthenticator::init(seed, config.into()).await?; + let config = + AuthenticatorConfig::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); @@ -422,12 +426,13 @@ impl Authenticator { paths: &StoragePaths, store: Arc, ) -> Result { - let config = - Config::from_json(config).map_err(|_| WalletKitError::InvalidInput { + let config = AuthenticatorConfig::from_json(config).map_err(|_| { + WalletKitError::InvalidInput { attribute: "config".to_string(), reason: "Invalid config".to_string(), - })?; - let authenticator = CoreAuthenticator::init(seed, config.into()).await?; + } + })?; + 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); @@ -615,10 +620,11 @@ impl InitializingAuthenticator { let recovery_address = Address::parse_from_ffi_optional(recovery_address, "recovery_address")?; - let config = Config::from_environment(environment, rpc_url, region)?; + let config = + AuthenticatorConfig::from_environment(environment, rpc_url, region)?; let initializing_authenticator = - CoreAuthenticator::register(seed, config.into(), recovery_address).await?; + CoreAuthenticator::register(seed, config, recovery_address).await?; Ok(Self(initializing_authenticator)) } @@ -644,14 +650,15 @@ impl InitializingAuthenticator { let recovery_address = Address::parse_from_ffi_optional(recovery_address, "recovery_address")?; - let config = - Config::from_json(config).map_err(|_| WalletKitError::InvalidInput { + let config = AuthenticatorConfig::from_json(config).map_err(|_| { + WalletKitError::InvalidInput { attribute: "config".to_string(), reason: "Invalid config".to_string(), - })?; + } + })?; let initializing_authenticator = - CoreAuthenticator::register(seed, config.into(), recovery_address).await?; + CoreAuthenticator::register(seed, config, recovery_address).await?; Ok(Self(initializing_authenticator)) } @@ -815,6 +822,7 @@ mod storage_tests { cleanup_test_storage, temp_root_path, InMemoryStorageProvider, }; use alloy::primitives::address; + use world_id_core::primitives::Config; async fn init_test_authenticator( seed: &[u8], diff --git a/walletkit-core/src/defaults.rs b/walletkit-core/src/defaults.rs index d1a7aad2..08e5b9c8 100644 --- a/walletkit-core/src/defaults.rs +++ b/walletkit-core/src/defaults.rs @@ -1,5 +1,5 @@ use alloy_primitives::{address, Address}; -use world_id_core::primitives::Config; +use world_id_core::{primitives::Config, AuthenticatorConfig, OhttpClientConfig}; use crate::{error::WalletKitError, Environment, Region}; @@ -66,6 +66,45 @@ pub trait DefaultConfig { Self: Sized; } +fn ohttp_relay_url(region: Region, environment: &Environment) -> String { + let path = match environment { + Environment::Staging => format!("{region}-world-id-stage"), + Environment::Production => format!("{region}-world-id"), + }; + format!("https://privacy-gateway.cloudflare.com/{path}") +} + +// TODO: replace with real base64-encoded HPKE key configs +const OHTTP_KEY_CONFIG_STAGING: &str = "TODO"; +const OHTTP_KEY_CONFIG_PRODUCTION: &str = "TODO"; + +impl DefaultConfig for AuthenticatorConfig { + fn from_environment( + environment: &Environment, + rpc_url: Option, + region: Option, + ) -> Result { + let region = region.unwrap_or_default(); + let config = Config::from_environment(environment, rpc_url, Some(region))?; + + let key_config_base64 = match environment { + Environment::Staging => OHTTP_KEY_CONFIG_STAGING, + Environment::Production => OHTTP_KEY_CONFIG_PRODUCTION, + }; + let relay_url = ohttp_relay_url(region, environment); + let ohttp = Some(OhttpClientConfig::new( + relay_url, + key_config_base64.to_string(), + )); + + Ok(Self { + config, + ohttp_indexer: ohttp.clone(), + ohttp_gateway: ohttp, + }) + } +} + impl DefaultConfig for Config { fn from_environment( environment: &Environment, diff --git a/walletkit-core/src/error.rs b/walletkit-core/src/error.rs index e32c412c..3428085f 100644 --- a/walletkit-core/src/error.rs +++ b/walletkit-core/src/error.rs @@ -140,6 +140,13 @@ pub enum WalletKitError { /// The error code from the NFC service (e.g. `document_expired`) error_code: String, }, + + /// An error occurred in the OHTTP privacy layer (relay, encapsulation, or framing). + #[error("ohttp_error: {error}")] + OhttpError { + /// The error message from the OHTTP layer + error: String, + }, } impl From for WalletKitError { @@ -227,6 +234,13 @@ impl From for WalletKitError { } AuthenticatorError::SessionIdMismatch => Self::SessionIdMismatch, + AuthenticatorError::OhttpEncapsulationError(_) + | AuthenticatorError::BhttpError(_) + | AuthenticatorError::OhttpRelayError { .. } + | AuthenticatorError::InvalidServiceResponse(_) => Self::OhttpError { + error: error.to_string(), + }, + _ => Self::AuthenticatorError { error: error.to_string(), },