diff --git a/lib/actions/identity-service-auth-actions.js b/lib/actions/identity-service-auth-actions.js
new file mode 100644
--- /dev/null
+++ b/lib/actions/identity-service-auth-actions.js
@@ -0,0 +1,66 @@
+// @flow
+
+import { mergeUserInfos } from './user-actions.js';
+import threadWatcher from '../shared/thread-watcher.js';
+import {
+  type LogInResult,
+  type IdentityServiceOlmAuthServerCall,
+} from '../types/account-types.js';
+import type {
+  CallServerEndpoint,
+  CallServerEndpointOptions,
+} from '../utils/call-server-endpoint.js';
+import { getConfig } from '../utils/config.js';
+
+const identityServiceOlmAuthActionTypes = Object.freeze({
+  started: 'IDENTITY_SERVICE_OLM_AUTH_STARTED',
+  success: 'IDENTITY_SERVICE_OLM_AUTH_SUCCESS',
+  failed: 'IDENTITY_SERVICE_OLM_AUTH_FAILED',
+});
+const identityServiceOlmAuthCallServerEndpointOptions = { timeout: 60000 };
+const identityServiceOlmAuth =
+  (
+    callServerEndpoint: CallServerEndpoint,
+  ): ((
+    identityServiceOlmAuthPayload: IdentityServiceOlmAuthServerCall,
+    options?: ?CallServerEndpointOptions,
+  ) => Promise<LogInResult>) =>
+  async (identityServiceOlmAuthPayload, options) => {
+    const watchedIDs = threadWatcher.getWatchedIDs();
+    const response = await callServerEndpoint(
+      'identity_service_olm_auth',
+      {
+        ...identityServiceOlmAuthPayload,
+        watchedIDs,
+        platformDetails: getConfig().platformDetails,
+      },
+      {
+        ...identityServiceOlmAuthCallServerEndpointOptions,
+        ...options,
+      },
+    );
+    const userInfos = mergeUserInfos(
+      response.userInfos,
+      response.cookieChange.userInfos,
+    );
+    return {
+      threadInfos: response.cookieChange.threadInfos,
+      currentUserInfo: response.currentUserInfo,
+      calendarResult: {
+        calendarQuery: identityServiceOlmAuthPayload.calendarQuery,
+        rawEntryInfos: response.rawEntryInfos,
+      },
+      messagesResult: {
+        messageInfos: response.rawMessageInfos,
+        truncationStatus: response.truncationStatuses,
+        watchedIDsAtRequestTime: watchedIDs,
+        currentAsOf: response.serverTime,
+      },
+      userInfos,
+      updatesCurrentAsOf: response.serverTime,
+      logInActionSource: identityServiceOlmAuthPayload.logInActionSource,
+      notAcknowledgedPolicies: response.notAcknowledgedPolicies,
+    };
+  };
+
+export { identityServiceOlmAuthActionTypes, identityServiceOlmAuth };
diff --git a/lib/types/account-types.js b/lib/types/account-types.js
--- a/lib/types/account-types.js
+++ b/lib/types/account-types.js
@@ -94,6 +94,8 @@
   logInFromWebForm: 'LOG_IN_FROM_WEB_FORM',
   logInFromNativeForm: 'LOG_IN_FROM_NATIVE_FORM',
   logInFromNativeSIWE: 'LOG_IN_FROM_NATIVE_SIWE',
+  logInFromNativeIdentityServiceOlm: 'LOG_IN_FROM_NATIVE_IDENTITY_SERVICE_OLM',
+  logInFromWebIdentityServiceOlm: 'LOG_IN_FROM_WEB_IDENTITY_SERVICE_OLM',
   corruptedDatabaseDeletion: 'CORRUPTED_DATABASE_DELETION',
   refetchUserDataAfterAcknowledgment: 'REFETCH_USER_DATA_AFTER_ACKNOWLEDGMENT',
 });
@@ -110,6 +112,7 @@
   +deviceTokenUpdateRequest?: ?DeviceTokenUpdateRequest,
   +signedIdentityKeysBlob?: SignedIdentityKeysBlob,
   +initialNotificationsEncryptedMessage?: string,
+  +initialContentEncryptedMessage?: string,
 };
 
 export type LogInInfo = {
@@ -158,6 +161,34 @@
   +notAcknowledgedPolicies?: $ReadOnlyArray<PolicyType>,
 };
 
+export type UserIdentifier =
+  | { username: string, userID: string }
+  | { walletAddress: string, userID: string };
+
+export type BaseIdentityServiceOlmAuthRequest = {
+  +identifier: UserIdentifier,
+  +signingPublicKey: string,
+  +calendarQuery: CalendarQuery,
+  +deviceTokenUpdateRequest?: ?DeviceTokenUpdateRequest,
+  +initialContentEncryptedMessage: string,
+  +initialNotificationsEncryptedMessage: string,
+  +doNotRegister?: boolean,
+};
+
+export type IdentityServiceOlmAuthRequest = {
+  ...BaseIdentityServiceOlmAuthRequest,
+  +watchedIDs: $ReadOnlyArray<string>,
+  +platformDetails: PlatformDetails,
+};
+
+export type IdentityServiceOlmAuthServerCall = {
+  +identifier: UserIdentifier,
+  +signingPublicKey: string,
+  +doNotRegister?: boolean,
+  +logInActionSource: LogInActionSource,
+  ...LogInExtraInfo,
+};
+
 export type UpdatePasswordRequest = {
   code: string,
   password: string,
diff --git a/lib/types/endpoints.js b/lib/types/endpoints.js
--- a/lib/types/endpoints.js
+++ b/lib/types/endpoints.js
@@ -101,6 +101,7 @@
   VERIFY_INVITE_LINK: 'verify_invite_link',
   SIWE_NONCE: 'siwe_nonce',
   SIWE_AUTH: 'siwe_auth',
+  IDENTITY_SERVICE_OLM_AUTH: 'identity_service_olm_auth',
   CLAIM_USERNAME: 'claim_username',
   UPDATE_USER_AVATAR: 'update_user_avatar',
   UPLOAD_MEDIA_METADATA: 'upload_media_metadata',