diff --git a/lib/components/debug-logs-context-provider.react.js b/lib/components/debug-logs-context-provider.react.js
new file mode 100644
index 000000000..f416920cb
--- /dev/null
+++ b/lib/components/debug-logs-context-provider.react.js
@@ -0,0 +1,45 @@
+// @flow
+
+import * as React from 'react';
+
+import { type DebugLog, DebugLogsContext } from './debug-logs-context.js';
+
+type Props = {
+  +children: React.Node,
+};
+
+function DebugLogsContextProvider(props: Props): React.Node {
+  const [logs, setLogs] = React.useState<$ReadOnlyArray<DebugLog>>([]);
+
+  const addLog = React.useCallback(
+    (title: string, message: string) =>
+      setLogs(prevLogs => [
+        ...prevLogs,
+        {
+          title,
+          message,
+          timestamp: Date.now(),
+        },
+      ]),
+    [],
+  );
+
+  const clearLogs = React.useCallback(() => setLogs([]), []);
+
+  const contextValue = React.useMemo(
+    () => ({
+      logs,
+      addLog,
+      clearLogs,
+    }),
+    [addLog, clearLogs, logs],
+  );
+
+  return (
+    <DebugLogsContext.Provider value={contextValue}>
+      {props.children}
+    </DebugLogsContext.Provider>
+  );
+}
+
+export { DebugLogsContextProvider };
diff --git a/lib/components/debug-logs-context.js b/lib/components/debug-logs-context.js
new file mode 100644
index 000000000..4989abadb
--- /dev/null
+++ b/lib/components/debug-logs-context.js
@@ -0,0 +1,31 @@
+// @flow
+
+import invariant from 'invariant';
+import * as React from 'react';
+
+export type DebugLog = {
+  +title: string,
+  +message: string,
+  +timestamp: number,
+};
+
+export type DebugLogsContextType = {
+  +logs: $ReadOnlyArray<DebugLog>,
+  +addLog: (title: string, message: string) => mixed,
+  +clearLogs: () => mixed,
+};
+
+const DebugLogsContext: React.Context<DebugLogsContextType> =
+  React.createContext<DebugLogsContextType>({
+    logs: [],
+    addLog: () => {},
+    clearLogs: () => {},
+  });
+
+function useDebugLogs(): DebugLogsContextType {
+  const debugLogsContext = React.useContext(DebugLogsContext);
+  invariant(debugLogsContext, 'Debug logs context should be present');
+  return debugLogsContext;
+}
+
+export { DebugLogsContext, useDebugLogs };
diff --git a/native/navigation/route-names.js b/native/navigation/route-names.js
index e87834af4..5cd61338f 100644
--- a/native/navigation/route-names.js
+++ b/native/navigation/route-names.js
@@ -1,419 +1,421 @@
 // @flow
 
 import type { RouteProp } from '@react-navigation/core';
 
 import type { ActionResultModalParams } from './action-result-modal.react.js';
 import type { InviteLinkModalParams } from './invite-link-modal.react';
 import type { ConnectSecondaryDeviceParams } from '../account/qr-auth/connect-secondary-device.react.js';
 import type { AvatarSelectionParams } from '../account/registration/avatar-selection.react.js';
 import type { ConnectEthereumParams } from '../account/registration/connect-ethereum.react.js';
 import type { ConnectFarcasterParams } from '../account/registration/connect-farcaster.react.js';
 import type { EmojiAvatarSelectionParams } from '../account/registration/emoji-avatar-selection.react.js';
 import type { ExistingEthereumAccountParams } from '../account/registration/existing-ethereum-account.react.js';
 import type { KeyserverSelectionParams } from '../account/registration/keyserver-selection.react.js';
 import type { PasswordSelectionParams } from '../account/registration/password-selection.react.js';
 import type { RegistrationTermsParams } from '../account/registration/registration-terms.react.js';
 import type { CreateSIWEBackupMessageParams } from '../account/registration/siwe-backup-message-creation.react.js';
 import type { UsernameSelectionParams } from '../account/registration/username-selection.react.js';
 import type { RestoreBackupScreenParams } from '../account/restore-backup-screen.react';
 import type { TermsAndPrivacyModalParams } from '../account/terms-and-privacy-modal.react.js';
 import type { RestoreSIWEBackupParams } from '../backup/restore-siwe-backup.react.js';
 import type { ThreadPickerModalParams } from '../calendar/thread-picker-modal.react.js';
 import type { ComposeSubchannelParams } from '../chat/compose-subchannel.react.js';
 import type { FullScreenThreadMediaGalleryParams } from '../chat/fullscreen-thread-media-gallery.react.js';
 import type { ImagePasteModalParams } from '../chat/image-paste-modal.react.js';
 import type { MessageListParams } from '../chat/message-list-types.js';
 import type { MessageReactionsModalParams } from '../chat/message-reactions-modal.react.js';
 import type { MultimediaMessageTooltipModalParams } from '../chat/multimedia-message-tooltip-modal.react.js';
 import type { PinnedMessagesScreenParams } from '../chat/pinned-messages-screen.react.js';
 import type { RobotextMessageTooltipModalParams } from '../chat/robotext-message-tooltip-modal.react.js';
 import type { AddUsersModalParams } from '../chat/settings/add-users-modal.react.js';
 import type { ColorSelectorModalParams } from '../chat/settings/color-selector-modal.react.js';
 import type { ComposeSubchannelModalParams } from '../chat/settings/compose-subchannel-modal.react.js';
 import type { DeleteThreadParams } from '../chat/settings/delete-thread.react.js';
 import type { EmojiThreadAvatarCreationParams } from '../chat/settings/emoji-thread-avatar-creation.react.js';
 import type { ThreadSettingsMemberTooltipModalParams } from '../chat/settings/thread-settings-member-tooltip-modal.react.js';
 import type { ThreadSettingsNotificationsParams } from '../chat/settings/thread-settings-notifications.react.js';
 import type { ThreadSettingsParams } from '../chat/settings/thread-settings.react.js';
 import type { SidebarListModalParams } from '../chat/sidebar-list-modal.react.js';
 import type { SubchannelListModalParams } from '../chat/subchannels-list-modal.react.js';
 import type { TextMessageTooltipModalParams } from '../chat/text-message-tooltip-modal.react.js';
 import type { TogglePinModalParams } from '../chat/toggle-pin-modal.react.js';
 import type { TagFarcasterChannelByNameParams } from '../community-settings/tag-farcaster-channel/tag-farcaster-channel-by-name.react.js';
 import type { TagFarcasterChannelParams } from '../community-settings/tag-farcaster-channel/tag-farcaster-channel.react.js';
 import type { CommunityJoinerModalParams } from '../components/community-joiner-modal.react.js';
 import type { InviteLinksNavigatorParams } from '../invite-links/invite-links-navigator.react.js';
 import type { ManagePublicLinkScreenParams } from '../invite-links/manage-public-link-screen.react.js';
 import type { ViewInviteLinksScreenParams } from '../invite-links/view-invite-links-screen.react.js';
 import type { ChatCameraModalParams } from '../media/chat-camera-modal.react.js';
 import type { ImageModalParams } from '../media/image-modal.react.js';
 import type { ThreadAvatarCameraModalParams } from '../media/thread-avatar-camera-modal.react.js';
 import type { VideoPlaybackModalParams } from '../media/video-playback-modal.react.js';
 import type { CustomServerModalParams } from '../profile/custom-server-modal.react.js';
 import type { KeyserverSelectionBottomSheetParams } from '../profile/keyserver-selection-bottom-sheet.react.js';
 import type { LinkedDevicesBottomSheetParams } from '../profile/linked-devices-bottom-sheet.react.js';
 import type { UserRelationshipTooltipModalParams } from '../profile/user-relationship-tooltip-modal.react.js';
 import type { ChangeRolesScreenParams } from '../roles/change-roles-screen.react.js';
 import type { CommunityRolesScreenParams } from '../roles/community-roles-screen.react.js';
 import type { CreateRolesScreenParams } from '../roles/create-roles-screen.react.js';
 import type { MessageSearchParams } from '../search/message-search.react.js';
 import type { NUXTipsOverlayParams } from '../tooltip/nux-tips-overlay.react.js';
 import type { UserProfileAvatarModalParams } from '../user-profile/user-profile-avatar-modal.react.js';
 import type { UserProfileBottomSheetParams } from '../user-profile/user-profile-bottom-sheet.react.js';
 
 export const ActionResultModalRouteName = 'ActionResultModal';
 export const AddUsersModalRouteName = 'AddUsersModal';
 export const AppearancePreferencesRouteName = 'AppearancePreferences';
 export const AppRouteName = 'App';
 export const AppsRouteName = 'Apps';
 export const BackgroundChatThreadListRouteName = 'BackgroundChatThreadList';
 export const BackupMenuRouteName = 'BackupMenu';
 export const BlockListRouteName = 'BlockList';
 export const BuildInfoRouteName = 'BuildInfo';
 export const CalendarRouteName = 'Calendar';
 export const CalendarScreenRouteName = 'CalendarScreen';
 export const ChangeRolesScreenRouteName = 'ChangeRolesScreen';
 export const ChatCameraModalRouteName = 'ChatCameraModal';
 export const ChatRouteName = 'Chat';
 export const ChatThreadListRouteName = 'ChatThreadList';
 export const ColorSelectorModalRouteName = 'ColorSelectorModal';
 export const ComposeSubchannelModalRouteName = 'ComposeSubchannelModal';
 export const ComposeSubchannelRouteName = 'ComposeSubchannel';
 export const CommunityDrawerNavigatorRouteName = 'CommunityDrawerNavigator';
 export const CustomServerModalRouteName = 'CustomServerModal';
 export const DefaultNotificationsPreferencesRouteName = 'DefaultNotifications';
 export const DeleteAccountRouteName = 'DeleteAccount';
 export const DeleteThreadRouteName = 'DeleteThread';
 export const DevToolsRouteName = 'DevTools';
 export const EditPasswordRouteName = 'EditPassword';
 export const EmojiThreadAvatarCreationRouteName = 'EmojiThreadAvatarCreation';
 export const EmojiUserAvatarCreationRouteName = 'EmojiUserAvatarCreation';
 export const FriendListRouteName = 'FriendList';
 export const FullScreenThreadMediaGalleryRouteName =
   'FullScreenThreadMediaGallery';
 export const HomeChatThreadListRouteName = 'HomeChatThreadList';
 export const ImageModalRouteName = 'ImageModal';
 export const ImagePasteModalRouteName = 'ImagePasteModal';
 export const InviteLinkModalRouteName = 'InviteLinkModal';
 export const InviteLinkNavigatorRouteName = 'InviteLinkNavigator';
 export const LinkedDevicesRouteName = 'LinkedDevices';
 export const LinkedDevicesBottomSheetRouteName = 'LinkedDevicesBottomSheet';
 export const LoggedOutModalRouteName = 'LoggedOutModal';
 export const ManagePublicLinkRouteName = 'ManagePublicLink';
 export const MessageListRouteName = 'MessageList';
 export const MessageReactionsModalRouteName = 'MessageReactionsModal';
 export const PinnedMessagesScreenRouteName = 'PinnedMessagesScreen';
 export const MultimediaMessageTooltipModalRouteName =
   'MultimediaMessageTooltipModal';
 export const PrivacyPreferencesRouteName = 'PrivacyPreferences';
 export const ProfileRouteName = 'Profile';
 export const ProfileScreenRouteName = 'ProfileScreen';
 export const UserRelationshipTooltipModalRouteName =
   'UserRelationshipTooltipModal';
 export const RobotextMessageTooltipModalRouteName =
   'RobotextMessageTooltipModal';
 export const SecondaryDeviceQRCodeScannerRouteName =
   'SecondaryDeviceQRCodeScanner';
 export const SidebarListModalRouteName = 'SidebarListModal';
 export const SubchannelsListModalRouteName = 'SubchannelsListModal';
 export const TabNavigatorRouteName = 'TabNavigator';
 export const TextMessageTooltipModalRouteName = 'TextMessageTooltipModal';
 export const ThreadAvatarCameraModalRouteName = 'ThreadAvatarCameraModal';
 export const ThreadPickerModalRouteName = 'ThreadPickerModal';
 export const ThreadSettingsMemberTooltipModalRouteName =
   'ThreadSettingsMemberTooltipModal';
 export const ThreadSettingsRouteName = 'ThreadSettings';
 export const TunnelbrokerMenuRouteName = 'TunnelbrokerMenu';
 export const UserAvatarCameraModalRouteName = 'UserAvatarCameraModal';
 export const TogglePinModalRouteName = 'TogglePinModal';
 export const VideoPlaybackModalRouteName = 'VideoPlaybackModal';
 export const ViewInviteLinksRouteName = 'ViewInviteLinks';
 export const TermsAndPrivacyRouteName = 'TermsAndPrivacyModal';
 export const AuthRouteName = 'Auth';
 export const KeyserverSelectionRouteName = 'KeyserverSelection';
 export const CoolOrNerdModeSelectionRouteName = 'CoolOrNerdModeSelection';
 export const ConnectEthereumRouteName = 'ConnectEthereum';
 export const CreateSIWEBackupMessageRouteName = 'CreateSIWEBackupMessage';
 export const CreateMissingSIWEBackupMessageRouteName =
   'CreateMissingSIWEBackupMessage';
 export const RestoreSIWEBackupRouteName = 'RestoreSIWEBackup';
 export const ExistingEthereumAccountRouteName = 'ExistingEthereumAccount';
 export const ConnectFarcasterRouteName = 'ConnectFarcaster';
 export const UsernameSelectionRouteName = 'UsernameSelection';
 export const CommunityCreationRouteName = 'CommunityCreation';
 export const CommunityConfigurationRouteName = 'CommunityConfiguration';
 export const MessageSearchRouteName = 'MessageSearch';
 export const PasswordSelectionRouteName = 'PasswordSelection';
 export const AvatarSelectionRouteName = 'AvatarSelection';
 export const EmojiAvatarSelectionRouteName = 'EmojiAvatarSelection';
 export const RegistrationUserAvatarCameraModalRouteName =
   'RegistrationUserAvatarCameraModal';
 export const RegistrationTermsRouteName = 'RegistrationTerms';
 export const RolesNavigatorRouteName = 'RolesNavigator';
 export const CommunityRolesScreenRouteName = 'CommunityRolesScreen';
 export const CreateRolesScreenRouteName = 'CreateRolesScreen';
 export const QRCodeScreenRouteName = 'QRCodeScreen';
 export const RestorePromptScreenRouteName = 'RestorePromptScreen';
 export const RestorePasswordAccountScreenRouteName =
   'RestorePasswordAccountScreen';
 export const RestoreBackupScreenRouteName = 'RestoreBackupScreen';
 export const UserProfileBottomSheetNavigatorRouteName =
   'UserProfileBottomSheetNavigator';
 export const UserProfileBottomSheetRouteName = 'UserProfileBottomSheet';
 export const UserProfileAvatarModalRouteName = 'UserProfileAvatarModal';
 export const KeyserverSelectionListRouteName = 'KeyserverSelectionList';
 export const AddKeyserverRouteName = 'AddKeyserver';
 export const KeyserverSelectionBottomSheetRouteName =
   'KeyserverSelectionBottomSheet';
 export const AccountDoesNotExistRouteName = 'AccountDoesNotExist';
 export const FarcasterAccountSettingsRouteName = 'FarcasterAccountSettings';
 export const ConnectFarcasterBottomSheetRouteName =
   'ConnectFarcasterBottomSheet';
 export const DirectoryPromptBottomSheetRouteName = 'DirectoryPromptBottomSheet';
 export const CommunityJoinerModalRouteName = 'CommunityJoinerModal';
 export const TagFarcasterChannelNavigatorRouteName =
   'TagFarcasterChannelNavigator';
 export const TagFarcasterChannelRouteName = 'TagFarcasterChannel';
 export const TagFarcasterChannelByNameRouteName = 'TagFarcasterChannelByName';
 export const ThreadSettingsNotificationsRouteName =
   'ThreadSettingsNotifications';
 export const IntroTipRouteName = 'IntroTip';
 export const CommunityDrawerTipRouteName = 'CommunityDrawerTip';
 export const HomeTabTipRouteName = 'HomeTabTip';
 export const MutedTabTipRouteName = 'MutedTabTip';
 export const NUXTipOverlayBackdropRouteName = 'NUXTipOverlayBackdrop';
 export const QRAuthNavigatorRouteName = 'QRAuthNavigator';
 export const QRAuthNotPrimaryDeviceRouteName = 'QRAuthNotPrimaryDevice';
 export const ConnectSecondaryDeviceRouteName = 'ConnectSecondaryDevice';
 export const SecondaryDeviceConnectedRouteName = 'SecondaryDeviceConnected';
 export const SecondaryDeviceNotRespondingRouteName =
   'SecondaryDeviceNotResponding';
+export const DebugLogsScreenRouteName = 'DebugLogsScreen';
 
 export type RootParamList = {
   +LoggedOutModal: void,
   +App: void,
   +ThreadPickerModal: ThreadPickerModalParams,
   +AddUsersModal: AddUsersModalParams,
   +CustomServerModal: CustomServerModalParams,
   +ColorSelectorModal: ColorSelectorModalParams,
   +ComposeSubchannelModal: ComposeSubchannelModalParams,
   +SidebarListModal: SidebarListModalParams,
   +ImagePasteModal: ImagePasteModalParams,
   +TermsAndPrivacyModal: TermsAndPrivacyModalParams,
   +SubchannelsListModal: SubchannelListModalParams,
   +MessageReactionsModal: MessageReactionsModalParams,
   +Auth: void,
   +CommunityCreation: void,
   +InviteLinkModal: InviteLinkModalParams,
   +InviteLinkNavigator: InviteLinksNavigatorParams,
   +RolesNavigator: void,
   +UserProfileBottomSheetNavigator: void,
   +TunnelbrokerMenu: void,
   +KeyserverSelectionBottomSheet: KeyserverSelectionBottomSheetParams,
   +LinkedDevicesBottomSheet: LinkedDevicesBottomSheetParams,
   +ConnectFarcasterBottomSheet: void,
   +DirectoryPromptBottomSheet: void,
   +CommunityJoinerModal: CommunityJoinerModalParams,
   +TagFarcasterChannelNavigator: void,
   +CreateMissingSIWEBackupMessage: void,
   +QRAuthNavigator: void,
 };
 
 export type NUXTipRouteNames =
   | typeof IntroTipRouteName
   | typeof CommunityDrawerTipRouteName
   | typeof HomeTabTipRouteName
   | typeof MutedTabTipRouteName;
 
 export type MessageTooltipRouteNames =
   | typeof RobotextMessageTooltipModalRouteName
   | typeof MultimediaMessageTooltipModalRouteName
   | typeof TextMessageTooltipModalRouteName;
 
 export const PinnableMessageTooltipRouteNames = [
   TextMessageTooltipModalRouteName,
   MultimediaMessageTooltipModalRouteName,
 ];
 
 export type TooltipModalParamList = {
   +MultimediaMessageTooltipModal: MultimediaMessageTooltipModalParams,
   +TextMessageTooltipModal: TextMessageTooltipModalParams,
   +ThreadSettingsMemberTooltipModal: ThreadSettingsMemberTooltipModalParams,
   +UserRelationshipTooltipModal: UserRelationshipTooltipModalParams,
   +RobotextMessageTooltipModal: RobotextMessageTooltipModalParams,
 };
 
 export type OverlayParamList = {
   +CommunityDrawerNavigator: void,
   +ImageModal: ImageModalParams,
   +ActionResultModal: ActionResultModalParams,
   +ChatCameraModal: ChatCameraModalParams,
   +UserAvatarCameraModal: void,
   +ThreadAvatarCameraModal: ThreadAvatarCameraModalParams,
   +VideoPlaybackModal: VideoPlaybackModalParams,
   +TogglePinModal: TogglePinModalParams,
   +IntroTip: NUXTipsOverlayParams,
   +CommunityDrawerTip: NUXTipsOverlayParams,
   +HomeTabTip: NUXTipsOverlayParams,
   +MutedTabTip: NUXTipsOverlayParams,
   +NUXTipOverlayBackdrop: void,
   ...TooltipModalParamList,
 };
 
 export type TabParamList = {
   +Calendar: void,
   +Chat: void,
   +Profile: void,
   +Apps: void,
 };
 
 export type ChatParamList = {
   +ChatThreadList: void,
   +MessageList: MessageListParams,
   +ComposeSubchannel: ComposeSubchannelParams,
   +ThreadSettings: ThreadSettingsParams,
   +EmojiThreadAvatarCreation: EmojiThreadAvatarCreationParams,
   +DeleteThread: DeleteThreadParams,
   +FullScreenThreadMediaGallery: FullScreenThreadMediaGalleryParams,
   +PinnedMessagesScreen: PinnedMessagesScreenParams,
   +MessageSearch: MessageSearchParams,
   +ChangeRolesScreen: ChangeRolesScreenParams,
   +ThreadSettingsNotifications: ThreadSettingsNotificationsParams,
 };
 
 export type ChatTopTabsParamList = {
   +HomeChatThreadList: void,
   +BackgroundChatThreadList: void,
 };
 
 export type ProfileParamList = {
   +ProfileScreen: void,
   +EmojiUserAvatarCreation: void,
   +EditPassword: void,
   +DeleteAccount: void,
   +BuildInfo: void,
   +DevTools: void,
   +AppearancePreferences: void,
   +PrivacyPreferences: void,
   +DefaultNotifications: void,
   +FriendList: void,
   +BlockList: void,
   +LinkedDevices: void,
   +BackupMenu: void,
   +TunnelbrokerMenu: void,
   +KeyserverSelectionList: void,
   +AddKeyserver: void,
   +FarcasterAccountSettings: void,
+  +DebugLogsScreen: void,
 };
 
 export type CalendarParamList = {
   +CalendarScreen: void,
 };
 
 export type CommunityDrawerParamList = { +TabNavigator: void };
 
 export type AuthParamList = {
   +CoolOrNerdModeSelection: void,
   +KeyserverSelection: KeyserverSelectionParams,
   +ConnectEthereum: ConnectEthereumParams,
   +ExistingEthereumAccount: ExistingEthereumAccountParams,
   +ConnectFarcaster: ConnectFarcasterParams,
   +CreateSIWEBackupMessage: CreateSIWEBackupMessageParams,
   +UsernameSelection: UsernameSelectionParams,
   +PasswordSelection: PasswordSelectionParams,
   +AvatarSelection: AvatarSelectionParams,
   +EmojiAvatarSelection: EmojiAvatarSelectionParams,
   +RegistrationUserAvatarCameraModal: void,
   +RegistrationTerms: RegistrationTermsParams,
   +AccountDoesNotExist: void,
   +QRCodeScreen: void,
   +RestorePromptScreen: void,
   +RestorePasswordAccountScreen: void,
   +RestoreBackupScreen: RestoreBackupScreenParams,
   +RestoreSIWEBackup: RestoreSIWEBackupParams,
 };
 
 export type InviteLinkParamList = {
   +ViewInviteLinks: ViewInviteLinksScreenParams,
   +ManagePublicLink: ManagePublicLinkScreenParams,
 };
 
 export type CommunityCreationParamList = {
   +CommunityConfiguration: void,
 };
 
 export type RolesParamList = {
   +CommunityRolesScreen: CommunityRolesScreenParams,
   +CreateRolesScreen: CreateRolesScreenParams,
 };
 
 export type TagFarcasterChannelParamList = {
   +TagFarcasterChannel: TagFarcasterChannelParams,
   +TagFarcasterChannelByName: TagFarcasterChannelByNameParams,
 };
 
 export type UserProfileBottomSheetParamList = {
   +UserProfileBottomSheet: UserProfileBottomSheetParams,
   +UserProfileAvatarModal: UserProfileAvatarModalParams,
   +UserRelationshipTooltipModal: UserRelationshipTooltipModalParams,
 };
 
 export type QRAuthNavigatorParamList = {
   +SecondaryDeviceQRCodeScanner: void,
   +QRAuthNotPrimaryDevice: void,
   +ConnectSecondaryDevice: ConnectSecondaryDeviceParams,
   +SecondaryDeviceConnected: void,
   +SecondaryDeviceNotResponding: void,
 };
 
 export type ScreenParamList = {
   ...RootParamList,
   ...OverlayParamList,
   ...TabParamList,
   ...ChatParamList,
   ...ChatTopTabsParamList,
   ...ProfileParamList,
   ...CalendarParamList,
   ...CommunityDrawerParamList,
   ...AuthParamList,
   ...InviteLinkParamList,
   ...CommunityCreationParamList,
   ...RolesParamList,
   ...UserProfileBottomSheetParamList,
   ...TagFarcasterChannelParamList,
   ...QRAuthNavigatorParamList,
 };
 
 export type NavigationRoute<RouteName: string = $Keys<ScreenParamList>> =
   RouteProp<ScreenParamList, RouteName>;
 
 export const accountModals = [LoggedOutModalRouteName, AuthRouteName];
 
 export const scrollBlockingModals = [
   ImageModalRouteName,
   MultimediaMessageTooltipModalRouteName,
   TextMessageTooltipModalRouteName,
   ThreadSettingsMemberTooltipModalRouteName,
   UserRelationshipTooltipModalRouteName,
   RobotextMessageTooltipModalRouteName,
   VideoPlaybackModalRouteName,
 ];
 
 export const chatRootModals = [
   AddUsersModalRouteName,
   ColorSelectorModalRouteName,
   ComposeSubchannelModalRouteName,
 ];
 
 export const threadRoutes = [
   MessageListRouteName,
   ThreadSettingsRouteName,
   DeleteThreadRouteName,
   ComposeSubchannelRouteName,
   FullScreenThreadMediaGalleryRouteName,
   PinnedMessagesScreenRouteName,
   MessageSearchRouteName,
   EmojiThreadAvatarCreationRouteName,
   CommunityRolesScreenRouteName,
   ThreadSettingsNotificationsRouteName,
 ];
diff --git a/native/profile/debug-logs-screen.react.js b/native/profile/debug-logs-screen.react.js
new file mode 100644
index 000000000..339dcd3e3
--- /dev/null
+++ b/native/profile/debug-logs-screen.react.js
@@ -0,0 +1,82 @@
+// @flow
+
+import Clipboard from '@react-native-clipboard/clipboard';
+import * as React from 'react';
+import { FlatList, View, Text } from 'react-native';
+
+import {
+  useDebugLogs,
+  type DebugLog,
+} from 'lib/components/debug-logs-context.js';
+
+import type { ProfileNavigationProp } from './profile.react.js';
+import PrimaryButton from '../components/primary-button.react.js';
+import type { NavigationRoute } from '../navigation/route-names.js';
+import { useStyles } from '../themes/colors.js';
+
+type Props = {
+  +navigation: ProfileNavigationProp<'DebugLogsScreen'>,
+  +route: NavigationRoute<'DebugLogsScreen'>,
+};
+
+// eslint-disable-next-line no-unused-vars
+function DebugLogsScreen(props: Props): React.Node {
+  const { logs, clearLogs } = useDebugLogs();
+
+  const copyLogs = React.useCallback(() => {
+    Clipboard.setString(JSON.stringify(logs));
+  }, [logs]);
+
+  const styles = useStyles(unboundStyles);
+
+  const renderItem = React.useCallback(
+    ({ item }: { +item: DebugLog, ... }) => {
+      const date = new Date(item.timestamp);
+      const timestampString = date.toISOString();
+      return (
+        <View style={styles.item}>
+          <Text style={styles.timestamp}>{timestampString}</Text>
+          <Text style={styles.title}>{item.title}</Text>
+          <Text style={styles.message}>{item.message}</Text>
+        </View>
+      );
+    },
+    [styles.item, styles.message, styles.timestamp, styles.title],
+  );
+
+  return (
+    <View style={styles.view}>
+      <FlatList data={logs} renderItem={renderItem} />
+      <PrimaryButton onPress={clearLogs} variant="danger" label="Clear Logs" />
+      <PrimaryButton onPress={copyLogs} variant="enabled" label="Copy Logs" />
+    </View>
+  );
+}
+
+const unboundStyles = {
+  view: {
+    flex: 1,
+    backgroundColor: 'panelBackground',
+    padding: 24,
+  },
+  item: {
+    backgroundColor: 'panelForeground',
+    borderWidth: 1,
+    borderTopWidth: 1,
+    borderColor: 'panelForegroundBorder',
+    marginBottom: 8,
+    padding: 8,
+  },
+  timestamp: {
+    color: 'panelForegroundLabel',
+  },
+  title: {
+    color: 'panelForegroundLabel',
+    fontSize: 16,
+  },
+  message: {
+    color: 'panelForegroundSecondaryLabel',
+  },
+};
+
+export default DebugLogsScreen;
diff --git a/native/profile/profile-screen.react.js b/native/profile/profile-screen.react.js
index 8d92e968f..d98a9f958 100644
--- a/native/profile/profile-screen.react.js
+++ b/native/profile/profile-screen.react.js
@@ -1,641 +1,652 @@
 // @flow
 
 import invariant from 'invariant';
 import * as React from 'react';
 import { View, Text, Platform, ScrollView } from 'react-native';
 import uuid from 'uuid';
 
 import {
   logOutActionTypes,
   useBaseLogOut,
   usePrimaryDeviceLogOut,
   useSecondaryDeviceLogOut,
 } from 'lib/actions/user-actions.js';
 import { useStringForUser } from 'lib/hooks/ens-cache.js';
 import { useCheckIfPrimaryDevice } from 'lib/hooks/primary-device-hooks.js';
 import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
 import { accountHasPassword } from 'lib/shared/account-utils.js';
 import {
   type OutboundDMOperationSpecification,
   dmOperationSpecificationTypes,
 } from 'lib/shared/dm-ops/dm-op-utils.js';
 import { useProcessAndSendDMOperation } from 'lib/shared/dm-ops/process-dm-ops.js';
 import type { LogOutResult } from 'lib/types/account-types.js';
 import type { DMCreateThreadOperation } from 'lib/types/dm-ops';
 import { thickThreadTypes } from 'lib/types/thread-types-enum.js';
 import { type CurrentUserInfo } from 'lib/types/user-types.js';
 import { useCurrentUserFID } from 'lib/utils/farcaster-utils.js';
 import {
   useDispatchActionPromise,
   type DispatchActionPromise,
 } from 'lib/utils/redux-promise-utils.js';
 import {
   usingCommServicesAccessToken,
   useIsRestoreFlowEnabled,
 } from 'lib/utils/services-utils.js';
 
 import type { ProfileNavigationProp } from './profile.react.js';
 import { deleteNativeCredentialsFor } from '../account/native-credentials.js';
 import EditUserAvatar from '../avatars/edit-user-avatar.react.js';
 import Action from '../components/action-row.react.js';
 import Button from '../components/button.react.js';
 import EditSettingButton from '../components/edit-setting-button.react.js';
 import SingleLine from '../components/single-line.react.js';
 import type { NavigationRoute } from '../navigation/route-names.js';
 import {
   EditPasswordRouteName,
   DeleteAccountRouteName,
   BuildInfoRouteName,
   DevToolsRouteName,
   AppearancePreferencesRouteName,
   FriendListRouteName,
   BlockListRouteName,
   PrivacyPreferencesRouteName,
   DefaultNotificationsPreferencesRouteName,
   LinkedDevicesRouteName,
   BackupMenuRouteName,
   KeyserverSelectionListRouteName,
   TunnelbrokerMenuRouteName,
   FarcasterAccountSettingsRouteName,
+  DebugLogsScreenRouteName,
 } from '../navigation/route-names.js';
 import { useSelector } from '../redux/redux-utils.js';
 import { type Colors, useColors, useStyles } from '../themes/colors.js';
 import Alert from '../utils/alert.js';
 import { useShowVersionUnsupportedAlert } from '../utils/hooks.js';
 import { useStaffCanSee } from '../utils/staff-utils.js';
 
 type ProfileRowProps = {
   +content: string,
   +onPress: () => void,
   +danger?: boolean,
 };
 
 function ProfileRow(props: ProfileRowProps): React.Node {
   const { content, onPress, danger } = props;
   return (
     <Action.Row onPress={onPress}>
       <Action.Text danger={danger} content={content} />
       <Action.Icon name="ios-arrow-forward" />
     </Action.Row>
   );
 }
 
 const unboundStyles = {
   avatarSection: {
     alignItems: 'center',
     paddingVertical: 16,
   },
   container: {
     flex: 1,
   },
   content: {
     flex: 1,
   },
   deleteAccountButton: {
     paddingHorizontal: 24,
     paddingVertical: 12,
   },
   editPasswordButton: {
     paddingTop: Platform.OS === 'android' ? 3 : 2,
   },
   header: {
     color: 'panelBackgroundLabel',
     fontSize: 12,
     fontWeight: '400',
     paddingBottom: 3,
     paddingHorizontal: 24,
   },
   label: {
     color: 'panelForegroundTertiaryLabel',
     fontSize: 16,
     paddingRight: 12,
   },
   loggedInLabel: {
     color: 'panelForegroundTertiaryLabel',
     fontSize: 16,
   },
   logOutText: {
     color: 'link',
     fontSize: 16,
     paddingLeft: 6,
   },
   row: {
     flex: 1,
     flexDirection: 'row',
     justifyContent: 'space-between',
   },
   scrollView: {
     backgroundColor: 'panelBackground',
   },
   scrollViewContentContainer: {
     paddingTop: 24,
   },
   paddedRow: {
     flex: 1,
     flexDirection: 'row',
     justifyContent: 'space-between',
     paddingHorizontal: 24,
     paddingVertical: 10,
   },
   section: {
     backgroundColor: 'panelForeground',
     borderBottomWidth: 1,
     borderColor: 'panelForegroundBorder',
     borderTopWidth: 1,
     marginBottom: 24,
     paddingVertical: 1,
   },
   unpaddedSection: {
     backgroundColor: 'panelForeground',
     borderBottomWidth: 1,
     borderColor: 'panelForegroundBorder',
     borderTopWidth: 1,
     marginBottom: 24,
   },
   username: {
     color: 'panelForegroundLabel',
     flex: 1,
   },
   value: {
     color: 'panelForegroundLabel',
     fontSize: 16,
     textAlign: 'right',
   },
 };
 
 type BaseProps = {
   +navigation: ProfileNavigationProp<'ProfileScreen'>,
   +route: NavigationRoute<'ProfileScreen'>,
 };
 type Props = {
   ...BaseProps,
   +currentUserInfo: ?CurrentUserInfo,
   +isPrimaryDevice: boolean,
   +logOutLoading: boolean,
   +colors: Colors,
   +styles: $ReadOnly<typeof unboundStyles>,
   +dispatchActionPromise: DispatchActionPromise,
   +logOut: () => Promise<LogOutResult>,
   +logOutPrimaryDevice: () => Promise<LogOutResult>,
   +logOutSecondaryDevice: () => Promise<LogOutResult>,
   +staffCanSee: boolean,
   +stringForUser: ?string,
   +isAccountWithPassword: boolean,
   +onCreateDMThread: () => Promise<void>,
   +currentUserFID: ?string,
   +usingRestoreFlow: boolean,
 };
 
 class ProfileScreen extends React.PureComponent<Props> {
   get loggedOutOrLoggingOut(): boolean {
     return (
       !this.props.currentUserInfo ||
       this.props.currentUserInfo.anonymous ||
       this.props.logOutLoading
     );
   }
 
   render(): React.Node {
     let developerTools,
       defaultNotifications,
       keyserverSelection,
-      tunnelbrokerMenu;
+      tunnelbrokerMenu,
+      debugLogs;
     const { staffCanSee } = this.props;
     if (staffCanSee) {
       developerTools = (
         <ProfileRow content="Developer tools" onPress={this.onPressDevTools} />
       );
 
       defaultNotifications = (
         <ProfileRow
           content="Default Notifications"
           onPress={this.onPressDefaultNotifications}
         />
       );
 
       keyserverSelection = (
         <ProfileRow
           content="Keyservers"
           onPress={this.onPressKeyserverSelection}
         />
       );
 
       tunnelbrokerMenu = (
         <ProfileRow
           content="Tunnelbroker menu"
           onPress={this.onPressTunnelbrokerMenu}
         />
       );
+
+      debugLogs = (
+        <ProfileRow content="Debug logs" onPress={this.onPressDebugLogs} />
+      );
     }
 
     let backupMenu;
     if (staffCanSee) {
       backupMenu = (
         <ProfileRow content="Backup menu" onPress={this.onPressBackupMenu} />
       );
     }
 
     let passwordEditionUI;
     if (
       accountHasPassword(this.props.currentUserInfo) &&
       this.props.isPrimaryDevice
     ) {
       passwordEditionUI = (
         <Action.Row>
           <Text style={this.props.styles.label}>Password</Text>
           <Text
             style={[this.props.styles.content, this.props.styles.value]}
             numberOfLines={1}
           >
             ••••••••••••••••
           </Text>
           <EditSettingButton
             onPress={this.onPressEditPassword}
             canChangeSettings={true}
             style={this.props.styles.editPasswordButton}
           />
         </Action.Row>
       );
     }
 
     let linkedDevices;
     if (this.props.usingRestoreFlow) {
       linkedDevices = (
         <ProfileRow content="Linked devices" onPress={this.onPressDevices} />
       );
     }
 
     let farcasterAccountSettings;
     if (usingCommServicesAccessToken || __DEV__) {
       farcasterAccountSettings = (
         <ProfileRow
           content="Farcaster account"
           onPress={this.onPressFaracsterAccount}
         />
       );
     }
 
     let dmActions;
     if (staffCanSee) {
       dmActions = (
         <>
           <ProfileRow
             content="Create a new local DM thread"
             onPress={this.onPressCreateThread}
           />
         </>
       );
     }
 
     return (
       <View style={this.props.styles.container}>
         <ScrollView
           contentContainerStyle={this.props.styles.scrollViewContentContainer}
           style={this.props.styles.scrollView}
         >
           <Text style={this.props.styles.header}>USER AVATAR</Text>
           <View
             style={[this.props.styles.section, this.props.styles.avatarSection]}
           >
             <EditUserAvatar
               userID={this.props.currentUserInfo?.id}
               fid={this.props.currentUserFID}
             />
           </View>
           <Text style={this.props.styles.header}>ACCOUNT</Text>
           <View style={this.props.styles.section}>
             <Action.Row>
               <Text style={this.props.styles.loggedInLabel}>Logged in as </Text>
               <SingleLine
                 style={[this.props.styles.label, this.props.styles.username]}
               >
                 {this.props.stringForUser}
               </SingleLine>
               <Button
                 onPress={this.onPressLogOut}
                 disabled={this.loggedOutOrLoggingOut}
               >
                 <Text style={this.props.styles.logOutText}>Log out</Text>
               </Button>
             </Action.Row>
             {passwordEditionUI}
           </View>
           <View style={this.props.styles.section}>
             <ProfileRow
               content="Friend list"
               onPress={this.onPressFriendList}
             />
             <ProfileRow content="Block list" onPress={this.onPressBlockList} />
           </View>
           <Text style={this.props.styles.header}>PREFERENCES</Text>
           <View style={this.props.styles.section}>
             <ProfileRow content="Appearance" onPress={this.onPressAppearance} />
             <ProfileRow content="Privacy" onPress={this.onPressPrivacy} />
             {defaultNotifications}
             {backupMenu}
             {tunnelbrokerMenu}
           </View>
           <View style={this.props.styles.section}>
             {farcasterAccountSettings}
             {linkedDevices}
             {keyserverSelection}
             <ProfileRow content="Build info" onPress={this.onPressBuildInfo} />
             {developerTools}
             {dmActions}
+            {debugLogs}
           </View>
           <View style={this.props.styles.unpaddedSection}>
             <ProfileRow
               content="Delete account..."
               danger
               onPress={this.onPressDeleteAccount}
             />
           </View>
         </ScrollView>
       </View>
     );
   }
 
   onPressLogOut = () => {
     if (this.loggedOutOrLoggingOut) {
       return;
     }
     if (this.props.usingRestoreFlow) {
       this.onPressNewLogout();
       return;
     }
 
     if (!this.props.isAccountWithPassword) {
       Alert.alert(
         'Log out',
         'Are you sure you want to log out?',
         [
           { text: 'No', style: 'cancel' },
           {
             text: 'Yes',
             onPress: this.logOutWithoutDeletingNativeCredentialsWrapper,
             style: 'destructive',
           },
         ],
         { cancelable: true },
       );
       return;
     }
     const alertTitle =
       Platform.OS === 'ios' ? 'Keep Login Info in Keychain' : 'Keep Login Info';
     const alertDescription =
       'We will automatically fill out log-in forms with your credentials ' +
       'in the app.';
     Alert.alert(
       alertTitle,
       alertDescription,
       [
         { text: 'Cancel', style: 'cancel' },
         {
           text: 'Keep',
           onPress: this.logOutWithoutDeletingNativeCredentialsWrapper,
         },
         {
           text: 'Remove',
           onPress: this.logOutAndDeleteNativeCredentialsWrapper,
           style: 'destructive',
         },
       ],
       { cancelable: true },
     );
   };
 
   onPressNewLogout = () => {
     void (async () => {
       if (this.loggedOutOrLoggingOut) {
         return;
       }
 
       let alertTitle, alertMessage, onPressAction;
       if (this.props.isPrimaryDevice) {
         alertTitle = 'Log out all devices?';
         alertMessage =
           'This device is your primary device, ' +
           'so logging out will cause all of your other devices to log out too.';
         onPressAction = this.logOutPrimaryDevice;
       } else {
         alertTitle = 'Log out?';
         alertMessage = 'Are you sure you want to log out of this device?';
         onPressAction = this.logOutSecondaryDevice;
       }
 
       Alert.alert(
         alertTitle,
         alertMessage,
         [
           { text: 'No', style: 'cancel' },
           {
             text: 'Yes',
             onPress: onPressAction,
             style: 'destructive',
           },
         ],
         { cancelable: true },
       );
     })();
   };
 
   logOutWithoutDeletingNativeCredentialsWrapper = () => {
     if (this.loggedOutOrLoggingOut) {
       return;
     }
     this.logOut();
   };
 
   logOutAndDeleteNativeCredentialsWrapper = async () => {
     if (this.loggedOutOrLoggingOut) {
       return;
     }
     await this.deleteNativeCredentials();
     this.logOut();
   };
 
   logOut() {
     void this.props.dispatchActionPromise(
       logOutActionTypes,
       this.props.logOut(),
     );
   }
 
   logOutPrimaryDevice = async () => {
     if (this.loggedOutOrLoggingOut) {
       return;
     }
     void this.props.dispatchActionPromise(
       logOutActionTypes,
       this.props.logOutPrimaryDevice(),
     );
   };
 
   logOutSecondaryDevice = async () => {
     if (this.loggedOutOrLoggingOut) {
       return;
     }
     void this.props.dispatchActionPromise(
       logOutActionTypes,
       this.props.logOutSecondaryDevice(),
     );
   };
 
   async deleteNativeCredentials() {
     await deleteNativeCredentialsFor();
   }
 
   onPressEditPassword = () => {
     this.props.navigation.navigate({ name: EditPasswordRouteName });
   };
 
   onPressDeleteAccount = () => {
     this.props.navigation.navigate({ name: DeleteAccountRouteName });
   };
 
   onPressFaracsterAccount = () => {
     this.props.navigation.navigate({ name: FarcasterAccountSettingsRouteName });
   };
 
   onPressDevices = () => {
     this.props.navigation.navigate({ name: LinkedDevicesRouteName });
   };
 
   onPressBuildInfo = () => {
     this.props.navigation.navigate({ name: BuildInfoRouteName });
   };
 
   onPressDevTools = () => {
     this.props.navigation.navigate({ name: DevToolsRouteName });
   };
 
   onPressAppearance = () => {
     this.props.navigation.navigate({ name: AppearancePreferencesRouteName });
   };
 
   onPressPrivacy = () => {
     this.props.navigation.navigate({ name: PrivacyPreferencesRouteName });
   };
 
   onPressDefaultNotifications = () => {
     this.props.navigation.navigate({
       name: DefaultNotificationsPreferencesRouteName,
     });
   };
 
   onPressFriendList = () => {
     this.props.navigation.navigate({ name: FriendListRouteName });
   };
 
   onPressBlockList = () => {
     this.props.navigation.navigate({ name: BlockListRouteName });
   };
 
   onPressBackupMenu = () => {
     this.props.navigation.navigate({ name: BackupMenuRouteName });
   };
 
   onPressTunnelbrokerMenu = () => {
     this.props.navigation.navigate({ name: TunnelbrokerMenuRouteName });
   };
 
   onPressKeyserverSelection = () => {
     this.props.navigation.navigate({ name: KeyserverSelectionListRouteName });
   };
 
   onPressCreateThread = () => {
     void this.props.onCreateDMThread();
   };
+
+  onPressDebugLogs = () => {
+    this.props.navigation.navigate({ name: DebugLogsScreenRouteName });
+  };
 }
 
 const logOutLoadingStatusSelector =
   createLoadingStatusSelector(logOutActionTypes);
 
 const ConnectedProfileScreen: React.ComponentType<BaseProps> =
   React.memo<BaseProps>(function ConnectedProfileScreen(props: BaseProps) {
     const currentUserInfo = useSelector(state => state.currentUserInfo);
     const logOutLoading =
       useSelector(logOutLoadingStatusSelector) === 'loading';
     const colors = useColors();
     const styles = useStyles(unboundStyles);
     const callPrimaryDeviceLogOut = usePrimaryDeviceLogOut();
     const callSecondaryDeviceLogOut = useSecondaryDeviceLogOut();
     const dispatchActionPromise = useDispatchActionPromise();
     const staffCanSee = useStaffCanSee();
     const stringForUser = useStringForUser(currentUserInfo);
     const isAccountWithPassword = useSelector(state =>
       accountHasPassword(state.currentUserInfo),
     );
     const currentUserID = useCurrentUserFID();
     const [isPrimaryDevice, setIsPrimaryDevice] = React.useState(false);
     const checkIfPrimaryDevice = useCheckIfPrimaryDevice();
 
     const showVersionUnsupportedAlert = useShowVersionUnsupportedAlert(false);
     const legacyLogOutOptions = React.useMemo(
       () => ({
         logOutType: 'legacy',
         handleUseNewFlowResponse: showVersionUnsupportedAlert,
       }),
       [showVersionUnsupportedAlert],
     );
     const callLegayLogOut = useBaseLogOut(legacyLogOutOptions);
 
     const userID = useSelector(
       state => state.currentUserInfo && state.currentUserInfo.id,
     );
     const processAndSendDMOperation = useProcessAndSendDMOperation();
 
     const onCreateDMThread = React.useCallback(async () => {
       invariant(userID, 'userID should be set');
       const op: DMCreateThreadOperation = {
         type: 'create_thread',
         threadID: uuid.v4(),
         creatorID: userID,
         time: Date.now(),
         threadType: thickThreadTypes.LOCAL,
         memberIDs: [],
         roleID: uuid.v4(),
         newMessageID: uuid.v4(),
       };
       const specification: OutboundDMOperationSpecification = {
         type: dmOperationSpecificationTypes.OUTBOUND,
         op,
         recipients: {
           type: 'self_devices',
         },
       };
       await processAndSendDMOperation(specification);
     }, [processAndSendDMOperation, userID]);
 
     React.useEffect(() => {
       void (async () => {
         const checkIfPrimaryDeviceResult = await checkIfPrimaryDevice();
         setIsPrimaryDevice(checkIfPrimaryDeviceResult);
       })();
     }, [checkIfPrimaryDevice]);
 
     const usingRestoreFlow = useIsRestoreFlowEnabled();
 
     return (
       <ProfileScreen
         {...props}
         currentUserInfo={currentUserInfo}
         isPrimaryDevice={isPrimaryDevice}
         logOutLoading={logOutLoading}
         colors={colors}
         styles={styles}
         logOut={callLegayLogOut}
         logOutPrimaryDevice={callPrimaryDeviceLogOut}
         logOutSecondaryDevice={callSecondaryDeviceLogOut}
         dispatchActionPromise={dispatchActionPromise}
         staffCanSee={staffCanSee}
         stringForUser={stringForUser}
         isAccountWithPassword={isAccountWithPassword}
         onCreateDMThread={onCreateDMThread}
         currentUserFID={currentUserID}
         usingRestoreFlow={usingRestoreFlow}
       />
     );
   });
 
 export default ConnectedProfileScreen;
diff --git a/native/profile/profile.react.js b/native/profile/profile.react.js
index ace059ec5..0dce268d7 100644
--- a/native/profile/profile.react.js
+++ b/native/profile/profile.react.js
@@ -1,241 +1,249 @@
 // @flow
 
 import type {
   StackNavigationProp,
   StackNavigationHelpers,
   StackHeaderProps,
   StackHeaderLeftButtonProps,
 } from '@react-navigation/core';
 import { createStackNavigator } from '@react-navigation/stack';
 import * as React from 'react';
 import { View, useWindowDimensions } from 'react-native';
 
 import AddKeyserver from './add-keyserver.react.js';
 import AppearancePreferences from './appearance-preferences.react.js';
 import BackupMenu from './backup-menu.react.js';
 import BuildInfo from './build-info.react.js';
+import DebugLogsScreen from './debug-logs-screen.react.js';
 import DefaultNotificationsPreferences from './default-notifications-preferences.react.js';
 import DeleteAccount from './delete-account.react.js';
 import DevTools from './dev-tools.react.js';
 import EditPassword from './edit-password.react.js';
 import EmojiUserAvatarCreation from './emoji-user-avatar-creation.react.js';
 import FarcasterAccountSettings from './farcaster-account-settings.react.js';
 import KeyserverSelectionListHeaderRightButton from './keyserver-selection-list-header-right-button.react.js';
 import KeyserverSelectionList from './keyserver-selection-list.react.js';
 import LinkedDevicesHeaderRightButton from './linked-devices-header-right-button.react.js';
 import LinkedDevices from './linked-devices.react.js';
 import PrivacyPreferences from './privacy-preferences.react.js';
 import ProfileHeader from './profile-header.react.js';
 import ProfileScreen from './profile-screen.react.js';
 import RelationshipList from './relationship-list.react.js';
 import TunnelbrokerMenu from './tunnelbroker-menu.react.js';
 import KeyboardAvoidingView from '../components/keyboard-avoiding-view.react.js';
 import CommunityDrawerButton from '../navigation/community-drawer-button.react.js';
 import HeaderBackButton from '../navigation/header-back-button.react.js';
 import {
   ProfileScreenRouteName,
   EditPasswordRouteName,
   DeleteAccountRouteName,
   EmojiUserAvatarCreationRouteName,
   BuildInfoRouteName,
   DevToolsRouteName,
   AppearancePreferencesRouteName,
   PrivacyPreferencesRouteName,
   FriendListRouteName,
   DefaultNotificationsPreferencesRouteName,
   BlockListRouteName,
   LinkedDevicesRouteName,
   BackupMenuRouteName,
   KeyserverSelectionListRouteName,
   AddKeyserverRouteName,
   FarcasterAccountSettingsRouteName,
   type ScreenParamList,
   type ProfileParamList,
   TunnelbrokerMenuRouteName,
+  DebugLogsScreenRouteName,
 } from '../navigation/route-names.js';
 import type { TabNavigationProp } from '../navigation/tab-navigator.react.js';
 import { useStyles, useColors } from '../themes/colors.js';
 
 const header = (props: StackHeaderProps) => <ProfileHeader {...props} />;
 const profileScreenOptions = { headerTitle: 'Profile' };
 const emojiAvatarCreationOptions = {
   headerTitle: 'Emoji avatar selection',
   headerBackTitleVisible: false,
 };
 const editPasswordOptions = { headerTitle: 'Change password' };
 const deleteAccountOptions = { headerTitle: 'Delete account' };
 const linkedDevicesOptions = {
   headerTitle: 'Linked devices',
   headerRight: () => <LinkedDevicesHeaderRightButton />,
 };
 const keyserverSelectionListOptions = {
   headerTitle: 'Keyservers',
   headerRight: () => <KeyserverSelectionListHeaderRightButton />,
 };
 const addKeyserverOptions = { headerTitle: 'Add keyserver' };
 const backupMenuOptions = { headerTitle: 'Backup menu' };
 const tunnelbrokerMenuOptions = { headerTitle: 'Tunnelbroker menu' };
 const buildInfoOptions = { headerTitle: 'Build info' };
 const devToolsOptions = { headerTitle: 'Developer tools' };
 const appearanceOptions = { headerTitle: 'Appearance' };
 const privacyOptions = { headerTitle: 'Privacy' };
 const friendListOptions = { headerTitle: 'Friend list' };
 const blockListOptions = { headerTitle: 'Block list' };
 const defaultNotificationsOptions = { headerTitle: 'Default Notifications' };
 const farcasterSettingsOptions = { headerTitle: 'Farcaster account' };
+const debugLogsScreenOptions = { headerTitle: 'Logs' };
 
 export type ProfileNavigationProp<
   RouteName: $Keys<ProfileParamList> = $Keys<ProfileParamList>,
 > = StackNavigationProp<ScreenParamList, RouteName>;
 
 const Profile = createStackNavigator<
   ScreenParamList,
   ProfileParamList,
   StackNavigationHelpers<ScreenParamList>,
 >();
 type Props = {
   +navigation: TabNavigationProp<'Profile'>,
   ...
 };
 
 function ProfileComponent(props: Props): React.Node {
   const styles = useStyles(unboundStyles);
   const colors = useColors();
 
   const headerLeftButton = React.useCallback(
     (headerProps: StackHeaderLeftButtonProps) =>
       headerProps.canGoBack ? (
         <HeaderBackButton {...headerProps} />
       ) : (
         <CommunityDrawerButton navigation={props.navigation} />
       ),
     [props.navigation],
   );
 
   const { width: screenWidth } = useWindowDimensions();
   const screenOptions = React.useMemo(
     () => ({
       header,
       headerLeft: headerLeftButton,
       headerStyle: {
         backgroundColor: colors.tabBarBackground,
         shadowOpacity: 0,
       },
       gestureEnabled: true,
       gestureResponseDistance: screenWidth,
     }),
     [colors.tabBarBackground, headerLeftButton, screenWidth],
   );
 
   return (
     <View style={styles.view}>
       <KeyboardAvoidingView
         behavior="padding"
         style={styles.keyboardAvoidingView}
       >
         <Profile.Navigator
           screenOptions={screenOptions}
           detachInactiveScreens={false}
         >
           <Profile.Screen
             name={ProfileScreenRouteName}
             component={ProfileScreen}
             options={profileScreenOptions}
           />
           <Profile.Screen
             name={EmojiUserAvatarCreationRouteName}
             component={EmojiUserAvatarCreation}
             options={emojiAvatarCreationOptions}
           />
           <Profile.Screen
             name={EditPasswordRouteName}
             component={EditPassword}
             options={editPasswordOptions}
           />
           <Profile.Screen
             name={DeleteAccountRouteName}
             component={DeleteAccount}
             options={deleteAccountOptions}
           />
           <Profile.Screen
             name={LinkedDevicesRouteName}
             component={LinkedDevices}
             options={linkedDevicesOptions}
           />
           <Profile.Screen
             name={KeyserverSelectionListRouteName}
             component={KeyserverSelectionList}
             options={keyserverSelectionListOptions}
           />
           <Profile.Screen
             name={AddKeyserverRouteName}
             component={AddKeyserver}
             options={addKeyserverOptions}
           />
           <Profile.Screen
             name={BackupMenuRouteName}
             component={BackupMenu}
             options={backupMenuOptions}
           />
           <Profile.Screen
             name={TunnelbrokerMenuRouteName}
             component={TunnelbrokerMenu}
             options={tunnelbrokerMenuOptions}
           />
           <Profile.Screen
             name={BuildInfoRouteName}
             component={BuildInfo}
             options={buildInfoOptions}
           />
           <Profile.Screen
             name={DevToolsRouteName}
             component={DevTools}
             options={devToolsOptions}
           />
           <Profile.Screen
             name={AppearancePreferencesRouteName}
             component={AppearancePreferences}
             options={appearanceOptions}
           />
           <Profile.Screen
             name={PrivacyPreferencesRouteName}
             component={PrivacyPreferences}
             options={privacyOptions}
           />
           <Profile.Screen
             name={DefaultNotificationsPreferencesRouteName}
             component={DefaultNotificationsPreferences}
             options={defaultNotificationsOptions}
           />
           <Profile.Screen
             name={FriendListRouteName}
             component={RelationshipList}
             options={friendListOptions}
           />
           <Profile.Screen
             name={BlockListRouteName}
             component={RelationshipList}
             options={blockListOptions}
           />
           <Profile.Screen
             name={FarcasterAccountSettingsRouteName}
             component={FarcasterAccountSettings}
             options={farcasterSettingsOptions}
           />
+          <Profile.Screen
+            name={DebugLogsScreenRouteName}
+            component={DebugLogsScreen}
+            options={debugLogsScreenOptions}
+          />
         </Profile.Navigator>
       </KeyboardAvoidingView>
     </View>
   );
 }
 
 const unboundStyles = {
   keyboardAvoidingView: {
     flex: 1,
   },
   view: {
     flex: 1,
     backgroundColor: 'panelBackground',
   },
 };
 
 export default ProfileComponent;
diff --git a/native/root.react.js b/native/root.react.js
index 51644d25b..55f89715a 100644
--- a/native/root.react.js
+++ b/native/root.react.js
@@ -1,447 +1,450 @@
 // @flow
 
 import { ActionSheetProvider } from '@expo/react-native-action-sheet';
 import { BottomSheetModalProvider } from '@gorhom/bottom-sheet';
 import AsyncStorage from '@react-native-async-storage/async-storage';
 import type {
   PossiblyStaleNavigationState,
   UnsafeContainerActionEvent,
   GenericNavigationAction,
 } from '@react-navigation/core';
 import { useReduxDevToolsExtension } from '@react-navigation/devtools';
 import { NavigationContainer } from '@react-navigation/native';
 import * as SplashScreen from 'expo-splash-screen';
 import invariant from 'invariant';
 import * as React from 'react';
 import { StyleSheet } from 'react-native';
 import { GestureHandlerRootView } from 'react-native-gesture-handler';
 import Orientation from 'react-native-orientation-locker';
 import {
   SafeAreaProvider,
   initialWindowMetrics,
 } from 'react-native-safe-area-context';
 import { Provider } from 'react-redux';
 import { PersistGate as ReduxPersistGate } from 'redux-persist/es/integration/react.js';
 
 import { ChatMentionContextProvider } from 'lib/components/chat-mention-provider.react.js';
+import { DebugLogsContextProvider } from 'lib/components/debug-logs-context-provider.react.js';
 import { EditUserAvatarProvider } from 'lib/components/edit-user-avatar-provider.react.js';
 import { ENSCacheProvider } from 'lib/components/ens-cache-provider.react.js';
 import { FarcasterChannelPrefetchHandler } from 'lib/components/farcaster-channel-prefetch-handler.react.js';
 import { FarcasterDataHandler } from 'lib/components/farcaster-data-handler.react.js';
 import { GlobalSearchIndexProvider } from 'lib/components/global-search-index-provider.react.js';
 import IntegrityHandler from 'lib/components/integrity-handler.react.js';
 import { MediaCacheProvider } from 'lib/components/media-cache-provider.react.js';
 import { NeynarClientProvider } from 'lib/components/neynar-client-provider.react.js';
 import PlatformDetailsSynchronizer from 'lib/components/platform-details-synchronizer.react.js';
 import PrekeysHandler from 'lib/components/prekeys-handler.react.js';
 import { SecondaryDeviceQRAuthContextProvider } from 'lib/components/secondary-device-qr-auth-context-provider.react.js';
 import { StaffContextProvider } from 'lib/components/staff-provider.react.js';
 import SyncCommunityStoreHandler from 'lib/components/sync-community-store-handler.react.js';
 import { UserIdentityCacheProvider } from 'lib/components/user-identity-cache.react.js';
 import { DBOpsHandler } from 'lib/handlers/db-ops-handler.react.js';
 import { HoldersHandler } from 'lib/handlers/holders-handler.react.js';
 import { InitialStateSharingHandler } from 'lib/handlers/initial-state-sharing-handler.react.js';
 import { TunnelbrokerDeviceTokenHandler } from 'lib/handlers/tunnelbroker-device-token-handler.react.js';
 import { UserInfosHandler } from 'lib/handlers/user-infos-handler.react.js';
 import { IdentitySearchProvider } from 'lib/identity-search/identity-search-context.js';
 import { CallKeyserverEndpointProvider } from 'lib/keyserver-conn/call-keyserver-endpoint-provider.react.js';
 import KeyserverConnectionsHandler from 'lib/keyserver-conn/keyserver-connections-handler.js';
 import { TunnelbrokerProvider } from 'lib/tunnelbroker/tunnelbroker-context.js';
 import { actionLogger } from 'lib/utils/action-logger.js';
 
 import { RegistrationContextProvider } from './account/registration/registration-context-provider.react.js';
 import NativeEditThreadAvatarProvider from './avatars/native-edit-thread-avatar-provider.react.js';
 import BackupHandler from './backup/backup-handler.js';
 import { BottomSheetProvider } from './bottom-sheet/bottom-sheet-provider.react.js';
 import ChatContextProvider from './chat/chat-context-provider.react.js';
 import MessageEditingContextProvider from './chat/message-editing-context-provider.react.js';
 import AccessTokenHandler from './components/access-token-handler.react.js';
 import { AutoJoinCommunityHandler } from './components/auto-join-community-handler.react.js';
 import BackgroundIdentityLoginHandler from './components/background-identity-login-handler.react.js';
 import ConnectFarcasterAlertHandler from './components/connect-farcaster-alert-handler.react.js';
 import DMActivityHandler from './components/dm-activity-handler.react.js';
 import { FeatureFlagsProvider } from './components/feature-flags-provider.react.js';
 import { NUXTipsContextProvider } from './components/nux-tips-context.react.js';
 import PersistedStateGate from './components/persisted-state-gate.js';
 import ReportHandler from './components/report-handler.react.js';
 import VersionSupportedChecker from './components/version-supported.react.js';
 import ConnectedStatusBar from './connected-status-bar.react.js';
 import { SQLiteDataHandler } from './data/sqlite-data-handler.js';
 import ErrorBoundary from './error-boundary.react.js';
 import IdentityServiceContextProvider from './identity-service/identity-service-context-provider.react.js';
 import InputStateContainer from './input/input-state-container.react.js';
 import LifecycleHandler from './lifecycle/lifecycle-handler.react.js';
 import MarkdownContextProvider from './markdown/markdown-context-provider.react.js';
 import { filesystemMediaCache } from './media/media-cache.js';
 import { DeepLinksContextProvider } from './navigation/deep-links-context-provider.react.js';
 import { defaultNavigationState } from './navigation/default-state.js';
 import { setGlobalNavContext } from './navigation/icky-global.js';
 import KeyserverReachabilityHandler from './navigation/keyserver-reachability-handler.js';
 import {
   NavContext,
   type NavContextType,
 } from './navigation/navigation-context.js';
 import NavigationHandler from './navigation/navigation-handler.react.js';
 import {
   validNavState,
   isShowingNUXTips,
 } from './navigation/navigation-utils.js';
 import OrientationHandler from './navigation/orientation-handler.react.js';
 import { navStateAsyncStorageKey } from './navigation/persistance.js';
 import RootNavigator from './navigation/root-navigator.react.js';
 import ConnectivityUpdater from './redux/connectivity-updater.react.js';
 import { DimensionsUpdater } from './redux/dimensions-updater.react.js';
 import { getPersistor } from './redux/persist.js';
 import { store } from './redux/redux-setup.js';
 import { useSelector } from './redux/redux-utils.js';
 import { RootContext } from './root-context.js';
 import { MessageSearchProvider } from './search/search-provider.react.js';
 import Socket from './socket.react.js';
 import { useLoadCommFonts } from './themes/fonts.js';
 import { DarkTheme, LightTheme } from './themes/navigation.js';
 import ThemeHandler from './themes/theme-handler.react.js';
 import { alchemyKey, ethersProvider } from './utils/ethers-utils.js';
 import { neynarKey } from './utils/neynar-utils.js';
 import {
   composeTunnelbrokerQRAuthMessage,
   handleSecondaryDeviceLogInError,
   parseTunnelbrokerQRAuthMessage,
   performBackupRestore,
   generateQRAuthAESKey,
 } from './utils/qr-code-utils.js';
 
 // Add custom items to expo-dev-menu
 import './dev-menu.js';
 import './types/message-types-validator.js';
 
 const navInitAction = Object.freeze({ type: 'NAV/@@INIT' });
 const navUnknownAction = Object.freeze({ type: 'NAV/@@UNKNOWN' });
 
 SplashScreen.preventAutoHideAsync().catch(console.log);
 
 function Root() {
   const navStateRef = React.useRef<?PossiblyStaleNavigationState>();
   const navDispatchRef =
     React.useRef<?(
       action:
         | GenericNavigationAction
         | (PossiblyStaleNavigationState => GenericNavigationAction),
     ) => void>();
   const navStateInitializedRef = React.useRef(false);
 
   // We call this here to start the loading process
   // We gate the UI on the fonts loading in AppNavigator
   useLoadCommFonts();
 
   const [navContext, setNavContext] = React.useState<?NavContextType>(null);
   const updateNavContext = React.useCallback(() => {
     if (
       !navStateRef.current ||
       !navDispatchRef.current ||
       !navStateInitializedRef.current
     ) {
       return;
     }
     const updatedNavContext = {
       state: navStateRef.current,
       dispatch: navDispatchRef.current,
     };
     setNavContext(updatedNavContext);
     setGlobalNavContext(updatedNavContext);
   }, []);
 
   const [initialState, setInitialState] = React.useState(
     __DEV__ ? undefined : defaultNavigationState,
   );
 
   React.useEffect(() => {
     Orientation.lockToPortrait();
     void (async () => {
       let loadedState = initialState;
       if (__DEV__) {
         try {
           const navStateString = await AsyncStorage.getItem(
             navStateAsyncStorageKey,
           );
           if (navStateString) {
             const savedState = JSON.parse(navStateString);
             if (validNavState(savedState) && !isShowingNUXTips(savedState)) {
               loadedState = savedState;
             }
           }
         } catch {}
       }
       if (!loadedState) {
         loadedState = defaultNavigationState;
       }
       if (loadedState !== initialState) {
         setInitialState(loadedState);
       }
       navStateRef.current = loadedState;
       updateNavContext();
       actionLogger.addOtherAction('navState', navInitAction, null, loadedState);
     })();
     // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [updateNavContext]);
 
   const setNavStateInitialized = React.useCallback(() => {
     navStateInitializedRef.current = true;
     updateNavContext();
   }, [updateNavContext]);
 
   const [rootContext, setRootContext] = React.useState(() => ({
     setNavStateInitialized,
   }));
 
   const detectUnsupervisedBackgroundRef = React.useCallback(
     (detectUnsupervisedBackground: ?(alreadyClosed: boolean) => boolean) => {
       setRootContext(prevRootContext => ({
         ...prevRootContext,
         detectUnsupervisedBackground,
       }));
     },
     [],
   );
 
   const frozen = useSelector(state => state.frozen);
   const queuedActionsRef = React.useRef<Array<GenericNavigationAction>>([]);
   const onNavigationStateChange = React.useCallback(
     (state: ?PossiblyStaleNavigationState) => {
       invariant(state, 'nav state should be non-null');
       const prevState = navStateRef.current;
       navStateRef.current = state;
       updateNavContext();
 
       const queuedActions = queuedActionsRef.current;
       queuedActionsRef.current = [];
       if (queuedActions.length === 0) {
         queuedActions.push(navUnknownAction);
       }
       for (const action of queuedActions) {
         actionLogger.addOtherAction('navState', action, prevState, state);
       }
 
       if (!__DEV__ || frozen) {
         return;
       }
 
       void (async () => {
         try {
           await AsyncStorage.setItem(
             navStateAsyncStorageKey,
             JSON.stringify(state),
           );
         } catch (e) {
           console.log('AsyncStorage threw while trying to persist navState', e);
         }
       })();
     },
     [updateNavContext, frozen],
   );
 
   const navContainerRef =
     React.useRef<?React.ElementRef<typeof NavigationContainer>>();
   const containerRef = React.useCallback(
     (navContainer: ?React.ElementRef<typeof NavigationContainer>) => {
       navContainerRef.current = navContainer;
       if (navContainer && !navDispatchRef.current) {
         navDispatchRef.current = navContainer.dispatch;
         updateNavContext();
       }
     },
     [updateNavContext],
   );
   useReduxDevToolsExtension(navContainerRef);
 
   const navContainer = navContainerRef.current;
   React.useEffect(() => {
     if (!navContainer) {
       return undefined;
     }
     return navContainer.addListener(
       '__unsafe_action__',
       (event: { +data: UnsafeContainerActionEvent, ... }) => {
         const { action, noop } = event.data;
         const navState = navStateRef.current;
         if (noop) {
           actionLogger.addOtherAction('navState', action, navState, navState);
           return;
         }
         queuedActionsRef.current.push({
           ...action,
           type: `NAV/${action.type}`,
         });
       },
     );
   }, [navContainer]);
 
   const activeTheme = useSelector(state => state.globalThemeInfo.activeTheme);
   const theme = (() => {
     if (activeTheme === 'light') {
       return LightTheme;
     } else if (activeTheme === 'dark') {
       return DarkTheme;
     }
     return undefined;
   })();
 
   const gated: React.Node = (
     <>
       <LifecycleHandler />
       <KeyserverReachabilityHandler />
       <DimensionsUpdater />
       <ConnectivityUpdater />
       <ThemeHandler />
       <OrientationHandler />
       <BackupHandler />
       <IntegrityHandler />
       <AccessTokenHandler />
       <DBOpsHandler />
       <UserInfosHandler />
       <TunnelbrokerDeviceTokenHandler />
       <HoldersHandler />
     </>
   );
   let navigation;
   if (initialState) {
     navigation = (
       <NavigationContainer
         initialState={initialState}
         onStateChange={onNavigationStateChange}
         theme={theme}
         ref={containerRef}
       >
         <BottomSheetModalProvider>
           <ChatContextProvider>
             <DeepLinksContextProvider>
               <ChatMentionContextProvider>
                 <GlobalSearchIndexProvider>
                   <NUXTipsContextProvider>
                     <RootNavigator />
                   </NUXTipsContextProvider>
                 </GlobalSearchIndexProvider>
               </ChatMentionContextProvider>
             </DeepLinksContextProvider>
           </ChatContextProvider>
           <NavigationHandler />
           <PersistedStateGate>
             <FarcasterDataHandler>
               <ConnectFarcasterAlertHandler />
             </FarcasterDataHandler>
           </PersistedStateGate>
         </BottomSheetModalProvider>
       </NavigationContainer>
     );
   }
   return (
-    <GestureHandlerRootView style={styles.app}>
-      <StaffContextProvider>
-        <IdentityServiceContextProvider>
-          <UserIdentityCacheProvider>
-            <ENSCacheProvider
-              ethersProvider={ethersProvider}
-              alchemyKey={alchemyKey}
-            >
-              <NeynarClientProvider apiKey={neynarKey}>
-                <TunnelbrokerProvider>
-                  <IdentitySearchProvider>
-                    <SecondaryDeviceQRAuthContextProvider
-                      parseTunnelbrokerQRAuthMessage={
-                        parseTunnelbrokerQRAuthMessage
-                      }
-                      composeTunnelbrokerQRAuthMessage={
-                        composeTunnelbrokerQRAuthMessage
-                      }
-                      generateAESKey={generateQRAuthAESKey}
-                      performBackupRestore={performBackupRestore}
-                      onLogInError={handleSecondaryDeviceLogInError}
-                    >
-                      <FeatureFlagsProvider>
-                        <NavContext.Provider value={navContext}>
-                          <RootContext.Provider value={rootContext}>
-                            <InputStateContainer>
-                              <MessageEditingContextProvider>
-                                <SafeAreaProvider
-                                  initialMetrics={initialWindowMetrics}
-                                >
-                                  <ActionSheetProvider>
-                                    <MediaCacheProvider
-                                      persistence={filesystemMediaCache}
-                                    >
-                                      <EditUserAvatarProvider>
-                                        <NativeEditThreadAvatarProvider>
-                                          <MarkdownContextProvider>
-                                            <MessageSearchProvider>
-                                              <BottomSheetProvider>
-                                                <RegistrationContextProvider>
-                                                  <SQLiteDataHandler />
-                                                  <ConnectedStatusBar />
-                                                  <ReduxPersistGate
-                                                    persistor={getPersistor()}
-                                                  >
-                                                    {gated}
-                                                  </ReduxPersistGate>
-                                                  <PersistedStateGate>
-                                                    <KeyserverConnectionsHandler
-                                                      socketComponent={Socket}
-                                                      detectUnsupervisedBackgroundRef={
-                                                        detectUnsupervisedBackgroundRef
-                                                      }
-                                                    />
-                                                    <DMActivityHandler />
-                                                    <VersionSupportedChecker />
-                                                    <PlatformDetailsSynchronizer />
-                                                    <BackgroundIdentityLoginHandler />
-                                                    <PrekeysHandler />
-                                                    <ReportHandler />
-                                                    <FarcasterChannelPrefetchHandler />
-                                                    <AutoJoinCommunityHandler />
-                                                    <SyncCommunityStoreHandler />
-                                                    <InitialStateSharingHandler />
-                                                  </PersistedStateGate>
-                                                  {navigation}
-                                                </RegistrationContextProvider>
-                                              </BottomSheetProvider>
-                                            </MessageSearchProvider>
-                                          </MarkdownContextProvider>
-                                        </NativeEditThreadAvatarProvider>
-                                      </EditUserAvatarProvider>
-                                    </MediaCacheProvider>
-                                  </ActionSheetProvider>
-                                </SafeAreaProvider>
-                              </MessageEditingContextProvider>
-                            </InputStateContainer>
-                          </RootContext.Provider>
-                        </NavContext.Provider>
-                      </FeatureFlagsProvider>
-                    </SecondaryDeviceQRAuthContextProvider>
-                  </IdentitySearchProvider>
-                </TunnelbrokerProvider>
-              </NeynarClientProvider>
-            </ENSCacheProvider>
-          </UserIdentityCacheProvider>
-        </IdentityServiceContextProvider>
-      </StaffContextProvider>
-    </GestureHandlerRootView>
+    <DebugLogsContextProvider>
+      <GestureHandlerRootView style={styles.app}>
+        <StaffContextProvider>
+          <IdentityServiceContextProvider>
+            <UserIdentityCacheProvider>
+              <ENSCacheProvider
+                ethersProvider={ethersProvider}
+                alchemyKey={alchemyKey}
+              >
+                <NeynarClientProvider apiKey={neynarKey}>
+                  <TunnelbrokerProvider>
+                    <IdentitySearchProvider>
+                      <SecondaryDeviceQRAuthContextProvider
+                        parseTunnelbrokerQRAuthMessage={
+                          parseTunnelbrokerQRAuthMessage
+                        }
+                        composeTunnelbrokerQRAuthMessage={
+                          composeTunnelbrokerQRAuthMessage
+                        }
+                        generateAESKey={generateQRAuthAESKey}
+                        performBackupRestore={performBackupRestore}
+                        onLogInError={handleSecondaryDeviceLogInError}
+                      >
+                        <FeatureFlagsProvider>
+                          <NavContext.Provider value={navContext}>
+                            <RootContext.Provider value={rootContext}>
+                              <InputStateContainer>
+                                <MessageEditingContextProvider>
+                                  <SafeAreaProvider
+                                    initialMetrics={initialWindowMetrics}
+                                  >
+                                    <ActionSheetProvider>
+                                      <MediaCacheProvider
+                                        persistence={filesystemMediaCache}
+                                      >
+                                        <EditUserAvatarProvider>
+                                          <NativeEditThreadAvatarProvider>
+                                            <MarkdownContextProvider>
+                                              <MessageSearchProvider>
+                                                <BottomSheetProvider>
+                                                  <RegistrationContextProvider>
+                                                    <SQLiteDataHandler />
+                                                    <ConnectedStatusBar />
+                                                    <ReduxPersistGate
+                                                      persistor={getPersistor()}
+                                                    >
+                                                      {gated}
+                                                    </ReduxPersistGate>
+                                                    <PersistedStateGate>
+                                                      <KeyserverConnectionsHandler
+                                                        socketComponent={Socket}
+                                                        detectUnsupervisedBackgroundRef={
+                                                          detectUnsupervisedBackgroundRef
+                                                        }
+                                                      />
+                                                      <DMActivityHandler />
+                                                      <VersionSupportedChecker />
+                                                      <PlatformDetailsSynchronizer />
+                                                      <BackgroundIdentityLoginHandler />
+                                                      <PrekeysHandler />
+                                                      <ReportHandler />
+                                                      <FarcasterChannelPrefetchHandler />
+                                                      <AutoJoinCommunityHandler />
+                                                      <SyncCommunityStoreHandler />
+                                                      <InitialStateSharingHandler />
+                                                    </PersistedStateGate>
+                                                    {navigation}
+                                                  </RegistrationContextProvider>
+                                                </BottomSheetProvider>
+                                              </MessageSearchProvider>
+                                            </MarkdownContextProvider>
+                                          </NativeEditThreadAvatarProvider>
+                                        </EditUserAvatarProvider>
+                                      </MediaCacheProvider>
+                                    </ActionSheetProvider>
+                                  </SafeAreaProvider>
+                                </MessageEditingContextProvider>
+                              </InputStateContainer>
+                            </RootContext.Provider>
+                          </NavContext.Provider>
+                        </FeatureFlagsProvider>
+                      </SecondaryDeviceQRAuthContextProvider>
+                    </IdentitySearchProvider>
+                  </TunnelbrokerProvider>
+                </NeynarClientProvider>
+              </ENSCacheProvider>
+            </UserIdentityCacheProvider>
+          </IdentityServiceContextProvider>
+        </StaffContextProvider>
+      </GestureHandlerRootView>
+    </DebugLogsContextProvider>
   );
 }
 
 const styles = StyleSheet.create({
   app: {
     flex: 1,
   },
 });
 
 function AppRoot(): React.Node {
   return (
     <Provider store={store}>
       <CallKeyserverEndpointProvider>
         <ErrorBoundary>
           <Root />
         </ErrorBoundary>
       </CallKeyserverEndpointProvider>
     </Provider>
   );
 }
 
 export default AppRoot;
diff --git a/web/root.js b/web/root.js
index 0fbd30f65..3d2dad0f9 100644
--- a/web/root.js
+++ b/web/root.js
@@ -1,88 +1,91 @@
 // @flow
 
 import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
 import localforage from 'localforage';
 import * as React from 'react';
 import { Provider } from 'react-redux';
 import { Router, Route } from 'react-router';
 import { createStore, applyMiddleware, type Store } from 'redux';
 import { composeWithDevTools } from 'redux-devtools-extension/logOnlyInProduction.js';
 import { persistReducer, persistStore } from 'redux-persist';
 import thunk from 'redux-thunk';
 import { WagmiProvider } from 'wagmi';
 
+import { DebugLogsContextProvider } from 'lib/components/debug-logs-context-provider.react.js';
 import IntegrityHandler from 'lib/components/integrity-handler.react.js';
 import PrekeysHandler from 'lib/components/prekeys-handler.react.js';
 import ReportHandler from 'lib/components/report-handler.react.js';
 import { UserIdentityCacheProvider } from 'lib/components/user-identity-cache.react.js';
 import { CallKeyserverEndpointProvider } from 'lib/keyserver-conn/call-keyserver-endpoint-provider.react.js';
 import { reduxLoggerMiddleware } from 'lib/utils/action-logger.js';
 import { getWagmiConfig } from 'lib/utils/wagmi-utils.js';
 
 import App from './app.react.js';
 import ErrorBoundary from './error-boundary.react.js';
 import IdentityServiceContextProvider from './grpc/identity-service-context-provider.react.js';
 import { defaultWebState } from './redux/default-state.js';
 import InitialReduxStateGate from './redux/initial-state-gate.js';
 import { persistConfig } from './redux/persist.js';
 import { type AppState, type Action, reducer } from './redux/redux-setup.js';
 import {
   synchronizeStoreWithOtherTabs,
   tabSynchronizationMiddleware,
 } from './redux/tab-synchronization.js';
 import history from './router-history.js';
 import { SQLiteDataHandler } from './shared-worker/sqlite-data-handler.js';
 import { localforageConfig } from './shared-worker/utils/constants.js';
 
 localforage.config(localforageConfig);
 
 const persistedReducer = persistReducer(persistConfig, reducer);
 const store: Store<AppState, Action> = createStore(
   persistedReducer,
   defaultWebState,
   composeWithDevTools({
     maxAge: 200,
   })(
     applyMiddleware(thunk, reduxLoggerMiddleware, tabSynchronizationMiddleware),
   ),
 );
 synchronizeStoreWithOtherTabs(store);
 const persistor = persistStore(store);
 
 const queryClient = new QueryClient();
 
 const wagmiConfig = getWagmiConfig([
   'injected',
   'rainbow',
   'metamask',
   'coinbase',
   'walletconnect',
 ]);
 
 const RootProvider = (): React.Node => (
   <Provider store={store}>
     <ErrorBoundary>
-      <WagmiProvider config={wagmiConfig}>
-        <QueryClientProvider client={queryClient}>
-          <CallKeyserverEndpointProvider>
-            <InitialReduxStateGate persistor={persistor}>
-              <IdentityServiceContextProvider>
-                <UserIdentityCacheProvider>
-                  <Router history={history.getHistoryObject()}>
-                    <Route path="*" component={App} />
-                  </Router>
-                  <PrekeysHandler />
-                  <SQLiteDataHandler />
-                  <IntegrityHandler />
-                  <ReportHandler canSendReports={true} />
-                </UserIdentityCacheProvider>
-              </IdentityServiceContextProvider>
-            </InitialReduxStateGate>
-          </CallKeyserverEndpointProvider>
-        </QueryClientProvider>
-      </WagmiProvider>
+      <DebugLogsContextProvider>
+        <WagmiProvider config={wagmiConfig}>
+          <QueryClientProvider client={queryClient}>
+            <CallKeyserverEndpointProvider>
+              <InitialReduxStateGate persistor={persistor}>
+                <IdentityServiceContextProvider>
+                  <UserIdentityCacheProvider>
+                    <Router history={history.getHistoryObject()}>
+                      <Route path="*" component={App} />
+                    </Router>
+                    <PrekeysHandler />
+                    <SQLiteDataHandler />
+                    <IntegrityHandler />
+                    <ReportHandler canSendReports={true} />
+                  </UserIdentityCacheProvider>
+                </IdentityServiceContextProvider>
+              </InitialReduxStateGate>
+            </CallKeyserverEndpointProvider>
+          </QueryClientProvider>
+        </WagmiProvider>
+      </DebugLogsContextProvider>
     </ErrorBoundary>
   </Provider>
 );
 
 export default RootProvider;
diff --git a/web/settings/account-settings.react.js b/web/settings/account-settings.react.js
index 4528bd9f9..265688925 100644
--- a/web/settings/account-settings.react.js
+++ b/web/settings/account-settings.react.js
@@ -1,337 +1,363 @@
 // @flow
 
 import invariant from 'invariant';
 import * as React from 'react';
 import uuid from 'uuid';
 
 import {
   useBaseLogOut,
   logOutActionTypes,
   useSecondaryDeviceLogOut,
 } from 'lib/actions/user-actions.js';
 import { useModalContext } from 'lib/components/modal-provider.react.js';
 import SWMansionIcon from 'lib/components/swmansion-icon.react.js';
 import { useStringForUser } from 'lib/hooks/ens-cache.js';
 import { useCheckIfPrimaryDevice } from 'lib/hooks/primary-device-hooks.js';
 import {
   dmOperationSpecificationTypes,
   type OutboundDMOperationSpecification,
 } from 'lib/shared/dm-ops/dm-op-utils.js';
 import { useProcessAndSendDMOperation } from 'lib/shared/dm-ops/process-dm-ops.js';
 import { IdentityClientContext } from 'lib/shared/identity-client-context.js';
 import { useTunnelbroker } from 'lib/tunnelbroker/tunnelbroker-context.js';
 import type { DMCreateThreadOperation } from 'lib/types/dm-ops.js';
 import { thickThreadTypes } from 'lib/types/thread-types-enum.js';
 import {
   createOlmSessionsWithOwnDevices,
   getContentSigningKey,
 } from 'lib/utils/crypto-utils.js';
 import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js';
 import { useIsRestoreFlowEnabled } from 'lib/utils/services-utils.js';
 
 import css from './account-settings.css';
 import AppearanceChangeModal from './appearance-change-modal.react.js';
 import BackupTestRestoreModal from './backup-test-restore-modal.react.js';
+import DebugLogsModal from './debug-logs-modal.react.js';
 import BlockListModal from './relationship/block-list-modal.react.js';
 import FriendListModal from './relationship/friend-list-modal.react.js';
 import TunnelbrokerMessagesScreen from './tunnelbroker-message-list.react.js';
 import TunnelbrokerTestScreen from './tunnelbroker-test.react.js';
 import EditUserAvatar from '../avatars/edit-user-avatar.react.js';
 import Button from '../components/button.react.js';
 import VersionUnsupportedModal from '../modals/version-unsupported-modal.react.js';
 import { useSelector } from '../redux/redux-utils.js';
 import { useStaffCanSee } from '../utils/staff-utils.js';
 
 function AccountSettings(): React.Node {
   const { pushModal, popModal } = useModalContext();
 
   const legacyLogOutOptions = React.useMemo(() => {
     const showVersionUnsupportedModal = () => {
       pushModal(<VersionUnsupportedModal />);
     };
     return {
       logOutType: 'legacy',
       handleUseNewFlowResponse: showVersionUnsupportedModal,
     };
   }, [pushModal]);
   const sendLegacyLogoutRequest = useBaseLogOut(legacyLogOutOptions);
 
   const sendSecondaryDeviceLogoutRequest = useSecondaryDeviceLogOut();
   const dispatchActionPromise = useDispatchActionPromise();
   const checkIfPrimaryDevice = useCheckIfPrimaryDevice();
   const usingRestoreFlow = useIsRestoreFlowEnabled();
   const logOutUser = React.useCallback(async () => {
     // if web is primary device, we're on legacy flow
     const isPrimaryDevice = await checkIfPrimaryDevice();
     if (usingRestoreFlow && !isPrimaryDevice) {
       return dispatchActionPromise(
         logOutActionTypes,
         sendSecondaryDeviceLogoutRequest(),
       );
     }
     return dispatchActionPromise(logOutActionTypes, sendLegacyLogoutRequest());
   }, [
     checkIfPrimaryDevice,
     dispatchActionPromise,
     sendLegacyLogoutRequest,
     sendSecondaryDeviceLogoutRequest,
     usingRestoreFlow,
   ]);
 
   const identityContext = React.useContext(IdentityClientContext);
 
   const userID = useSelector(state => state.currentUserInfo?.id);
   const [deviceID, setDeviceID] = React.useState<?string>();
 
   React.useEffect(() => {
     void (async () => {
       const contentSigningKey = await getContentSigningKey();
       setDeviceID(contentSigningKey);
     })();
   }, []);
 
   const openFriendList = React.useCallback(
     () => pushModal(<FriendListModal />),
     [pushModal],
   );
 
   const openBlockList = React.useCallback(
     () => pushModal(<BlockListModal />),
     [pushModal],
   );
 
   const currentUserInfo = useSelector(state => state.currentUserInfo);
   const stringForUser = useStringForUser(currentUserInfo);
 
   const staffCanSee = useStaffCanSee();
   const { sendMessageToDevice, socketState, addListener, removeListener } =
     useTunnelbroker();
   const openTunnelbrokerModal = React.useCallback(
     () =>
       pushModal(
         <TunnelbrokerTestScreen
           sendMessageToDevice={sendMessageToDevice}
           onClose={popModal}
         />,
       ),
     [popModal, pushModal, sendMessageToDevice],
   );
 
   const openTunnelbrokerMessagesModal = React.useCallback(
     () =>
       pushModal(
         <TunnelbrokerMessagesScreen
           addListener={addListener}
           removeListener={removeListener}
           onClose={popModal}
         />,
       ),
     [addListener, popModal, pushModal, removeListener],
   );
 
   const onCreateOlmSessions = React.useCallback(async () => {
     if (!identityContext) {
       return;
     }
     const authMetadata = await identityContext.getAuthMetadata();
     try {
       await createOlmSessionsWithOwnDevices(
         authMetadata,
         identityContext.identityClient,
         sendMessageToDevice,
       );
     } catch (e) {
       console.log(`Error creating olm sessions with own devices: ${e.message}`);
     }
   }, [identityContext, sendMessageToDevice]);
 
   const openBackupTestRestoreModal = React.useCallback(
     () => pushModal(<BackupTestRestoreModal onClose={popModal} />),
     [popModal, pushModal],
   );
 
   const processAndSendDMOperation = useProcessAndSendDMOperation();
   const onCreateDMThread = React.useCallback(async () => {
     invariant(userID, 'userID should be set');
     const op: DMCreateThreadOperation = {
       type: 'create_thread',
       threadID: uuid.v4(),
       creatorID: userID,
       time: Date.now(),
       threadType: thickThreadTypes.LOCAL,
       memberIDs: [],
       roleID: uuid.v4(),
       newMessageID: uuid.v4(),
     };
     const specification: OutboundDMOperationSpecification = {
       type: dmOperationSpecificationTypes.OUTBOUND,
       op,
       recipients: {
         type: 'self_devices',
       },
     };
     await processAndSendDMOperation(specification);
   }, [processAndSendDMOperation, userID]);
 
   const showAppearanceModal = React.useCallback(
     () => pushModal(<AppearanceChangeModal />),
     [pushModal],
   );
 
+  const openDebugLogs = React.useCallback(
+    () => pushModal(<DebugLogsModal />),
+    [pushModal],
+  );
+
   if (!currentUserInfo || currentUserInfo.anonymous) {
     return null;
   }
 
   let preferences;
   if (staffCanSee) {
     preferences = (
       <div className={css.preferencesContainer}>
         <h4 className={css.preferencesHeader}>Preferences</h4>
         <div className={css.content}>
           <ul>
             <li>
               <span>Appearance</span>
               <a className={css.editPasswordLink} onClick={showAppearanceModal}>
                 <SWMansionIcon icon="edit-1" size={22} />
               </a>
             </li>
           </ul>
         </div>
       </div>
     );
   }
   let tunnelbroker;
   if (staffCanSee) {
     tunnelbroker = (
       <div className={css.preferencesContainer}>
         <h4 className={css.preferencesHeader}>Tunnelbroker menu</h4>
         <div className={css.content}>
           <ul>
             <li>
               <span>Connected</span>
               <span>{socketState.connected.toString()}</span>
             </li>
             <li>
               <span>Send message to device</span>
               <Button variant="text" onClick={openTunnelbrokerModal}>
                 <p className={css.buttonText}>Insert data</p>
               </Button>
             </li>
             <li>
               <span>Trace received messages</span>
               <Button variant="text" onClick={openTunnelbrokerMessagesModal}>
                 <p className={css.buttonText}>Show list</p>
               </Button>
             </li>
             <li>
               <span>Create session with own devices</span>
               <Button variant="text" onClick={onCreateOlmSessions}>
                 <p className={css.buttonText}>Create</p>
               </Button>
             </li>
           </ul>
         </div>
       </div>
     );
   }
   let backup;
   if (staffCanSee) {
     backup = (
       <div className={css.preferencesContainer}>
         <h4 className={css.preferencesHeader}>Backup menu</h4>
         <div className={css.content}>
           <ul>
             <li>
               <span>Test backup restore</span>
               <Button variant="text" onClick={openBackupTestRestoreModal}>
                 <p className={css.buttonText}>Insert data</p>
               </Button>
             </li>
           </ul>
         </div>
       </div>
     );
   }
   let deviceData;
   if (staffCanSee) {
     deviceData = (
       <div className={css.preferencesContainer}>
         <h4 className={css.preferencesHeader}>Device ID</h4>
         <div className={css.content}>
           <ul>
             <li>
               <span>{deviceID}</span>
             </li>
           </ul>
         </div>
         <h4 className={css.preferencesHeader}>User ID</h4>
         <div className={css.content}>
           <ul>
             <li>
               <span>{userID}</span>
             </li>
           </ul>
         </div>
       </div>
     );
   }
   let dms;
   if (staffCanSee) {
     dms = (
       <div className={css.preferencesContainer}>
         <h4 className={css.preferencesHeader}>DMs menu</h4>
         <div className={css.content}>
           <ul>
             <li>
               <span>Create a new local DM thread</span>
               <Button variant="text" onClick={onCreateDMThread}>
                 <p className={css.buttonText}>Create</p>
               </Button>
             </li>
           </ul>
         </div>
       </div>
     );
   }
 
+  let debugLogs;
+  if (staffCanSee) {
+    debugLogs = (
+      <div className={css.preferencesContainer}>
+        <h4 className={css.preferencesHeader}>Debug menu</h4>
+        <div className={css.content}>
+          <ul>
+            <li>
+              <span>See debug logs</span>
+              <Button variant="text" onClick={openDebugLogs}>
+                <p className={css.buttonText}>See List</p>
+              </Button>
+            </li>
+          </ul>
+        </div>
+      </div>
+    );
+  }
+
   return (
     <div className={css.container}>
       <div className={css.contentContainer}>
         <h4 className={css.header}>My Account</h4>
         <EditUserAvatar userID={currentUserInfo.id} />
         <div className={css.content}>
           <ul>
             <li>
               <p className={css.logoutContainer}>
                 <span className={css.logoutLabel}>{'Logged in as '}</span>
                 <span className={css.username}>{stringForUser}</span>
               </p>
               <Button variant="text" onClick={logOutUser}>
                 <p className={css.buttonText}>Log out</p>
               </Button>
             </li>
             <li>
               <span>Friend List</span>
               <Button variant="text" onClick={openFriendList}>
                 <p className={css.buttonText}>See List</p>
               </Button>
             </li>
             <li>
               <span>Block List</span>
               <Button variant="text" onClick={openBlockList}>
                 <p className={css.buttonText}>See List</p>
               </Button>
             </li>
           </ul>
         </div>
         {preferences}
         {tunnelbroker}
         {backup}
         {deviceData}
         {dms}
+        {debugLogs}
       </div>
     </div>
   );
 }
 
 export default AccountSettings;
diff --git a/web/settings/debug-logs-modal.css b/web/settings/debug-logs-modal.css
new file mode 100644
index 000000000..0f180f7f0
--- /dev/null
+++ b/web/settings/debug-logs-modal.css
@@ -0,0 +1,47 @@
+.container {
+  display: flex;
+  flex-direction: column;
+  height: 60vh;
+  gap: 8px;
+}
+
+.logsList {
+  display: flex;
+  flex-direction: column;
+  flex: 1;
+  overflow-y: scroll;
+}
+
+.item {
+  margin: 4px 0;
+  padding: 4px 0;
+  color: var(--text-background-secondary-default);
+  transition: 0.1s;
+}
+
+.item:hover {
+  background-color: var(--modal-listItem-primary-hover);
+}
+
+.timestamp {
+  font-size: var(--m-font-16);
+}
+
+.title {
+  font-size: var(--l-font-18);
+  color: var(--text-background-primary-default);
+}
+
+.message {
+  font-size: var(--m-font-16);
+}
+
+.buttons {
+  display: flex;
+  gap: 8px;
+  justify-content: space-between;
+}
+
+.button {
+  flex: 1;
+}
diff --git a/web/settings/debug-logs-modal.react.js b/web/settings/debug-logs-modal.react.js
new file mode 100644
index 000000000..eb66086c9
--- /dev/null
+++ b/web/settings/debug-logs-modal.react.js
@@ -0,0 +1,58 @@
+// @flow
+
+import * as React from 'react';
+
+import { useDebugLogs } from 'lib/components/debug-logs-context.js';
+import { useModalContext } from 'lib/components/modal-provider.react.js';
+
+import css from './debug-logs-modal.css';
+import Button, { buttonThemes } from '../components/button.react.js';
+import Modal from '../modals/modal.react.js';
+
+function DebugLogsModal(): React.Node {
+  const { logs, clearLogs } = useDebugLogs();
+  const { popModal } = useModalContext();
+
+  const messageList = React.useMemo(
+    () =>
+      logs.map((item, index) => {
+        const date = new Date(item.timestamp);
+        const timestampString = date.toISOString();
+        return (
+          <div key={index} className={css.item}>
+            <div className={css.timestamp}>{timestampString}</div>
+            <div className={css.title}>{item.title}</div>
+            <div className={css.message}>{item.message}</div>
+          </div>
+        );
+      }),
+    [logs],
+  );
+
+  const copyLogs = React.useCallback(async () => {
+    await navigator.clipboard.writeText(JSON.stringify(logs));
+  }, [logs]);
+
+  return (
+    <Modal name="Debug Logs" onClose={popModal} size="large">
+      <div className={css.container}>
+        <div className={css.logsList}>{messageList}</div>
+        <div className={css.buttons}>
+          <Button variant="filled" className={css.button} onClick={copyLogs}>
+            Copy Logs
+          </Button>
+          <Button
+            variant="filled"
+            buttonColor={buttonThemes.danger}
+            className={css.button}
+            onClick={clearLogs}
+          >
+            Clear Logs
+          </Button>
+        </div>
+      </div>
+    </Modal>
+  );
+}
+
+export default DebugLogsModal;