#![cfg(feature = "authenticator")]
use alloy::primitives::U256;
use backon::{ExponentialBuilder, Retryable};
use world_id_core::{Authenticator, AuthenticatorError, api_types::GatewayRequestState};
use world_id_gateway::{
BatchPolicyConfig, GatewayConfig, SignerArgs, defaults, spawn_gateway_for_tests,
};
use world_id_primitives::{Config, ServiceEndpoint};
use world_id_test_utils::anvil::TestAnvil;
#[tokio::test(flavor = "multi_thread", worker_threads = 1)]
async fn test_authenticator_registration() {
rustls::crypto::aws_lc_rs::default_provider()
.install_default()
.expect("can install");
let anvil = TestAnvil::spawn().expect("failed to spawn anvil");
let deployer = anvil.signer(0).unwrap();
let registry_address = anvil
.deploy_world_id_registry(deployer.clone())
.await
.unwrap();
let signer_args = SignerArgs::from_wallet(hex::encode(deployer.to_bytes()));
let gateway_config = GatewayConfig {
registry_addr: registry_address,
registry_version: None,
provider: world_id_gateway::ProviderArgs {
http: Some(vec![anvil.endpoint().parse().unwrap()]),
signer: Some(signer_args),
..Default::default()
},
listen_addr: (std::net::Ipv4Addr::LOCALHOST, 0).into(),
max_create_batch_size: 10,
max_ops_batch_size: 10,
redis_url: std::env::var("REDIS_URL")
.unwrap_or_else(|_| "redis://localhost:6379".to_string()),
request_timeout_secs: 10,
rate_limit_max_requests: None,
rate_limit_window_secs: None,
sweeper_interval_secs: defaults::SWEEPER_INTERVAL_SECS,
stale_queued_threshold_secs: defaults::STALE_QUEUED_THRESHOLD_SECS,
stale_submitted_threshold_secs: defaults::STALE_SUBMITTED_THRESHOLD_SECS,
batch_policy: BatchPolicyConfig::default(),
};
let gateway = spawn_gateway_for_tests(gateway_config)
.await
.expect("failed to spawn gateway");
let gw_addr = gateway.listen_addr;
let gateway_url = format!("http://{}:{}", gw_addr.ip(), gw_addr.port());
let config = Config::new(
Some(anvil.endpoint().to_string()),
anvil.instance.chain_id(),
registry_address,
ServiceEndpoint::direct("http://127.0.0.1:0".to_string()), ServiceEndpoint::direct(gateway_url.clone()),
Vec::new(),
2,
)
.unwrap();
let seed = [1u8; 32];
let recovery_address = anvil.signer(1).unwrap().address();
let result = Authenticator::init(&seed, config.clone()).await;
assert!(matches!(
result,
Err(AuthenticatorError::AccountDoesNotExist)
),);
let start = std::time::Instant::now();
let initializing_account =
Authenticator::register(&seed, config.clone(), Some(recovery_address))
.await
.unwrap();
let poller = || async {
match initializing_account.poll_status().await {
Ok(GatewayRequestState::Finalized { .. }) => Ok(()),
_ => Err(""),
}
};
poller
.retry(ExponentialBuilder::default().with_max_times(10))
.await
.unwrap();
let authenticator = Authenticator::init(&seed, config.clone()).await.unwrap();
let elapsed = start.elapsed();
tracing::info!("Account creation successful in {elapsed:?}");
assert_eq!(authenticator.leaf_index(), 1);
assert_eq!(authenticator.recovery_counter(), U256::from(0));
let authenticator = Authenticator::init(&seed, config).await.unwrap();
assert_eq!(authenticator.leaf_index(), 1);
}