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<String>,
+    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<String, Identity>,
+}
+
+#[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<EthereumIdentity>,
+  #[serde(rename = "farcasterID")]
+  pub farcaster_id: Option<String>,
+}
+
+impl TryFrom<UserIdentitiesResponse> for UserIdentities {
+  type Error = Error;
+
+  fn try_from(response: UserIdentitiesResponse) -> Result<Self, Self::Error> {
+    let identities: HashMap<String, Identity> = 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<String>,
+) -> Result<String, Error> {
+  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<String>,
+      promise_id: u32,
+    );
+
     // Argon2
     #[cxx_name = "compute_backup_key"]
     fn compute_backup_key_str(