diff --git a/native/native_rust_library/src/identity.rs b/native/native_rust_library/src/identity.rs --- a/native/native_rust_library/src/identity.rs +++ b/native/native_rust_library/src/identity.rs @@ -12,6 +12,7 @@ pub mod device_list; pub mod exact_user_search; pub mod farcaster; +pub mod find_user_identities; pub mod login; pub mod registration; pub mod x3dh; @@ -23,6 +24,7 @@ pub use device_list::ffi::*; pub use exact_user_search::ffi::*; pub use farcaster::ffi::*; + pub use find_user_identities::ffi::*; pub use login::ffi::*; pub use registration::ffi::*; pub use x3dh::ffi::*; diff --git a/native/native_rust_library/src/identity/find_user_identities.rs b/native/native_rust_library/src/identity/find_user_identities.rs new file mode 100644 --- /dev/null +++ b/native/native_rust_library/src/identity/find_user_identities.rs @@ -0,0 +1,108 @@ +use grpc_clients::identity::get_auth_client; +use grpc_clients::identity::protos::auth::{ + UserIdentitiesRequest, UserIdentitiesResponse, +}; +use serde::Serialize; +use std::collections::HashMap; + +use crate::identity::AuthInfo; +use crate::utils::jsi_callbacks::handle_string_result_as_callback; +use crate::{Error, CODE_VERSION, DEVICE_TYPE, IDENTITY_SOCKET_ADDR, RUNTIME}; + +pub mod ffi { + use super::*; + + pub fn find_user_identities( + auth_user_id: String, + auth_device_id: String, + auth_access_token: String, + user_ids: Vec, + promise_id: u32, + ) { + RUNTIME.spawn(async move { + let auth_info = AuthInfo { + access_token: auth_access_token, + user_id: auth_user_id, + device_id: auth_device_id, + }; + let result = find_user_identities_helper(auth_info, user_ids).await; + handle_string_result_as_callback(result, promise_id); + }); + } +} + +#[derive(Serialize)] +pub struct UserIdentities { + pub identities: HashMap, +} + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +pub struct EthereumIdentity { + pub wallet_address: String, + pub siwe_message: String, + pub siwe_signature: String, +} + +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Identity { + pub username: String, + pub eth_identity: Option, + #[serde(rename = "farcasterID")] + pub farcaster_id: Option, +} + +impl TryFrom for UserIdentities { + type Error = Error; + + fn try_from(response: UserIdentitiesResponse) -> Result { + let identities: HashMap = response + .identities + .into_iter() + .map(|(user_id, identity)| { + let eth_identity = + identity.eth_identity.map(|eth_identity| EthereumIdentity { + wallet_address: eth_identity.wallet_address, + siwe_message: eth_identity.siwe_message, + siwe_signature: eth_identity.siwe_signature, + }); + + ( + user_id, + Identity { + username: identity.username, + eth_identity, + farcaster_id: identity.farcaster_id, + }, + ) + }) + .collect(); + + Ok(UserIdentities { identities }) + } +} + +async fn find_user_identities_helper( + auth_info: AuthInfo, + user_ids: Vec, +) -> Result { + let mut identity_client = get_auth_client( + IDENTITY_SOCKET_ADDR, + auth_info.user_id, + auth_info.device_id, + auth_info.access_token, + CODE_VERSION, + DEVICE_TYPE.as_str_name().to_lowercase(), + ) + .await?; + + let response = identity_client + .find_user_identities(UserIdentitiesRequest { user_ids }) + .await? + .into_inner(); + + let user_identities = UserIdentities::try_from(response)?; + + Ok(serde_json::to_string(&user_identities.identities)?) +} diff --git a/native/native_rust_library/src/lib.rs b/native/native_rust_library/src/lib.rs --- a/native/native_rust_library/src/lib.rs +++ b/native/native_rust_library/src/lib.rs @@ -273,6 +273,15 @@ promise_id: u32, ); + #[cxx_name = "identityFindUserIdentities"] + fn find_user_identities( + user_id: String, + device_id: String, + access_token: String, + user_ids: Vec, + promise_id: u32, + ); + // Argon2 #[cxx_name = "compute_backup_key"] fn compute_backup_key_str(