diff --git a/native/components/identity-handler.react.js b/native/components/identity-handler.react.js
new file mode 100644
--- /dev/null
+++ b/native/components/identity-handler.react.js
@@ -0,0 +1,123 @@
+// @flow
+
+import * as React from 'react';
+
+import { setAccessTokenActionType } from 'lib/actions/user-actions.js';
+import { isLoggedIn } from 'lib/selectors/user-selectors.js';
+import { getOneTimeKeyArray } from 'lib/shared/crypto-utils.js';
+import { useDispatch } from 'lib/utils/redux-utils.js';
+import { isValidEthereumAddress } from 'lib/utils/siwe-utils.js';
+
+import { fetchNativeCredentials } from '../account/native-credentials.js';
+import { commCoreModule, commRustModule } from '../native-modules.js';
+import { useSelector } from '../redux/redux-utils.js';
+
+const ONE_TIME_KEYS_NUMBER = 10;
+
+function IdentityHandler(): React.Node {
+ const loggedIn = useSelector(isLoggedIn);
+ const dispatch = useDispatch();
+
+ React.useEffect(() => {
+ void (async () => {
+ if (loggedIn) {
+ await commCoreModule.initializeCryptoAccount();
+ const authMetadata = await commCoreModule.getCommServicesAuthMetadata();
+ console.log(authMetadata);
+ if (authMetadata.accessToken) {
+ console.log('CSAT present');
+ return;
+ }
+
+ const credentials = await fetchNativeCredentials();
+ if (!credentials) {
+ return;
+ }
+ const { username, password } = credentials;
+ if (!username || isValidEthereumAddress(username)) {
+ return;
+ }
+
+ const [
+ {
+ notificationIdentityPublicKeys,
+ primaryIdentityPublicKeys,
+ signature,
+ },
+ notificationsOneTimeKeys,
+ primaryOneTimeKeys,
+ prekeys,
+ ] = await Promise.all([
+ commCoreModule.getUserPublicKey(),
+ commCoreModule.getNotificationsOneTimeKeys(ONE_TIME_KEYS_NUMBER),
+ commCoreModule.getPrimaryOneTimeKeys(ONE_TIME_KEYS_NUMBER),
+ commCoreModule.generateAndGetPrekeys(),
+ ]);
+
+ const keyPayload = JSON.stringify({
+ notificationIdentityPublicKeys,
+ primaryIdentityPublicKeys,
+ });
+
+ let authResult: ?string = null;
+
+ try {
+ authResult = await commRustModule.registerUser(
+ username,
+ password,
+ keyPayload,
+ signature,
+ prekeys.contentPrekey,
+ prekeys.contentPrekeySignature,
+ prekeys.notifPrekey,
+ prekeys.notifPrekeySignature,
+ getOneTimeKeyArray(primaryOneTimeKeys),
+ getOneTimeKeyArray(notificationsOneTimeKeys),
+ );
+ console.log('Registered to identity');
+ } catch (registerError) {
+ console.log(
+ 'User PROBABLY already exists, trying to log in: ',
+ registerError,
+ );
+ try {
+ authResult = await commRustModule.loginPasswordUser(
+ username,
+ password,
+ keyPayload,
+ signature,
+ prekeys.contentPrekey,
+ prekeys.contentPrekeySignature,
+ prekeys.notifPrekey,
+ prekeys.notifPrekeySignature,
+ getOneTimeKeyArray(primaryOneTimeKeys),
+ getOneTimeKeyArray(notificationsOneTimeKeys),
+ );
+ console.log('Logged in to identity');
+ } catch (loginError) {
+ console.log('Login error ', loginError);
+ }
+ }
+
+ if (!authResult) {
+ return;
+ }
+ const { userID, accessToken } = JSON.parse(authResult);
+ await commCoreModule.setCommServicesAuthMetadata(
+ userID,
+ primaryIdentityPublicKeys.ed25519,
+ accessToken,
+ );
+ dispatch({ type: setAccessTokenActionType, payload: accessToken });
+ console.log('CSAT set, now Tunnelbroker should be connected');
+ } else {
+ await commCoreModule.clearCommServicesAccessToken();
+ console.log('clearing CSAT');
+ }
+ })();
+ }, [dispatch, loggedIn]);
+
+ return null;
+}
+
+export default IdentityHandler;
diff --git a/native/root.react.js b/native/root.react.js
--- a/native/root.react.js
+++ b/native/root.react.js
@@ -39,6 +39,7 @@
import ChatContextProvider from './chat/chat-context-provider.react.js';
import MessageEditingContextProvider from './chat/message-editing-context-provider.react.js';
import { FeatureFlagsProvider } from './components/feature-flags-provider.react.js';
+import IdentityHandler from './components/identity-handler.react.js';
import PersistedStateGate from './components/persisted-state-gate.js';
import VersionSupportedChecker from './components/version-supported.react.js';
import ConnectedStatusBar from './connected-status-bar.react.js';
@@ -75,7 +76,6 @@
import ThemeHandler from './themes/theme-handler.react.js';
import { provider } from './utils/ethers-utils.js';
import { useTunnelbrokerInitMessage } from './utils/tunnelbroker-utils.js';
-
// Add custom items to expo-dev-menu
import './dev-menu.js';
import './types/message-types-validator.js';
@@ -328,6 +328,7 @@
}
/>
+
{navigation}