diff --git a/groupChat/manager.go b/groupChat/manager.go
index c5ec117c76ae0903487c7c6b7d015294bb616e33..c67aae9bcb9c677d05709634ae8aca95e000d95e 100644
--- a/groupChat/manager.go
+++ b/groupChat/manager.go
@@ -8,18 +8,25 @@
 package groupChat
 
 import (
+	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/catalog"
 	"gitlab.com/elixxir/client/cmix"
 	"gitlab.com/elixxir/client/cmix/message"
 	"gitlab.com/elixxir/client/e2e"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
+	"gitlab.com/elixxir/client/e2e/receive"
 	gs "gitlab.com/elixxir/client/groupChat/groupStore"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
+	crypto "gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/group"
 	"gitlab.com/xx_network/primitives/id"
+	"gitlab.com/xx_network/primitives/id/ephemeral"
+	"time"
 )
 
 // Error messages.
@@ -29,22 +36,50 @@ const (
 	leaveGroupErr    = "failed to leave group %s: %+v"
 )
 
+// GroupCmix is a subset of the cmix.Client interface containing only the methods needed by GroupChat
+type GroupCmix interface {
+	SendMany(messages []cmix.TargetedCmixMessage, p cmix.CMIXParams) (
+		id.Round, []ephemeral.Id, error)
+	AddService(clientID *id.ID, newService message.Service,
+		response message.Processor)
+	DeleteService(clientID *id.ID, toDelete message.Service,
+		processor message.Processor)
+}
+
+// GroupE2e is a subset of the e2e.Handler interface containing only the methods needed by GroupChat
+type GroupE2e interface {
+	SendE2E(mt catalog.MessageType, recipient *id.ID, payload []byte,
+		params e2e.Params) ([]id.Round, crypto.MessageID, time.Time, error)
+	RegisterListener(senderID *id.ID,
+		messageType catalog.MessageType,
+		newListener receive.Listener) receive.ListenerID
+	AddService(tag string, processor message.Processor) error
+	AddPartner(partnerID *id.ID,
+		partnerPubKey, myPrivKey *cyclic.Int,
+		partnerSIDHPubKey *sidh.PublicKey,
+		mySIDHPrivKey *sidh.PrivateKey, sendParams,
+		receiveParams session.Params) (partner.Manager, error)
+	GetPartner(partnerID *id.ID) (partner.Manager, error)
+	GetHistoricalDHPubkey() *cyclic.Int
+	GetHistoricalDHPrivkey() *cyclic.Int
+}
+
 // Manager handles the list of groups a user is a part of.
 type Manager struct {
-	e2e e2e.Handler
+	e2e GroupE2e
 
 	receptionId *id.ID
 	rng         *fastRNG.StreamGenerator
 	grp         *cyclic.Group
 	gs          *gs.Store
-	services    cmix.Client
+	services    GroupCmix
 
 	requestFunc RequestCallback
 	receiveFunc ReceiveCallback
 }
 
 // NewManager creates a new group chat manager
-func NewManager(services cmix.Client, e2e e2e.Handler, receptionId *id.ID,
+func NewManager(services GroupCmix, e2e GroupE2e, receptionId *id.ID,
 	rng *fastRNG.StreamGenerator, grp *cyclic.Group, kv *versioned.KV,
 	requestFunc RequestCallback, receiveFunc ReceiveCallback) (*Manager, error) {
 
diff --git a/groupChat/receive.go b/groupChat/receive.go
index 8555fafa98e39a73565a6c1c4975e3d83004f803..b559a0b0d4776cd70425f86c0744b3b6eac2b5f4 100644
--- a/groupChat/receive.go
+++ b/groupChat/receive.go
@@ -10,8 +10,8 @@ package groupChat
 import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/cmix/rounds"
 	"gitlab.com/elixxir/client/cmix/identity/receptionID"
+	"gitlab.com/elixxir/client/cmix/rounds"
 	gs "gitlab.com/elixxir/client/groupChat/groupStore"
 	"gitlab.com/elixxir/crypto/group"
 	"gitlab.com/elixxir/primitives/format"
@@ -25,7 +25,6 @@ const (
 	unmarshalInternalMsgErr = "failed to unmarshal group internal message: %+v"
 	unmarshalSenderIdErr    = "failed to unmarshal sender ID: %+v"
 	unmarshalPublicMsgErr   = "failed to unmarshal group cMix message contents: %+v"
-	findGroupKeyFpErr       = "no group with key fingerprint %s"
 	genCryptKeyMacErr       = "failed to generate encryption key for group " +
 		"cMix message because MAC verification failed (epoch %d could be off)"
 )
diff --git a/groupChat/utils_test.go b/groupChat/utils_test.go
index e8e4ee7d84f271a980d5894ca0c46906914e55b8..4854e56500b3964a01628475f8e9a17d69a86264 100644
--- a/groupChat/utils_test.go
+++ b/groupChat/utils_test.go
@@ -13,19 +13,14 @@ import (
 	"github.com/pkg/errors"
 	"gitlab.com/elixxir/client/catalog"
 	"gitlab.com/elixxir/client/cmix"
-	"gitlab.com/elixxir/client/cmix/gateway"
-	"gitlab.com/elixxir/client/cmix/identity"
 	"gitlab.com/elixxir/client/cmix/message"
-	"gitlab.com/elixxir/client/cmix/rounds"
 	clientE2E "gitlab.com/elixxir/client/e2e"
 	"gitlab.com/elixxir/client/e2e/ratchet/partner"
 	"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/e2e/receive"
 	"gitlab.com/elixxir/client/event"
 	gs "gitlab.com/elixxir/client/groupChat/groupStore"
-	"gitlab.com/elixxir/client/stoppable"
 	"gitlab.com/elixxir/client/storage/versioned"
-	net "gitlab.com/elixxir/comms/network"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/e2e"
@@ -33,7 +28,6 @@ import (
 	"gitlab.com/elixxir/crypto/group"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/elixxir/primitives/format"
-	"gitlab.com/xx_network/comms/connect"
 	"gitlab.com/xx_network/crypto/csprng"
 	"gitlab.com/xx_network/crypto/large"
 	"gitlab.com/xx_network/primitives/id"
@@ -221,7 +215,7 @@ func getGroup() *cyclic.Group {
 		large.NewIntFromString(getNDF().E2E.Generator, 16))
 }
 
-func newTestNetworkManager(sendErr int, t *testing.T) cmix.Client {
+func newTestNetworkManager(sendErr int, t *testing.T) GroupCmix {
 	return &testNetworkManager{
 		receptionMessages: [][]format.Message{},
 		sendMessages:      [][]cmix.TargetedCmixMessage{},
@@ -242,7 +236,8 @@ type testE2eMessage struct {
 	Payload   []byte
 }
 
-func (tnm *testE2eManager) AddPartner(partnerID *id.ID, partnerPubKey, myPrivKey *cyclic.Int, partnerSIDHPubKey *sidh.PublicKey, mySIDHPrivKey *sidh.PrivateKey, sendParams, receiveParams session.Params) (partner.Manager, error) {
+func (tnm *testE2eManager) AddPartner(partnerID *id.ID, partnerPubKey, myPrivKey *cyclic.Int,
+	partnerSIDHPubKey *sidh.PublicKey, mySIDHPrivKey *sidh.PrivateKey, sendParams, receiveParams session.Params) (partner.Manager, error) {
 	return nil, nil
 }
 
@@ -250,14 +245,6 @@ func (tnm *testE2eManager) GetPartner(partnerID *id.ID) (partner.Manager, error)
 	return nil, nil
 }
 
-func (tnm *testE2eManager) DeletePartner(partnerId *id.ID) error {
-	panic("implement me")
-}
-
-func (tnm *testE2eManager) GetAllPartnerIDs() []*id.ID {
-	panic("implement me")
-}
-
 func (tnm *testE2eManager) GetHistoricalDHPubkey() *cyclic.Int {
 	panic("implement me")
 }
@@ -266,173 +253,6 @@ func (tnm *testE2eManager) GetHistoricalDHPrivkey() *cyclic.Int {
 	panic("implement me")
 }
 
-func (tnm *testE2eManager) GetReceptionID() *id.ID {
-	panic("implement me")
-}
-
-// testNetworkManager is a test implementation of NetworkManager interface.
-type testNetworkManager struct {
-	receptionMessages [][]format.Message
-	sendMessages      [][]cmix.TargetedCmixMessage
-	errSkip           int
-	sendErr           int
-	sync.RWMutex
-}
-
-func (tnm *testNetworkManager) Send(recipient *id.ID, fingerprint format.Fingerprint, service message.Service, payload, mac []byte, cmixParams cmix.CMIXParams) (id.Round, ephemeral.Id, error) {
-	panic("implement me")
-}
-
-func (tnm *testNetworkManager) SendMany(messages []cmix.TargetedCmixMessage, p cmix.CMIXParams) (id.Round, []ephemeral.Id, error) {
-	if tnm.sendErr == 1 {
-		return 0, nil, errors.New("SendManyCMIX error")
-	}
-
-	tnm.Lock()
-	defer tnm.Unlock()
-
-	tnm.sendMessages = append(tnm.sendMessages, messages)
-
-	receiveMessages := []format.Message{}
-	for _, msg := range messages {
-		receiveMsg := format.Message{}
-		receiveMsg.SetMac(msg.Mac)
-		receiveMsg.SetContents(msg.Payload)
-		receiveMsg.SetKeyFP(msg.Fingerprint)
-		receiveMessages = append(receiveMessages, receiveMsg)
-	}
-	tnm.receptionMessages = append(tnm.receptionMessages, receiveMessages)
-	return 0, nil, nil
-}
-
-func (tnm *testNetworkManager) GetIdentity(get *id.ID) (identity.TrackedID, error) {
-	panic("implement me")
-}
-
-func (tnm *testNetworkManager) GetInstance() *net.Instance {
-	panic("implement me")
-}
-
-func (tnm *testNetworkManager) GetVerboseRounds() string {
-	panic("implement me")
-}
-
-func (*testNetworkManager) Follow(report cmix.ClientErrorReport) (stoppable.Stoppable, error) {
-	panic("implement me")
-}
-
-func (*testNetworkManager) GetMaxMessageLength() int {
-	panic("implement me")
-}
-
-func (*testNetworkManager) AddIdentity(id *id.ID, validUntil time.Time, persistent bool) {
-	panic("implement me")
-}
-
-func (*testNetworkManager) RemoveIdentity(id *id.ID) {
-	panic("implement me")
-}
-
-func (*testNetworkManager) AddFingerprint(identity *id.ID, fingerprint format.Fingerprint, mp message.Processor) error {
-	panic("implement me")
-}
-
-func (*testNetworkManager) DeleteFingerprint(identity *id.ID, fingerprint format.Fingerprint) {
-	panic("implement me")
-}
-
-func (*testNetworkManager) DeleteClientFingerprints(identity *id.ID) {
-	panic("implement me")
-}
-
-func (*testNetworkManager) AddService(clientID *id.ID, newService message.Service, response message.Processor) {
-	panic("implement me")
-}
-
-func (*testNetworkManager) DeleteService(clientID *id.ID, toDelete message.Service, processor message.Processor) {
-	panic("implement me")
-}
-
-func (*testNetworkManager) DeleteClientService(clientID *id.ID) {
-	panic("implement me")
-}
-
-func (*testNetworkManager) TrackServices(tracker message.ServicesTracker) {
-	panic("implement me")
-}
-
-func (*testNetworkManager) CheckInProgressMessages() {
-	panic("implement me")
-}
-
-func (*testNetworkManager) IsHealthy() bool {
-	panic("implement me")
-}
-
-func (*testNetworkManager) WasHealthy() bool {
-	panic("implement me")
-}
-
-func (*testNetworkManager) AddHealthCallback(f func(bool)) uint64 {
-	panic("implement me")
-}
-
-func (*testNetworkManager) RemoveHealthCallback(u uint64) {
-	panic("implement me")
-}
-
-func (*testNetworkManager) HasNode(nid *id.ID) bool {
-	panic("implement me")
-}
-
-func (*testNetworkManager) NumRegisteredNodes() int {
-	panic("implement me")
-}
-
-func (*testNetworkManager) TriggerNodeRegistration(nid *id.ID) {
-	panic("implement me")
-}
-
-func (*testNetworkManager) GetRoundResults(timeout time.Duration, roundCallback cmix.RoundEventCallback, roundList ...id.Round) error {
-	panic("implement me")
-}
-
-func (*testNetworkManager) LookupHistoricalRound(rid id.Round, callback rounds.RoundResultCallback) error {
-	panic("implement me")
-}
-
-func (*testNetworkManager) SendToAny(sendFunc func(host *connect.Host) (interface{}, error), stop *stoppable.Single) (interface{}, error) {
-	panic("implement me")
-}
-
-func (*testNetworkManager) SendToPreferred(targets []*id.ID, sendFunc gateway.SendToPreferredFunc, stop *stoppable.Single, timeout time.Duration) (interface{}, error) {
-	panic("implement me")
-}
-
-func (*testNetworkManager) SetGatewayFilter(f gateway.Filter) {
-	panic("implement me")
-}
-
-func (*testNetworkManager) GetHostParams() connect.HostParams {
-	panic("implement me")
-}
-
-func (*testNetworkManager) GetAddressSpace() uint8 {
-	panic("implement me")
-}
-
-func (*testNetworkManager) RegisterAddressSpaceNotification(tag string) (chan uint8, error) {
-	panic("implement me")
-}
-
-func (*testNetworkManager) UnregisterAddressSpaceNotification(tag string) {
-	panic("implement me")
-}
-
-func (*testE2eManager) StartProcesses() (stoppable.Stoppable, error) {
-	panic("implement me")
-}
-
 func (tnm *testE2eManager) SendE2E(mt catalog.MessageType, recipient *id.ID, payload []byte, params clientE2E.Params) ([]id.Round, e2e.MessageID, time.Time, error) {
 	tnm.Lock()
 	defer tnm.Unlock()
@@ -456,56 +276,63 @@ func (*testE2eManager) RegisterListener(user *id.ID, messageType catalog.Message
 	panic("implement me")
 }
 
-func (*testE2eManager) RegisterFunc(name string, user *id.ID, messageType catalog.MessageType, newListener receive.ListenerFunc) receive.ListenerID {
+func (*testE2eManager) AddService(tag string, processor message.Processor) error {
 	panic("implement me")
 }
 
-func (*testE2eManager) RegisterChannel(name string, user *id.ID, messageType catalog.MessageType, newListener chan receive.Message) receive.ListenerID {
+func (*testE2eManager) GetDefaultHistoricalDHPubkey() *cyclic.Int {
 	panic("implement me")
 }
 
-func (*testE2eManager) Unregister(listenerID receive.ListenerID) {
+func (*testE2eManager) GetDefaultHistoricalDHPrivkey() *cyclic.Int {
 	panic("implement me")
 }
 
-func (*testE2eManager) AddService(tag string, processor message.Processor) error {
-	panic("implement me")
+func (tnm *testE2eManager) GetE2eMsg(i int) testE2eMessage {
+	tnm.RLock()
+	defer tnm.RUnlock()
+	return tnm.e2eMessages[i]
 }
 
-func (*testE2eManager) RemoveService(tag string) error {
-	panic("implement me")
+// testNetworkManager is a test implementation of NetworkManager interface.
+type testNetworkManager struct {
+	receptionMessages [][]format.Message
+	sendMessages      [][]cmix.TargetedCmixMessage
+	errSkip           int
+	sendErr           int
+	sync.RWMutex
 }
 
-func (*testE2eManager) SendUnsafe(mt catalog.MessageType, recipient *id.ID, payload []byte, params clientE2E.Params) ([]id.Round, time.Time, error) {
-	panic("implement me")
-}
+func (tnm *testNetworkManager) SendMany(messages []cmix.TargetedCmixMessage, p cmix.CMIXParams) (id.Round, []ephemeral.Id, error) {
+	if tnm.sendErr == 1 {
+		return 0, nil, errors.New("SendManyCMIX error")
+	}
 
-func (*testE2eManager) EnableUnsafeReception() {
-	panic("implement me")
-}
+	tnm.Lock()
+	defer tnm.Unlock()
 
-func (*testE2eManager) GetGroup() *cyclic.Group {
-	panic("implement me")
-}
+	tnm.sendMessages = append(tnm.sendMessages, messages)
 
-func (*testE2eManager) GetDefaultHistoricalDHPubkey() *cyclic.Int {
-	panic("implement me")
+	receiveMessages := []format.Message{}
+	for _, msg := range messages {
+		receiveMsg := format.Message{}
+		receiveMsg.SetMac(msg.Mac)
+		receiveMsg.SetContents(msg.Payload)
+		receiveMsg.SetKeyFP(msg.Fingerprint)
+		receiveMessages = append(receiveMessages, receiveMsg)
+	}
+	tnm.receptionMessages = append(tnm.receptionMessages, receiveMessages)
+	return 0, nil, nil
 }
 
-func (*testE2eManager) GetDefaultHistoricalDHPrivkey() *cyclic.Int {
+func (*testNetworkManager) AddService(clientID *id.ID, newService message.Service, response message.Processor) {
 	panic("implement me")
 }
 
-func (*testE2eManager) GetDefaultID() *id.ID {
+func (*testNetworkManager) DeleteService(clientID *id.ID, toDelete message.Service, processor message.Processor) {
 	panic("implement me")
 }
 
-func (tnm *testE2eManager) GetE2eMsg(i int) testE2eMessage {
-	tnm.RLock()
-	defer tnm.RUnlock()
-	return tnm.e2eMessages[i]
-}
-
 type dummyEventMgr struct{}
 
 func (d *dummyEventMgr) Report(int, string, string, string) {}