diff --git a/bindings/dummy.go b/bindings/dummy.go
new file mode 100644
index 0000000000000000000000000000000000000000..51d36dac453e40dbfe222bbefa4459ab5b30feac
--- /dev/null
+++ b/bindings/dummy.go
@@ -0,0 +1,84 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                           //
+//                                                                            //
+// Use of this source code is governed by a license that can be found in the  //
+// LICENSE file                                                               //
+////////////////////////////////////////////////////////////////////////////////
+
+package bindings
+
+import (
+	"gitlab.com/elixxir/client/dummy"
+	"time"
+)
+
+// DummyTraffic is the bindings-layer dummy (or "cover") traffic manager. T
+// The manager can be used to set and get the status of the thread responsible for
+// sending dummy messages.
+type DummyTraffic struct {
+	m *dummy.Manager
+}
+
+// NewDummyTrafficManager creates a DummyTraffic manager and initialises the
+// dummy traffic sending thread. Note that the manager does not start sending dummy
+// traffic until `True` is passed into DummyTraffic.SetStatus. The time duration
+// between each sending operation and the amount of messages sent each interval
+// are randomly generated values with bounds defined by the
+// given parameters below.
+//
+// Params:
+//  - cmixId - a Cmix object ID in the tracker.
+//  - maxNumMessages - the upper bound of the random number of messages sent
+//    each sending cycle.
+//  - avgSendDeltaMS - the average duration, in milliseconds, to wait
+//    between sends.
+//  - randomRangeMS - the upper bound of the interval between sending cycles,
+//    in milliseconds. Sends occur every avgSendDeltaMS +/- a random duration
+//    with an upper bound of randomRangeMS.
+func NewDummyTrafficManager(cmixId, maxNumMessages, avgSendDeltaMS,
+	randomRangeMS int) (*DummyTraffic, error) {
+
+	// Get user from singleton
+	net, err := cmixTrackerSingleton.get(cmixId)
+	if err != nil {
+		return nil, err
+	}
+
+	avgSendDelta := time.Duration(avgSendDeltaMS) * time.Millisecond
+	randomRange := time.Duration(randomRangeMS) * time.Millisecond
+
+	m := dummy.NewManager(
+		maxNumMessages, avgSendDelta, randomRange, net.api)
+
+	return &DummyTraffic{m}, net.api.AddService(m.StartDummyTraffic)
+}
+
+// SetStatus sets the state of the dummy traffic send thread by passing in
+// a boolean parameter. There may be a small delay in between this call
+// and the status of the sending thread to change accordingly. For example,
+// passing False into this call while the sending thread is currently sending messages
+// will not cancel nor halt the sending operation, but will pause the thread once that
+// operation has completed.
+//
+// Params:
+//  - boolean - True: Sending thread is sending dummy messages.
+//  			False: Sending thread is paused/stopped and is not sending dummy messages.
+// Returns:
+//  - error - if the DummyTraffic.SetStatus is called too frequently, causing the
+//    internal status channel to fill.
+func (dt *DummyTraffic) SetStatus(status bool) error {
+	return dt.m.SetStatus(status)
+}
+
+// GetStatus returns the current state of the dummy traffic sending thread.
+// Note that this function does not return the status set by the most recent call to
+// SetStatus directly. Instead, this call returns the current status of the sending thread.
+// This is due to the small delay that may occur between calling SetStatus and the
+// sending thread taking into effect that status change.
+//
+// Returns:
+//   - boolean - True: Sending thread is sending dummy messages.
+//  		   - False: Sending thread is paused/stopped and is not sending dummy messages.
+func (dt *DummyTraffic) GetStatus() bool {
+	return dt.m.GetStatus()
+}
diff --git a/dummy/manager.go b/dummy/manager.go
index 4832f3ef505ea37114c2f4d202c82604ddd7eab0..6a58eb981dda9dfa34876d6cfbd9c553e8c5b969 100644
--- a/dummy/manager.go
+++ b/dummy/manager.go
@@ -12,7 +12,7 @@ package dummy
 
 import (
 	"github.com/pkg/errors"
-	"gitlab.com/elixxir/client/interfaces"
+	"gitlab.com/elixxir/client/cmix"
 	"gitlab.com/elixxir/client/stoppable"
 	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/client/xxdk"
@@ -57,26 +57,38 @@ type Manager struct {
 	statusChan chan bool
 
 	// Cmix interfaces
-	net            *xxdk.Cmix
-	store          *storage.Session
-	networkManager interfaces.NetworkManager
-	rng            *fastRNG.StreamGenerator
+	net   cmix.Client
+	store storage.Session
+	rng   *fastRNG.StreamGenerator
 }
 
-// NewManager creates a new dummy Manager with the specified average send delta
-// and the range used for generating random durations.
-func NewManager(maxNumMessages int, avgSendDelta, randomRange time.Duration,
-	net *xxdk.Cmix, manager interfaces.NetworkManager) *Manager {
-	clientStorage := net.GetStorage()
-	return newManager(maxNumMessages, avgSendDelta, randomRange, net,
-		&clientStorage, manager, net.GetRng())
+// NewManager creates a Manager object and initialises the
+// dummy traffic sending thread. Note that the Manager does not start sending dummy
+// traffic until True is passed into Manager.SetStatus. The time duration
+// between each sending operation and the amount of messages sent each interval
+// are randomly generated values with bounds defined by the
+// given parameters below.
+//
+// Params:
+//  - maxNumMessages - the upper bound of the random number of messages sent
+//    each sending cycle.
+//  - avgSendDeltaMS - the average duration, in milliseconds, to wait
+//    between sends.
+//  - randomRangeMS - the upper bound of the interval between sending cycles.
+//    Sends occur every avgSendDeltaMS +/- a random duration with an
+//    upper bound of randomRangeMS
+func NewManager(maxNumMessages int,
+	avgSendDelta, randomRange time.Duration,
+	net *xxdk.Cmix) *Manager {
+
+	return newManager(maxNumMessages, avgSendDelta, randomRange, net.GetCmix(),
+		net.GetStorage(), net.GetRng())
 }
 
 // newManager builds a new dummy Manager from fields explicitly passed in. This
 // function is a helper function for NewManager to make it easier to test.
 func newManager(maxNumMessages int, avgSendDelta, randomRange time.Duration,
-	net *xxdk.Cmix, store *storage.Session, networkManager interfaces.NetworkManager,
-	rng *fastRNG.StreamGenerator) *Manager {
+	net cmix.Client, store storage.Session, rng *fastRNG.StreamGenerator) *Manager {
 	return &Manager{
 		maxNumMessages: maxNumMessages,
 		avgSendDelta:   avgSendDelta,
@@ -85,7 +97,6 @@ func newManager(maxNumMessages int, avgSendDelta, randomRange time.Duration,
 		statusChan:     make(chan bool, statusChanLen),
 		net:            net,
 		store:          store,
-		networkManager: networkManager,
 		rng:            rng,
 	}
 }
@@ -99,13 +110,19 @@ func (m *Manager) StartDummyTraffic() (stoppable.Stoppable, error) {
 	return stop, nil
 }
 
-// SetStatus sets the state of the dummy traffic send thread, which determines
-// if the thread is running or paused. The possible statuses are:
-//  true  = send thread is sending dummy messages
-//  false = send thread is paused/stopped and not sending dummy messages
-// Returns an error if the channel is full.
-// Note that this function cannot change the status of the send thread if it has
-// yet to be started via StartDummyTraffic or if it has been stopped.
+// SetStatus sets the state of the dummy traffic send thread by passing in
+// a boolean parameter. There may be a small delay in between this call
+// and the status of the sending thread to change accordingly. For example,
+// passing False into this call while the sending thread is currently sending messages
+// will not cancel nor halt the sending operation, but will pause the thread once that
+// operation has completed.
+//
+// Params:
+//  - boolean - True: Sending thread is sending dummy messages.
+//  			False: Sending thread is paused/stopped and is not sending dummy messages
+// Returns:
+//  - error - if the DummyTraffic.SetStatus is called too frequently, causing the
+//    internal status channel to fill.
 func (m *Manager) SetStatus(status bool) error {
 	select {
 	case m.statusChan <- status:
@@ -115,13 +132,15 @@ func (m *Manager) SetStatus(status bool) error {
 	}
 }
 
-// GetStatus returns the current state of the dummy traffic send thread. It has
-// the following return values:
-//  true  = send thread is sending dummy messages
-//  false = send thread is paused/stopped and not sending dummy messages
-// Note that this function does not return the status set by SetStatus directly;
-// it returns the current status of the send thread, which means any call to
-// SetStatus will have a small delay before it is returned by GetStatus.
+// GetStatus returns the current state of the dummy traffic sending thread.
+// Note that this function does not return the status set by the most recent call to
+// SetStatus directly. Instead, this call returns the current status of the sending thread.
+// This is due to the small delay that may occur between calling SetStatus and the
+// sending thread taking into effect that status change.
+//
+// Returns:
+//   - boolean - True: Sending thread is sending dummy messages.
+//  		   - False: Sending thread is paused/stopped and is not sending dummy messages.
 func (m *Manager) GetStatus() bool {
 	switch atomic.LoadUint32(&m.status) {
 	case running:
diff --git a/dummy/manager_test.go b/dummy/manager_test.go
index 6a49bcc6a597ebf476ee8bbfb8f45a79045a4488..7d1b490812b883142060211b9342de8929317257 100644
--- a/dummy/manager_test.go
+++ b/dummy/manager_test.go
@@ -27,7 +27,7 @@ func Test_newManager(t *testing.T) {
 	}
 
 	received := newManager(expected.maxNumMessages, expected.avgSendDelta,
-		expected.randomRange, nil, nil, nil, nil)
+		expected.randomRange, nil, nil, nil)
 
 	if statusChanLen != cap(received.statusChan) {
 		t.Errorf("Capacity of status channel unexpected."+
@@ -59,7 +59,7 @@ func TestManager_StartDummyTraffic(t *testing.T) {
 
 	msgChan := make(chan bool)
 	go func() {
-		for m.networkManager.(*testNetworkManager).GetMsgListLen() == 0 {
+		for m.net.(*mockCmix).GetMsgListLen() == 0 {
 			time.Sleep(5 * time.Millisecond)
 		}
 		msgChan <- true
@@ -71,7 +71,7 @@ func TestManager_StartDummyTraffic(t *testing.T) {
 		t.Errorf("Timed out after %s waiting for messages to be sent.",
 			3*m.avgSendDelta)
 	case <-msgChan:
-		numReceived += m.networkManager.(*testNetworkManager).GetMsgListLen()
+		numReceived += m.net.(*mockCmix).GetMsgListLen()
 	}
 
 	err = stop.Close()
@@ -86,7 +86,7 @@ func TestManager_StartDummyTraffic(t *testing.T) {
 
 	msgChan = make(chan bool)
 	go func() {
-		for m.networkManager.(*testNetworkManager).GetMsgListLen() == numReceived {
+		for m.net.(*mockCmix).GetMsgListLen() == numReceived {
 			time.Sleep(5 * time.Millisecond)
 		}
 		msgChan <- true
@@ -118,10 +118,10 @@ func TestManager_SetStatus(t *testing.T) {
 	go func() {
 		var numReceived int
 		for i := 0; i < 2; i++ {
-			for m.networkManager.(*testNetworkManager).GetMsgListLen() == numReceived {
+			for m.net.(*mockCmix).GetMsgListLen() == numReceived {
 				time.Sleep(5 * time.Millisecond)
 			}
-			numReceived = m.networkManager.(*testNetworkManager).GetMsgListLen()
+			numReceived = m.net.(*mockCmix).GetMsgListLen()
 			msgChan <- true
 		}
 	}()
@@ -161,7 +161,7 @@ func TestManager_SetStatus(t *testing.T) {
 		t.Errorf("Timed out after %s waiting for messages to be sent.",
 			3*m.avgSendDelta)
 	case <-msgChan:
-		numReceived += m.networkManager.(*testNetworkManager).GetMsgListLen()
+		numReceived += m.net.(*mockCmix).GetMsgListLen()
 	}
 
 	// Setting status to true multiple times does not interrupt sending
@@ -177,10 +177,10 @@ func TestManager_SetStatus(t *testing.T) {
 		t.Errorf("Timed out after %s waiting for messages to be sent.",
 			3*m.avgSendDelta)
 	case <-msgChan:
-		if m.networkManager.(*testNetworkManager).GetMsgListLen() <= numReceived {
+		if m.net.(*mockCmix).GetMsgListLen() <= numReceived {
 			t.Errorf("Failed to receive second send."+
 				"\nmessages on last receive: %d\nmessages on this receive: %d",
-				numReceived, m.networkManager.(*testNetworkManager).GetMsgListLen())
+				numReceived, m.net.(*mockCmix).GetMsgListLen())
 		}
 	}
 
@@ -254,10 +254,10 @@ func TestManager_GetStatus(t *testing.T) {
 	go func() {
 		var numReceived int
 		for i := 0; i < 2; i++ {
-			for m.networkManager.(*testNetworkManager).GetMsgListLen() == numReceived {
+			for m.net.(*mockCmix).GetMsgListLen() == numReceived {
 				time.Sleep(5 * time.Millisecond)
 			}
-			numReceived = m.networkManager.(*testNetworkManager).GetMsgListLen()
+			numReceived = m.net.(*mockCmix).GetMsgListLen()
 			msgChan <- true
 		}
 	}()
@@ -292,7 +292,7 @@ func TestManager_GetStatus(t *testing.T) {
 		t.Errorf("Timed out after %s waiting for messages to be sent.",
 			3*m.avgSendDelta)
 	case <-msgChan:
-		numReceived += m.networkManager.(*testNetworkManager).GetMsgListLen()
+		numReceived += m.net.(*mockCmix).GetMsgListLen()
 	}
 
 	// Setting status to true multiple times does not interrupt sending
@@ -311,10 +311,10 @@ func TestManager_GetStatus(t *testing.T) {
 		t.Errorf("Timed out after %s waiting for messages to be sent.",
 			3*m.avgSendDelta)
 	case <-msgChan:
-		if m.networkManager.(*testNetworkManager).GetMsgListLen() <= numReceived {
+		if m.net.(*mockCmix).GetMsgListLen() <= numReceived {
 			t.Errorf("Failed to receive second send."+
 				"\nmessages on last receive: %d\nmessages on this receive: %d",
-				numReceived, m.networkManager.(*testNetworkManager).GetMsgListLen())
+				numReceived, m.net.(*mockCmix).GetMsgListLen())
 		}
 	}
 
diff --git a/dummy/mockCmix_test.go b/dummy/mockCmix_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..bcee48e70c04c878a6283f154a0d07f6808147dc
--- /dev/null
+++ b/dummy/mockCmix_test.go
@@ -0,0 +1,217 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                           //
+//                                                                            //
+// Use of this source code is governed by a license that can be found in the  //
+// LICENSE file                                                               //
+////////////////////////////////////////////////////////////////////////////////
+
+package dummy
+
+import (
+	"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"
+	"gitlab.com/elixxir/client/stoppable"
+	"gitlab.com/elixxir/comms/network"
+	"gitlab.com/elixxir/primitives/format"
+	"gitlab.com/xx_network/comms/connect"
+	"gitlab.com/xx_network/primitives/id"
+	"gitlab.com/xx_network/primitives/id/ephemeral"
+	"sync"
+	"time"
+)
+
+// mockCmix is a testing structure that adheres to cmix.Client.
+type mockCmix struct {
+	messages map[id.ID][]byte
+	sync.RWMutex
+}
+
+func newMockCmix() cmix.Client {
+
+	return &mockCmix{
+		messages: make(map[id.ID][]byte),
+	}
+}
+
+func (m *mockCmix) Send(recipient *id.ID, fingerprint format.Fingerprint, service message.Service, payload, mac []byte, cmixParams cmix.CMIXParams) (id.Round, ephemeral.Id, error) {
+	m.Lock()
+	defer m.Unlock()
+	m.messages[*recipient] = fingerprint.Bytes()
+
+	return 0, ephemeral.Id{}, nil
+}
+
+func (m *mockCmix) GetMsgListLen() int {
+	m.RLock()
+	defer m.RUnlock()
+	return len(m.messages)
+}
+
+func (m *mockCmix) GetMsgList() map[id.ID][]byte {
+	m.RLock()
+	defer m.RUnlock()
+	return m.messages
+}
+
+func (m mockCmix) Follow(report cmix.ClientErrorReport) (stoppable.Stoppable, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) GetMaxMessageLength() int {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m *mockCmix) SendMany(messages []cmix.TargetedCmixMessage, p cmix.CMIXParams) (id.Round, []ephemeral.Id, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m *mockCmix) AddIdentity(id *id.ID, validUntil time.Time, persistent bool) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m *mockCmix) RemoveIdentity(id *id.ID) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) GetIdentity(get *id.ID) (identity.TrackedID, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) AddFingerprint(identity *id.ID, fingerprint format.Fingerprint, mp message.Processor) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) DeleteFingerprint(identity *id.ID, fingerprint format.Fingerprint) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) DeleteClientFingerprints(identity *id.ID) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) AddService(clientID *id.ID, newService message.Service, response message.Processor) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) DeleteService(clientID *id.ID, toDelete message.Service, processor message.Processor) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) DeleteClientService(clientID *id.ID) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) TrackServices(tracker message.ServicesTracker) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) CheckInProgressMessages() {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) IsHealthy() bool {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) WasHealthy() bool {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) AddHealthCallback(f func(bool)) uint64 {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) RemoveHealthCallback(u uint64) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) HasNode(nid *id.ID) bool {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) NumRegisteredNodes() int {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) TriggerNodeRegistration(nid *id.ID) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) GetRoundResults(timeout time.Duration, roundCallback cmix.RoundEventCallback, roundList ...id.Round) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) LookupHistoricalRound(rid id.Round, callback rounds.RoundResultCallback) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) SendToAny(sendFunc func(host *connect.Host) (interface{}, error), stop *stoppable.Single) (interface{}, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) SendToPreferred(targets []*id.ID, sendFunc gateway.SendToPreferredFunc, stop *stoppable.Single, timeout time.Duration) (interface{}, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) SetGatewayFilter(f gateway.Filter) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) GetHostParams() connect.HostParams {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) GetAddressSpace() uint8 {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) RegisterAddressSpaceNotification(tag string) (chan uint8, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) UnregisterAddressSpaceNotification(tag string) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) GetInstance() *network.Instance {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockCmix) GetVerboseRounds() string {
+	//TODO implement me
+	panic("implement me")
+}
diff --git a/dummy/send.go b/dummy/send.go
index 84271b67ea4310bf91af057a58ffe2256520460a..ffb6fed4247c16675e36e242b63fdfac355d527b 100644
--- a/dummy/send.go
+++ b/dummy/send.go
@@ -8,6 +8,7 @@
 package dummy
 
 import (
+	"gitlab.com/elixxir/client/cmix/message"
 	"sync"
 	"sync/atomic"
 	"time"
@@ -32,7 +33,7 @@ const (
 
 // sendThread is a thread that sends the dummy messages at random intervals.
 func (m *Manager) sendThread(stop *stoppable.Single) {
-	jww.DEBUG.Print("Starting dummy traffic sending thread.")
+	jww.INFO.Print("Starting dummy traffic sending thread.")
 
 	nextSendChan := make(<-chan time.Time)
 	nextSendChanPtr := &(nextSendChan)
@@ -57,15 +58,16 @@ func (m *Manager) sendThread(stop *stoppable.Single) {
 			go func() {
 				// get list of random messages and recipients
 				rng := m.rng.GetStream()
+				defer rng.Close()
 				msgs, err := m.newRandomMessages(rng)
 				if err != nil {
-					jww.FATAL.Panicf("Failed to generate dummy messages: %+v", err)
+					jww.ERROR.Printf("Failed to generate dummy messages: %+v", err)
+					return
 				}
-				rng.Close()
 
-				err = m.sendMessages(msgs)
+				err = m.sendMessages(msgs, rng)
 				if err != nil {
-					jww.FATAL.Panicf("Failed to send dummy messages: %+v", err)
+					jww.ERROR.Printf("Failed to send dummy messages: %+v", err)
 				}
 			}()
 
@@ -84,7 +86,7 @@ func (m *Manager) stopSendThread(stop *stoppable.Single) {
 }
 
 // sendMessages generates and sends random messages.
-func (m *Manager) sendMessages(msgs map[id.ID]format.Message) error {
+func (m *Manager) sendMessages(msgs map[id.ID]format.Message, rng csprng.Source) error {
 	var sent, i int64
 	var wg sync.WaitGroup
 
@@ -95,18 +97,9 @@ func (m *Manager) sendMessages(msgs map[id.ID]format.Message) error {
 			defer wg.Done()
 
 			// Fill the preimage with random data to ensure it is not repeatable
-			p := cmix.GetDefaultParams()
-			// FIXME: these fields no longer available
-			//        through these params objects
-			// p.IdentityPreimage = make([]byte, 32)
-			// rng := m.rng.GetStream()
-			// if _, err := rng.Read(p.IdentityPreimage); err != nil {
-			// 	jww.FATAL.Panicf("Failed to generate data for random identity "+
-			// 		"preimage in e2e send: %+v", err)
-			// }
-			// rng.Close()
-			// p.DebugTag = "dummy"
-			_, _, err := m.networkManager.SendCMIX(msg, &recipient, p)
+			p := cmix.GetDefaultCMIXParams()
+			_, _, err := m.net.Send(&recipient, msg.GetKeyFP(),
+				message.GetRandomService(rng), msg.GetContents(), msg.GetMac(), p)
 			if err != nil {
 				jww.WARN.Printf("Failed to send dummy message %d/%d via "+
 					"Send: %+v", i, len(msgs), err)
@@ -156,8 +149,7 @@ func (m *Manager) newRandomMessages(rng csprng.Source) (
 // generated payload, fingerprint, and MAC.
 func (m *Manager) newRandomCmixMessage(rng csprng.Source) (format.Message, error) {
 	// Create new empty cMix message
-	clientStorage := *m.store
-	cMixMsg := format.NewMessage(clientStorage.GetCmixGroup().GetP().ByteLen())
+	cMixMsg := format.NewMessage(m.store.GetCmixGroup().GetP().ByteLen())
 
 	// Generate random message
 	randomMsg, err := newRandomPayload(cMixMsg.ContentsSize(), rng)
diff --git a/dummy/send_test.go b/dummy/send_test.go
index 9af8ee8796e4d76faa7d45188c60db271d772335..625a203ae5b2d6beb9a8287d1f7adcfe412deebf 100644
--- a/dummy/send_test.go
+++ b/dummy/send_test.go
@@ -40,10 +40,10 @@ func TestManager_sendThread(t *testing.T) {
 	go func() {
 		var numReceived int
 		for i := 0; i < 2; i++ {
-			for m.networkManager.(*testNetworkManager).GetMsgListLen() == numReceived {
+			for m.net.(*mockCmix).GetMsgListLen() == numReceived {
 				time.Sleep(5 * time.Millisecond)
 			}
-			numReceived = m.networkManager.(*testNetworkManager).GetMsgListLen()
+			numReceived = m.net.(*mockCmix).GetMsgListLen()
 			msgChan <- true
 		}
 	}()
@@ -54,7 +54,7 @@ func TestManager_sendThread(t *testing.T) {
 		t.Errorf("Timed out after %s waiting for messages to be sent.",
 			3*m.avgSendDelta)
 	case <-msgChan:
-		numReceived += m.networkManager.(*testNetworkManager).GetMsgListLen()
+		numReceived += m.net.(*mockCmix).GetMsgListLen()
 	}
 
 	select {
@@ -62,10 +62,10 @@ func TestManager_sendThread(t *testing.T) {
 		t.Errorf("Timed out after %s waiting for messages to be sent.",
 			3*m.avgSendDelta)
 	case <-msgChan:
-		if m.networkManager.(*testNetworkManager).GetMsgListLen() <= numReceived {
+		if m.net.(*mockCmix).GetMsgListLen() <= numReceived {
 			t.Errorf("Failed to receive second send."+
 				"\nmessages on last receive: %d\nmessages on this receive: %d",
-				numReceived, m.networkManager.(*testNetworkManager).GetMsgListLen())
+				numReceived, m.net.(*mockCmix).GetMsgListLen())
 		}
 	}
 
@@ -109,13 +109,13 @@ func TestManager_sendMessages(t *testing.T) {
 	}
 
 	// Send the messages
-	err := m.sendMessages(msgs)
+	err := m.sendMessages(msgs, prng)
 	if err != nil {
 		t.Errorf("sendMessages returned an error: %+v", err)
 	}
 
 	// get sent messages
-	receivedMsgs := m.networkManager.(*testNetworkManager).GetMsgList()
+	receivedMsgs := m.net.(*mockCmix).GetMsgList()
 
 	// Test that all messages were received
 	if len(receivedMsgs) != len(msgs) {
@@ -128,9 +128,10 @@ func TestManager_sendMessages(t *testing.T) {
 		receivedMsg, exists := receivedMsgs[recipient]
 		if !exists {
 			t.Errorf("Failed to receive message from %s: %+v", &recipient, msg)
-		} else if !reflect.DeepEqual(msg, receivedMsg) {
+		} else if !reflect.DeepEqual(msg.GetKeyFP().Bytes(), receivedMsg) {
+			// In mockCmix.Send, we map recipientId to the passed fingerprint.
 			t.Errorf("Received unexpected message for recipient %s."+
-				"\nexpected: %+v\nreceived: %+v", &recipient, msg, receivedMsg)
+				"\nexpected: %+v\nreceived: %+v", &recipient, msg.GetKeyFP(), receivedMsg)
 		}
 	}
 }
diff --git a/dummy/utils_test.go b/dummy/utils_test.go
index bc838731f5f42b345c4fbdfd849750b4551c0ef5..bef9291f030af9f5d67119e65d5d5ec25640c0bf 100644
--- a/dummy/utils_test.go
+++ b/dummy/utils_test.go
@@ -8,27 +8,12 @@
 package dummy
 
 import (
-	"github.com/pkg/errors"
-	"gitlab.com/elixxir/client/cmix"
-	"gitlab.com/elixxir/client/cmix/gateway"
-	"gitlab.com/elixxir/client/cmix/message"
-	"gitlab.com/elixxir/client/event"
-	"gitlab.com/elixxir/client/interfaces"
-	"gitlab.com/elixxir/client/stoppable"
 	"gitlab.com/elixxir/client/storage"
-	"gitlab.com/elixxir/comms/mixmessages"
-	"gitlab.com/elixxir/comms/network"
-	"gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/elixxir/crypto/fastRNG"
-	"gitlab.com/elixxir/primitives/format"
-	"gitlab.com/xx_network/comms/connect"
 	"gitlab.com/xx_network/crypto/csprng"
-	"gitlab.com/xx_network/primitives/id"
-	"gitlab.com/xx_network/primitives/id/ephemeral"
 	"gitlab.com/xx_network/primitives/ndf"
 	"io"
 	"math/rand"
-	"sync"
 	"testing"
 	"time"
 )
@@ -58,156 +43,14 @@ func newTestManager(maxNumMessages int, avgSendDelta, randomRange time.Duration,
 		avgSendDelta:   avgSendDelta,
 		randomRange:    randomRange,
 		statusChan:     make(chan bool, statusChanLen),
-		store:          &store,
-		networkManager: newTestNetworkManager(sendErr, t),
+		store:          store,
+		net:            newMockCmix(),
 		rng:            fastRNG.NewStreamGenerator(1000, 10, csprng.NewSystemRNG),
 	}
 
 	return m
 }
 
-// ////////////////////////////////////////////////////////////////////////////////
-// // Test Network State                                                       //
-// ////////////////////////////////////////////////////////////////////////////////
-
-// // testNetworkManager is a test implementation of NetworkManager interface.
-type testNetworkManager struct {
-	instance *network.Instance
-	messages map[id.ID]format.Message
-	sendErr  bool
-	sync.RWMutex
-}
-
-func newTestNetworkManager(sendErr bool, t *testing.T) interfaces.NetworkManager {
-	instanceComms := &connect.ProtoComms{
-		Manager: connect.NewManagerTesting(t),
-	}
-
-	thisInstance, err := network.NewInstanceTesting(instanceComms, getNDF(),
-		getNDF(), nil, nil, t)
-	if err != nil {
-		t.Fatalf("Failed to create new test instance: %v", err)
-	}
-
-	return &testNetworkManager{
-		instance: thisInstance,
-		messages: make(map[id.ID]format.Message),
-		sendErr:  sendErr,
-	}
-}
-
-func (tnm *testNetworkManager) GetMsgListLen() int {
-	tnm.RLock()
-	defer tnm.RUnlock()
-	return len(tnm.messages)
-}
-
-func (tnm *testNetworkManager) GetMsgList() map[id.ID]format.Message {
-	tnm.RLock()
-	defer tnm.RUnlock()
-	return tnm.messages
-}
-
-func (tnm *testNetworkManager) GetMsg(recipient id.ID) format.Message {
-	tnm.RLock()
-	defer tnm.RUnlock()
-	return tnm.messages[recipient]
-}
-
-// TEST
-func (tnm *testNetworkManager) SendE2E() (
-	[]id.Round, e2e.MessageID, time.Time, error) {
-	return nil, e2e.MessageID{}, time.Time{}, nil
-}
-
-// TEST
-func (tnm *testNetworkManager) SendUnsafe() ([]id.Round, error) {
-	return []id.Round{}, nil
-}
-
-func (tnm *testNetworkManager) SendCMIX(message format.Message,
-	recipient *id.ID, _ cmix.Params) (id.Round, ephemeral.Id, error) {
-	tnm.Lock()
-	defer tnm.Unlock()
-
-	if tnm.sendErr {
-		return 0, ephemeral.Id{}, errors.New("Send error")
-	}
-
-	tnm.messages[*recipient] = message
-
-	return 0, ephemeral.Id{}, nil
-}
-
-func (tnm *testNetworkManager) SendManyCMIX([]cmix.TargetedCmixMessage, cmix.Params) (
-	id.Round, []ephemeral.Id, error) {
-	return 0, nil, nil
-}
-
-type dummyEventMgr struct{}
-
-func (d *dummyEventMgr) Report(int, string, string, string) {}
-func (tnm *testNetworkManager) GetEventManager() event.Reporter {
-	return &dummyEventMgr{}
-}
-
-func (tnm *testNetworkManager) GetInstance() *network.Instance             { return tnm.instance }
-func (tnm *testNetworkManager) GetAddressSpace() uint8                     { return 0 }
-func (tnm *testNetworkManager) GetHostParams() connect.HostParams          { return connect.HostParams{} }
-func (tnm *testNetworkManager) GetHealthTracker() interfaces.HealthTracker { return nil }
-func (tnm *testNetworkManager) Follow(interfaces.ClientErrorReport) (stoppable.Stoppable, error) {
-	return nil, nil
-}
-func (tnm *testNetworkManager) CheckGarbledMessages()        {}
-func (tnm *testNetworkManager) CheckInProgressMessages()     {}
-func (tnm *testNetworkManager) InProgressRegistrations() int { return 0 }
-func (tnm *testNetworkManager) GetSender() *gateway.Sender   { return nil }
-func (tnm *testNetworkManager) GetAddressSize() uint8        { return 0 }
-func (tnm *testNetworkManager) RegisterAddressSizeNotification(string) (chan uint8, error) {
-	return nil, nil
-}
-func (tnm *testNetworkManager) UnregisterAddressSizeNotification(string) {}
-func (tnm *testNetworkManager) SetPoolFilter(gateway.Filter)             {}
-func (tnm *testNetworkManager) GetVerboseRounds() string                 { return "" }
-func (tnm *testNetworkManager) HasNode(*id.ID) bool                      { return false }
-func (tnm *testNetworkManager) LookupHistoricalRound(id.Round, func(*mixmessages.RoundInfo, bool)) error {
-	return nil
-}
-func (tnm *testNetworkManager) NumRegisteredNodes() int { return 0 }
-func (tnm *testNetworkManager) RegisterAddressSpaceNotification(string) (chan uint8, error) {
-	return nil, nil
-}
-func (tnm *testNetworkManager) SendToAny(func(*connect.Host) (interface{}, error), *stoppable.Single) (interface{}, error) {
-	return nil, nil
-}
-func (tnm *testNetworkManager) SendToPreferred([]*id.ID, func(*connect.Host, *id.ID, time.Duration) (interface{}, error), *stoppable.Single, time.Duration) (interface{}, error) {
-	return nil, nil
-}
-func (tnm *testNetworkManager) SetGatewayFilter(func(map[id.ID]int, *ndf.NetworkDefinition) map[id.ID]int) {
-}
-func (tnm *testNetworkManager) TrackServices(message.ServicesTracker)     {}
-func (tnm *testNetworkManager) TriggerNodeRegistration(*id.ID)            {}
-func (tnm *testNetworkManager) UnregisterAddressSpaceNotification(string) {}
-
-func (tnm *testNetworkManager) AddFingerprint(*id.ID, format.Fingerprint, message.Processor) error {
-	return nil
-}
-func (tnm *testNetworkManager) DeleteFingerprint(*id.ID, format.Fingerprint) {}
-func (tnm *testNetworkManager) DeleteClientFingerprints(*id.ID)              {}
-
-func (tnm *testNetworkManager) AddIdentity(*id.ID, time.Time, bool) error { return nil }
-func (tnm *testNetworkManager) RemoveIdentity(*id.ID)                     {}
-
-func (tnm *testNetworkManager) AddTrigger(*id.ID, message.Service, message.Processor) {}
-func (tnm *testNetworkManager) DeleteTrigger(*id.ID, interfaces.Preimage, message.Processor) error {
-	return nil
-}
-func (tnm *testNetworkManager) DeleteClientTriggers(*id.ID) {}
-
-// ////////////////////////////////////////////////////////////////////////////////
-// // NDF Primes                                                                 //
-// ////////////////////////////////////////////////////////////////////////////////
-
 func getNDF() *ndf.NetworkDefinition {
 	return &ndf.NetworkDefinition{
 		E2E: ndf.Group{
diff --git a/interfaces/networkManager.go b/interfaces/networkManager.go
deleted file mode 100644
index 2139e9597c6a4cdc51714e47308d6aa91d3481c5..0000000000000000000000000000000000000000
--- a/interfaces/networkManager.go
+++ /dev/null
@@ -1,244 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// Copyright © 2020 xx network SEZC                                          //
-//                                                                           //
-// Use of this source code is governed by a license that can be found in the //
-// LICENSE file                                                              //
-///////////////////////////////////////////////////////////////////////////////
-
-package interfaces
-
-import (
-	"time"
-
-	"gitlab.com/elixxir/comms/network"
-	"gitlab.com/xx_network/comms/connect"
-	"gitlab.com/xx_network/primitives/ndf"
-
-	"gitlab.com/elixxir/client/cmix"
-	"gitlab.com/elixxir/client/cmix/message"
-	"gitlab.com/elixxir/client/stoppable"
-	"gitlab.com/elixxir/comms/mixmessages"
-	"gitlab.com/elixxir/primitives/format"
-	"gitlab.com/xx_network/primitives/id"
-	"gitlab.com/xx_network/primitives/id/ephemeral"
-)
-
-type NetworkManager interface {
-	// Follow starts the tracking of the network in a new thread.
-	// Errors that occur are reported on the ClientErrorReport function if
-	// passed. The returned stopable can be used to stop the follower.
-	// Only one follower may run at a time.
-	Follow(report ClientErrorReport) (stoppable.Stoppable, error)
-
-	/*===Sending==========================================================*/
-
-	// SendCMIX sends a "raw" CMIX message payload to the provided
-	// recipient.  Returns the round ID of the round the payload
-	// was sent or an error if it fails.
-	SendCMIX(message format.Message, recipient *id.ID, p cmix.Params) (
-		id.Round, ephemeral.Id, error)
-
-	// SendManyCMIX sends many "raw" cMix message payloads to each
-	// of the provided recipients. Used to send messages in group
-	// chats. Metadata is NOT as well protected with this call and
-	// can leak data about yourself. Should be replaced with
-	// multiple uses of SendCmix in most cases. Returns the round
-	// ID of the round the payload was sent or an error if it
-	// fails.
-	// WARNING: Potentially Unsafe
-	SendManyCMIX(messages []cmix.TargetedCmixMessage, p cmix.Params) (
-		id.Round, []ephemeral.Id, error)
-
-	/*===Message Reception================================================*/
-	/* Identities are all network identities which the client is currently
-	trying to pick up message on. An identity must be added
-	to receive messages, fake ones will be used to poll the network
-	if none are present. On creation of the network handler, the identity in
-	session storage will be automatically added*/
-
-	// AddIdentity adds an identity to be tracked
-	// If persistent is false, the identity will not be stored to disk and
-	// will be dropped on reload.
-	AddIdentity(id *id.ID, validUntil time.Time, persistent bool) error
-	// RemoveIdentity removes a currently tracked identity.
-	RemoveIdentity(id *id.ID)
-
-	/* Fingerprints are the primary mechanism of identifying a
-	picked up message over cMix. They are a unique one time use
-	255 bit vector generally associated with a specific encryption
-	key, but can be used for an alternative protocol.When
-	registering a fingerprint, a MessageProcessor is registered to
-	handle the message.*/
-
-	// AddFingerprint - Adds a fingerprint which will be handled by a
-	// specific processor for messages received by the given identity
-	AddFingerprint(identity *id.ID, fingerprint format.Fingerprint,
-		mp message.Processor) error
-
-	// DeleteFingerprint deletes a single fingerprint associated
-	// with the given identity if it exists
-
-	DeleteFingerprint(identity *id.ID, fingerprint format.Fingerprint)
-	// DeleteClientFingerprints deletes al fingerprint associated
-	// with the given identity if it exists
-	DeleteClientFingerprints(identity *id.ID)
-
-	/* trigger - predefined hash based tags appended to all cMix messages
-	which, though trial hashing, are used to determine if a message applies
-	to this client
-
-	Triggers are used for 2 purposes - They can be processed by the
-	notifications system, or can be used to implement custom non fingerprint
-	processing of payloads. I.E. key negotiation, broadcast negotiation
-
-	A tag is appended to the message of the format tag =
-	H(H(messageContents), preimage) and trial hashing is used to
-	determine if a message adheres to a tag.
-
-	WARNING: If a preimage is known by an adversary, they can
-	determine which messages are for the client on reception
-	(which is normally hidden due to collision between ephemeral
-	IDs.
-
-	Due to the extra overhead of trial hashing, triggers are
-	processed after fingerprints.  If a fingerprint match occurs
-	on the message, triggers will not be handled.
-
-	Triggers are address to the session. When starting a new
-	client, all triggers must be re-added before
-	StartNetworkFollower is called.
-	*/
-
-	// AddTrigger - Adds a trigger which can call a message
-	// handing function or be used for notifications. Multiple
-	// triggers can be registered for the same preimage.
-	//   preimage - the preimage which is triggered on
-	//   type - a descriptive string of the trigger. Generally
-	//          used in notifications
-	//   source - a byte buffer of related data. Generally used in
-	//            notifications.
-	//     Example: Sender ID
-	AddTrigger(identity *id.ID, newTrigger message.Service,
-		response message.Processor)
-
-	// DeleteTrigger - If only a single response is associated with the
-	// preimage, the entire preimage is removed. If there is more than one
-	// response, only the given response is removed if nil is passed in for
-	// response, all triggers for the preimage will be removed
-	DeleteTrigger(identity *id.ID, preimage Preimage,
-		response message.Processor) error
-
-	// DeleteClientTriggers - deletes all triggers assoseated with
-	// the given identity
-	DeleteClientTriggers(identity *id.ID)
-
-	// TrackServices - Registers a callback which will get called
-	// every time triggers change.
-	// It will receive the triggers list every time it is modified.
-	// Will only get callbacks while the Network Follower is running.
-	// Multiple trackTriggers can be registered
-	TrackServices(message.ServicesTracker)
-
-	/* In inProcess */
-	// it is possible to receive a message over cMix before the
-	// fingerprints or triggers are registered. As a result, when
-	// handling fails, messages are put in the inProcess que for a
-	// set number of retries.
-
-	// CheckInProgressMessages - retry processing all messages in check in
-	// progress messages. Call this after adding fingerprints or triggers
-	//while the follower is running.
-	CheckInProgressMessages()
-
-	/*===Nodes============================================================*/
-	/* Keys must be registed with nodes in order to send messages
-	throug them.  this process is in general automatically handled
-	by the Network Manager*/
-
-	// HasNode can be used to determine if a keying relationship
-	// exists with a node.
-	HasNode(nid *id.ID) bool
-
-	// NumRegisteredNodes Returns the total number of nodes we have a keying
-	// relationship with
-	NumRegisteredNodes() int
-
-	// TriggerNodeRegistration triggers the generation of a keying
-	// relationship with a given node
-	TriggerNodeRegistration(nid *id.ID)
-
-	/*===Historical Rounds================================================*/
-	/* A complete set of round info is not kept on the client, and sometimes
-	the network will need to be queried to get round info. Historical rounds
-	is the system internal to the Network Manager to do this.
-	It can be used externally as well.*/
-
-	// LookupHistoricalRound - looks up the passed historical round on the
-	// network
-	LookupHistoricalRound(rid id.Round,
-		callback func(info *mixmessages.RoundInfo,
-		success bool)) error
-
-	/*===Sender===========================================================*/
-	/* The sender handles sending comms to the network. It tracks
-	connections to gateways and handles proxying to gateways for
-	targeted comms. It can be used externally to contact gateway
-	directly, bypassing the majority of the network package*/
-
-	// SendToAny can be used to send the comm to any gateway in the network.
-	SendToAny(sendFunc func(host *connect.Host) (interface{}, error),
-		stop *stoppable.Single) (interface{}, error)
-
-	// SendToPreferred sends to a specific gateway, doing so through another
-	// gateway as a proxy if not directly connected.
-	SendToPreferred(targets []*id.ID, sendFunc func(host *connect.Host,
-		target *id.ID, timeout time.Duration) (interface{}, error),
-		stop *stoppable.Single, timeout time.Duration) (interface{},
-		error)
-
-	// SetGatewayFilter sets a function which will be used to
-	// filter gateways before connecting.
-	SetGatewayFilter(f func(map[id.ID]int,
-		*ndf.NetworkDefinition) map[id.ID]int)
-
-	// GetHostParams - returns the host params used when
-	// connectign to gateways
-	GetHostParams() connect.HostParams
-
-	/*===Address Space====================================================*/
-	// The network compasses identities into a smaller address
-	// space to cause collisions and hide the actual recipient of
-	// messages. These functions allow for the tracking of this
-	// addresses space. In general, address space issues are
-	// completely handled by the network package
-
-	// GetAddressSpace GetAddressSize returns the current address
-	// size of IDs. Blocks until an address size is known.
-	GetAddressSpace() uint8
-
-	// RegisterAddressSpaceNotification returns a channel that
-	// will trigger for every address space size update. The
-	// provided tag is the unique ID for the channel. Returns an
-	// error if the tag is already used.
-	RegisterAddressSpaceNotification(tag string) (chan uint8, error)
-
-	// UnregisterAddressSpaceNotification stops broadcasting
-	// address space size updates on the channel with the
-	// specified tag.
-	UnregisterAddressSpaceNotification(tag string)
-
-	/*===Accessors========================================================*/
-
-	// GetInstance returns the network instance object, which tracks the
-	// state of the network
-	GetInstance() *network.Instance
-
-	// GetHealthTracker returns the health tracker, which using a polling or
-	// event api lets you determine if network following is functioning
-	GetHealthTracker() HealthTracker
-
-	// GetVerboseRounds returns stringification of verbose round info
-	GetVerboseRounds() string
-}
-
-type Preimage [32]byte