diff --git a/preload.js b/preload.js
index 73ed478ee..d7f99256c 100644
--- a/preload.js
+++ b/preload.js
@@ -445,7 +445,6 @@ window.lokiFeatureFlags = {
   useFileOnionRequests: true,
   useFileOnionRequestsV2: true, // more compact encoding of files in response
   onionRequestHops: 3,
-  useExplicitGroupUpdatesSending: false,
 };
 
 // eslint-disable-next-line no-extend-native,func-names
@@ -479,7 +478,6 @@ if (config.environment.includes('test-integration')) {
     useOnionRequests: false,
     useFileOnionRequests: false,
     useOnionRequestsV2: false,
-    useExplicitGroupUpdatesSending: false,
   };
   /* eslint-disable global-require, import/no-extraneous-dependencies */
   window.sinon = require('sinon');
diff --git a/ts/components/session/SessionInboxView.tsx b/ts/components/session/SessionInboxView.tsx
index d1b079de6..99250aed7 100644
--- a/ts/components/session/SessionInboxView.tsx
+++ b/ts/components/session/SessionInboxView.tsx
@@ -132,7 +132,7 @@ export class SessionInboxView extends React.Component<Props, State> {
       return null;
     }
 
-    const msg = window.getMessageController().get(m.identifier);
+    const msg = MessageController.getInstance().get(m.identifier);
 
     if (!msg || !msg.message) {
       return null;
diff --git a/ts/receiver/closedGroups.ts b/ts/receiver/closedGroups.ts
index a45f025fc..a43dd2761 100644
--- a/ts/receiver/closedGroups.ts
+++ b/ts/receiver/closedGroups.ts
@@ -22,11 +22,11 @@ import {
 } from '../session/messages/outgoing/content/data/group/ClosedGroupNewMessage';
 
 import { ECKeyPair } from './keypairs';
-import { getOurNumber } from '../session/utils/User';
 import { UserUtils } from '../session/utils';
 import { ConversationModel } from '../../js/models/conversations';
 import _ from 'lodash';
 import { forceSyncConfigurationNowIfNeeded } from '../session/utils/syncUtils';
+import { MessageController } from '../session/messages';
 
 export async function handleClosedGroupControlMessage(
   envelope: EnvelopePlus,
@@ -481,6 +481,9 @@ async function performIfValid(
   }
 
   if (groupUpdate.type === Type.UPDATE) {
+    window.log.warn(
+      'Received a groupUpdate non explicit. This should not happen anymore.'
+    );
     await handleUpdateClosedGroup(envelope, groupUpdate, convo);
   } else if (groupUpdate.type === Type.NAME_CHANGE) {
     await handleClosedGroupNameChanged(envelope, groupUpdate, convo);
@@ -693,7 +696,7 @@ export async function createClosedGroup(
 ) {
   const setOfMembers = new Set(members);
 
-  const ourNumber = await getOurNumber();
+  const ourNumber = await UserUtils.getOurNumber();
   // Create Group Identity
   // Generate the key pair that'll be used for encryption and decryption
   // Generate the group's public key
@@ -734,7 +737,7 @@ export async function createClosedGroup(
     groupDiff,
     'outgoing'
   );
-  window.getMessageController().register(dbMessage.id, dbMessage);
+  MessageController.getInstance().register(dbMessage.id, dbMessage);
 
   // be sure to call this before sending the message.
   // the sending pipeline needs to know from GroupUtils when a message is for a medium group
diff --git a/ts/session/group/index.ts b/ts/session/group/index.ts
index 86aeb0024..5a2c45b60 100644
--- a/ts/session/group/index.ts
+++ b/ts/session/group/index.ts
@@ -33,6 +33,7 @@ import {
   ClosedGroupRemovedMembersMessage,
   ClosedGroupUpdateMessage,
 } from '../messages/outgoing/content/data/group';
+import { MessageController } from '../messages';
 
 export interface GroupInfo {
   id: string;
@@ -122,111 +123,6 @@ export async function initiateGroupUpdate(
     expireTimer: convo.get('expireTimer'),
   };
 
-  if (!window.lokiFeatureFlags.useExplicitGroupUpdatesSending) {
-    // we still don't send any explicit group updates for now - only the receiving side is enabled
-    const dbMessageAdded = await addUpdateMessage(convo, diff, 'outgoing');
-    window.getMessageController().register(dbMessageAdded.id, dbMessageAdded);
-    // Check preconditions
-    const hexEncryptionKeyPair = await getLatestClosedGroupEncryptionKeyPair(
-      groupId
-    );
-    if (!hexEncryptionKeyPair) {
-      throw new Error("Couldn't get key pair for closed group");
-    }
-
-    const encryptionKeyPair = ECKeyPair.fromHexKeyPair(hexEncryptionKeyPair);
-    const removedMembers = diff.leavingMembers || [];
-    const newMembers = diff.joiningMembers || []; // joining members
-    const wasAnyUserRemoved = removedMembers.length > 0;
-    const ourPrimary = await UserUtils.getOurNumber();
-    const isUserLeaving = removedMembers.includes(ourPrimary.key);
-    const isCurrentUserAdmin = convo
-      .get('groupAdmins')
-      ?.includes(ourPrimary.key);
-    const expireTimerToShare = groupDetails.expireTimer || 0;
-
-    const admins = convo.get('groupAdmins') || [];
-    if (removedMembers.includes(admins[0]) && newMembers.length !== 0) {
-      throw new Error(
-        "Can't remove admin from closed group without removing everyone."
-      ); // Error.invalidClosedGroupUpdate
-    }
-
-    if (isUserLeaving && newMembers.length !== 0) {
-      if (removedMembers.length !== 1 || newMembers.length !== 0) {
-        throw new Error(
-          "Can't remove self and add or remove others simultaneously."
-        );
-      }
-    }
-
-    // Send the update to the group
-    const mainClosedGroupUpdate = new ClosedGroupUpdateMessage({
-      timestamp: Date.now(),
-      groupId,
-      name: groupName,
-      members,
-      identifier: dbMessageAdded.id || uuid(),
-      expireTimer: expireTimerToShare,
-    });
-
-    if (isUserLeaving) {
-      window.log.info(
-        `We are leaving the group ${groupId}. Sending our leaving message.`
-      );
-      // sent the message to the group and once done, remove everything related to this group
-      window.SwarmPolling.removePubkey(groupId);
-      await getMessageQueue().sendToGroup(mainClosedGroupUpdate, async () => {
-        window.log.info(
-          `Leaving message sent ${groupId}. Removing everything related to this group.`
-        );
-        await removeAllClosedGroupEncryptionKeyPairs(groupId);
-      });
-    } else {
-      // Send the group update, and only once sent, generate and distribute a new encryption key pair if needed
-      await getMessageQueue().sendToGroup(mainClosedGroupUpdate, async () => {
-        if (wasAnyUserRemoved && isCurrentUserAdmin) {
-          // we send the new encryption key only to members already here before the update
-          const membersNotNew = members.filter(m => !newMembers.includes(m));
-          window.log.info(
-            `Sending group update: A user was removed from ${groupId} and we are the admin. Generating and sending a new EncryptionKeyPair`
-          );
-
-          await generateAndSendNewEncryptionKeyPair(groupId, membersNotNew);
-        }
-      });
-
-      if (newMembers.length) {
-        // Send closed group update messages to any new members individually
-        const newClosedGroupUpdate = new ClosedGroupNewMessage({
-          timestamp: Date.now(),
-          name: groupName,
-          groupId,
-          admins,
-          members,
-          keypair: encryptionKeyPair,
-          identifier: dbMessageAdded.id || uuid(),
-          expireTimer: expireTimerToShare,
-        });
-
-        const promises = newMembers.map(async m => {
-          await ConversationController.getInstance().getOrCreateAndWait(
-            m,
-            'private'
-          );
-          const memberPubKey = PubKey.cast(m);
-          await getMessageQueue().sendToPubKey(
-            memberPubKey,
-            newClosedGroupUpdate
-          );
-        });
-        await Promise.all(promises);
-      }
-    }
-
-    return;
-  }
-
   if (diff.newName?.length) {
     const nameOnlyDiff: GroupDiff = { newName: diff.newName };
     const dbMessageName = await addUpdateMessage(
@@ -234,7 +130,7 @@ export async function initiateGroupUpdate(
       nameOnlyDiff,
       'outgoing'
     );
-    window.getMessageController().register(dbMessageName.id, dbMessageName);
+    MessageController.getInstance().register(dbMessageName.id, dbMessageName);
     await sendNewName(convo, diff.newName, dbMessageName.id);
   }
 
@@ -245,7 +141,7 @@ export async function initiateGroupUpdate(
       joiningOnlyDiff,
       'outgoing'
     );
-    window.getMessageController().register(dbMessageAdded.id, dbMessageAdded);
+    MessageController.getInstance().register(dbMessageAdded.id, dbMessageAdded);
     await sendAddedMembers(
       convo,
       diff.joiningMembers,
@@ -261,9 +157,10 @@ export async function initiateGroupUpdate(
       leavingOnlyDiff,
       'outgoing'
     );
-    window
-      .getMessageController()
-      .register(dbMessageLeaving.id, dbMessageLeaving);
+    MessageController.getInstance().register(
+      dbMessageLeaving.id,
+      dbMessageLeaving
+    );
     const stillMembers = members;
     await sendRemovedMembers(
       convo,
@@ -435,7 +332,7 @@ export async function leaveClosedGroup(groupId: string) {
   } else {
     // otherwise, just the exclude ourself from the members and trigger an update with this
     convo.set({ left: true });
-    members = convo.get('members').filter(m => m !== ourNumber.key);
+    members = convo.get('members').filter((m: string) => m !== ourNumber.key);
     admins = convo.get('groupAdmins') || [];
   }
   convo.set({ members });
@@ -449,29 +346,15 @@ export async function leaveClosedGroup(groupId: string) {
     sent_at: now,
     received_at: now,
   });
-  window.getMessageController().register(dbMessage.id, dbMessage);
+  MessageController.getInstance().register(dbMessage.id, dbMessage);
   const existingExpireTimer = convo.get('expireTimer') || 0;
   // Send the update to the group
-  let ourLeavingMessage;
-
-  if (window.lokiFeatureFlags.useExplicitGroupUpdatesSending) {
-    ourLeavingMessage = new ClosedGroupMemberLeftMessage({
-      timestamp: Date.now(),
-      groupId,
-      identifier: dbMessage.id,
-      expireTimer: existingExpireTimer,
-    });
-  } else {
-    const ourPubkey = await UserUtils.getOurNumber();
-    ourLeavingMessage = new ClosedGroupUpdateMessage({
-      timestamp: Date.now(),
-      groupId,
-      identifier: dbMessage.id,
-      expireTimer: existingExpireTimer,
-      name: convo.get('name'),
-      members: convo.get('members').filter(m => m !== ourPubkey.key),
-    });
-  }
+  const ourLeavingMessage = new ClosedGroupMemberLeftMessage({
+    timestamp: Date.now(),
+    groupId,
+    identifier: dbMessage.id,
+    expireTimer: existingExpireTimer,
+  });
 
   window.log.info(
     `We are leaving the group ${groupId}. Sending our leaving message.`
diff --git a/ts/window.d.ts b/ts/window.d.ts
index 75c3cc702..6bd056219 100644
--- a/ts/window.d.ts
+++ b/ts/window.d.ts
@@ -63,7 +63,6 @@ declare global {
       useOnionRequestsV2: boolean;
       useFileOnionRequests: boolean;
       useFileOnionRequestsV2: boolean;
-      useExplicitGroupUpdatesSending: boolean;
       onionRequestHops: number;
     };
     lokiFileServerAPI: LokiFileServerInstance;