diff --git a/lib/utils/drawer-utils.react.js b/lib/utils/drawer-utils.react.js
--- a/lib/utils/drawer-utils.react.js
+++ b/lib/utils/drawer-utils.react.js
@@ -1,6 +1,7 @@
 // @flow
 
 import { threadIsChannel } from '../shared/thread-utils.js';
+import type { InviteLink } from '../types/link-types.js';
 import {
   type ThreadInfo,
   type ResolvedThreadInfo,
@@ -12,6 +13,7 @@
   +itemChildren?: $ReadOnlyArray<CommunityDrawerItemData<T>>,
   +hasSubchannelsButton: boolean,
   +labelStyle: T,
+  +inviteLink: ?InviteLink,
 };
 
 function createRecursiveDrawerItemsData<LabelStyleType>(
@@ -19,12 +21,14 @@
   communities: $ReadOnlyArray<ResolvedThreadInfo>,
   labelStyles: $ReadOnlyArray<LabelStyleType>,
   maxDepth: number,
+  inviteLinks: ?{ +[threadID: string]: InviteLink },
 ): $ReadOnlyArray<CommunityDrawerItemData<LabelStyleType>> {
   const result = communities.map(community => ({
     threadInfo: community,
     itemChildren: [],
     labelStyle: labelStyles[0],
     hasSubchannelsButton: false,
+    inviteLink: inviteLinks?.[community.id],
   }));
   let queue = result.map(item => [item, 0]);
 
@@ -42,6 +46,7 @@
           hasSubchannelsButton:
             lvl + 1 === maxDepth &&
             threadHasSubchannels(childItem, childThreadInfosMap),
+          inviteLink: inviteLinks?.[item.threadInfo.id],
         }));
       queue = queue.concat(
         item.itemChildren.map(childItem => [childItem, lvl + 1]),
diff --git a/native/navigation/community-drawer-content.react.js b/native/navigation/community-drawer-content.react.js
--- a/native/navigation/community-drawer-content.react.js
+++ b/native/navigation/community-drawer-content.react.js
@@ -1,14 +1,26 @@
 // @flow
 
+import { useDrawerStatus } from '@react-navigation/drawer';
+import { useNavigation } from '@react-navigation/native';
 import * as React from 'react';
 import { FlatList, Platform } from 'react-native';
 import { SafeAreaView } from 'react-native-safe-area-context';
 import { useSelector } from 'react-redux';
 
+import {
+  fetchPrimaryInviteLinkActionTypes,
+  fetchPrimaryInviteLinks,
+} from 'lib/actions/link-actions.js';
 import {
   childThreadInfos,
   communityThreadSelector,
 } from 'lib/selectors/thread-selectors.js';
+import type { InviteLink } from 'lib/types/link-types';
+import type { ThreadInfo } from 'lib/types/thread-types';
+import {
+  useDispatchActionPromise,
+  useServerCall,
+} from 'lib/utils/action-utils.js';
 import {
   createRecursiveDrawerItemsData,
   appendSuffix,
@@ -16,6 +28,7 @@
 import { useResolvedThreadInfos } from 'lib/utils/entity-helpers.js';
 
 import CommunityDrawerItemCommunity from './community-drawer-item-community.react.js';
+import { ViewInviteLinksModalRouteName } from './route-names.js';
 import { useNavigateToThread } from '../chat/message-list-types.js';
 import { useStyles } from '../themes/colors.js';
 
@@ -34,6 +47,30 @@
   );
   const styles = useStyles(unboundStyles);
 
+  const [inviteLinks, setInviteLinks] = React.useState(null);
+  const callFetchPrimaryLinks = useServerCall(fetchPrimaryInviteLinks);
+  const dispatchActionPromise = useDispatchActionPromise();
+  const drawerStatus = useDrawerStatus();
+  React.useEffect(() => {
+    (async () => {
+      if (drawerStatus !== 'open') {
+        return;
+      }
+      const createFetchPrimaryLinksPromise = async () => {
+        const response = await callFetchPrimaryLinks();
+        const links = {};
+        for (const link of response.links) {
+          links[link.communityID] = link;
+        }
+        setInviteLinks(links);
+      };
+      await dispatchActionPromise(
+        fetchPrimaryInviteLinkActionTypes,
+        createFetchPrimaryLinksPromise(),
+      );
+    })();
+  }, [callFetchPrimaryLinks, dispatchActionPromise, drawerStatus]);
+
   const [openCommunity, setOpenCommunity] = React.useState(
     communitiesSuffixed.length === 1 ? communitiesSuffixed[0].id : null,
   );
@@ -45,6 +82,20 @@
     setOpenCommunity(open => (open === index ? null : index));
   }, []);
 
+  const { navigate } = useNavigation();
+  const navigateToInviteLinksView = React.useCallback(
+    (community: ThreadInfo, inviteLink: InviteLink) => {
+      navigate<'ViewInviteLinksModal'>({
+        name: ViewInviteLinksModalRouteName,
+        params: {
+          community,
+          inviteLink,
+        },
+      });
+    },
+    [navigate],
+  );
+
   const renderItem = React.useCallback(
     ({ item }) => (
       <CommunityDrawerItemCommunity
@@ -53,9 +104,15 @@
         toggleExpanded={setOpenCommunityOrClose}
         expanded={item.threadInfo.id === openCommunity}
         navigateToThread={navigateToThread}
+        navigateToInviteLinksView={navigateToInviteLinksView}
       />
     ),
-    [navigateToThread, openCommunity, setOpenCommunityOrClose],
+    [
+      navigateToInviteLinksView,
+      navigateToThread,
+      openCommunity,
+      setOpenCommunityOrClose,
+    ],
   );
 
   const labelStylesObj = useStyles(labelUnboundStyles);
@@ -75,8 +132,9 @@
         communitiesSuffixed,
         labelStyles,
         maxDepth,
+        inviteLinks,
       ),
-    [childThreadInfosMap, communitiesSuffixed, labelStyles],
+    [childThreadInfosMap, communitiesSuffixed, inviteLinks, labelStyles],
   );
 
   return (
diff --git a/native/navigation/community-drawer-item.react.js b/native/navigation/community-drawer-item.react.js
--- a/native/navigation/community-drawer-item.react.js
+++ b/native/navigation/community-drawer-item.react.js
@@ -1,8 +1,12 @@
 // @flow
 
+import { useActionSheet } from '@expo/react-native-action-sheet';
 import * as React from 'react';
 import { View, FlatList, TouchableOpacity } from 'react-native';
+import { useSafeAreaInsets } from 'react-native-safe-area-context';
 
+import type { InviteLink } from 'lib/types/link-types';
+import type { ThreadInfo } from 'lib/types/thread-types';
 import type { CommunityDrawerItemData } from 'lib/utils/drawer-utils.react.js';
 import { useResolvedThreadInfo } from 'lib/utils/entity-helpers.js';
 
@@ -11,6 +15,7 @@
 import ThreadAvatar from '../avatars/thread-avatar.react.js';
 import type { MessageListParams } from '../chat/message-list-types.js';
 import { SingleLine } from '../components/single-line.react.js';
+import SWMansionIcon from '../components/swmansion-icon.react.js';
 import { useStyles } from '../themes/colors.js';
 import type { TextStyle } from '../types/styles.js';
 import { useShouldRenderAvatars } from '../utils/avatar-utils.js';
@@ -20,14 +25,25 @@
   +toggleExpanded: (threadID: string) => void,
   +expanded: boolean,
   +navigateToThread: (params: MessageListParams) => void,
+  +navigateToInviteLinksView: (
+    community: ThreadInfo,
+    inviteLink: InviteLink,
+  ) => void,
 };
 
 function CommunityDrawerItem(props: DrawerItemProps): React.Node {
   const {
-    itemData: { threadInfo, itemChildren, labelStyle, hasSubchannelsButton },
+    itemData: {
+      threadInfo,
+      itemChildren,
+      labelStyle,
+      hasSubchannelsButton,
+      inviteLink,
+    },
     navigateToThread,
     expanded,
     toggleExpanded,
+    navigateToInviteLinksView,
   } = props;
 
   const styles = useStyles(unboundStyles);
@@ -38,9 +54,10 @@
         key={item.threadInfo.id}
         itemData={item}
         navigateToThread={navigateToThread}
+        navigateToInviteLinksView={navigateToInviteLinksView}
       />
     ),
-    [navigateToThread],
+    [navigateToInviteLinksView, navigateToThread],
   );
 
   const children = React.useMemo(() => {
@@ -95,6 +112,49 @@
     );
   }, [shouldRenderAvatars, styles.avatarContainer, threadInfo]);
 
+  const insets = useSafeAreaInsets();
+  const { showActionSheetWithOptions } = useActionSheet();
+  const inviteLinksButton = React.useMemo(() => {
+    if (!inviteLink) {
+      return null;
+    }
+    const options = ['Invite Link', 'Cancel'];
+    const containerStyle = {
+      paddingBottom: insets.bottom,
+    };
+    return (
+      <TouchableOpacity
+        onPress={() =>
+          showActionSheetWithOptions(
+            {
+              options,
+              cancelButtonIndex: 1,
+              containerStyle,
+            },
+            selectedIndex => {
+              if (selectedIndex === 0) {
+                navigateToInviteLinksView(threadInfo, inviteLink);
+              }
+            },
+          )
+        }
+      >
+        <SWMansionIcon
+          name="menu-vertical"
+          size={22}
+          style={styles.inviteLinksButton}
+        />
+      </TouchableOpacity>
+    );
+  }, [
+    insets.bottom,
+    inviteLink,
+    navigateToInviteLinksView,
+    showActionSheetWithOptions,
+    styles.inviteLinksButton,
+    threadInfo,
+  ]);
+
   return (
     <View>
       <View style={styles.threadEntry}>
@@ -107,6 +167,7 @@
           {avatar}
           <SingleLine style={labelStyle}>{uiName}</SingleLine>
         </TouchableOpacity>
+        {inviteLinksButton}
       </View>
       {children}
     </View>
@@ -120,6 +181,9 @@
   chatView: {
     marginLeft: 16,
   },
+  inviteLinksButton: {
+    color: 'drawerItemLabelLevel0',
+  },
   threadEntry: {
     flexDirection: 'row',
     marginVertical: 6,
@@ -138,6 +202,7 @@
 export type CommunityDrawerItemChatProps = {
   +itemData: CommunityDrawerItemData<TextStyle>,
   +navigateToThread: (params: MessageListParams) => void,
+  +navigateToInviteLinksView: () => void,
 };
 
 function CommunityDrawerItemChat(