diff --git a/api/client.go b/api/client.go
index a9e632ee8c20b3ade858d47fd33f30c658e3e0f4..02d8cb741e863a6d44810615dd9958dcd15e9d28 100644
--- a/api/client.go
+++ b/api/client.go
@@ -63,7 +63,7 @@ type Client struct {
 	//object used to register and communicate with permissioning
 	permissioning *registration.Registration
 	//object containing auth interactions
-	auth *auth.Manager
+	auth *auth.State
 
 	//services system to track running threads
 	followerServices *services
diff --git a/auth/callback.go b/auth/callback.go
index c82f0c85086ce903c1317056d26e620c1a0930fa..73b0a6bbe668a9643a38f0b20eb03c150fd5daf6 100644
--- a/auth/callback.go
+++ b/auth/callback.go
@@ -30,7 +30,7 @@ import (
 	"gitlab.com/xx_network/primitives/id"
 )
 
-func (m *Manager) StartProcesses() (stoppable.Stoppable, error) {
+func (s *State) StartProcesses() (stoppable.Stoppable, error) {
 	stop := stoppable.NewSingle("Auth")
 
 	go func() {
@@ -39,8 +39,8 @@ func (m *Manager) StartProcesses() (stoppable.Stoppable, error) {
 			case <-stop.Quit():
 				stop.ToStopped()
 				return
-			case msg := <-m.rawMessages:
-				m.processAuthMessage(msg)
+			case msg := <-s.rawMessages:
+				s.processAuthMessage(msg)
 			}
 		}
 	}()
@@ -48,8 +48,8 @@ func (m *Manager) StartProcesses() (stoppable.Stoppable, error) {
 	return stop, nil
 }
 
-func (m *Manager) processAuthMessage(msg message.Receive) {
-	authStore := m.storage.Auth()
+func (s *State) processAuthMessage(msg message.Receive) {
+	authStore := s.storage.Auth()
 	//lookup the message, check if it is an auth request
 	cmixMsg, err := format.Unmarshal(msg.Payload)
 	if err != nil {
@@ -72,24 +72,24 @@ func (m *Manager) processAuthMessage(msg message.Receive) {
 	}
 
 	//denote that the message is not garbled
-	m.storage.GetGarbledMessages().Remove(cmixMsg)
-	grp := m.storage.E2e().GetGroup()
+	s.storage.GetGarbledMessages().Remove(cmixMsg)
+	grp := s.storage.E2e().GetGroup()
 
 	switch fpType {
 	case auth2.General:
 		// if it is general, that means a new request has
 		// been received
-		m.handleRequest(cmixMsg, myHistoricalPrivKey, grp)
+		s.handleRequest(cmixMsg, myHistoricalPrivKey, grp)
 	case auth2.Specific:
 		// if it is specific, that means the original request was sent
 		// by this users and a confirmation has been received
 		jww.INFO.Printf("Received AuthConfirm from %s, msgDigest: %s",
 			sr.GetPartner(), cmixMsg.Digest())
-		m.handleConfirm(cmixMsg, sr, grp)
+		s.handleConfirm(cmixMsg, sr, grp)
 	}
 }
 
-func (m *Manager) handleRequest(cmixMsg format.Message,
+func (s *State) handleRequest(cmixMsg format.Message,
 	myHistoricalPrivKey *cyclic.Int, grp *cyclic.Group) {
 	//decode the outer format
 	baseFmt, partnerPubKey, err := handleBaseFormat(
@@ -155,7 +155,7 @@ func (m *Manager) handleRequest(cmixMsg format.Message,
 		return
 	}
 
-	events := m.net.GetEventManager()
+	events := s.net.GetEventManager()
 	em := fmt.Sprintf("Received AuthRequest from %s,"+
 		" msgDigest: %s", partnerID, cmixMsg.Digest())
 	jww.INFO.Print(em)
@@ -168,34 +168,34 @@ func (m *Manager) handleRequest(cmixMsg format.Message,
 	// a negotiation or authenticated channel in progress
 	fp := cAuth.CreateNegotiationFingerprint(partnerPubKey,
 		partnerSIDHPubKey)
-	newFP, latest := m.storage.Auth().AddIfNew(partnerID, fp)
+	newFP, latest := s.storage.Auth().AddIfNew(partnerID, fp)
 	resetSession := false
 	autoConfirm := false
 	if baseFmt.GetVersion() >= 1 && newFP && latest {
 		// If we had an existing session and it's new, then yes, we
 		// want to reset
-		if _, err := m.storage.E2e().GetPartner(partnerID); err == nil {
+		if _, err := s.storage.E2e().GetPartner(partnerID); err == nil {
 			jww.INFO.Printf("Resetting session for %s", partnerID)
 			resetSession = true
 			// Most likely, we got 2 reset sessions at once, so this
 			// is a non-fatal error but we will record a warning
 			// just in case.
-			err = m.storage.E2e().DeletePartner(partnerID)
+			err = s.storage.E2e().DeletePartner(partnerID)
 			if err != nil {
 				jww.WARN.Printf("Unable to delete channel: %+v",
 					err)
 			}
 			// Also delete any existing request, sent or received
-			m.storage.Auth().Delete(partnerID)
+			s.storage.Auth().Delete(partnerID)
 		}
 		// If we had an existing negotiation open, then it depends
 
 		// If we've only received, then user has not confirmed, treat as
 		// a non-duplicate request, so delete the old one (to cause new
 		// callback to be called)
-		rType, _, _, err := m.storage.Auth().GetRequest(partnerID)
+		rType, _, _, err := s.storage.Auth().GetRequest(partnerID)
 		if err != nil && rType == auth2.Receive {
-			m.storage.Auth().Delete(partnerID)
+			s.storage.Auth().Delete(partnerID)
 		}
 
 		// If we've already Sent and are now receiving,
@@ -228,7 +228,7 @@ func (m *Manager) handleRequest(cmixMsg format.Message,
 	// if it does and the keys used are the same as we have, send a
 	// confirmation in case there are state issues.
 	// do not store
-	if _, err := m.storage.E2e().GetPartner(partnerID); err == nil {
+	if _, err := s.storage.E2e().GetPartner(partnerID); err == nil {
 		em := fmt.Sprintf("Received Auth request for %s, "+
 			"channel already exists. Ignoring", partnerID)
 		jww.WARN.Print(em)
@@ -237,7 +237,7 @@ func (m *Manager) handleRequest(cmixMsg format.Message,
 		return
 	} else {
 		//check if the relationship already exists,
-		rType, _, c, err := m.storage.Auth().GetRequest(partnerID)
+		rType, _, c, err := s.storage.Auth().GetRequest(partnerID)
 		if err != nil && !strings.Contains(err.Error(), auth2.NoRequest) {
 			// if another error is received, print it and exit
 			em := fmt.Sprintf("Received new Auth request for %s, "+
@@ -257,8 +257,8 @@ func (m *Manager) handleRequest(cmixMsg format.Message,
 				events.Report(5, "Auth", "DuplicateRequest", em)
 				// if the caller of the API wants requests replayed,
 				// replay the duplicate request
-				if m.replayRequests {
-					cbList := m.requestCallbacks.Get(c.ID)
+				if s.replayRequests {
+					cbList := s.requestCallbacks.Get(c.ID)
 					for _, cb := range cbList {
 						rcb := cb.(interfaces.RequestCallback)
 						go rcb(c)
@@ -283,7 +283,7 @@ func (m *Manager) handleRequest(cmixMsg format.Message,
 
 				// Check if I need to resend by comparing the
 				// IDs
-				myBytes := m.storage.GetUser().ReceptionID.Bytes()
+				myBytes := s.storage.GetUser().ReceptionID.Bytes()
 				theirBytes := partnerID.Bytes()
 				for i := 0; i < len(myBytes); i++ {
 					if myBytes[i] > theirBytes[i] {
@@ -301,7 +301,7 @@ func (m *Manager) handleRequest(cmixMsg format.Message,
 				}
 
 				// If I do, delete my request on disk
-				m.storage.Auth().Delete(partnerID)
+				s.storage.Auth().Delete(partnerID)
 
 				// Do the normal, fall out of this if block and
 				// create the contact, note that we use the data
@@ -336,7 +336,7 @@ func (m *Manager) handleRequest(cmixMsg format.Message,
 	// fixme: the client will never be notified of the channel creation if a
 	// crash occurs after the store but before the conclusion of the callback
 	//create the auth storage
-	if err = m.storage.Auth().AddReceived(c, partnerSIDHPubKey); err != nil {
+	if err = s.storage.Auth().AddReceived(c, partnerSIDHPubKey); err != nil {
 		em := fmt.Sprintf("failed to store contact Auth "+
 			"Request: %s", err)
 		jww.WARN.Print(em)
@@ -349,7 +349,7 @@ func (m *Manager) handleRequest(cmixMsg format.Message,
 	var rndNum id.Round
 	if autoConfirm || resetSession {
 		// Call ConfirmRequestAuth to send confirmation
-		rndNum, err = m.ConfirmRequestAuth(c)
+		rndNum, err = s.ConfirmRequestAuth(c)
 		if err != nil {
 			jww.ERROR.Printf("Could not ConfirmRequestAuth: %+v",
 				err)
@@ -359,7 +359,7 @@ func (m *Manager) handleRequest(cmixMsg format.Message,
 		if autoConfirm {
 			jww.INFO.Printf("ConfirmRequestAuth to %s on round %d",
 				partnerID, rndNum)
-			cbList := m.confirmCallbacks.Get(c.ID)
+			cbList := s.confirmCallbacks.Get(c.ID)
 			for _, cb := range cbList {
 				ccb := cb.(interfaces.ConfirmCallback)
 				go ccb(c)
@@ -368,7 +368,7 @@ func (m *Manager) handleRequest(cmixMsg format.Message,
 		if resetSession {
 			jww.INFO.Printf("Reset Auth %s on round %d",
 				partnerID, rndNum)
-			cbList := m.resetCallbacks.Get(c.ID)
+			cbList := s.resetCallbacks.Get(c.ID)
 			for _, cb := range cbList {
 				ccb := cb.(interfaces.ResetNotificationCallback)
 				go ccb(c)
@@ -377,7 +377,7 @@ func (m *Manager) handleRequest(cmixMsg format.Message,
 	} else {
 		//  fixme: if a crash occurs before or during the calls, the notification
 		//  will never be sent.
-		cbList := m.requestCallbacks.Get(c.ID)
+		cbList := s.requestCallbacks.Get(c.ID)
 		for _, cb := range cbList {
 			rcb := cb.(interfaces.RequestCallback)
 			go rcb(c)
@@ -386,17 +386,17 @@ func (m *Manager) handleRequest(cmixMsg format.Message,
 	return
 }
 
-func (m *Manager) handleConfirm(cmixMsg format.Message, sr *auth2.SentRequest,
+func (s *State) handleConfirm(cmixMsg format.Message, sr *auth2.SentRequest,
 	grp *cyclic.Group) {
-	events := m.net.GetEventManager()
+	events := s.net.GetEventManager()
 
 	// check if relationship already exists
-	if mgr, err := m.storage.E2e().GetPartner(sr.GetPartner()); mgr != nil || err == nil {
+	if mgr, err := s.storage.E2e().GetPartner(sr.GetPartner()); mgr != nil || err == nil {
 		em := fmt.Sprintf("Cannot confirm auth for %s, channel already "+
 			"exists.", sr.GetPartner())
 		jww.WARN.Print(em)
 		events.Report(10, "Auth", "ConfirmError", em)
-		m.storage.Auth().Done(sr.GetPartner())
+		s.storage.Auth().Done(sr.GetPartner())
 		return
 	}
 
@@ -407,7 +407,7 @@ func (m *Manager) handleConfirm(cmixMsg format.Message, sr *auth2.SentRequest,
 		em := fmt.Sprintf("Failed to handle auth confirm: %s", err)
 		jww.WARN.Print(em)
 		events.Report(10, "Auth", "ConfirmError", em)
-		m.storage.Auth().Done(sr.GetPartner())
+		s.storage.Auth().Done(sr.GetPartner())
 		return
 	}
 
@@ -426,7 +426,7 @@ func (m *Manager) handleConfirm(cmixMsg format.Message, sr *auth2.SentRequest,
 			"check")
 		jww.WARN.Print(em)
 		events.Report(10, "Auth", "ConfirmError", em)
-		m.storage.Auth().Done(sr.GetPartner())
+		s.storage.Auth().Done(sr.GetPartner())
 		return
 	}
 
@@ -436,7 +436,7 @@ func (m *Manager) handleConfirm(cmixMsg format.Message, sr *auth2.SentRequest,
 			"encrypted payload: %s", err)
 		jww.WARN.Print(em)
 		events.Report(10, "Auth", "ConfirmError", em)
-		m.storage.Auth().Done(sr.GetPartner())
+		s.storage.Auth().Done(sr.GetPartner())
 		return
 	}
 
@@ -446,26 +446,26 @@ func (m *Manager) handleConfirm(cmixMsg format.Message, sr *auth2.SentRequest,
 			err)
 		jww.WARN.Print(em)
 		events.Report(10, "Auth", "ConfirmError", em)
-		m.storage.Auth().Done(sr.GetPartner())
+		s.storage.Auth().Done(sr.GetPartner())
 		return
 	}
 	jww.TRACE.Printf("handleConfirm PARTNERSIDHPUBKEY: %v",
 		partnerSIDHPubKey)
 
 	// finalize the confirmation
-	if err := m.doConfirm(sr, grp, partnerPubKey, sr.GetMyPrivKey(),
+	if err := s.doConfirm(sr, grp, partnerPubKey, sr.GetMyPrivKey(),
 		sr.GetPartnerHistoricalPubKey(),
 		ecrFmt.GetOwnership(),
 		partnerSIDHPubKey); err != nil {
 		em := fmt.Sprintf("Confirmation failed: %s", err)
 		jww.WARN.Print(em)
 		events.Report(10, "Auth", "ConfirmError", em)
-		m.storage.Auth().Done(sr.GetPartner())
+		s.storage.Auth().Done(sr.GetPartner())
 		return
 	}
 }
 
-func (m *Manager) doConfirm(sr *auth2.SentRequest, grp *cyclic.Group,
+func (s *State) doConfirm(sr *auth2.SentRequest, grp *cyclic.Group,
 	partnerPubKey, myPrivateKeyOwnershipProof, partnerPubKeyOwnershipProof *cyclic.Int,
 	ownershipProof []byte, partnerSIDHPubKey *sidh.PublicKey) error {
 	// verify the message came from the intended recipient
@@ -477,8 +477,8 @@ func (m *Manager) doConfirm(sr *auth2.SentRequest, grp *cyclic.Group,
 
 	// fixme: channel can get into a bricked state if the first save occurs and
 	// the second does not
-	p := m.storage.E2e().GetE2ESessionParams()
-	if err := m.storage.E2e().AddPartner(sr.GetPartner(),
+	p := s.storage.E2e().GetE2ESessionParams()
+	if err := s.storage.E2e().AddPartner(sr.GetPartner(),
 		partnerPubKey, sr.GetMyPrivKey(), partnerSIDHPubKey,
 		sr.GetMySIDHPrivKey(), p, p); err != nil {
 		return errors.Errorf("Failed to create channel with partner (%s) "+
@@ -486,24 +486,24 @@ func (m *Manager) doConfirm(sr *auth2.SentRequest, grp *cyclic.Group,
 			sr.GetPartner(), err)
 	}
 
-	m.backupTrigger("received confirmation from request")
+	s.backupTrigger("received confirmation from request")
 
 	//remove the confirm fingerprint
 	fp := sr.GetFingerprint()
-	if err := m.storage.GetEdge().Remove(edge.Preimage{
+	if err := s.storage.GetEdge().Remove(edge.Preimage{
 		Data:   preimage.Generate(fp[:], catalog.Confirm),
 		Type:   catalog.Confirm,
 		Source: sr.GetPartner()[:],
-	}, m.storage.GetUser().ReceptionID); err != nil {
+	}, s.storage.GetUser().ReceptionID); err != nil {
 		jww.WARN.Printf("Failed delete the preimage for confirm from %s: %+v",
 			sr.GetPartner(), err)
 	}
 
-	addPreimages(sr.GetPartner(), m.storage)
+	addPreimages(sr.GetPartner(), s.storage)
 
 	// delete the in progress negotiation
 	// this undoes the request lock
-	if err := m.storage.Auth().Delete(sr.GetPartner()); err != nil {
+	if err := s.storage.Auth().Delete(sr.GetPartner()); err != nil {
 		return errors.Errorf("UNRECOVERABLE! Failed to delete in "+
 			"progress negotiation with partner (%s) after confirmation: %+v",
 			sr.GetPartner(), err)
@@ -519,13 +519,13 @@ func (m *Manager) doConfirm(sr *auth2.SentRequest, grp *cyclic.Group,
 
 	//  fixme: if a crash occurs before or during the calls, the notification
 	//  will never be sent.
-	cbList := m.confirmCallbacks.Get(c.ID)
+	cbList := s.confirmCallbacks.Get(c.ID)
 	for _, cb := range cbList {
 		ccb := cb.(interfaces.ConfirmCallback)
 		go ccb(c)
 	}
 
-	m.net.CheckGarbledMessages()
+	s.net.CheckGarbledMessages()
 
 	return nil
 }
@@ -535,22 +535,3 @@ func copySlice(s []byte) []byte {
 	copy(c, s)
 	return c
 }
-
-func handleBaseFormat(cmixMsg format.Message, grp *cyclic.Group) (baseFormat,
-	*cyclic.Int, error) {
-
-	baseFmt, err := unmarshalBaseFormat(cmixMsg.GetContents(),
-		grp.GetP().ByteLen())
-	if err != nil && baseFmt == nil {
-		return baseFormat{}, nil, errors.WithMessage(err, "Failed to"+
-			" unmarshal auth")
-	}
-
-	if !grp.BytesInside(baseFmt.pubkey) {
-		return baseFormat{}, nil, errors.WithMessage(err, "Received "+
-			"auth confirmation public key is not in the e2e cyclic group")
-	}
-	partnerPubKey := grp.NewIntFromBytes(baseFmt.pubkey)
-
-	return *baseFmt, partnerPubKey, nil
-}
diff --git a/auth/callbacks.go b/auth/callbacks.go
index 2168c82d3636bdd9ff25c9d1c4c4cddf606b2445..428cf29db3411417590935014ce5333f3bd8b242 100644
--- a/auth/callbacks.go
+++ b/auth/callbacks.go
@@ -8,70 +8,45 @@
 package auth
 
 import (
+	"gitlab.com/elixxir/client/network/historical"
+	"gitlab.com/elixxir/client/network/identity/receptionID"
+	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/xx_network/primitives/id"
 	"sync"
 )
 
+type Callback func(requestor contact.Contact,
+	receptionID receptionID.EphemeralIdentity, round historical.Round)
+
 type callbackMap struct {
-	generalCallback  []interface{}
-	specificCallback map[id.ID]interface{}
-	overrideCallback []interface{}
-	mux              sync.RWMutex
+	callbacks map[id.ID]Callback
+	mux       sync.RWMutex
 }
 
 func newCallbackMap() *callbackMap {
 	return &callbackMap{
-		generalCallback:  make([]interface{}, 0),
-		specificCallback: make(map[id.ID]interface{}),
-		overrideCallback: make([]interface{}, 0),
+		callbacks: make(map[id.ID]Callback),
 	}
 }
 
 //adds a general callback. This will be preempted by any specific callback
-func (cm *callbackMap) AddGeneral(cb interface{}) {
-	cm.mux.Lock()
-	cm.generalCallback = append(cm.generalCallback, cb)
-	cm.mux.Unlock()
-}
-
-//adds an override callback. This will NOT be preempted by any callback
-func (cm *callbackMap) AddOverride(cb interface{}) {
-	cm.mux.Lock()
-	cm.overrideCallback = append(cm.overrideCallback, cb)
-	cm.mux.Unlock()
-}
-
-// adds a callback for a specific user ID. Only only callback can exist for a
-// user ID. False will be returned if a callback already exists and the new
-// one was not added
-func (cm *callbackMap) AddSpecific(id *id.ID, cb interface{}) bool {
+func (cm *callbackMap) AddCallback(recipeint *id.ID, cb Callback) {
 	cm.mux.Lock()
 	defer cm.mux.Unlock()
-	if _, ok := cm.specificCallback[*id]; ok {
-		return false
-	}
-	cm.specificCallback[*id] = cb
-	return true
+	cm.callbacks[*recipeint] = cb
 }
 
 // removes a callback for a specific user ID if it exists.
-func (cm *callbackMap) RemoveSpecific(id *id.ID) {
+func (cm *callbackMap) RemoveCallback(id *id.ID) {
 	cm.mux.Lock()
 	defer cm.mux.Unlock()
-	delete(cm.specificCallback, *id)
+	delete(cm.callbacks, *id)
 }
 
 //get all callback which fit with the passed id
-func (cm *callbackMap) Get(id *id.ID) []interface{} {
+func (cm *callbackMap) Get(id *id.ID) (Callback, bool) {
 	cm.mux.RLock()
 	defer cm.mux.RUnlock()
-	cbList := cm.overrideCallback
-
-	if specific, ok := cm.specificCallback[*id]; ok {
-		cbList = append(cbList, specific)
-	} else {
-		cbList = append(cbList, cm.generalCallback...)
-	}
-
-	return cbList
+	cb, exist := cm.callbacks[*id]
+	return cb, exist
 }
diff --git a/auth/confirm.go b/auth/confirm.go
index 59e374b9d589275065118ab6ece63b86aad5614e..40f7f82ec491a9af8ccef5221377fd876e405793 100644
--- a/auth/confirm.go
+++ b/auth/confirm.go
@@ -9,14 +9,14 @@ package auth
 
 import (
 	"fmt"
-	"gitlab.com/elixxir/client/catalog"
-
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/interfaces/params"
-	"gitlab.com/elixxir/client/interfaces/preimage"
-	"gitlab.com/elixxir/client/storage"
-	"gitlab.com/elixxir/client/storage/edge"
+	"gitlab.com/elixxir/client/auth/store"
+	"gitlab.com/elixxir/client/catalog"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
+	"gitlab.com/elixxir/client/event"
+	"gitlab.com/elixxir/client/network"
+	"gitlab.com/elixxir/client/network/message"
 	util "gitlab.com/elixxir/client/storage/utility"
 	"gitlab.com/elixxir/crypto/contact"
 	cAuth "gitlab.com/elixxir/crypto/e2e/auth"
@@ -24,214 +24,151 @@ import (
 	"gitlab.com/xx_network/primitives/id"
 )
 
-func (m *Manager) ConfirmRequestAuth(partner contact.Contact) (id.Round, error) {
-
-	/*edge checking*/
+func (s *State) ConfirmRequestAuth(partner contact.Contact, me *id.ID) (
+	id.Round, error) {
 
 	// check that messages can be sent over the network
-	if !m.net.GetHealthTracker().IsHealthy() {
+	if !s.net.IsHealthy() {
 		return 0, errors.New("Cannot confirm authenticated message " +
 			"when the network is not healthy")
 	}
 
-	// Cannot confirm already established channels
-	if _, err := m.storage.E2e().GetPartner(partner.ID); err == nil {
-		em := fmt.Sprintf("Cannot ConfirmRequestAuth for %s, "+
-			"channel already exists. Ignoring", partner.ID)
-		jww.WARN.Print(em)
-		m.net.GetEventManager().Report(5, "Auth",
-			"ConfirmRequestAuthIgnored", em)
-		//exit
-		return 0, errors.New(em)
-	}
-
-	// check if the partner has an auth in progress
-	// this takes the lock, from this point forward any errors need to
-	// release the lock
-	storedContact, theirSidhKey, err := m.storage.Auth().GetReceivedRequest(
-		partner.ID)
-	if err != nil {
-		return 0, errors.Errorf(
-			"failed to find a pending Auth Request: %s",
-			err)
-	}
-	defer m.storage.Auth().Done(partner.ID)
-
-	// verify the passed contact matches what is stored
-	if storedContact.DhPubKey.Cmp(partner.DhPubKey) != 0 {
-		return 0, errors.WithMessage(err,
-			"Pending Auth Request has different pubkey than stored")
-	}
+	return s.confirmRequestAuth(partner, me)
 
-	grp := m.storage.E2e().GetGroup()
-
-	/*cryptographic generation*/
-
-	// generate ownership proof
-	ownership := cAuth.MakeOwnershipProof(m.storage.E2e().GetDHPrivateKey(),
-		partner.DhPubKey, m.storage.E2e().GetGroup())
-
-	rng := m.rng.GetStream()
-
-	// generate new keypair
-	dhGrp := grp
-	dhPriv, dhPub := genDHKeys(dhGrp, rng)
-	sidhVariant := util.GetCompatibleSIDHVariant(theirSidhKey.Variant())
-	sidhPriv, sidhPub := util.GenerateSIDHKeyPair(sidhVariant, rng)
+}
 
-	rng.Close()
+func (s *State) confirmRequestAuth(partner contact.Contact, me *id.ID) (
+	id.Round, error) {
 
-	/*construct message*/
-	// we build the payload before we save because it is technically fallible
-	// which can get into a bricked state if it fails
-	cmixMsg := format.NewMessage(m.storage.Cmix().GetGroup().GetP().ByteLen())
-	baseFmt := newBaseFormat(cmixMsg.ContentsSize(), grp.GetP().ByteLen())
-	ecrFmt := newEcrFormat(baseFmt.GetEcrPayloadLen())
+	// check that messages can be sent over the network
+	if !s.net.IsHealthy() {
+		return 0, errors.New("Cannot confirm authenticated message " +
+			"when the network is not healthy")
+	}
 
-	// setup the encrypted payload
-	ecrFmt.SetOwnership(ownership)
-	ecrFmt.SetSidHPubKey(sidhPub)
-	// confirmation has no custom payload
+	kp := s.registeredIDs[*me]
 
-	// encrypt the payload
-	ecrPayload, mac := cAuth.Encrypt(dhPriv, partner.DhPubKey,
-		ecrFmt.data, grp)
+	var sentRound id.Round
 
-	// get the fingerprint from the old ownership proof
-	fp := cAuth.MakeOwnershipProofFP(storedContact.OwnershipProof)
-	preimg := preimage.Generate(fp[:], catalog.Confirm)
+	//run the handler
+	err := s.store.HandleReceivedRequest(partner.ID, me, func(rr *store.ReceivedRequest) error {
+		// verify the passed contact matches what is stored
+		if rr.GetContact().DhPubKey.Cmp(partner.DhPubKey) != 0 {
+			return errors.New("pending Auth Request has different " +
+				"pubkey than stored")
+		}
 
-	// final construction
-	baseFmt.SetEcrPayload(ecrPayload)
-	baseFmt.SetPubKey(dhPub)
+		/*cryptographic generation*/
+
+		// generate ownership proof
+		ownership := cAuth.MakeOwnershipProof(kp.privkey, partner.DhPubKey,
+			s.e2e.GetGroup())
+
+		rng := s.rng.GetStream()
+
+		// generate new keypair
+		dhPriv, dhPub := genDHKeys(s.e2e.GetGroup(), rng)
+		sidhVariant := util.GetCompatibleSIDHVariant(
+			rr.GetTheirSidHPubKeyA().Variant())
+		sidhPriv, sidhPub := util.GenerateSIDHKeyPair(sidhVariant, rng)
+
+		rng.Close()
+
+		/*construct message*/
+		// we build the payload before we save because it is technically fallible
+		// which can get into a bricked state if it fails
+		baseFmt := newBaseFormat(s.net.GetMaxMessageLength(),
+			s.e2e.GetGroup().GetP().ByteLen())
+		ecrFmt := newEcrFormat(baseFmt.GetEcrPayloadLen())
+
+		// setup the encrypted payload
+		ecrFmt.SetOwnership(ownership)
+		ecrFmt.SetSidHPubKey(sidhPub)
+		// confirmation has no custom payload
+
+		// encrypt the payload
+		ecrPayload, mac := cAuth.Encrypt(dhPriv, partner.DhPubKey,
+			ecrFmt.data, s.e2e.GetGroup())
+
+		// get the fingerprint from the old ownership proof
+		fp := cAuth.MakeOwnershipProofFP(rr.GetContact().OwnershipProof)
+
+		// final construction
+		baseFmt.SetEcrPayload(ecrPayload)
+		baseFmt.SetPubKey(dhPub)
+
+		jww.TRACE.Printf("SendConfirm PARTNERPUBKEY: %v",
+			partner.DhPubKey.Bytes())
+		jww.TRACE.Printf("SendConfirm MYPUBKEY: %v", dhPub.Bytes())
+
+		jww.TRACE.Printf("SendConfirm ECRPAYLOAD: %v", baseFmt.GetEcrPayload())
+		jww.TRACE.Printf("SendConfirm MAC: %v", mac)
+
+		// warning: channel can get into a bricked state if the first save occurs and
+		// the second does not or the two occur and the storage into critical
+		// messages does not occur
+
+		// create local relationship
+		p := session.GetDefaultParams()
+		_, err := s.e2e.AddPartner(me, partner.ID, partner.DhPubKey, dhPriv,
+			rr.GetTheirSidHPubKeyA(), sidhPriv, p, p)
+		if err != nil {
+			em := fmt.Sprintf("Failed to create channel with partner (%s) "+
+				"on confirmation, this is likley a replay: %s",
+				partner.ID, err.Error())
+			jww.WARN.Print(em)
+			s.event.Report(10, "Auth", "SendConfirmError", em)
+		}
 
-	cmixMsg.SetKeyFP(fp)
-	cmixMsg.SetMac(mac)
-	cmixMsg.SetContents(baseFmt.Marshal())
+		//todo: s.backupTrigger("confirmed authenticated channel")
 
-	jww.TRACE.Printf("SendConfirm cMixMsg contents: %v",
-		cmixMsg.GetContents())
+		jww.INFO.Printf("Confirming Auth from %s to %s, msgDigest: %s",
+			partner.ID, me, format.DigestContents(baseFmt.Marshal()))
 
-	jww.TRACE.Printf("SendConfirm PARTNERPUBKEY: %v",
-		partner.DhPubKey.Bytes())
-	jww.TRACE.Printf("SendConfirm MYPUBKEY: %v", dhPub.Bytes())
+		//service used for noticiation only
 
-	jww.TRACE.Printf("SendConfirm ECRPAYLOAD: %v", baseFmt.GetEcrPayload())
-	jww.TRACE.Printf("SendConfirm MAC: %v", mac)
+		/*send message*/
+		if err = s.store.StoreConfirmation(partner.ID, me, baseFmt.Marshal(),
+			mac, fp); err == nil {
+			jww.WARN.Printf("Failed to store confirmation for replay "+
+				"for relationship between %s and %s, cannot be replayed: %+v",
+				partner.ID, me, err)
+		}
 
-	// fixme: channel can get into a bricked state if the first save occurs and
-	// the second does not or the two occur and the storage into critical
-	// messages does not occur
+		//send confirmation
+		sentRound, err = sendAuthConfirm(s.net, partner.ID, me, fp,
+			baseFmt.Marshal(), mac, s.event)
 
-	events := m.net.GetEventManager()
+		return nil
+	})
+	return sentRound, err
+}
 
-	// create local relationship
-	p := m.storage.E2e().GetE2ESessionParams()
-	if err := m.storage.E2e().AddPartner(partner.ID, partner.DhPubKey,
-		dhPriv, theirSidhKey, sidhPriv,
-		p, p); err != nil {
-		em := fmt.Sprintf("Failed to create channel with partner (%s) "+
-			"on confirmation, this is likley a replay: %s",
-			partner.ID, err.Error())
-		jww.WARN.Print(em)
-		events.Report(10, "Auth", "SendConfirmError", em)
+func sendAuthConfirm(net network.Manager, partner, me *id.ID,
+	fp format.Fingerprint, payload, mac []byte, event event.Manager) (
+	id.Round, error) {
+	svc := message.Service{
+		Identifier: partner.Marshal(),
+		Tag:        catalog.Default,
+		Metadata:   nil,
 	}
 
-	m.backupTrigger("confirmed authenticated channel")
-
-	addPreimages(partner.ID, m.storage)
-
-	// delete the in progress negotiation
-	// this unlocks the request lock
-	// fixme - do these deletes at a later date
-	/*if err := storage.Auth().Delete(partner.ID); err != nil {
-		return 0, errors.Errorf("UNRECOVERABLE! Failed to delete in "+
-			"progress negotiation with partner (%s) after creating confirmation: %+v",
-			partner.ID, err)
-	}*/
-
-	jww.INFO.Printf("Confirming Auth with %s, msgDigest: %s",
-		partner.ID, cmixMsg.Digest())
-
-	param := params.GetDefaultCMIX()
-	param.IdentityPreimage = preimg
-	param.DebugTag = "auth.Confirm"
-	/*send message*/
-	round, _, err := m.net.SendCMIX(cmixMsg, partner.ID, param)
+	cmixParam := network.GetDefaultCMIXParams()
+	cmixParam.DebugTag = "auth.Confirm"
+	cmixParam.Critical = true
+	sentRound, _, err := net.SendCMIX(partner, fp, svc, payload, mac, cmixParam)
 	if err != nil {
 		// if the send fails just set it to failed, it will but automatically
 		// retried
-		jww.INFO.Printf("Auth Confirm with %s (msgDigest: %s) failed "+
-			"to transmit: %+v", partner.ID, cmixMsg.Digest(), err)
-		return 0, errors.WithMessage(err, "Auth Confirm Failed to transmit")
+		jww.WARN.Printf("Auth Confirm with %s (msgDigest: %s) failed "+
+			"to transmit: %+v, will be handled by critical messages",
+			partner, format.DigestContents(payload), err)
+		return 0, nil
 	}
 
 	em := fmt.Sprintf("Confirm Request with %s (msgDigest: %s) sent on round %d",
-		partner.ID, cmixMsg.Digest(), round)
+		partner, format.DigestContents(payload), sentRound)
 	jww.INFO.Print(em)
-	events.Report(1, "Auth", "SendConfirm", em)
-
-	return round, nil
-}
-
-func addPreimages(partner *id.ID, store *storage.Session) {
-	// add the preimages
-	sessionPartner, err := store.E2e().GetPartner(partner)
-	if err != nil {
-		jww.FATAL.Panicf("Cannot find %s right after creating: %+v",
-			partner, err)
-	}
-
-	// Delete any known pre-existing edges for this partner
-	existingEdges, _ := store.GetEdge().Get(partner)
-	for i := range existingEdges {
-		delete := true
-		switch existingEdges[i].Type {
-		case catalog.E2e:
-		case catalog.Silent:
-		case catalog.EndFT:
-		case catalog.GroupRq:
-		default:
-			delete = false
-		}
-
-		if delete {
-			err = store.GetEdge().Remove(existingEdges[i], partner)
-			if err != nil {
-				jww.ERROR.Printf(
-					"Unable to delete %s edge for %s: %v",
-					existingEdges[i].Type, partner, err)
-			}
-		}
-	}
-
-	me := store.GetUser().ReceptionID
-
-	// e2e
-	store.GetEdge().Add(edge.Preimage{
-		Data:   sessionPartner.GetE2EPreimage(),
-		Type:   catalog.E2e,
-		Source: partner[:],
-	}, me)
-
-	// silent (rekey)
-	store.GetEdge().Add(edge.Preimage{
-		Data:   sessionPartner.GetSilentPreimage(),
-		Type:   catalog.Silent,
-		Source: partner[:],
-	}, me)
-
-	// File transfer end
-	store.GetEdge().Add(edge.Preimage{
-		Data:   sessionPartner.GetFileTransferPreimage(),
-		Type:   catalog.EndFT,
-		Source: partner[:],
-	}, me)
-
-	// group Request
-	store.GetEdge().Add(edge.Preimage{
-		Data:   sessionPartner.GetGroupRequestPreimage(),
-		Type:   catalog.GroupRq,
-		Source: partner[:],
-	}, me)
+	event.Report(1, "Auth", "SendConfirm", em)
+	return sentRound, nil
 }
diff --git a/auth/fmt.go b/auth/fmt.go
index cf38aaed44967d8a825a27451783bf5318038544..6ec925c7efd8be0cbd1b48ff09b1766e0080bd03 100644
--- a/auth/fmt.go
+++ b/auth/fmt.go
@@ -14,6 +14,7 @@ import (
 	sidhinterface "gitlab.com/elixxir/client/interfaces/sidh"
 	util "gitlab.com/elixxir/client/storage/utility"
 	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/primitives/id"
 )
 
@@ -250,3 +251,23 @@ func (rf requestFormat) MsgPayloadLen() int {
 func (rf requestFormat) GetMsgPayload() []byte {
 	return rf.msgPayload
 }
+
+//utility functions
+func handleBaseFormat(cmixMsg format.Message, grp *cyclic.Group) (baseFormat,
+	*cyclic.Int, error) {
+
+	baseFmt, err := unmarshalBaseFormat(cmixMsg.GetContents(),
+		grp.GetP().ByteLen())
+	if err != nil && baseFmt == nil {
+		return baseFormat{}, nil, errors.WithMessage(err, "Failed to"+
+			" unmarshal auth")
+	}
+
+	if !grp.BytesInside(baseFmt.pubkey) {
+		return baseFormat{}, nil, errors.WithMessage(err, "Received "+
+			"auth confirmation public key is not in the e2e cyclic group")
+	}
+	partnerPubKey := grp.NewIntFromBytes(baseFmt.pubkey)
+
+	return *baseFmt, partnerPubKey, nil
+}
diff --git a/auth/manager.go b/auth/manager.go
deleted file mode 100644
index 2d817ec301fe4a24f26a41e3b5384ddb43bc3661..0000000000000000000000000000000000000000
--- a/auth/manager.go
+++ /dev/null
@@ -1,135 +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 auth
-
-import (
-	"gitlab.com/elixxir/client/auth/store"
-	"gitlab.com/elixxir/client/e2e"
-	"gitlab.com/elixxir/client/event"
-	"gitlab.com/elixxir/client/interfaces"
-	"gitlab.com/elixxir/client/interfaces/message"
-	"gitlab.com/elixxir/client/network"
-	"gitlab.com/elixxir/client/storage"
-	"gitlab.com/elixxir/client/switchboard"
-	"gitlab.com/elixxir/crypto/cyclic"
-	"gitlab.com/elixxir/crypto/fastRNG"
-	"gitlab.com/xx_network/primitives/id"
-)
-
-type Manager struct {
-	requestCallbacks *callbackMap
-	confirmCallbacks *callbackMap
-	resetCallbacks   *callbackMap
-
-	net network.Manager
-	e2e e2e.Handler
-	rng *fastRNG.StreamGenerator
-
-	store *store.Store
-	grp   *cyclic.Group
-	event event.Manager
-
-	registeredIDs map[id.ID]keypair
-
-	replayRequests bool
-}
-
-type keypair struct {
-	privkey *cyclic.Int
-	//generated from pubkey on instantiation
-	pubkey *cyclic.Int
-}
-
-func NewManager(sw interfaces.Switchboard, storage *storage.Session,
-	net interfaces.NetworkManager, rng *fastRNG.StreamGenerator,
-	backupTrigger interfaces.TriggerBackup, replayRequests bool) *Manager {
-	m := &Manager{
-		requestCallbacks: newCallbackMap(),
-		confirmCallbacks: newCallbackMap(),
-		resetCallbacks:   newCallbackMap(),
-		rawMessages:      make(chan message.Receive, 1000),
-		storage:          storage,
-		net:              net,
-		rng:              rng,
-		backupTrigger:    backupTrigger,
-		replayRequests:   replayRequests,
-	}
-
-	sw.RegisterChannel("Auth", switchboard.AnyUser(), message.Raw, m.rawMessages)
-
-	return m
-}
-
-// Adds a general callback to be used on auth requests. This will be preempted
-// by any specific callback
-func (m *Manager) AddGeneralRequestCallback(cb interfaces.RequestCallback) {
-	m.requestCallbacks.AddGeneral(cb)
-}
-
-// Adds a general callback to be used on auth requests. This will not be
-// preempted by any specific callback. It is recommended that the specific
-// callbacks are used, this is primarily for debugging.
-func (m *Manager) AddOverrideRequestCallback(cb interfaces.RequestCallback) {
-	m.requestCallbacks.AddOverride(cb)
-}
-
-// Adds a specific callback to be used on auth requests. This will preempt a
-// general callback, meaning the request will be heard on this callback and not
-// the general. Request will still be heard on override callbacks.
-func (m *Manager) AddSpecificRequestCallback(id *id.ID, cb interfaces.RequestCallback) {
-	m.requestCallbacks.AddSpecific(id, cb)
-}
-
-// Removes a specific callback to be used on auth requests.
-func (m *Manager) RemoveSpecificRequestCallback(id *id.ID) {
-	m.requestCallbacks.RemoveSpecific(id)
-}
-
-// Adds a general callback to be used on auth confirms. This will be preempted
-// by any specific callback
-func (m *Manager) AddGeneralConfirmCallback(cb interfaces.ConfirmCallback) {
-	m.confirmCallbacks.AddGeneral(cb)
-}
-
-// Adds a general callback to be used on auth confirms. This will not be
-// preempted by any specific callback. It is recommended that the specific
-// callbacks are used, this is primarily for debugging.
-func (m *Manager) AddOverrideConfirmCallback(cb interfaces.ConfirmCallback) {
-	m.confirmCallbacks.AddOverride(cb)
-}
-
-// Adds a specific callback to be used on auth confirms. This will preempt a
-// general callback, meaning the request will be heard on this callback and not
-// the general. Request will still be heard on override callbacks.
-func (m *Manager) AddSpecificConfirmCallback(id *id.ID, cb interfaces.ConfirmCallback) {
-	m.confirmCallbacks.AddSpecific(id, cb)
-}
-
-// Removes a specific callback to be used on auth confirm.
-func (m *Manager) RemoveSpecificConfirmCallback(id *id.ID) {
-	m.confirmCallbacks.RemoveSpecific(id)
-}
-
-// Adds a general callback to be used on auth session renegotiations.
-func (m *Manager) AddResetNotificationCallback(cb interfaces.ResetNotificationCallback) {
-	m.resetCallbacks.AddOverride(cb)
-}
-
-// ReplayRequests will iterate through all pending contact requests and resend them
-// to the desired contact.
-func (m *Manager) ReplayRequests() {
-	cList := m.storage.Auth().GetAllReceived()
-	for i := range cList {
-		c := cList[i]
-		cbList := m.requestCallbacks.Get(c.ID)
-		for _, cb := range cbList {
-			rcb := cb.(interfaces.RequestCallback)
-			go rcb(c)
-		}
-	}
-}
diff --git a/auth/params.go b/auth/params.go
new file mode 100644
index 0000000000000000000000000000000000000000..8832b06d1881b3a6df3cc986996aac9e81012a7e
--- /dev/null
+++ b/auth/params.go
@@ -0,0 +1 @@
+package auth
diff --git a/auth/receivedConfirm.go b/auth/receivedConfirm.go
new file mode 100644
index 0000000000000000000000000000000000000000..ed6ccdd7654b92705f6e5d4ae82b82f015c6b391
--- /dev/null
+++ b/auth/receivedConfirm.go
@@ -0,0 +1,119 @@
+package auth
+
+import (
+	"encoding/base64"
+	"fmt"
+	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/auth/store"
+	"gitlab.com/elixxir/client/catalog"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
+	"gitlab.com/elixxir/client/network/historical"
+	"gitlab.com/elixxir/client/network/identity/receptionID"
+	"gitlab.com/elixxir/client/network/message"
+	"gitlab.com/elixxir/crypto/contact"
+	cAuth "gitlab.com/elixxir/crypto/e2e/auth"
+	"gitlab.com/elixxir/primitives/fact"
+	"gitlab.com/elixxir/primitives/format"
+)
+
+type receivedConfirmService struct {
+	s *State
+	*store.SentRequest
+}
+
+func (rcs *receivedConfirmService) Process(msg format.Message,
+	receptionID receptionID.EphemeralIdentity, round historical.Round) {
+
+	state := rcs.s
+
+	//parse the confirm
+	baseFmt, partnerPubKey, err := handleBaseFormat(msg, state.e2e.GetGroup())
+	if err != nil {
+		em := fmt.Sprintf("Failed to handle auth confirm: %s", err)
+		jww.WARN.Print(em)
+		state.event.Report(10, "Auth", "ConfirmError", em)
+		return
+	}
+
+	// lookup keypair
+	kp := state.registeredIDs[*receptionID.Source]
+
+	jww.TRACE.Printf("processing confirm: \n\t MYPUBKEY: %s "+
+		"\n\t PARTNERPUBKEY: %s \n\t ECRPAYLOAD: %s \n\t MAC: %s",
+		kp.pubkey.TextVerbose(16, 0),
+		partnerPubKey.TextVerbose(16, 0),
+		base64.StdEncoding.EncodeToString(baseFmt.data),
+		base64.StdEncoding.EncodeToString(msg.GetMac()))
+
+	// decrypt the payload
+	success, payload := cAuth.Decrypt(rcs.GetMyPrivKey(), partnerPubKey,
+		baseFmt.GetEcrPayload(), msg.GetMac(), state.e2e.GetGroup())
+
+	if !success {
+		em := fmt.Sprintf("Received auth confirmation failed its mac " +
+			"check")
+		jww.WARN.Print(em)
+		state.event.Report(10, "Auth", "ConfirmError", em)
+		return
+	}
+
+	// parse the data
+	ecrFmt, err := unmarshalEcrFormat(payload)
+	if err != nil {
+		em := fmt.Sprintf("Failed to unmarshal auth confirmation's "+
+			"encrypted payload: %s", err)
+		jww.WARN.Print(em)
+		state.event.Report(10, "Auth", "ConfirmError", em)
+		return
+	}
+
+	partnerSIDHPubKey, err := ecrFmt.GetSidhPubKey()
+	if err != nil {
+		em := fmt.Sprintf("Could not get auth conf SIDH Pubkey: %s",
+			err)
+		jww.WARN.Print(em)
+		state.event.Report(10, "Auth", "ConfirmError", em)
+		return
+	}
+
+	jww.TRACE.Printf("handleConfirm PARTNERSIDHPUBKEY: %v",
+		partnerSIDHPubKey)
+
+	// check the ownership proof, this verifies the respondent owns the
+	// initial identity
+	if !cAuth.VerifyOwnershipProof(kp.privkey, rcs.GetPartnerHistoricalPubKey(),
+		state.e2e.GetGroup(), ecrFmt.GetOwnership()) {
+		jww.WARN.Printf("Failed authenticate identity for auth "+
+			"confirmation of %s", rcs.GetPartner())
+		return
+	}
+
+	// add the partner
+	p := session.GetDefaultParams()
+	_, err = state.e2e.AddPartner(receptionID.Source, rcs.GetPartner(), partnerPubKey,
+		rcs.GetMyPrivKey(), partnerSIDHPubKey, rcs.GetMySIDHPrivKey(), p, p)
+	if err != nil {
+		jww.WARN.Printf("Failed to create channel with partner %s and "+
+			"%s : %+v", rcs.GetPartner(), receptionID.Source, err)
+	}
+
+	//todo: trigger backup
+
+	// remove the service used for notifications of the confirm
+	confirmFP := rcs.GetFingerprint()
+	state.net.DeleteService(receptionID.Source, message.Service{
+		Identifier: confirmFP[:],
+		Tag:        catalog.Confirm,
+	}, nil)
+
+	// callbacks
+	c := contact.Contact{
+		ID:             rcs.GetPartner().DeepCopy(),
+		DhPubKey:       partnerPubKey.DeepCopy(),
+		OwnershipProof: ecrFmt.GetOwnership(),
+		Facts:          make([]fact.Fact, 0),
+	}
+	if cb, exists := state.confirmCallbacks.Get(receptionID.Source); exists {
+		cb(c, receptionID, round)
+	}
+}
diff --git a/auth/receivedRequest.go b/auth/receivedRequest.go
index bb92273031b13c3ef26655e1d7fb21e9d51080a2..327a746ed4b1130e0d95632c526ba01606b306a1 100644
--- a/auth/receivedRequest.go
+++ b/auth/receivedRequest.go
@@ -6,31 +6,54 @@ import (
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/auth/store"
+	"gitlab.com/elixxir/client/e2e/ratchet"
 	"gitlab.com/elixxir/client/network/historical"
 	"gitlab.com/elixxir/client/network/identity/receptionID"
+	"gitlab.com/elixxir/crypto/contact"
 	cAuth "gitlab.com/elixxir/crypto/e2e/auth"
 	"gitlab.com/elixxir/primitives/fact"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/primitives/id"
+	"strings"
 )
 
+const dummyerr = "dummy error so we dont delete the request"
+
 type receivedRequestService struct {
-	m *Manager
+	s *State
 }
 
 func (rrs *receivedRequestService) Process(message format.Message,
 	receptionID receptionID.EphemeralIdentity, round historical.Round) {
 
+	state := rrs.s
+
+	// check if the timestamp is before the id was created and therefore
+	// should be ignored
+	tid, err := state.net.GetIdentity(receptionID.Source)
+	if err != nil {
+		jww.ERROR.Printf("received a request on %s which does not exist, " +
+			"this should not be possible")
+		return
+	}
+	if tid.Creation.After(round.GetEndTimestamp()) {
+		jww.INFO.Printf("received a request on %s which was sent before " +
+			"creation of the identity, dropping because it is likely old " +
+			"(before a reset from backup")
+		return
+	}
+
 	//decode the outer format
 	baseFmt, partnerPubKey, err := handleBaseFormat(
-		message, rrs.m.grp)
+		message, state.e2e.GetGroup())
 	if err != nil {
 		jww.WARN.Printf("Failed to handle auth request: %s", err)
 		return
 	}
 
 	//lookup the keypair
-	kp := rrs.m.registeredIDs[*receptionID.Source]
+	kp := state.registeredIDs[*receptionID.Source]
 
 	jww.TRACE.Printf("processing requests: \n\t MYPUBKEY: %s "+
 		"\n\t PARTNERPUBKEY: %s \n\t ECRPAYLOAD: %s \n\t MAC: %s",
@@ -41,7 +64,7 @@ func (rrs *receivedRequestService) Process(message format.Message,
 
 	//Attempt to decrypt the payload
 	success, payload := cAuth.Decrypt(kp.privkey, partnerPubKey,
-		baseFmt.GetEcrPayload(), message.GetMac(), rrs.m.grp)
+		baseFmt.GetEcrPayload(), message.GetMac(), state.e2e.GetGroup())
 
 	if !success {
 		jww.WARN.Printf("Received auth request of %s failed its mac "+
@@ -50,60 +73,226 @@ func (rrs *receivedRequestService) Process(message format.Message,
 	}
 
 	//extract data from the decrypted payload
-	partnerID, partnerSIDHPubKey, facts, err := processDecryptedMessage(payload)
+	partnerID, partnerSIDHPubKey, facts, ownershipProof, err :=
+		processDecryptedMessage(payload)
 	if err != nil {
 		jww.WARN.Printf("Failed to decode the auth request: %+v", err)
 		return
 	}
 
-	em := fmt.Sprintf("Received AuthRequest from %s,"+
-		" msgDigest: %s", partnerID, format.DigestContents(message.GetContents()))
-	jww.INFO.Print(em)
-	rrs.m.event.Report(1, "Auth", "RequestReceived", em)
+	//create the contact, note that no facts are sent in the payload
+	c := contact.Contact{
+		ID:             partnerID.DeepCopy(),
+		DhPubKey:       partnerPubKey.DeepCopy(),
+		OwnershipProof: copySlice(ownershipProof),
+		Facts:          facts,
+	}
 
-	// check the uniqueness of the request. Requests can be duplicated, so we must
-	// verify this is is not a duplicate, and drop if it is
 	fp := cAuth.CreateNegotiationFingerprint(partnerPubKey,
 		partnerSIDHPubKey)
-	newFP, latest := rrs.m.store.CheckIfNegotiationIsNew(partnerID,
+	em := fmt.Sprintf("Received AuthRequest from %s,"+
+		" msgDigest: %s, FP: %s", partnerID,
+		format.DigestContents(message.GetContents()),
+		base64.StdEncoding.EncodeToString(fp))
+	jww.INFO.Print(em)
+	state.event.Report(1, "Auth", "RequestReceived", em)
+
+	// check the uniqueness of the request. Requests can be duplicated, so we
+	// must verify this is is not a duplicate, and drop if it is
+	newFP, position := state.store.CheckIfNegotiationIsNew(partnerID,
 		receptionID.Source, fp)
 
+	if !newFP {
+		// if its the newest, resend the confirm
+		if position == 0 {
+			jww.INFO.Printf("Not new request received from %s to %s "+
+				"with fp %s at position %d, resending confirm", partnerID,
+				receptionID.Source, base64.StdEncoding.EncodeToString(fp),
+				position)
+
+			// check if we already accepted, if we did, resend the confirm if
+			// we can load it
+			if _, err = state.e2e.GetPartner(partnerID, receptionID.Source); err != nil {
+				//attempt to load the confirm, if we can, resend it
+				confirmPayload, mac, keyfp, err :=
+					state.store.LoadConfirmation(partnerID, receptionID.Source)
+				if err != nil {
+					jww.ERROR.Printf("Could not reconfirm a duplicate "+
+						"request of an accepted confirm from %s to %s because "+
+						"the confirm could not be loaded: %+v", partnerID,
+						receptionID.Source, err)
+				}
+				// resend the confirm. It sends as a critical message, so errors
+				// do not need to be handled
+				_, _ = sendAuthConfirm(state.net, partnerID, receptionID.Source,
+					keyfp, confirmPayload, mac, state.event)
+			} else if state.replayRequests {
+				//if we did not already accept, auto replay the request
+				if cb, exist := state.requestCallbacks.Get(receptionID.Source); exist {
+					cb(c, receptionID, round)
+				}
+			}
+			//if not confirm, and params.replay requests is true, we need to replay
+		} else {
+			jww.INFO.Printf("Not new request received from %s to %s "+
+				"with fp %s at position %d, dropping", partnerID,
+				receptionID.Source, base64.StdEncoding.EncodeToString(fp),
+				position)
+		}
+		return
+	}
+
+	reset := false
+	// check if we have a relationship, given this is a new request, if we have
+	// a relationship, this must be a reset, which which case we delete all
+	// state and then continue like a new request
+	// delete only deletes if the partner is present, so we can just call delete
+	// instead of checking if it exists and then calling delete, and check the
+	// error to see if it did or didnt exist
+	// Note: due to the newFP handling above, this can ONLY run in the event of
+	// a reset or when the partner doesnt exist, so it is safe
+	if err = state.e2e.DeletePartner(partnerID, receptionID.Source); err != nil {
+		if !strings.Contains(err.Error(), ratchet.NoPartnerErrorStr) {
+			jww.FATAL.Panicf("Failed to do actual partner deletion: %+v", err)
+		}
+	} else {
+		reset = true
+		_ = state.store.DeleteConfirmation(partnerID, receptionID.Source)
+		_ = state.store.DeleteSentRequest(partnerID, receptionID.Source)
+	}
+
+	// if a new, unique request is received when one already exists, delete the
+	// old one and process the new one
+	if err = state.store.DeleteReceivedRequest(partnerID, receptionID.Source); err != nil {
+		if !strings.Contains(err.Error(), store.NoRequestFound) {
+			jww.FATAL.Panicf("Failed to delete old received request: %+v",
+				err)
+		}
+	}
+
+	// if a sent request already exists, that means we requested at the same
+	// time they did. We need to auto-confirm if we are randomly selected
+	// (SIDH keys have polarity, so both sent keys cannot be used together)
+	autoConfirm := false
+	bail := false
+	err = state.store.HandleSentRequest(partnerID, receptionID.Source,
+		func(request *store.SentRequest) error {
+
+			//if this code is running, then we know we sent a request and can
+			//auto accept
+			//This runner will auto delete the sent request if successful
+
+			//verify ownership proof
+			if !cAuth.VerifyOwnershipProof(kp.pubkey, partnerPubKey,
+				state.e2e.GetGroup(), ownershipProof) {
+				jww.WARN.Printf("Invalid ownership proof from %s to %s "+
+					"received, discarding msdDigest: %s, fp: %s",
+					partnerID, receptionID.Source,
+					format.DigestContents(message.GetContents()),
+					base64.StdEncoding.EncodeToString(fp))
+			}
+
+			if !iShouldResend(partnerID, receptionID.Source) {
+				// return an error so the store layer does not delete the request
+				// because the other side will confirm it
+				bail = true
+				return errors.Errorf(dummyerr)
+			}
+
+			jww.INFO.Printf("Received AuthRequest from %s to %s,"+
+				" msgDigest: %s, fp: %s which has been requested, auto-confirming",
+				partnerID, receptionID.Source,
+				format.DigestContents(message.GetContents()),
+				base64.StdEncoding.EncodeToString(fp))
+			return nil
+		})
+	if bail {
+		jww.INFO.Printf("Received AuthRequest from %s to %s,"+
+			" msgDigest: %s, fp: %s which has been requested, not auto-confirming, "+
+			" is other's responsibility",
+			partnerID, receptionID.Source,
+			format.DigestContents(message.GetContents()),
+			base64.StdEncoding.EncodeToString(fp))
+		return
+	}
+	//set the autoconfirm
+	autoConfirm = err == nil
+
+	// warning: the client will never be notified of the channel creation if a
+	// crash occurs after the store but before the conclusion of the callback
+	//create the auth storage
+	if err = state.store.AddReceived(receptionID.Source, c, partnerSIDHPubKey); err != nil {
+		em := fmt.Sprintf("failed to store contact Auth "+
+			"Request: %s", err)
+		jww.WARN.Print(em)
+		state.event.Report(10, "Auth", "RequestError", em)
+		return
+	}
+
+	//autoconfirm if we should
+	if autoConfirm || reset {
+		_, _ = state.confirmRequestAuth(c, receptionID.Source)
+		//handle callbacks
+		if autoConfirm {
+			if cb, exist := state.confirmCallbacks.Get(receptionID.Source); exist {
+				cb(c, receptionID, round)
+			}
+		} else if reset {
+			if cb, exist := state.requestCallbacks.Get(receptionID.Source); exist {
+				cb(c, receptionID, round)
+			}
+		}
+	} else {
+		//otherwise call callbacks
+		if cb, exist := state.requestCallbacks.Get(receptionID.Source); exist {
+			cb(c, receptionID, round)
+		}
+	}
 }
 
 func processDecryptedMessage(b []byte) (*id.ID, *sidh.PublicKey, fact.FactList,
-	error) {
+	[]byte, error) {
 	//decode the ecr format
 	ecrFmt, err := unmarshalEcrFormat(b)
 	if err != nil {
-		return nil, nil, nil, errors.WithMessage(err, "Failed to "+
+		return nil, nil, nil, nil, errors.WithMessage(err, "Failed to "+
 			"unmarshal auth request's encrypted payload")
 	}
 
 	partnerSIDHPubKey, err := ecrFmt.GetSidhPubKey()
 	if err != nil {
-		return nil, nil, nil, errors.WithMessage(err, "Could not "+
+		return nil, nil, nil, nil, errors.WithMessage(err, "Could not "+
 			"unmarshal partner SIDH Pubkey")
 	}
 
 	//decode the request format
 	requestFmt, err := newRequestFormat(ecrFmt)
 	if err != nil {
-		return nil, nil, nil, errors.WithMessage(err, "Failed to "+
+		return nil, nil, nil, nil, errors.WithMessage(err, "Failed to "+
 			"unmarshal auth request's internal payload")
 	}
 
 	partnerID, err := requestFmt.GetID()
 	if err != nil {
-		return nil, nil, nil, errors.WithMessage(err, "Failed to "+
+		return nil, nil, nil, nil, errors.WithMessage(err, "Failed to "+
 			"unmarshal auth request's sender ID")
 	}
 
 	facts, _, err := fact.UnstringifyFactList(
 		string(requestFmt.msgPayload))
 	if err != nil {
-		return nil, nil, nil, errors.WithMessage(err, "Failed to "+
+		return nil, nil, nil, nil, errors.WithMessage(err, "Failed to "+
 			"unmarshal auth request's facts")
 	}
 
-	return partnerID, partnerSIDHPubKey, facts, nil
+	return partnerID, partnerSIDHPubKey, facts, ecrFmt.GetOwnership(), nil
+}
+
+func iShouldResend(partner, me *id.ID) bool {
+	myBytes := me.Bytes()
+	theirBytes := partner.Bytes()
+	i := 0
+	for ; myBytes[i] == theirBytes[i] && i < len(myBytes); i++ {
+	}
+	return myBytes[i] < theirBytes[i]
 }
diff --git a/auth/request.go b/auth/request.go
index daaa3f071e334a08aa3ab8545000f6dcb089a93d..cf34b7c0830577a031a7214a493a777a33b0a8b1 100644
--- a/auth/request.go
+++ b/auth/request.go
@@ -9,67 +9,59 @@ package auth
 
 import (
 	"fmt"
-	auth2 "gitlab.com/elixxir/client/auth/store"
-	"gitlab.com/elixxir/client/catalog"
-	e2e2 "gitlab.com/elixxir/client/e2e/ratchet"
-	"gitlab.com/elixxir/client/network"
-	"gitlab.com/elixxir/client/network/message"
-	"gitlab.com/elixxir/primitives/format"
-	"gitlab.com/xx_network/crypto/signature/rsa"
-	"io"
-	"strings"
-
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/interfaces"
-	"gitlab.com/elixxir/client/interfaces/params"
-	"gitlab.com/elixxir/client/interfaces/preimage"
-	"gitlab.com/elixxir/client/storage"
-	"gitlab.com/elixxir/client/storage/edge"
+	"gitlab.com/elixxir/client/catalog"
+	"gitlab.com/elixxir/client/e2e/ratchet"
+	"gitlab.com/elixxir/client/network"
+	"gitlab.com/elixxir/client/network/message"
 	util "gitlab.com/elixxir/client/storage/utility"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/diffieHellman"
 	cAuth "gitlab.com/elixxir/crypto/e2e/auth"
+	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/primitives/id"
+	"io"
+	"strings"
 )
 
 const terminator = ";"
 
-func (m *Manager) RequestAuth(partner, me contact.Contact,
+func (s *State) RequestAuth(partner, me contact.Contact,
 	originDHPrivKey *cyclic.Int) (id.Round, error) {
 	// check that an authenticated channel does not already exist
-	if _, err := m.e2e.GetPartner(partner.ID, me.ID); err == nil ||
-		!strings.Contains(err.Error(), e2e2.NoPartnerErrorStr) {
+	if _, err := s.e2e.GetPartner(partner.ID, me.ID); err == nil ||
+		!strings.Contains(err.Error(), ratchet.NoPartnerErrorStr) {
 		return 0, errors.Errorf("Authenticated channel already " +
 			"established with partner")
 	}
 
-	return m.requestAuth(partner, me, originDHPrivKey)
+	return s.requestAuth(partner, me, originDHPrivKey)
 }
 
 // requestAuth internal helper
-func (m *Manager) requestAuth(partner, me contact.Contact,
+func (s *State) requestAuth(partner, me contact.Contact,
 	originDHPrivKey *cyclic.Int) (id.Round, error) {
 
 	//do key generation
-	rng := m.rng.GetStream()
+	rng := s.rng.GetStream()
 	defer rng.Close()
 
-	dhPriv, dhPub := genDHKeys(m.grp, rng)
+	dhPriv, dhPub := genDHKeys(s.e2e.GetGroup(), rng)
 	sidhPriv, sidhPub := util.GenerateSIDHKeyPair(
 		sidh.KeyVariantSidhA, rng)
 
 	ownership := cAuth.MakeOwnershipProof(originDHPrivKey, partner.DhPubKey,
-		m.grp)
+		s.e2e.GetGroup())
 	confirmFp := cAuth.MakeOwnershipProofFP(ownership)
 
 	// Add the sent request and use the return to build the send. This will
 	// replace the send with an old one if one was in process, wasting the key
 	// generation above. This is considered a reasonable loss due to the increase
 	// in code simplicity of this approach
-	sr, err := m.store.AddSent(partner.ID, me.ID, partner.DhPubKey, dhPriv, dhPub,
+	sr, err := s.store.AddSent(partner.ID, me.ID, partner.DhPubKey, dhPriv, dhPub,
 		sidhPriv, sidhPub, confirmFp)
 	if err != nil {
 		if sr == nil {
@@ -91,14 +83,24 @@ func (m *Manager) requestAuth(partner, me contact.Contact,
 	// Create the request packet.
 	request, mac, err := createRequestAuth(partner.ID, msgPayload, ownership,
 		dhPriv, dhPub, partner.DhPubKey, sidhPub,
-		m.grp, m.net.GetMaxMessageLength())
+		s.e2e.GetGroup(), s.net.GetMaxMessageLength())
 	if err != nil {
 		return 0, err
 	}
 	contents := request.Marshal()
 
-	//todo-register correct service
-	m.net.AddService(me.ID, message.Service{
+	//register the confirm fingerprint to pick up confirm
+	err = s.net.AddFingerprint(me.ID, confirmFp, &receivedConfirmService{
+		s:           s,
+		SentRequest: sr,
+	})
+	if err != nil {
+		return 0, errors.Errorf("Failed to register fingperint  request "+
+			"to %s from %s, bailing request", partner.ID, me)
+	}
+
+	//register service for notification on confirmation
+	s.net.AddService(me.ID, message.Service{
 		Identifier: confirmFp[:],
 		Tag:        catalog.Confirm,
 		Metadata:   partner.ID[:],
@@ -112,12 +114,12 @@ func (m *Manager) requestAuth(partner, me contact.Contact,
 
 	p := network.GetDefaultCMIXParams()
 	p.DebugTag = "auth.Request"
-	s := message.Service{
+	svc := message.Service{
 		Identifier: partner.ID.Marshal(),
 		Tag:        catalog.Default,
 		Metadata:   nil,
 	}
-	round, _, err := m.net.SendCMIX(partner.ID, requestfp, s, contents, mac, p)
+	round, _, err := s.net.SendCMIX(partner.ID, requestfp, svc, contents, mac, p)
 	if err != nil {
 		// if the send fails just set it to failed, it will
 		// but automatically retried
@@ -129,7 +131,7 @@ func (m *Manager) requestAuth(partner, me contact.Contact,
 	em := fmt.Sprintf("Auth Request with %s (msgDigest: %s) sent"+
 		" on round %d", partner.ID, format.DigestContents(contents), round)
 	jww.INFO.Print(em)
-	m.event.Report(1, "Auth", "RequestSent", em)
+	s.event.Report(1, "Auth", "RequestSent", em)
 	return round, nil
 
 }
diff --git a/auth/reset.go b/auth/reset.go
index 2a28016164b72f03816cbb6cdeba25686b6a1d8e..c257a274b7e3bc1343452b0cb4a7d7da73195a44 100644
--- a/auth/reset.go
+++ b/auth/reset.go
@@ -2,31 +2,23 @@ package auth
 
 import (
 	jww "github.com/spf13/jwalterweatherman"
-	auth2 "gitlab.com/elixxir/client/auth/store"
-	"gitlab.com/elixxir/client/interfaces"
-	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/xx_network/primitives/id"
-	"io"
 )
 
-func (m *Manager) ResetSession(partner, me contact.Contact, rng io.Reader) (id.Round, error) {
+func (s *State) ResetSession(partner contact.Contact, me *id.ID) (id.Round, error) {
 
 	// Delete authenticated channel if it exists.
-	if err := storage.E2e().DeletePartner(partner.ID); err != nil {
+	if err := s.e2e.DeletePartner(partner.ID, me); err != nil {
 		jww.WARN.Printf("Unable to delete partner when "+
 			"resetting session: %+v", err)
-	} else {
-		// Delete any stored sent/received requests
-		storage.Auth().Delete(partner.ID)
 	}
 
-	rqType, _, _, err := storage.Auth().GetRequest(partner.ID)
-	if err == nil && rqType == auth2.Sent {
-		return 0, errors.New("Cannot reset a session after " +
-			"sending request, caller must resend request instead")
-	}
+	//clean any data which is present
+	_ = s.store.DeleteConfirmation(partner.ID, me)
+	_ = s.store.DeleteSentRequest(partner.ID, me)
+	_ = s.store.DeleteReceivedRequest(partner.ID, me)
 
 	// Try to initiate a clean session request
-	return requestAuth(partner, me, rng, true, storage, net)
+	return s.confirmRequestAuth(partner, me)
 }
diff --git a/auth/state.go b/auth/state.go
new file mode 100644
index 0000000000000000000000000000000000000000..6cb7f5ebc1453d5cc6a7acb8b5bb4475e768f546
--- /dev/null
+++ b/auth/state.go
@@ -0,0 +1,79 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+package auth
+
+import (
+	"gitlab.com/elixxir/client/auth/store"
+	"gitlab.com/elixxir/client/e2e"
+	"gitlab.com/elixxir/client/event"
+	"gitlab.com/elixxir/client/interfaces"
+	"gitlab.com/elixxir/client/interfaces/message"
+	"gitlab.com/elixxir/client/network"
+	"gitlab.com/elixxir/client/storage"
+	"gitlab.com/elixxir/client/switchboard"
+	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/crypto/fastRNG"
+	"gitlab.com/xx_network/primitives/id"
+)
+
+type State struct {
+	requestCallbacks *callbackMap
+	confirmCallbacks *callbackMap
+	resetCallbacks   *callbackMap
+
+	net network.Manager
+	e2e e2e.Handler
+	rng *fastRNG.StreamGenerator
+
+	store *store.Store
+	event event.Manager
+
+	registeredIDs map[id.ID]keypair
+
+	replayRequests bool
+}
+
+type keypair struct {
+	privkey *cyclic.Int
+	//generated from pubkey on instantiation
+	pubkey *cyclic.Int
+}
+
+func NewManager(sw interfaces.Switchboard, storage *storage.Session,
+	net interfaces.NetworkManager, rng *fastRNG.StreamGenerator,
+	backupTrigger interfaces.TriggerBackup, replayRequests bool) *State {
+	m := &State{
+		requestCallbacks: newCallbackMap(),
+		confirmCallbacks: newCallbackMap(),
+		resetCallbacks:   newCallbackMap(),
+		rawMessages:      make(chan message.Receive, 1000),
+		storage:          storage,
+		net:              net,
+		rng:              rng,
+		backupTrigger:    backupTrigger,
+		replayRequests:   replayRequests,
+	}
+
+	sw.RegisterChannel("Auth", switchboard.AnyUser(), message.Raw, m.rawMessages)
+
+	return m
+}
+
+// ReplayRequests will iterate through all pending contact requests and resend them
+// to the desired contact.
+func (s *State) ReplayRequests() {
+	cList := s.storage.Auth().GetAllReceived()
+	for i := range cList {
+		c := cList[i]
+		cbList := s.requestCallbacks.Get(c.ID)
+		for _, cb := range cbList {
+			rcb := cb.(interfaces.RequestCallback)
+			go rcb(c)
+		}
+	}
+}
diff --git a/auth/manager_test.go b/auth/state_test.go
similarity index 99%
rename from auth/manager_test.go
rename to auth/state_test.go
index 2e384f83ffa6829624b07ab35ac2ef7b259b0e34..d023abfad0542ce7374ef57f796e0dd5d831d45b 100644
--- a/auth/manager_test.go
+++ b/auth/state_test.go
@@ -31,7 +31,7 @@ func TestManager_ReplayRequests(t *testing.T) {
 	numReceived := 10
 
 	// Construct barebones manager
-	m := Manager{
+	m := State{
 		requestCallbacks: newCallbackMap(),
 		storage:          s,
 		replayRequests:   true,
diff --git a/auth/store/confirmation.go b/auth/store/confirmation.go
index a321c354c5258f7e0613fd4d4cf67429672b9a88..ba61ec4efedc746c79f185e1b1d55e37571d409a 100644
--- a/auth/store/confirmation.go
+++ b/auth/store/confirmation.go
@@ -9,7 +9,9 @@ package store
 
 import (
 	"encoding/base64"
+	"encoding/json"
 	"gitlab.com/elixxir/client/storage/versioned"
+	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
 )
@@ -19,43 +21,69 @@ const (
 	currentConfirmationVersion = 0
 )
 
+type storedConfirm struct {
+	Payload []byte
+	Mac     []byte
+	Keyfp   []byte
+}
+
 // StoreConfirmation saves the confirmation to storage for the given partner and
 // fingerprint.
-func (s *Store) StoreConfirmation(
-	partner *id.ID, fingerprint, confirmation []byte) error {
+func (s *Store) StoreConfirmation(partner *id.ID, me *id.ID,
+	confirmationPayload, mac []byte, fp format.Fingerprint) error {
+	confirm := storedConfirm{
+		Payload: confirmationPayload,
+		Mac:     mac,
+		Keyfp:   fp[:],
+	}
+
+	confirmBytes, err := json.Marshal(&confirm)
+	if err != nil {
+		return err
+	}
+
 	obj := &versioned.Object{
 		Version:   currentConfirmationVersion,
 		Timestamp: netTime.Now(),
-		Data:      confirmation,
+		Data:      confirmBytes,
 	}
 
-	return s.kv.Set(makeConfirmationKey(partner, fingerprint),
+	return s.kv.Set(makeConfirmationKey(partner, me),
 		currentConfirmationVersion, obj)
 }
 
 // LoadConfirmation loads the confirmation for the given partner and fingerprint
 // from storage.
-func (s *Store) LoadConfirmation(partner *id.ID, fingerprint []byte) (
-	[]byte, error) {
+func (s *Store) LoadConfirmation(partner, me *id.ID) (
+	[]byte, []byte, format.Fingerprint, error) {
 	obj, err := s.kv.Get(
-		makeConfirmationKey(partner, fingerprint), currentConfirmationVersion)
+		makeConfirmationKey(partner, me), currentConfirmationVersion)
 	if err != nil {
-		return nil, err
+		return nil, nil, format.Fingerprint{}, err
 	}
 
-	return obj.Data, nil
+	confirm := storedConfirm{}
+	if err = json.Unmarshal(obj.Data, &confirm); err != nil {
+		return nil, nil, format.Fingerprint{}, err
+	}
+
+	fp := format.Fingerprint{}
+	copy(fp[:], confirm.Keyfp)
+
+	return confirm.Payload, confirm.Mac, fp, nil
 }
 
-// deleteConfirmation deletes the confirmation for the given partner and
+// DeleteConfirmation deletes the confirmation for the given partner and
 // fingerprint from storage.
-func (s *Store) deleteConfirmation(partner *id.ID, fingerprint []byte) error {
+func (s *Store) DeleteConfirmation(partner, me *id.ID) error {
 	return s.kv.Delete(
-		makeConfirmationKey(partner, fingerprint), currentConfirmationVersion)
+		makeConfirmationKey(partner, me), currentConfirmationVersion)
 }
 
 // makeConfirmationKey generates the key used to load and store confirmations
 // for the partner and fingerprint.
-func makeConfirmationKey(partner *id.ID, fingerprint []byte) string {
+func makeConfirmationKey(partner, me *id.ID) string {
 	return confirmationKeyPrefix + base64.StdEncoding.EncodeToString(
-		partner.Marshal()) + "/" + base64.StdEncoding.EncodeToString(fingerprint)
+		partner.Marshal()) + base64.StdEncoding.EncodeToString(
+		me.Marshal())
 }
diff --git a/auth/store/confirmation_test.go b/auth/store/confirmation_test.go
index 6e53a62958bad90184be184d9ab10ee543fe82fe..b33ec582f2242fc963f2b67ca76385e463345575 100644
--- a/auth/store/confirmation_test.go
+++ b/auth/store/confirmation_test.go
@@ -78,7 +78,7 @@ func TestStore_StoreConfirmation_LoadConfirmation(t *testing.T) {
 	}
 }
 
-// Tests that Store.deleteConfirmation deletes the correct confirmation from
+// Tests that Store.DeleteConfirmation deletes the correct confirmation from
 // storage and that it cannot be loaded from storage.
 func TestStore_deleteConfirmation(t *testing.T) {
 	s := &Store{kv: versioned.NewKV(make(ekv.Memstore))}
@@ -120,9 +120,9 @@ func TestStore_deleteConfirmation(t *testing.T) {
 	}
 
 	for i, val := range testValues {
-		err := s.deleteConfirmation(val.partner, val.fingerprint)
+		err := s.DeleteConfirmation(val.partner, val.fingerprint)
 		if err != nil {
-			t.Errorf("deleteConfirmation returned an error (%d): %+v", i, err)
+			t.Errorf("DeleteConfirmation returned an error (%d): %+v", i, err)
 		}
 
 		loadedConfirmation, err := s.LoadConfirmation(val.partner, val.fingerprint)
diff --git a/auth/store/deletion.go b/auth/store/deletion.go
index 140a9940c8aefd9f97fd04afd0319a544ebdd636..1eff026fbbe940b7c2f90a5a95dc5059ae8c8bb9 100644
--- a/auth/store/deletion.go
+++ b/auth/store/deletion.go
@@ -7,6 +7,8 @@ import (
 	"gitlab.com/xx_network/primitives/id"
 )
 
+const NoRequestFound = "no request found"
+
 // DeleteAllRequests clears the request map and all associated storage objects
 // containing request data.
 func (s *Store) DeleteAllRequests() error {
@@ -74,6 +76,59 @@ func (s *Store) DeleteSentRequests() error {
 	return nil
 }
 
+// DeleteReceivedRequest deletes the received request for the given partnerID
+// pair.
+func (s *Store) DeleteReceivedRequest(partner, me *id.ID) error {
+
+	aid := makeAuthIdentity(partner, me)
+	s.mux.Lock()
+	rr, exist := s.receivedByID[aid]
+	s.mux.Unlock()
+
+	if !exist {
+		return errors.New(NoRequestFound)
+	}
+
+	rr.mux.Lock()
+	s.mux.Lock()
+	_, exist = s.receivedByID[aid]
+	delete(s.receivedByID, aid)
+	rr.mux.Unlock()
+	s.mux.Unlock()
+
+	if !exist {
+		return errors.New(NoRequestFound)
+	}
+
+	return nil
+}
+
+// DeleteSentRequest deletes the sent request for the given partnerID pair.
+func (s *Store) DeleteSentRequest(partner, me *id.ID) error {
+
+	aid := makeAuthIdentity(partner, me)
+	s.mux.Lock()
+	sr, exist := s.sentByID[aid]
+	s.mux.Unlock()
+
+	if !exist {
+		return errors.New(NoRequestFound)
+	}
+
+	sr.mux.Lock()
+	s.mux.Lock()
+	_, exist = s.sentByID[aid]
+	delete(s.receivedByID, aid)
+	s.mux.Unlock()
+	sr.mux.Unlock()
+
+	if !exist {
+		return errors.New(NoRequestFound)
+	}
+
+	return nil
+}
+
 // DeleteReceiveRequests deletes all Receive receivedByID from Store.
 func (s *Store) DeleteReceiveRequests() error {
 	s.mux.Lock()
diff --git a/auth/store/previousNegotiations.go b/auth/store/previousNegotiations.go
index 80db8cab9fe42d37116af2c4a35311e1484dfc95..5eb1cb1ec1bc71245aef9271eec5101703c5428e 100644
--- a/auth/store/previousNegotiations.go
+++ b/auth/store/previousNegotiations.go
@@ -31,10 +31,11 @@ const (
 // If the partner does not exist, it will add it and the new fingerprint and
 // return newFingerprint = true.
 // If the partner exists and the fingerprint does not exist, add it adds it as
-// the latest fingerprint and returns newFingerprint = true, latest = true
+// the latest fingerprint and returns newFingerprint = true,
 // If the partner exists and the fingerprint exists, return
-// newFingerprint = false, latest = false or latest = true if it is the last one
-// in the list.
+// newFingerprint = false
+// in all cases it will return the position of the fingerprint, with the newest
+// always at position 0
 func (s *Store) CheckIfNegotiationIsNew(partner, myID *id.ID, negotiationFingerprint []byte) (
 	newFingerprint bool, position uint) {
 	s.mux.Lock()
@@ -62,8 +63,7 @@ func (s *Store) CheckIfNegotiationIsNew(partner, myID *id.ID, negotiationFingerp
 		}
 
 		newFingerprint = true
-		latest = true
-
+		position = 0
 		return
 	}
 
@@ -81,7 +81,8 @@ func (s *Store) CheckIfNegotiationIsNew(partner, myID *id.ID, negotiationFingerp
 			newFingerprint = false
 
 			// Latest = true if it is the last fingerprint in the list
-			latest = i == len(fingerprints)-1
+			lastPost := len(fingerprints) - 1
+			position = uint(lastPost - i)
 
 			return
 		}
@@ -97,7 +98,7 @@ func (s *Store) CheckIfNegotiationIsNew(partner, myID *id.ID, negotiationFingerp
 	}
 
 	newFingerprint = true
-	latest = true
+	position = 0
 
 	return
 }
diff --git a/bindings/ud.go b/bindings/ud.go
index df34f572de41569a8c2969c24c9fc24b869348a0..9ca14b91815e2ccf92a8037ebbd23ef54a355cb3 100644
--- a/bindings/ud.go
+++ b/bindings/ud.go
@@ -35,12 +35,12 @@ type UserDiscovery struct {
 func NewUserDiscovery(client *Client) (*UserDiscovery, error) {
 	single, err := client.getSingle()
 	if err != nil {
-		return nil, errors.WithMessage(err, "Failed to create User Discovery Manager")
+		return nil, errors.WithMessage(err, "Failed to create User Discovery State")
 	}
 	m, err := ud.NewManager(&client.api, single)
 
 	if err != nil {
-		return nil, errors.WithMessage(err, "Failed to create User Discovery Manager")
+		return nil, errors.WithMessage(err, "Failed to create User Discovery State")
 	} else {
 		return &UserDiscovery{ud: m}, nil
 	}
@@ -335,7 +335,7 @@ func (ud *UserDiscovery) SetAlternativeUserDiscovery(address, cert, contactFile
 }
 
 // UnsetAlternativeUserDiscovery clears out the information from
-// the Manager object.
+// the State object.
 func (ud *UserDiscovery) UnsetAlternativeUserDiscovery() error {
 	return ud.ud.UnsetAlternativeUserDiscovery()
 }
diff --git a/dummy/send_test.go b/dummy/send_test.go
index 6a5a91feff0c152b70982e60e769aae53c37813e..ba299018a2b0d117d1037bc50b66ecf99f3c6aa3 100644
--- a/dummy/send_test.go
+++ b/dummy/send_test.go
@@ -19,7 +19,7 @@ import (
 	"time"
 )
 
-// Tests that Manager.sendThread sends multiple sets of messages.
+// Tests that State.sendThread sends multiple sets of messages.
 func TestManager_sendThread(t *testing.T) {
 	m := newTestManager(10, 50*time.Millisecond, 10*time.Millisecond, false, t)
 
@@ -86,7 +86,7 @@ func TestManager_sendThread(t *testing.T) {
 
 }
 
-// Tests that Manager.sendMessages sends all the messages with the correct
+// Tests that State.sendMessages sends all the messages with the correct
 // recipient.
 func TestManager_sendMessages(t *testing.T) {
 	m := newTestManager(100, 0, 0, false, t)
@@ -135,7 +135,7 @@ func TestManager_sendMessages(t *testing.T) {
 	}
 }
 
-// Tests that Manager.newRandomMessages creates a non-empty map of messages and
+// Tests that State.newRandomMessages creates a non-empty map of messages and
 // that each message is unique.
 func TestManager_newRandomMessages(t *testing.T) {
 	m := newTestManager(10, 0, 0, false, t)
@@ -161,7 +161,7 @@ func TestManager_newRandomMessages(t *testing.T) {
 	}
 }
 
-// Tests that Manager.newRandomCmixMessage generates a cMix message with
+// Tests that State.newRandomCmixMessage generates a cMix message with
 // populated contents, fingerprint, and MAC.
 func TestManager_newRandomCmixMessage(t *testing.T) {
 	m := newTestManager(0, 0, 0, false, t)
diff --git a/dummy/utils_test.go b/dummy/utils_test.go
index 8a0b0ab9786b7f527fb1fd767fe3d2d6c2d6640d..12af098f4046497b493c2fc7b3a06f383883706b 100644
--- a/dummy/utils_test.go
+++ b/dummy/utils_test.go
@@ -65,7 +65,7 @@ func newTestManager(maxNumMessages int, avgSendDelta, randomRange time.Duration,
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// Test Network Manager                                                       //
+// Test Network State                                                       //
 ////////////////////////////////////////////////////////////////////////////////
 
 // testNetworkManager is a test implementation of NetworkManager interface.
diff --git a/e2e/ratchet/partner/manager.go b/e2e/ratchet/partner/manager.go
index 9bded0aa5856f4f9b7482c66e0096f1074f4ccca..c0a4c153ac37c8fb0a7aa94dbf4d88b7bcac98d0 100644
--- a/e2e/ratchet/partner/manager.go
+++ b/e2e/ratchet/partner/manager.go
@@ -25,7 +25,7 @@ import (
 	"golang.org/x/crypto/blake2b"
 )
 
-const managerPrefix = "Manager{partner:%s}"
+const managerPrefix = "State{partner:%s}"
 const originMyPrivKeyKey = "originMyPrivKey"
 const originPartnerPubKey = "originPartnerPubKey"
 
diff --git a/e2e/ratchet/partner/manager_test.go b/e2e/ratchet/partner/manager_test.go
index 776f48f707a3a190cb7be490e54245ea6edb5efa..797aca1d46b29be41f07283f26abe84cb59657ee 100644
--- a/e2e/ratchet/partner/manager_test.go
+++ b/e2e/ratchet/partner/manager_test.go
@@ -39,7 +39,7 @@ func Test_newManager(t *testing.T) {
 
 	// Check if the new relationship matches the expected
 	if !managersEqual(expectedM, m, t) {
-		t.Errorf("newManager() did not produce the expected Manager."+
+		t.Errorf("newManager() did not produce the expected State."+
 			"\n\texpected: %+v\n\treceived: %+v", expectedM, m)
 	}
 }
@@ -58,7 +58,7 @@ func TestLoadManager(t *testing.T) {
 
 	// Check if the loaded relationship matches the expected
 	if !managersEqual(expectedM, m, t) {
-		t.Errorf("LoadManager() did not produce the expected Manager."+
+		t.Errorf("LoadManager() did not produce the expected State."+
 			"\n\texpected: %+v\n\treceived: %+v", expectedM, m)
 	}
 }
@@ -166,7 +166,7 @@ func TestManager_NewSendSession(t *testing.T) {
 	}
 }
 
-//Tests happy path of Manager.GetKeyForSending.
+//Tests happy path of State.GetKeyForSending.
 func TestManager_GetKeyForSending(t *testing.T) {
 	// Set up test values
 	m, _ := newTestManager(t)
@@ -213,7 +213,7 @@ func TestManager_GetKeyForSending(t *testing.T) {
 	}
 }
 
-// Tests that Manager.GetKeyForSending returns an error for invalid SendType.
+// Tests that State.GetKeyForSending returns an error for invalid SendType.
 func TestManager_GetKeyForSending_Error(t *testing.T) {
 	// Set up test values
 	m, _ := newTestManager(t)
diff --git a/e2e/ratchet/partner/session/session.go b/e2e/ratchet/partner/session/session.go
index a62cf91618ce7706b0838b7ec5c0ff6d816da5a0..dcb72b84ad1da1f31a3d890c36a7d6bd068ab4ab 100644
--- a/e2e/ratchet/partner/session/session.go
+++ b/e2e/ratchet/partner/session/session.go
@@ -387,7 +387,7 @@ func (s *Session) Status() Status {
 
 // Moving from Unconfirmed to Sending and from Confirmed to NewSessionTriggered
 // is handled by  Session.TriggerNegotiation() which is called by the
-// Manager as part of Manager.TriggerNegotiations() and will be rejected
+// State as part of State.TriggerNegotiations() and will be rejected
 // from this function
 
 var legalStateChanges = [][]bool{
diff --git a/e2e/ratchet/partner/session/session_test.go b/e2e/ratchet/partner/session/session_test.go
index c22fdc582fcebf1a29b021bdafc6ed8b5cebd127..049d4ecea617c8932bfc50a331259caae3325499 100644
--- a/e2e/ratchet/partner/session/session_test.go
+++ b/e2e/ratchet/partner/session/session_test.go
@@ -157,7 +157,7 @@ func TestSession_Serialization(t *testing.T) {
 
 	sDeserialized := &Session{
 		//relationship: &ratchet.relationship{
-		//	manager: &partner.Manager{ctx: ctx},
+		//	manager: &partner.State{ctx: ctx},
 		//},
 		grp: s.grp,
 		kv:  s.kv,
diff --git a/e2e/ratchet/partner/utils_test.go b/e2e/ratchet/partner/utils_test.go
index 70f056f31d4fe12951b738bd459af051d507f2cc..3667f4d7e67de1a6bb18e46b88eab53a46c4ff8e 100644
--- a/e2e/ratchet/partner/utils_test.go
+++ b/e2e/ratchet/partner/utils_test.go
@@ -89,31 +89,31 @@ func newTestManager(t *testing.T) (*Manager, *versioned.KV) {
 func managersEqual(expected, received *Manager, t *testing.T) bool {
 	equal := true
 	if !reflect.DeepEqual(expected.cyHandler, received.cyHandler) {
-		t.Errorf("Did not Receive expected Manager.ctx."+
+		t.Errorf("Did not Receive expected State.ctx."+
 			"\n\texpected: %+v\n\treceived: %+v",
 			expected.cyHandler, received.cyHandler)
 		equal = false
 	}
 	if !reflect.DeepEqual(expected.kv, received.kv) {
-		t.Errorf("Did not Receive expected Manager.kv."+
+		t.Errorf("Did not Receive expected State.kv."+
 			"\n\texpected: %+v\n\treceived: %+v",
 			expected.kv, received.kv)
 		equal = false
 	}
 	if !expected.partner.Cmp(received.partner) {
-		t.Errorf("Did not Receive expected Manager.partner."+
+		t.Errorf("Did not Receive expected State.partner."+
 			"\n\texpected: %+v\n\treceived: %+v",
 			expected.partner, received.partner)
 		equal = false
 	}
 	if !relationshipsEqual(expected.receive, received.receive) {
-		t.Errorf("Did not Receive expected Manager.Receive."+
+		t.Errorf("Did not Receive expected State.Receive."+
 			"\n\texpected: %+v\n\treceived: %+v",
 			expected.receive, received.receive)
 		equal = false
 	}
 	if !relationshipsEqual(expected.send, received.send) {
-		t.Errorf("Did not Receive expected Manager.Send."+
+		t.Errorf("Did not Receive expected State.Send."+
 			"\n\texpected: %+v\n\treceived: %+v",
 			expected.send, received.send)
 		equal = false
diff --git a/e2e/ratchet/ratchet_test.go b/e2e/ratchet/ratchet_test.go
index 1b87c88acda50c3725660bfbb0270aa9a5d0f827..c73ebca4c675934ec0d2a87faa8156ac064144c5 100644
--- a/e2e/ratchet/ratchet_test.go
+++ b/e2e/ratchet/ratchet_test.go
@@ -115,7 +115,7 @@ func TestStore_AddPartner(t *testing.T) {
 
 	m, exists := r.managers[relationshipId]
 	if !exists {
-		t.Errorf("Manager does not exist in map.\n\tmap: %+v",
+		t.Errorf("State does not exist in map.\n\tmap: %+v",
 			r.managers)
 	}
 
@@ -183,7 +183,7 @@ func TestStore_GetPartner(t *testing.T) {
 	}
 
 	if !reflect.DeepEqual(expectedManager, m) {
-		t.Errorf("GetPartner() returned wrong Manager."+
+		t.Errorf("GetPartner() returned wrong State."+
 			"\n\texpected: %v\n\treceived: %v", expectedManager, m)
 	}
 }
diff --git a/e2e/ratchet/utils_test.go b/e2e/ratchet/utils_test.go
index 2856948e6f8a67d1566f907e679b1d168f7609c9..8e61934e4851c15e7cc851146c74e7b98b29ca2e 100644
--- a/e2e/ratchet/utils_test.go
+++ b/e2e/ratchet/utils_test.go
@@ -45,34 +45,34 @@ func makeTestRatchet() (*Ratchet, *versioned.KV, error) {
 func managersEqual(expected, received *partner.Manager, t *testing.T) bool {
 	equal := true
 	if !reflect.DeepEqual(expected.GetPartnerID(), received.GetPartnerID()) {
-		t.Errorf("Did not Receive expected Manager.partnerID."+
+		t.Errorf("Did not Receive expected State.partnerID."+
 			"\n\texpected: %+v\n\treceived: %+v",
 			expected.GetPartnerID(), received.GetPartnerID())
 		equal = false
 	}
 
 	if !strings.EqualFold(expected.GetRelationshipFingerprint(), received.GetRelationshipFingerprint()) {
-		t.Errorf("Did not Receive expected Manager.Receive."+
+		t.Errorf("Did not Receive expected State.Receive."+
 			"\n\texpected: %+v\n\treceived: %+v",
 			expected.GetRelationshipFingerprint(), received.GetRelationshipFingerprint())
 		equal = false
 	}
 	if !reflect.DeepEqual(expected.GetMyID(), received.GetMyID()) {
-		t.Errorf("Did not Receive expected Manager.myId."+
+		t.Errorf("Did not Receive expected State.myId."+
 			"\n\texpected: %+v\n\treceived: %+v",
 			expected.GetMyID(), received.GetPartnerID())
 		equal = false
 	}
 
 	if !reflect.DeepEqual(expected.GetMyOriginPrivateKey(), received.GetMyOriginPrivateKey()) {
-		t.Errorf("Did not Receive expected Manager.MyPrivateKey."+
+		t.Errorf("Did not Receive expected State.MyPrivateKey."+
 			"\n\texpected: %+v\n\treceived: %+v",
 			expected.GetMyOriginPrivateKey(), received.GetMyOriginPrivateKey())
 		equal = false
 	}
 
 	if !reflect.DeepEqual(expected.GetSendRelationshipFingerprint(), received.GetSendRelationshipFingerprint()) {
-		t.Errorf("Did not Receive expected Manager.SendRelationshipFingerprint."+
+		t.Errorf("Did not Receive expected State.SendRelationshipFingerprint."+
 			"\n\texpected: %+v\n\treceived: %+v",
 			expected.GetSendRelationshipFingerprint(), received.GetSendRelationshipFingerprint())
 		equal = false
diff --git a/fileTransfer/oldTransferRecovery_test.go b/fileTransfer/oldTransferRecovery_test.go
index 561785100d4611e7923b6eb6bd6e4e80d48ea4d1..5a352a1d3bc839cd490843448d53739f5ee16061 100644
--- a/fileTransfer/oldTransferRecovery_test.go
+++ b/fileTransfer/oldTransferRecovery_test.go
@@ -25,7 +25,7 @@ import (
 	"time"
 )
 
-// Tests that Manager.oldTransferRecovery adds all unsent parts to the queue.
+// Tests that State.oldTransferRecovery adds all unsent parts to the queue.
 func TestManager_oldTransferRecovery(t *testing.T) {
 	kv := versioned.NewKV(make(ekv.Memstore))
 	m, sti, _ := newTestManagerWithTransfers(
@@ -188,7 +188,7 @@ func TestManager_oldTransferRecovery(t *testing.T) {
 	}
 }
 
-// Tests that Manager.updateSentRounds updates the status of each round
+// Tests that State.updateSentRounds updates the status of each round
 // correctly by using the part tracker and checks that all the correct parts
 // were added to the queue.
 func TestManager_updateSentRounds(t *testing.T) {
@@ -312,7 +312,7 @@ func TestManager_updateSentRounds(t *testing.T) {
 	}
 }
 
-// Error path: tests that Manager.updateSentRounds returns the expected error
+// Error path: tests that State.updateSentRounds returns the expected error
 // when getRoundResults returns only errors.
 func TestManager_updateSentRounds_Error(t *testing.T) {
 	kv := versioned.NewKV(make(ekv.Memstore))
diff --git a/fileTransfer/receiveNew_test.go b/fileTransfer/receiveNew_test.go
index 4aea311faa6e0fedadf6f627e8f4b43eb544753e..abc470cd0636db4c5235dc77b38eb69599087fbe 100644
--- a/fileTransfer/receiveNew_test.go
+++ b/fileTransfer/receiveNew_test.go
@@ -19,7 +19,7 @@ import (
 	"time"
 )
 
-// Tests that Manager.receiveNewFileTransfer receives the sent message and that
+// Tests that State.receiveNewFileTransfer receives the sent message and that
 // it reports the correct data to the callback.
 func TestManager_receiveNewFileTransfer(t *testing.T) {
 	// Create new ReceiveCallback that sends the results on a channel
@@ -88,7 +88,7 @@ func TestManager_receiveNewFileTransfer(t *testing.T) {
 	}
 }
 
-// Tests that Manager.receiveNewFileTransfer stops receiving messages when the
+// Tests that State.receiveNewFileTransfer stops receiving messages when the
 // stoppable is triggered.
 func TestManager_receiveNewFileTransfer_Stop(t *testing.T) {
 	// Create new ReceiveCallback that sends the results on a channel
@@ -149,7 +149,7 @@ func TestManager_receiveNewFileTransfer_Stop(t *testing.T) {
 	}
 }
 
-// Tests that Manager.receiveNewFileTransfer does not report on the callback
+// Tests that State.receiveNewFileTransfer does not report on the callback
 // when the received message is of the wrong type.
 func TestManager_receiveNewFileTransfer_InvalidMessageError(t *testing.T) {
 	// Create new ReceiveCallback that sends the results on a channel
@@ -191,7 +191,7 @@ func TestManager_receiveNewFileTransfer_InvalidMessageError(t *testing.T) {
 	}
 }
 
-// Tests that Manager.readNewFileTransferMessage returns the expected sender ID,
+// Tests that State.readNewFileTransferMessage returns the expected sender ID,
 // file size, and preview.
 func TestManager_readNewFileTransferMessage(t *testing.T) {
 	m := newTestManager(false, nil, nil, nil, nil, t)
@@ -251,7 +251,7 @@ func TestManager_readNewFileTransferMessage(t *testing.T) {
 	}
 }
 
-// Error path: tests that Manager.readNewFileTransferMessage returns the
+// Error path: tests that State.readNewFileTransferMessage returns the
 // expected error when the message.Receive has the wrong MessageType.
 func TestManager_readNewFileTransferMessage_MessageTypeError(t *testing.T) {
 	m := newTestManager(false, nil, nil, nil, nil, t)
@@ -271,7 +271,7 @@ func TestManager_readNewFileTransferMessage_MessageTypeError(t *testing.T) {
 	}
 }
 
-// Error path: tests that Manager.readNewFileTransferMessage returns the
+// Error path: tests that State.readNewFileTransferMessage returns the
 // expected error when the payload of the message.Receive cannot be
 // unmarshalled.
 func TestManager_readNewFileTransferMessage_ProtoUnmarshalError(t *testing.T) {
diff --git a/fileTransfer/receive_test.go b/fileTransfer/receive_test.go
index cc28fc24f1b910128ceba15d1486b1ef9e120966..5a24712cebd7efe9642d9493caf326de9a57148c 100644
--- a/fileTransfer/receive_test.go
+++ b/fileTransfer/receive_test.go
@@ -20,7 +20,7 @@ import (
 	"time"
 )
 
-// Tests that Manager.receive returns the correct progress on the callback when
+// Tests that State.receive returns the correct progress on the callback when
 // receiving a single message.
 func TestManager_receive(t *testing.T) {
 	// Build a manager for sending and a manger for receiving
@@ -133,7 +133,7 @@ func TestManager_receive(t *testing.T) {
 	<-done
 }
 
-// Tests that Manager.receive the progress callback is not called when the
+// Tests that State.receive the progress callback is not called when the
 // stoppable is triggered.
 func TestManager_receive_Stop(t *testing.T) {
 	// Build a manager for sending and a manger for receiving
@@ -232,7 +232,7 @@ func TestManager_receive_Stop(t *testing.T) {
 	<-done1
 }
 
-// Tests that Manager.readMessage reads the message without errors and that it
+// Tests that State.readMessage reads the message without errors and that it
 // reports the correct progress on the callback. It also gets the file and
 // checks that the part is where it should be.
 func TestManager_readMessage(t *testing.T) {
diff --git a/fileTransfer/sendNew_test.go b/fileTransfer/sendNew_test.go
index 8a4da00a6d666001813c728311496ba39fcf9a1b..f7accd75b04723c2edd9e2fd50af8d328bbe2bfb 100644
--- a/fileTransfer/sendNew_test.go
+++ b/fileTransfer/sendNew_test.go
@@ -23,7 +23,7 @@ import (
 	"testing"
 )
 
-// Tests that the E2E message sent via Manager.sendNewFileTransfer matches
+// Tests that the E2E message sent via State.sendNewFileTransfer matches
 // expected.
 func TestManager_sendNewFileTransfer(t *testing.T) {
 	m := newTestManager(false, nil, nil, nil, nil, t)
@@ -69,7 +69,7 @@ func TestManager_sendNewFileTransfer(t *testing.T) {
 	}
 }
 
-// Error path: tests that Manager.sendNewFileTransfer returns the expected error
+// Error path: tests that State.sendNewFileTransfer returns the expected error
 // when SendE2E fails.
 func TestManager_sendNewFileTransfer_E2eError(t *testing.T) {
 	// Create new test manager with a SendE2E error triggered
diff --git a/fileTransfer/send_test.go b/fileTransfer/send_test.go
index 35e1f239a8c4a3249cbd91a3ac05d3e96e47cce9..c4c2a4132f811fc9f8d9b75220cfc069bda455fc 100644
--- a/fileTransfer/send_test.go
+++ b/fileTransfer/send_test.go
@@ -35,7 +35,7 @@ import (
 	"time"
 )
 
-// Tests that Manager.sendThread successfully sends the parts and reports their
+// Tests that State.sendThread successfully sends the parts and reports their
 // progress on the callback.
 func TestManager_sendThread(t *testing.T) {
 	m, sti, _ := newTestManagerWithTransfers(
@@ -114,7 +114,7 @@ func TestManager_sendThread(t *testing.T) {
 	}
 }
 
-// Tests that Manager.sendThread successfully sends the parts and reports their
+// Tests that State.sendThread successfully sends the parts and reports their
 // progress on the callback.
 func TestManager_sendThread_NetworkNotHealthy(t *testing.T) {
 	m, _, _ := newTestManagerWithTransfers(
@@ -156,7 +156,7 @@ func TestManager_sendThread_NetworkNotHealthy(t *testing.T) {
 	}
 }
 
-// Tests that Manager.sendThread successfully sends a partially filled batch
+// Tests that State.sendThread successfully sends a partially filled batch
 // of the correct length when its times out waiting for messages.
 func TestManager_sendThread_Timeout(t *testing.T) {
 	m, sti, _ := newTestManagerWithTransfers(
@@ -232,7 +232,7 @@ func TestManager_sendThread_Timeout(t *testing.T) {
 	}
 }
 
-// Tests that Manager.sendParts sends all the correct cMix messages and calls
+// Tests that State.sendParts sends all the correct cMix messages and calls
 // the progress callbacks with the correct values.
 func TestManager_sendParts(t *testing.T) {
 	m, sti, _ := newTestManagerWithTransfers(
@@ -316,7 +316,7 @@ func TestManager_sendParts(t *testing.T) {
 	wg.Wait()
 }
 
-// Error path: tests that, on SendManyCMIX failure, Manager.sendParts adds the
+// Error path: tests that, on SendManyCMIX failure, State.sendParts adds the
 // parts back into the queue, does not call the callback, and does not update
 // the progress.
 func TestManager_sendParts_SendManyCmixError(t *testing.T) {
@@ -374,7 +374,7 @@ func TestManager_sendParts_SendManyCmixError(t *testing.T) {
 	wg.Wait()
 }
 
-// Error path: tests that Manager.sendParts returns the expected error whe
+// Error path: tests that State.sendParts returns the expected error whe
 // getRoundResults returns an error.
 func TestManager_sendParts_RoundResultsError(t *testing.T) {
 	m, sti, _ := newTestManagerWithTransfers(
@@ -410,7 +410,7 @@ func TestManager_sendParts_RoundResultsError(t *testing.T) {
 	}
 }
 
-// Tests that Manager.buildMessages returns the expected values for a group
+// Tests that State.buildMessages returns the expected values for a group
 // of 11 file parts from three different transfers.
 func TestManager_buildMessages(t *testing.T) {
 	m, sti, _ := newTestManagerWithTransfers(
@@ -505,7 +505,7 @@ func TestManager_buildMessages(t *testing.T) {
 	}
 }
 
-// Tests that Manager.buildMessages skips file parts with deleted transfers or
+// Tests that State.buildMessages skips file parts with deleted transfers or
 // transfers that have run out of fingerprints.
 func TestManager_buildMessages_MessageBuildFailureError(t *testing.T) {
 	m := newTestManager(false, nil, nil, nil, nil, t)
@@ -601,7 +601,7 @@ func TestManager_buildMessages_MessageBuildFailureError(t *testing.T) {
 	}
 }
 
-// Tests that Manager.buildMessages returns the expected error when a queued
+// Tests that State.buildMessages returns the expected error when a queued
 // part has an invalid part number.
 func TestManager_buildMessages_NewCmixMessageError(t *testing.T) {
 	m := newTestManager(false, nil, nil, nil, nil, t)
@@ -631,7 +631,7 @@ func TestManager_buildMessages_NewCmixMessageError(t *testing.T) {
 
 }
 
-// Tests that Manager.newCmixMessage returns a format.Message with the correct
+// Tests that State.newCmixMessage returns a format.Message with the correct
 // MAC, fingerprint, and contents.
 func TestManager_newCmixMessage(t *testing.T) {
 	m := newTestManager(false, nil, nil, nil, nil, t)
@@ -679,7 +679,7 @@ func TestManager_newCmixMessage(t *testing.T) {
 	}
 }
 
-// Tests that Manager.makeRoundEventCallback returns a callback that calls the
+// Tests that State.makeRoundEventCallback returns a callback that calls the
 // progress callback when a round succeeds.
 func TestManager_makeRoundEventCallback(t *testing.T) {
 	sendE2eChan := make(chan message.Receive, 100)
@@ -783,7 +783,7 @@ func TestManager_makeRoundEventCallback(t *testing.T) {
 	}
 }
 
-// Tests that Manager.makeRoundEventCallback returns a callback that calls the
+// Tests that State.makeRoundEventCallback returns a callback that calls the
 // progress callback with no parts sent on round failure. Also checks that the
 // file parts were added back into the queue.
 func TestManager_makeRoundEventCallback_RoundFailure(t *testing.T) {
@@ -873,7 +873,7 @@ func TestManager_makeRoundEventCallback_RoundFailure(t *testing.T) {
 	}
 }
 
-// Tests that Manager.sendEndE2eMessage sends an E2E message with the expected
+// Tests that State.sendEndE2eMessage sends an E2E message with the expected
 // recipient and message type. This does not test round tracking or critical
 // messages.
 func TestManager_sendEndE2eMessage(t *testing.T) {
@@ -918,7 +918,7 @@ func TestManager_sendEndE2eMessage(t *testing.T) {
 	}
 }
 
-// Tests that Manager.queueParts adds all the expected parts to the sendQueue
+// Tests that State.queueParts adds all the expected parts to the sendQueue
 // channel.
 func TestManager_queueParts(t *testing.T) {
 	m := newTestManager(false, nil, nil, nil, nil, t)
@@ -996,7 +996,7 @@ func Test_makeListOfPartNums(t *testing.T) {
 	}
 }
 
-// Tests that the part size returned by Manager.GetPartSize matches the manually
+// Tests that the part size returned by State.GetPartSize matches the manually
 // calculated part size.
 func TestManager_getPartSize(t *testing.T) {
 	m := newTestManager(false, nil, nil, nil, nil, t)
diff --git a/fileTransfer/utils_test.go b/fileTransfer/utils_test.go
index 0ea0e5386b39c9a926fad4a774a11cd103b86410..fc07d1394b9120ff39a9e39bf28c1637b61d14b4 100644
--- a/fileTransfer/utils_test.go
+++ b/fileTransfer/utils_test.go
@@ -392,7 +392,7 @@ type receivedTransferInfo struct {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-// Test Network Manager                                                       //
+// Test Network State                                                       //
 ////////////////////////////////////////////////////////////////////////////////
 
 func newTestNetworkManager(sendErr bool, sendChan,
diff --git a/groupChat/makeGroup_test.go b/groupChat/makeGroup_test.go
index 056355d31a0dbe49fa0189f3314d39edd76827c9..e4a0ca4c4a0676ccd24ed8ef519a20ccd999c07a 100644
--- a/groupChat/makeGroup_test.go
+++ b/groupChat/makeGroup_test.go
@@ -130,7 +130,7 @@ func TestManager_MakeGroup_AddGroupError(t *testing.T) {
 	}
 }
 
-// Unit test of Manager.buildMembership.
+// Unit test of State.buildMembership.
 func TestManager_buildMembership(t *testing.T) {
 	prng := rand.New(rand.NewSource(42))
 	m, _ := newTestManager(prng, t)
diff --git a/groupChat/manager_test.go b/groupChat/manager_test.go
index b3367230a80faaf3b2f752e627414914d8c8fbfe..0688539249fc4af3cd8ebf59ce612d99fec45061 100644
--- a/groupChat/manager_test.go
+++ b/groupChat/manager_test.go
@@ -20,7 +20,7 @@ import (
 	"time"
 )
 
-// Unit test of Manager.newManager.
+// Unit test of State.newManager.
 func Test_newManager(t *testing.T) {
 	kv := versioned.NewKV(make(ekv.Memstore))
 	user := group.Member{
@@ -64,7 +64,7 @@ func Test_newManager(t *testing.T) {
 	}
 }
 
-// Tests that Manager.newManager loads a group storage when it exists.
+// Tests that State.newManager loads a group storage when it exists.
 func Test_newManager_LoadStorage(t *testing.T) {
 	prng := rand.New(rand.NewSource(42))
 	kv := versioned.NewKV(make(ekv.Memstore))
diff --git a/groupChat/receive_test.go b/groupChat/receive_test.go
index 1592f19f2185852de918a76ba17f5dd767f62018..718ec51b76c99ac1e4f1c3275b2f61395e69974f 100644
--- a/groupChat/receive_test.go
+++ b/groupChat/receive_test.go
@@ -22,13 +22,13 @@ import (
 	"time"
 )
 
-// Tests that Manager.receive returns the correct message on the callback.
+// Tests that State.receive returns the correct message on the callback.
 func TestManager_receive(t *testing.T) {
 	// Setup callback
 	msgChan := make(chan MessageReceive)
 	receiveFunc := func(msg MessageReceive) { msgChan <- msg }
 
-	// Create new test Manager and Group
+	// Create new test State and Group
 	prng := rand.New(rand.NewSource(42))
 	m, g := newTestManagerWithStore(prng, 10, 0, nil, receiveFunc, t)
 
@@ -86,7 +86,7 @@ func TestManager_receive_ReadMessageError(t *testing.T) {
 	msgChan := make(chan MessageReceive)
 	receiveFunc := func(msg MessageReceive) { msgChan <- msg }
 
-	// Create new test Manager and Group
+	// Create new test State and Group
 	prng := rand.New(rand.NewSource(42))
 	m, _ := newTestManagerWithStore(prng, 10, 0, nil, receiveFunc, t)
 
@@ -108,7 +108,7 @@ func TestManager_receive_ReadMessageError(t *testing.T) {
 
 // Tests that the quit channel exits the function.
 func TestManager_receive_QuitChan(t *testing.T) {
-	// Create new test Manager and Group
+	// Create new test State and Group
 	prng := rand.New(rand.NewSource(42))
 	m, _ := newTestManagerWithStore(prng, 10, 0, nil, nil, t)
 
@@ -132,10 +132,10 @@ func TestManager_receive_QuitChan(t *testing.T) {
 	}
 }
 
-// Tests that Manager.readMessage returns the message data for the correct
+// Tests that State.readMessage returns the message data for the correct
 // group.
 func TestManager_readMessage(t *testing.T) {
-	// Create new test Manager and Group
+	// Create new test State and Group
 	prng := rand.New(rand.NewSource(42))
 	m, expectedGrp := newTestManagerWithStore(prng, 10, 0, nil, nil, t)
 
@@ -204,7 +204,7 @@ func TestManager_readMessage(t *testing.T) {
 // Error path: an error is returned when a group with a matching group
 // fingerprint cannot be found.
 func TestManager_readMessage_FindGroupKpError(t *testing.T) {
-	// Create new test Manager and Group
+	// Create new test State and Group
 	prng := rand.New(rand.NewSource(42))
 	m, g := newTestManagerWithStore(prng, 10, 0, nil, nil, t)
 
@@ -238,10 +238,10 @@ func TestManager_readMessage_FindGroupKpError(t *testing.T) {
 	}
 }
 
-// Tests that a cMix message created by Manager.newCmixMsg can be read by
-// Manager.readMessage.
+// Tests that a cMix message created by State.newCmixMsg can be read by
+// State.readMessage.
 func TestManager_decryptMessage(t *testing.T) {
-	// Create new test Manager and Group
+	// Create new test State and Group
 	prng := rand.New(rand.NewSource(42))
 	m, g := newTestManager(prng, t)
 
@@ -297,7 +297,7 @@ func TestManager_decryptMessage(t *testing.T) {
 // Error path: an error is returned when the wrong timestamp is passed in and
 // the decryption key cannot be generated because of the wrong epoch.
 func TestManager_decryptMessage_GetCryptKeyError(t *testing.T) {
-	// Create new test Manager and Group
+	// Create new test State and Group
 	prng := rand.New(rand.NewSource(42))
 	m, g := newTestManager(prng, t)
 
@@ -327,7 +327,7 @@ func TestManager_decryptMessage_GetCryptKeyError(t *testing.T) {
 // Error path: an error is returned when the decrypted payload cannot be
 // unmarshalled.
 func TestManager_decryptMessage_UnmarshalInternalMsgError(t *testing.T) {
-	// Create new test Manager and Group
+	// Create new test State and Group
 	prng := rand.New(rand.NewSource(42))
 	m, g := newTestManager(prng, t)
 
diff --git a/groupChat/sendRequests_test.go b/groupChat/sendRequests_test.go
index c5ec225a4d4638e518fca793da97bdfabfea5162..f52544e53b9d654fcef0d54a12a64c3d59ab2f7c 100644
--- a/groupChat/sendRequests_test.go
+++ b/groupChat/sendRequests_test.go
@@ -120,7 +120,7 @@ func TestManager_ResendRequest_GetGroupError(t *testing.T) {
 	}
 }
 
-// Tests that Manager.sendRequests sends all expected requests successfully.
+// Tests that State.sendRequests sends all expected requests successfully.
 func TestManager_sendRequests(t *testing.T) {
 	prng := rand.New(rand.NewSource(42))
 	m, g := newTestManagerWithStore(prng, 10, 0, nil, nil, t)
@@ -197,7 +197,7 @@ func TestManager_sendRequests(t *testing.T) {
 	}
 }
 
-// Tests that Manager.sendRequests returns the correct status when all sends
+// Tests that State.sendRequests returns the correct status when all sends
 // fail.
 func TestManager_sendRequests_SendAllFail(t *testing.T) {
 	prng := rand.New(rand.NewSource(42))
@@ -226,7 +226,7 @@ func TestManager_sendRequests_SendAllFail(t *testing.T) {
 	}
 }
 
-// Tests that Manager.sendRequests returns the correct status when some sends
+// Tests that State.sendRequests returns the correct status when some sends
 // fail.
 func TestManager_sendRequests_SendPartialSent(t *testing.T) {
 	prng := rand.New(rand.NewSource(42))
@@ -268,7 +268,7 @@ func TestManager_sendRequests_SendPartialSent(t *testing.T) {
 	}
 }
 
-// Unit test of Manager.sendRequest.
+// Unit test of State.sendRequest.
 func TestManager_sendRequest(t *testing.T) {
 	prng := rand.New(rand.NewSource(42))
 	m, g := newTestManagerWithStore(prng, 10, 0, nil, nil, t)
diff --git a/groupChat/send_test.go b/groupChat/send_test.go
index 38042203e9ee2f42a922307e16e1891eaf38821c..0a8bbefe9307b531930fe41f1ed16bfc3ffa790d 100644
--- a/groupChat/send_test.go
+++ b/groupChat/send_test.go
@@ -137,7 +137,7 @@ func TestManager_Send_SendManyCMIXError(t *testing.T) {
 	}
 }
 
-// Tests that Manager.createMessages generates the messages for the correct
+// Tests that State.createMessages generates the messages for the correct
 // group.
 func TestManager_createMessages(t *testing.T) {
 	prng := rand.New(rand.NewSource(42))
@@ -200,7 +200,7 @@ func TestManager_createMessages(t *testing.T) {
 func TestManager_createMessages_InvalidGroupIdError(t *testing.T) {
 	expectedErr := strings.SplitN(newNoGroupErr, "%", 2)[0]
 
-	// Create new test Manager and Group
+	// Create new test State and Group
 	prng := rand.New(rand.NewSource(42))
 	m, _ := newTestManagerWithStore(prng, 10, 0, nil, nil, t)
 
@@ -213,7 +213,7 @@ func TestManager_createMessages_InvalidGroupIdError(t *testing.T) {
 	}
 }
 
-// Tests that Manager.newMessage returns messages with correct data.
+// Tests that State.newMessage returns messages with correct data.
 func TestGroup_newMessages(t *testing.T) {
 	prng := rand.New(rand.NewSource(42))
 	m, g := newTestManager(prng, t)
@@ -276,7 +276,7 @@ func TestGroup_newMessages(t *testing.T) {
 	}
 }
 
-// Error path: an error is returned when Manager.neCmixMsg returns an error.
+// Error path: an error is returned when State.neCmixMsg returns an error.
 func TestGroup_newMessages_NewCmixMsgError(t *testing.T) {
 	expectedErr := strings.SplitN(newCmixErr, "%", 2)[0]
 	prng := rand.New(rand.NewSource(42))
@@ -291,7 +291,7 @@ func TestGroup_newMessages_NewCmixMsgError(t *testing.T) {
 
 // Tests that the message returned by newCmixMsg has all the expected parts.
 func TestGroup_newCmixMsg(t *testing.T) {
-	// Create new test Manager and Group
+	// Create new test State and Group
 	prng := rand.New(rand.NewSource(42))
 	m, g := newTestManager(prng, t)
 
@@ -388,7 +388,7 @@ func TestGroup_newCmixMsg_SaltReaderError(t *testing.T) {
 func TestGroup_newCmixMsg_InternalMsgSizeError(t *testing.T) {
 	expectedErr := strings.SplitN(messageLenErr, "%", 2)[0]
 
-	// Create new test Manager and Group
+	// Create new test State and Group
 	prng := rand.New(rand.NewSource(42))
 	m, g := newTestManager(prng, t)
 
diff --git a/interfaces/auth.go b/interfaces/auth.go
index d82625c723150b433959d22c83241c909fb3781e..60ba0d311342b154238caf251d2eb0c22f339d53 100644
--- a/interfaces/auth.go
+++ b/interfaces/auth.go
@@ -9,42 +9,6 @@ package interfaces
 
 import (
 	"gitlab.com/elixxir/crypto/contact"
-	"gitlab.com/xx_network/primitives/id"
 )
 
 type RequestCallback func(requestor contact.Contact)
-type ConfirmCallback func(partner contact.Contact)
-type ResetNotificationCallback func(partner contact.Contact)
-
-type Auth interface {
-	// Adds a general callback to be used on auth requests. This will be preempted
-	// by any specific callback
-	AddGeneralRequestCallback(cb RequestCallback)
-	// Adds a general callback to be used on auth requests. This will not be
-	// preempted by any specific callback. It is recommended that the specific
-	// callbacks are used, this is primarily for debugging.
-	AddOverrideRequestCallback(cb RequestCallback)
-	// Adds a specific callback to be used on auth requests. This will preempt a
-	// general callback, meaning the request will be heard on this callback and not
-	// the general. Request will still be heard on override callbacks.
-	AddSpecificRequestCallback(id *id.ID, cb RequestCallback)
-	// Removes a specific callback to be used on auth requests.
-	RemoveSpecificRequestCallback(id *id.ID)
-	// Adds a general callback to be used on auth confirms. This will be preempted
-	// by any specific callback
-	AddGeneralConfirmCallback(cb ConfirmCallback)
-	// Adds a general callback to be used on auth confirms. This will not be
-	// preempted by any specific callback. It is recommended that the specific
-	// callbacks are used, this is primarily for debugging.
-	AddOverrideConfirmCallback(cb ConfirmCallback)
-	// Adds a specific callback to be used on auth confirms. This will preempt a
-	// general callback, meaning the request will be heard on this callback and not
-	// the general. Request will still be heard on override callbacks.
-	AddSpecificConfirmCallback(id *id.ID, cb ConfirmCallback)
-	// Removes a specific callback to be used on auth confirm.
-	RemoveSpecificConfirmCallback(id *id.ID)
-	// Add a callback to receive session renegotiation notifications
-	AddResetNotificationCallback(cb ResetNotificationCallback)
-	//Replays all pending received requests over tha callbacks
-	ReplayRequests()
-}
diff --git a/interfaces/networkManager.go b/interfaces/networkManager.go
index b5104d1018151632d4d1ae41767378333990d1bd..2450f4038a0233d9c6bafd14b1aa37b4cbea0526 100644
--- a/interfaces/networkManager.go
+++ b/interfaces/networkManager.go
@@ -137,7 +137,7 @@ type NetworkManager interface {
 
 	/*===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*/
+	this process is in general automatically handled by the Network State*/
 
 	// HasNode can be used to determine if a keying relationship exists with a
 	// node.
@@ -153,7 +153,7 @@ type NetworkManager interface {
 	/*===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.
+	is the system internal to the Network State to do this.
 	It can be used externally as well.*/
 
 	// LookupHistoricalRound - looks up the passed historical round on the
diff --git a/network/identity/tracker.go b/network/identity/tracker.go
index 5dd895176dbbbaba5c62564c431db5ffb8b8915e..c19144301c8dcb166dc8003d7d68de200889fe14 100644
--- a/network/identity/tracker.go
+++ b/network/identity/tracker.go
@@ -9,6 +9,7 @@ package identity
 
 import (
 	"encoding/json"
+	"github.com/pkg/errors"
 	"io"
 	"os"
 	"sync"
@@ -52,29 +53,30 @@ type Tracker interface {
 }
 
 type manager struct {
-	tracked        []trackedID
+	tracked        []TrackedID
 	store          *receptionID.Store
 	session        storage.Session
-	newIdentity    chan trackedID
+	newIdentity    chan TrackedID
 	deleteIdentity chan *id.ID
 	addrSpace      address.Space
 	mux            *sync.Mutex
 }
 
-type trackedID struct {
+type TrackedID struct {
 	NextGeneration time.Time
 	LastGeneration time.Time
 	Source         *id.ID
 	ValidUntil     time.Time
 	Persistent     bool
+	Creation       time.Time
 }
 
 func NewOrLoadTracker(session storage.Session, addrSpace address.Space) *manager {
 	// Initialization
 	t := &manager{
-		tracked:        make([]trackedID, 0),
+		tracked:        make([]TrackedID, 0),
 		session:        session,
-		newIdentity:    make(chan trackedID, trackedIDChanSize),
+		newIdentity:    make(chan TrackedID, trackedIDChanSize),
 		deleteIdentity: make(chan *id.ID, deleteIDChanSize),
 		addrSpace:      addrSpace,
 		mux:            &sync.Mutex{},
@@ -88,7 +90,7 @@ func NewOrLoadTracker(session storage.Session, addrSpace address.Space) *manager
 			jww.WARN.Printf("No tracked identities found, creating a new " +
 				"tracked identity from legacy stored timestamp.")
 
-			t.tracked = append(t.tracked, trackedID{
+			t.tracked = append(t.tracked, TrackedID{
 				// Make the next generation now so a generation triggers on
 				// first run
 				NextGeneration: netTime.Now(),
@@ -103,7 +105,7 @@ func NewOrLoadTracker(session storage.Session, addrSpace address.Space) *manager
 				"stored timestamp found; creating a new tracked identity " +
 				"from scratch.")
 
-			t.tracked = append(t.tracked, trackedID{
+			t.tracked = append(t.tracked, TrackedID{
 				// Make the next generation now so a generation triggers on
 				// first run
 				NextGeneration: netTime.Now(),
@@ -137,12 +139,13 @@ func (t manager) StartProcesses() stoppable.Stoppable {
 
 // AddIdentity adds an identity to be tracked.
 func (t *manager) AddIdentity(id *id.ID, validUntil time.Time, persistent bool) {
-	t.newIdentity <- trackedID{
+	t.newIdentity <- TrackedID{
 		NextGeneration: netTime.Now().Add(-time.Second),
 		LastGeneration: time.Time{},
 		Source:         id,
 		ValidUntil:     validUntil,
 		Persistent:     persistent,
+		Creation:       netTime.Now(),
 	}
 }
 
@@ -157,6 +160,18 @@ func (t *manager) GetEphemeralIdentity(rng io.Reader, addressSize uint8) (
 	return t.store.GetIdentity(rng, addressSize)
 }
 
+// GetIdentity returns a currently tracked identity
+func (t *manager) GetIdentity(get *id.ID) (TrackedID, error) {
+	t.mux.Lock()
+	defer t.mux.Unlock()
+	for i := range t.tracked {
+		if get.Cmp(t.tracked[i].Source) {
+			return t.tracked[i], nil
+		}
+	}
+	return TrackedID{}, errors.Errorf("could not find id %s", get)
+}
+
 func (t *manager) track(stop *stoppable.Single) {
 	// Wait until the ID size is retrieved from the network
 	addressSize := t.addrSpace.GetAddressSpace()
@@ -227,7 +242,7 @@ trackerLoop:
 
 		// Process any deletions
 		if len(toRemove) > 0 {
-			newTracked := make([]trackedID, 0, len(t.tracked))
+			newTracked := make([]TrackedID, 0, len(t.tracked))
 			for i := range t.tracked {
 				if _, remove := toRemove[i]; !remove {
 					newTracked = append(newTracked, t.tracked[i])
@@ -352,7 +367,7 @@ func generateIdentitiesOverRange(lastGeneration, generateThrough time.Time,
 func (t *manager) save() {
 	t.mux.Lock()
 	defer t.mux.Unlock()
-	persistent := make([]trackedID, 0, len(t.tracked))
+	persistent := make([]TrackedID, 0, len(t.tracked))
 
 	for i := range t.tracked {
 		if t.tracked[i].Persistent {
@@ -366,7 +381,7 @@ func (t *manager) save() {
 
 	data, err := json.Marshal(&persistent)
 	if err != nil {
-		jww.FATAL.Panicf("Unable to marshal trackedID list: %+v", err)
+		jww.FATAL.Panicf("Unable to marshal TrackedID list: %+v", err)
 	}
 
 	obj := &versioned.Object{
@@ -377,7 +392,7 @@ func (t *manager) save() {
 
 	err = t.session.GetKV().Set(TrackerListKey, TrackerListVersion, obj)
 	if err != nil {
-		jww.FATAL.Panicf("Unable to save trackedID list: %+v", err)
+		jww.FATAL.Panicf("Unable to save TrackedID list: %+v", err)
 	}
 }
 
diff --git a/network/interface.go b/network/interface.go
index 3a6f8dbf7d3cb0f40c9c3c881b4ba14f3aa5c34d..6992bd3f3bc48440bd0e83f68421a8f09283f141 100644
--- a/network/interface.go
+++ b/network/interface.go
@@ -3,6 +3,7 @@ package network
 import (
 	"gitlab.com/elixxir/client/network/gateway"
 	"gitlab.com/elixxir/client/network/historical"
+	"gitlab.com/elixxir/client/network/identity"
 	"gitlab.com/elixxir/client/network/message"
 	"gitlab.com/elixxir/client/stoppable"
 	"gitlab.com/elixxir/comms/network"
@@ -91,6 +92,9 @@ type Manager interface {
 	// RemoveIdentity removes a currently tracked identity.
 	RemoveIdentity(id *id.ID)
 
+	//GetIdentity returns a currently tracked identity
+	GetIdentity(get *id.ID) (identity.TrackedID, error)
+
 	/* Fingerprints are the primary mechanism of identifying a picked up message
 	   over cMix. They are a unique one time use a 255-bit vector generally
 	   associated with a specific encryption key, but can be used for an
@@ -200,7 +204,7 @@ type Manager interface {
 	/* === Nodes ============================================================ */
 	/* Keys must be registered with nodes in order to send messages through
 	   them. This process is, in general, automatically handled by the Network
-	   Manager. */
+	   State. */
 
 	// HasNode can be used to determine if a keying relationship exists with a
 	// node.
@@ -217,7 +221,7 @@ type Manager interface {
 	/* === 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
+	   is the system internal to the Network State to do this. It can be used
 	   externally as well. */
 
 	// GetRoundResults adjudicates on the rounds requested. Checks if they are
diff --git a/single/manager_test.go b/single/manager_test.go
index 1af9467c086613d77adfc0aad4c6e71e6cd3b46c..754433c161eed7cc87b8ab619452e087df09edc1 100644
--- a/single/manager_test.go
+++ b/single/manager_test.go
@@ -52,7 +52,7 @@ func Test_newManager(t *testing.T) {
 
 	if e.client != m.client || e.store != m.store || e.net != m.net ||
 		e.rng != m.rng || !reflect.DeepEqual(e.p, m.p) {
-		t.Errorf("NewHandler() did not return the expected new Manager."+
+		t.Errorf("NewHandler() did not return the expected new State."+
 			"\nexpected: %+v\nreceived: %+v", e, m)
 	}
 }
diff --git a/storage/ud/facts.go b/storage/ud/facts.go
index 9762bc068b915c4d5138226bf827157911508332..db60c88191477cf1ff50c5779009c652ce01e49c 100644
--- a/storage/ud/facts.go
+++ b/storage/ud/facts.go
@@ -23,7 +23,7 @@ const (
 	factNotInStoreErr             = "Fact %v does not exist in store"
 )
 
-// Store is the storage object for the higher level ud.Manager object.
+// Store is the storage object for the higher level ud.State object.
 // This storage implementation is written for client side.
 type Store struct {
 	// confirmedFacts contains facts that have been confirmed
diff --git a/ud/addFact_test.go b/ud/addFact_test.go
index 7fecfc4d6d59a3a15666e662cbb149af52c6795d..9e9699a989a3ef2e358a71dc233ad2a2ab3b1422 100644
--- a/ud/addFact_test.go
+++ b/ud/addFact_test.go
@@ -45,7 +45,7 @@ func TestAddFact(t *testing.T) {
 		t.Errorf("Failed to start client comms: %+v", err)
 	}
 
-	// Create our Manager object
+	// Create our State object
 	m := Manager{
 		comms:      comms,
 		net:        newTestNetworkManager(t),
diff --git a/ud/manager.go b/ud/manager.go
index e0c0d8ea3dd6349e7e7b961a694d5bd5d592fdd4..b8cee0a4928de9850ea0a5e6cd7a8620c0e2066f 100644
--- a/ud/manager.go
+++ b/ud/manager.go
@@ -63,7 +63,7 @@ func NewManager(client *api.Client, single *single.Manager) (*Manager, error) {
 	jww.INFO.Println("ud.NewManager()")
 	if client.NetworkFollowerStatus() != api.Running {
 		return nil, errors.New(
-			"cannot start UD Manager when network follower is not running.")
+			"cannot start UD State when network follower is not running.")
 	}
 
 	m := &Manager{
diff --git a/ud/manager_test.go b/ud/manager_test.go
index 1dcb6c273df1c6ec7ed92980b15fc8990cfab01a..e7ddfe11110c3ff35a017622186e773f643e5273 100644
--- a/ud/manager_test.go
+++ b/ud/manager_test.go
@@ -67,7 +67,7 @@ func TestManager_SetAlternativeUserDiscovery(t *testing.T) {
 		t.Errorf("Failed to start client comms: %+v", err)
 	}
 
-	// Create our Manager object
+	// Create our State object
 	m := Manager{
 		comms:      comms,
 		net:        newTestNetworkManager(t),
diff --git a/ud/search_test.go b/ud/search_test.go
index d0a1edfb9c9dbd1623ae5e5b9e1234c421c87b44..5fb6b33cefe636422d1deee8161db714bbbc1f8b 100644
--- a/ud/search_test.go
+++ b/ud/search_test.go
@@ -105,7 +105,7 @@ func TestManager_Search(t *testing.T) {
 // func TestManager_Search_CallbackError(t *testing.T) {
 // 	isReg := uint32(1)
 // 	// Set up manager
-// 	m := &Manager{
+// 	m := &State{
 // 		rng:        fastRNG.NewStreamGenerator(12, 3, csprng.NewSystemRNG),
 // 		grp:        cyclic.NewGroup(large.NewInt(107), large.NewInt(2)),
 // 		storage:    storage.InitTestingSession(t),
@@ -172,7 +172,7 @@ func TestManager_Search(t *testing.T) {
 // func TestManager_Search_EventChanTimeout(t *testing.T) {
 // 	isReg := uint32(1)
 // 	// Set up manager
-// 	m := &Manager{
+// 	m := &State{
 // 		rng:        fastRNG.NewStreamGenerator(12, 3, csprng.NewSystemRNG),
 // 		grp:        cyclic.NewGroup(large.NewInt(107), large.NewInt(2)),
 // 		storage:    storage.InitTestingSession(t),