diff --git a/lib/shared/crypto-utils.js b/lib/shared/crypto-utils.js
--- a/lib/shared/crypto-utils.js
+++ b/lib/shared/crypto-utils.js
@@ -1,8 +1,62 @@
 //@flow
 
-import type { OLMOneTimeKeys } from '../types/crypto-types';
+import * as React from 'react';
+
+import {
+  getOlmSessionInitializationData,
+  getOlmSessionInitializationDataActionTypes,
+} from '../actions/user-actions.js';
+import type { OLMIdentityKeys, OLMOneTimeKeys } from '../types/crypto-types';
+import type { OlmSessionInitializationInfo } from '../types/request-types';
+import {
+  useServerCall,
+  useDispatchActionPromise,
+} from '../utils/action-utils.js';
+import type { CallServerEndpointOptions } from '../utils/call-server-endpoint.js';
 import { values } from '../utils/objects.js';
 
+function useInitialNotificationsEncryptedMessage(
+  platformSpecificSessionCreator: (
+    notificationsIdentityKeys: OLMIdentityKeys,
+    notificationsInitializationInfo: OlmSessionInitializationInfo,
+  ) => Promise<string>,
+): (callServerEndpointOptions?: ?CallServerEndpointOptions) => Promise<string> {
+  const callGetOlmSessionInitializationData = useServerCall(
+    getOlmSessionInitializationData,
+  );
+  const dispatchActionPromise = useDispatchActionPromise();
+
+  return React.useCallback(
+    async callServerEndpointOptions => {
+      const olmSessionDataPromise = callGetOlmSessionInitializationData(
+        callServerEndpointOptions,
+      );
+
+      dispatchActionPromise(
+        getOlmSessionInitializationDataActionTypes,
+        olmSessionDataPromise,
+      );
+
+      const { signedIdentityKeysBlob, notifInitializationInfo } =
+        await olmSessionDataPromise;
+
+      const { notificationIdentityPublicKeys } = JSON.parse(
+        signedIdentityKeysBlob.payload,
+      );
+
+      return await platformSpecificSessionCreator(
+        notificationIdentityPublicKeys,
+        notifInitializationInfo,
+      );
+    },
+    [
+      callGetOlmSessionInitializationData,
+      dispatchActionPromise,
+      platformSpecificSessionCreator,
+    ],
+  );
+}
+
 function getOneTimeKeyValues(
   oneTimeKeys: OLMOneTimeKeys,
 ): $ReadOnlyArray<string> {
@@ -14,4 +68,8 @@
   return getOneTimeKeyValues(oneTimeKeys);
 }
 
-export { getOneTimeKeyValues, getOneTimeKeyValuesFromBlob };
+export {
+  getOneTimeKeyValues,
+  getOneTimeKeyValuesFromBlob,
+  useInitialNotificationsEncryptedMessage,
+};
diff --git a/native/account/log-in-panel.react.js b/native/account/log-in-panel.react.js
--- a/native/account/log-in-panel.react.js
+++ b/native/account/log-in-panel.react.js
@@ -18,6 +18,7 @@
   validEmailRegex,
   oldValidUsernameRegex,
 } from 'lib/shared/account-utils.js';
+import { useInitialNotificationsEncryptedMessage } from 'lib/shared/crypto-utils.js';
 import {
   type LogInInfo,
   type LogInExtraInfo,
@@ -45,7 +46,7 @@
 import { nativeLogInExtraInfoSelector } from '../selectors/account-selectors.js';
 import type { KeyPressEvent } from '../types/react-native.js';
 import Alert from '../utils/alert.js';
-import { useInitialNotificationsEncryptedMessage } from '../utils/crypto-utils.js';
+import { nativeNotificationsSessionCreator } from '../utils/crypto-utils.js';
 import type { StateContainer } from '../utils/state-container.js';
 
 export type LogInState = {
@@ -388,7 +389,9 @@
     const dispatchActionPromise = useDispatchActionPromise();
     const callLogIn = useServerCall(logIn);
     const getInitialNotificationsEncryptedMessage =
-      useInitialNotificationsEncryptedMessage();
+      useInitialNotificationsEncryptedMessage(
+        nativeNotificationsSessionCreator,
+      );
 
     return (
       <LogInPanel
diff --git a/native/account/logged-out-modal.react.js b/native/account/logged-out-modal.react.js
--- a/native/account/logged-out-modal.react.js
+++ b/native/account/logged-out-modal.react.js
@@ -24,6 +24,7 @@
   urlPrefixSelector,
 } from 'lib/selectors/keyserver-selectors.js';
 import { isLoggedIn } from 'lib/selectors/user-selectors.js';
+import { useInitialNotificationsEncryptedMessage } from 'lib/shared/crypto-utils.js';
 import { logInActionSources } from 'lib/types/account-types.js';
 import type { Dispatch } from 'lib/types/redux-types.js';
 import { fetchNewCookieFromNativeCredentials } from 'lib/utils/action-utils.js';
@@ -68,7 +69,7 @@
   runTiming,
   ratchetAlongWithKeyboardHeight,
 } from '../utils/animation-utils.js';
-import { useInitialNotificationsEncryptedMessage } from '../utils/crypto-utils.js';
+import { nativeNotificationsSessionCreator } from '../utils/crypto-utils.js';
 import {
   type StateContainer,
   type StateChange,
@@ -817,7 +818,9 @@
 
     const dispatch = useDispatch();
     const getInitialNotificationsEncryptedMessage =
-      useInitialNotificationsEncryptedMessage();
+      useInitialNotificationsEncryptedMessage(
+        nativeNotificationsSessionCreator,
+      );
     return (
       <LoggedOutModal
         {...props}
diff --git a/native/account/register-panel.react.js b/native/account/register-panel.react.js
--- a/native/account/register-panel.react.js
+++ b/native/account/register-panel.react.js
@@ -24,6 +24,7 @@
   combineLoadingStatuses,
 } from 'lib/selectors/loading-selectors.js';
 import { validUsernameRegex } from 'lib/shared/account-utils.js';
+import { useInitialNotificationsEncryptedMessage } from 'lib/shared/crypto-utils.js';
 import type {
   RegisterInfo,
   LogInExtraInfo,
@@ -47,7 +48,7 @@
 import { nativeLogInExtraInfoSelector } from '../selectors/account-selectors.js';
 import type { KeyPressEvent } from '../types/react-native.js';
 import Alert from '../utils/alert.js';
-import { useInitialNotificationsEncryptedMessage } from '../utils/crypto-utils.js';
+import { nativeNotificationsSessionCreator } from '../utils/crypto-utils.js';
 import { type StateContainer } from '../utils/state-container.js';
 
 export type RegisterState = {
@@ -493,7 +494,9 @@
     const dispatchActionPromise = useDispatchActionPromise();
     const callRegister = useServerCall(register);
     const getInitialNotificationsEncryptedMessage =
-      useInitialNotificationsEncryptedMessage();
+      useInitialNotificationsEncryptedMessage(
+        nativeNotificationsSessionCreator,
+      );
 
     return (
       <RegisterPanel
diff --git a/native/account/siwe-hooks.js b/native/account/siwe-hooks.js
--- a/native/account/siwe-hooks.js
+++ b/native/account/siwe-hooks.js
@@ -3,6 +3,7 @@
 import * as React from 'react';
 
 import { siweAuth, siweAuthActionTypes } from 'lib/actions/siwe-actions.js';
+import { useInitialNotificationsEncryptedMessage } from 'lib/shared/crypto-utils.js';
 import type { LogInStartingPayload } from 'lib/types/account-types.js';
 import {
   useServerCall,
@@ -13,7 +14,7 @@
 import { NavContext } from '../navigation/navigation-context.js';
 import { useSelector } from '../redux/redux-utils.js';
 import { nativeLogInExtraInfoSelector } from '../selectors/account-selectors.js';
-import { useInitialNotificationsEncryptedMessage } from '../utils/crypto-utils.js';
+import { nativeNotificationsSessionCreator } from '../utils/crypto-utils.js';
 
 type SIWEServerCallParams = {
   +message: string,
@@ -58,7 +59,7 @@
   );
 
   const getInitialNotificationsEncryptedMessage =
-    useInitialNotificationsEncryptedMessage();
+    useInitialNotificationsEncryptedMessage(nativeNotificationsSessionCreator);
 
   const dispatchActionPromise = useDispatchActionPromise();
   return React.useCallback(
diff --git a/native/data/sqlite-data-handler.js b/native/data/sqlite-data-handler.js
--- a/native/data/sqlite-data-handler.js
+++ b/native/data/sqlite-data-handler.js
@@ -13,6 +13,7 @@
   urlPrefixSelector,
 } from 'lib/selectors/keyserver-selectors.js';
 import { isLoggedIn } from 'lib/selectors/user-selectors.js';
+import { useInitialNotificationsEncryptedMessage } from 'lib/shared/crypto-utils.js';
 import {
   logInActionSources,
   type LogInActionSource,
@@ -26,7 +27,7 @@
 import { useSelector } from '../redux/redux-utils.js';
 import { StaffContext } from '../staff/staff-context.js';
 import Alert from '../utils/alert.js';
-import { useInitialNotificationsEncryptedMessage } from '../utils/crypto-utils.js';
+import { nativeNotificationsSessionCreator } from '../utils/crypto-utils.js';
 import { isTaskCancelledError } from '../utils/error-handling.js';
 import { useStaffCanSee } from '../utils/staff-utils.js';
 
@@ -48,7 +49,7 @@
   );
   const mediaCacheContext = React.useContext(MediaCacheContext);
   const getInitialNotificationsEncryptedMessage =
-    useInitialNotificationsEncryptedMessage();
+    useInitialNotificationsEncryptedMessage(nativeNotificationsSessionCreator);
 
   const callFetchNewCookieFromNativeCredentials = React.useCallback(
     async (source: LogInActionSource) => {
diff --git a/native/socket.react.js b/native/socket.react.js
--- a/native/socket.react.js
+++ b/native/socket.react.js
@@ -14,6 +14,7 @@
 } from 'lib/selectors/keyserver-selectors.js';
 import { isLoggedIn } from 'lib/selectors/user-selectors.js';
 import { accountHasPassword } from 'lib/shared/account-utils.js';
+import { useInitialNotificationsEncryptedMessage } from 'lib/shared/crypto-utils.js';
 import Socket, { type BaseSocketProps } from 'lib/socket/socket.react.js';
 import { logInActionSources } from 'lib/types/account-types.js';
 import {
@@ -37,7 +38,7 @@
   nativeSessionStateFuncSelector,
 } from './selectors/socket-selectors.js';
 import Alert from './utils/alert.js';
-import { useInitialNotificationsEncryptedMessage } from './utils/crypto-utils.js';
+import { nativeNotificationsSessionCreator } from './utils/crypto-utils.js';
 import { decompressMessage } from './utils/decompress.js';
 
 const NativeSocket: React.ComponentType<BaseSocketProps> =
@@ -65,7 +66,9 @@
     const preRequestUserState = useSelector(preRequestUserStateSelector);
 
     const getInitialNotificationsEncryptedMessage =
-      useInitialNotificationsEncryptedMessage();
+      useInitialNotificationsEncryptedMessage(
+        nativeNotificationsSessionCreator,
+      );
 
     const getClientResponses = useSelector(state =>
       nativeGetClientResponsesSelector({
diff --git a/native/utils/crypto-utils.js b/native/utils/crypto-utils.js
--- a/native/utils/crypto-utils.js
+++ b/native/utils/crypto-utils.js
@@ -1,54 +1,21 @@
 // @flow
 
-import * as React from 'react';
-
-import {
-  getOlmSessionInitializationData,
-  getOlmSessionInitializationDataActionTypes,
-} from 'lib/actions/user-actions.js';
-import {
-  useServerCall,
-  useDispatchActionPromise,
-} from 'lib/utils/action-utils.js';
-import type { CallServerEndpointOptions } from 'lib/utils/call-server-endpoint.js';
+import type { OLMIdentityKeys } from 'lib/types/crypto-types';
+import type { OlmSessionInitializationInfo } from 'lib/types/request-types';
 
 import { commCoreModule } from '../native-modules.js';
 
-function useInitialNotificationsEncryptedMessage(): (
-  callServerEndpointOptions?: ?CallServerEndpointOptions,
-) => Promise<string> {
-  const callGetOlmSessionInitializationData = useServerCall(
-    getOlmSessionInitializationData,
-  );
-  const dispatchActionPromise = useDispatchActionPromise();
-
-  return React.useCallback(
-    async callServerEndpointOptions => {
-      const olmSessionDataPromise = callGetOlmSessionInitializationData(
-        callServerEndpointOptions,
-      );
-
-      dispatchActionPromise(
-        getOlmSessionInitializationDataActionTypes,
-        olmSessionDataPromise,
-      );
-
-      const { signedIdentityKeysBlob, notifInitializationInfo } =
-        await olmSessionDataPromise;
-
-      const { notificationIdentityPublicKeys } = JSON.parse(
-        signedIdentityKeysBlob.payload,
-      );
-
-      const { prekey, prekeySignature, oneTimeKey } = notifInitializationInfo;
-      return await commCoreModule.initializeNotificationsSession(
-        JSON.stringify(notificationIdentityPublicKeys),
-        prekey,
-        prekeySignature,
-        oneTimeKey,
-      );
-    },
-    [callGetOlmSessionInitializationData, dispatchActionPromise],
+function nativeNotificationsSessionCreator(
+  notificationsIdentityKeys: OLMIdentityKeys,
+  notificationsInitializationInfo: OlmSessionInitializationInfo,
+): Promise<string> {
+  const { prekey, prekeySignature, oneTimeKey } =
+    notificationsInitializationInfo;
+  return commCoreModule.initializeNotificationsSession(
+    JSON.stringify(notificationsIdentityKeys),
+    prekey,
+    prekeySignature,
+    oneTimeKey,
   );
 }
 
@@ -60,4 +27,4 @@
   return ed25519;
 }
 
-export { useInitialNotificationsEncryptedMessage, getContentSigningKey };
+export { getContentSigningKey, nativeNotificationsSessionCreator };