diff --git a/README.md b/README.md
index 497f2c99231e3e0aa8908f4680aa1b76af8f802e..ebf490f59a5ab4ac6c8a154785443cff0ed28310 100644
--- a/README.md
+++ b/README.md
@@ -154,6 +154,8 @@ Available Commands:
 Flags:
       --accept-channel            Accept the channel request for the
                                   corresponding recipient ID
+      --delete-channel            Delete the channel information for the
+                                  corresponding recipient ID                            
       --destfile string           Read this contact file for the destination id
   -d, --destid string             ID to send message to (if below 40, will be
                                   precanned. Use '0x' or 'b64:' for hex and
diff --git a/api/client.go b/api/client.go
index 5bbad8f8c76dbcafc87b9f50955339a5decaa5d2..20ccffacd0b7cec3d3b5542c68378dfff0a9e488 100644
--- a/api/client.go
+++ b/api/client.go
@@ -30,6 +30,7 @@ import (
 	"gitlab.com/xx_network/crypto/signature/rsa"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/ndf"
+	"math"
 	"sync"
 	"time"
 )
@@ -235,6 +236,8 @@ func Login(storageDir string, password []byte, parameters params.Network) (*Clie
 
 	if def.Notification.Address != "" {
 		hp := connect.GetDefaultHostParams()
+		// Client will not send KeepAlive packets
+		hp.KaClientOpts.Time = time.Duration(math.MaxInt64)
 		hp.AuthEnabled = false
 		hp.MaxRetries = 5
 		_, err = c.comms.AddHost(&id.NotificationBot, def.Notification.Address, []byte(def.Notification.TlsCertificate), hp)
@@ -392,11 +395,10 @@ func (c *Client) StartNetworkFollower(timeout time.Duration) (<-chan interfaces.
 	jww.INFO.Printf("StartNetworkFollower() \n\tTransmisstionID: %s "+
 		"\n\tReceptionID: %s", u.TransmissionID, u.ReceptionID)
 
-	if status := c.status.get(); status != Stopped{
+	if status := c.status.get(); status != Stopped {
 		return nil, errors.Errorf("Cannot Stop the Network Follower when it is not running, status: %s", status)
 	}
 
-
 	c.clientErrorChannel = make(chan interfaces.ClientError, 1000)
 
 	cer := func(source, message, trace string) {
@@ -456,7 +458,7 @@ func (c *Client) StopNetworkFollower() error {
 	c.followerLock.Lock()
 	defer c.followerLock.Unlock()
 
-	if status := c.status.get(); status != Running{
+	if status := c.status.get(); status != Running {
 		return errors.Errorf("Cannot Stop the Network Follower when it is not running, status: %s", status)
 	}
 
@@ -570,6 +572,19 @@ func (c *Client) GetNodeRegistrationStatus() (int, int, error) {
 	return numRegistered, len(nodes), nil
 }
 
+// DeleteContact is a function which removes a partner from Client's storage
+func (c *Client) DeleteContact(partnerId *id.ID) error {
+	jww.DEBUG.Printf("Deleting contact with ID %s", partnerId)
+	if err := c.storage.E2e().DeletePartner(partnerId); err != nil {
+		return err
+	}
+	if err := c.storage.Auth().Delete(partnerId); err != nil {
+		return err
+	}
+	c.storage.Conversations().Delete(partnerId)
+	return nil
+}
+
 // ----- Utility Functions -----
 // parseNDF parses the initial ndf string for the client. do not check the
 // signature, it is deprecated.
diff --git a/api/notifications.go b/api/notifications.go
index 6be89c87670c88002f921d872c603104892c5a36..2a7d1b7c107128360f89930c8bf0bcb16dfc54de 100644
--- a/api/notifications.go
+++ b/api/notifications.go
@@ -8,7 +8,6 @@
 package api
 
 import (
-	"fmt"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/comms/mixmessages"
@@ -26,7 +25,6 @@ import (
 // risk to the user.
 func (c *Client) RegisterForNotifications(token string) error {
 	jww.INFO.Printf("RegisterForNotifications(%s)", token)
-	fmt.Println("RegisterforNotifications")
 	// Pull the host from the manage
 	notificationBotHost, ok := c.comms.GetHost(&id.NotificationBot)
 	if !ok {
@@ -36,16 +34,15 @@ func (c *Client) RegisterForNotifications(token string) error {
 	if err != nil {
 		return err
 	}
-	fmt.Println("Sending message")
 	// Send the register message
 	_, err = c.comms.RegisterForNotifications(notificationBotHost,
 		&mixmessages.NotificationRegisterRequest{
 			Token:                 token,
 			IntermediaryId:        intermediaryReceptionID,
-			TransmissionRsa:       rsa.CreatePublicKeyPem(c.GetUser().TransmissionRSA.GetPublic()),
-			TransmissionRsaSig:    sig,
+			TransmissionRsa:       rsa.CreatePublicKeyPem(c.GetStorage().User().GetCryptographicIdentity().GetTransmissionRSA().GetPublic()),
 			TransmissionSalt:      c.GetUser().TransmissionSalt,
-			IIDTransmissionRsaSig: []byte("temp"),
+			TransmissionRsaSig:    c.GetStorage().User().GetTransmissionRegistrationValidationSignature(),
+			IIDTransmissionRsaSig: sig,
 			RegistrationTimestamp: c.GetUser().RegistrationTimestamp.UnixNano(),
 		})
 	if err != nil {
@@ -97,9 +94,12 @@ func (c *Client) getIidAndSig() ([]byte, []byte, error) {
 		return nil, nil, errors.WithMessage(err, "RegisterForNotifications: Failed to write intermediary ID to hash")
 	}
 
-	sig, err := rsa.Sign(c.rng.GetStream(), c.GetUser().TransmissionRSA, hash.CMixHash, h.Sum(nil), nil)
+	stream := c.rng.GetStream()
+	c.GetUser()
+	sig, err := rsa.Sign(stream, c.storage.User().GetCryptographicIdentity().GetTransmissionRSA(), hash.CMixHash, h.Sum(nil), nil)
 	if err != nil {
 		return nil, nil, errors.WithMessage(err, "RegisterForNotifications: Failed to sign intermediary ID")
 	}
+	stream.Close()
 	return intermediaryReceptionID, sig, nil
 }
diff --git a/api/version_vars.go b/api/version_vars.go
index ab6b7356d36db61e2e5d548fa1893167ddcd05d5..494f2d6a7cee377c706e92d3268951f85a464490 100644
--- a/api/version_vars.go
+++ b/api/version_vars.go
@@ -1,9 +1,9 @@
 // Code generated by go generate; DO NOT EDIT.
 // This file was generated by robots at
-// 2021-05-24 13:15:09.546928 -0500 CDT m=+0.071553794
+// 2021-06-22 11:16:35.397077 -0500 CDT m=+0.025546669
 package api
 
-const GITVERSION = `c85adeb9 Merge branch 'Anne/CI2' into 'release'`
+const GITVERSION = `b7692cd7 added Keepalive opts`
 const SEMVER = "2.7.0"
 const DEPENDENCIES = `module gitlab.com/elixxir/client
 
@@ -11,7 +11,7 @@ go 1.13
 
 require (
 	github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3
-	github.com/golang/protobuf v1.4.3
+	github.com/golang/protobuf v1.5.2
 	github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
 	github.com/magiconair/properties v1.8.4 // indirect
 	github.com/mitchellh/mapstructure v1.4.0 // indirect
@@ -24,21 +24,18 @@ require (
 	github.com/spf13/jwalterweatherman v1.1.0
 	github.com/spf13/viper v1.7.1
 	gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228
-	gitlab.com/elixxir/comms v0.0.4-0.20210524170509-89dd425cb228
-	gitlab.com/elixxir/crypto v0.0.7-0.20210524170447-264b215ce90b
+	gitlab.com/elixxir/comms v0.0.4-0.20210622161439-b694033c9507
+	gitlab.com/elixxir/crypto v0.0.7-0.20210614155844-c1e9c23a6ba7
 	gitlab.com/elixxir/ekv v0.1.5
-	gitlab.com/elixxir/primitives v0.0.3-0.20210524170524-9780695d2b55
-	gitlab.com/xx_network/comms v0.0.4-0.20210524170426-175f698a7b07
-	gitlab.com/xx_network/crypto v0.0.5-0.20210524170434-dc9a398a2581
-	gitlab.com/xx_network/primitives v0.0.4-0.20210524170438-ab712af183db
+	gitlab.com/elixxir/primitives v0.0.3-0.20210614155726-ebcf2d47a527
+	gitlab.com/xx_network/comms v0.0.4-0.20210622161535-4f3d927d4c8c
+	gitlab.com/xx_network/crypto v0.0.5-0.20210614155554-8c333814205b
+	gitlab.com/xx_network/primitives v0.0.4-0.20210617180018-6472489fd418
 	golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
-	golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
-	golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect
+	golang.org/x/net v0.0.0-20210525063256-abc453219eb5
 	google.golang.org/genproto v0.0.0-20210105202744-fe13368bc0e1 // indirect
-	google.golang.org/grpc v1.34.0 // indirect
-	google.golang.org/protobuf v1.26.0-rc.1
+	google.golang.org/protobuf v1.26.0
 	gopkg.in/ini.v1 v1.62.0 // indirect
+	gopkg.in/yaml.v2 v2.4.0 // indirect
 )
-
-replace google.golang.org/grpc => github.com/grpc/grpc-go v1.27.1
 `
diff --git a/auth/request.go b/auth/request.go
index 76af994787f8e1658e13345bf14883e091e7790d..a6b9ab7dcc765509017e4b0c5d8efe988e1d1c9b 100644
--- a/auth/request.go
+++ b/auth/request.go
@@ -61,13 +61,13 @@ func RequestAuth(partner, me contact.Contact, message string, rng io.Reader,
 				"receiving a request")
 		} else if rqType == auth.Sent {
 			resend = true
-		}else{
-			return 0, errors.Errorf("Cannot send a request after " +
+		} else {
+			return 0, errors.Errorf("Cannot send a request after "+
 				" a stored request with unknown rqType: %d", rqType)
 		}
-	}else if !strings.Contains(err.Error(), auth.NoRequest){
+	} else if !strings.Contains(err.Error(), auth.NoRequest) {
 		return 0, errors.WithMessage(err,
-			"Cannot send a request after receiving unknown error " +
+			"Cannot send a request after receiving unknown error "+
 				"on requesting contact status")
 	}
 
@@ -105,11 +105,11 @@ func RequestAuth(partner, me contact.Contact, message string, rng io.Reader,
 
 	// in this case we have an ongoing request so we can resend the extant
 	// request
-	if resend{
+	if resend {
 		newPrivKey = sr.GetMyPrivKey()
 		newPubKey = sr.GetMyPubKey()
-	//in this case it is a new request and we must generate new keys
-	}else{
+		//in this case it is a new request and we must generate new keys
+	} else {
 		//generate new keypair
 		newPrivKey = diffieHellman.GeneratePrivateKey(256, grp, rng)
 		newPubKey = diffieHellman.GeneratePublicKey(newPrivKey, grp)
@@ -143,7 +143,7 @@ func RequestAuth(partner, me contact.Contact, message string, rng io.Reader,
 	/*store state*/
 	//fixme: channel is bricked if the first store succedes but the second fails
 	//store the in progress auth
-	if !resend{
+	if !resend {
 		err = storage.Auth().AddSent(partner.ID, partner.DhPubKey, newPrivKey,
 			newPrivKey, confirmFp)
 		if err != nil {
@@ -160,7 +160,7 @@ func RequestAuth(partner, me contact.Contact, message string, rng io.Reader,
 	if err != nil {
 		// if the send fails just set it to failed, it will
 		// but automatically retried
-		return 0, errors.WithMessagef(err, "Auth Request with %s " +
+		return 0, errors.WithMessagef(err, "Auth Request with %s "+
 			"(msgDigest: %s) failed to transmit: %+v", partner.ID,
 			cmixMsg.Digest(), err)
 	}
diff --git a/bindings/client.go b/bindings/client.go
index 432ba95160cf5373b8664e044b5d61e3098a60d5..6c430b96327fc732ff09e0cd90cccc08fd799c12 100644
--- a/bindings/client.go
+++ b/bindings/client.go
@@ -424,6 +424,15 @@ func (c *Client) GetNodeRegistrationStatus() (*NodeRegistrationsStatus, error) {
 	return &NodeRegistrationsStatus{registered, total}, err
 }
 
+// DeleteContact is a function which removes a contact from Client's storage
+func (c *Client) DeleteContact(b []byte) error {
+	contactObj, err := UnmarshalContact(b)
+	if err != nil {
+		return err
+	}
+	return c.api.DeleteContact(contactObj.c.ID)
+}
+
 /*
 // SearchWithHandler is a non-blocking search that also registers
 // a callback interface for user disovery events.
diff --git a/bindings/timeNow.go b/bindings/timeNow.go
index 82cc2d798d8da4c16936b53b2ed3621b175e0e02..fc457b459ae43452a1920c26a8b9e24c53725d74 100644
--- a/bindings/timeNow.go
+++ b/bindings/timeNow.go
@@ -19,6 +19,6 @@ type TimeSource interface {
 // SetTimeSource sets the network time to a custom source.
 func SetTimeSource(timeNow TimeSource) {
 	netTime.Now = func() time.Time {
-		return time.Unix(0,timeNow.NowMs()*int64(time.Millisecond))
+		return time.Unix(0, timeNow.NowMs()*int64(time.Millisecond))
 	}
 }
diff --git a/cmd/getndf.go b/cmd/getndf.go
index 7ac150020c911d695f646993e3a409c18d6cb8da..7562acd153adc1257667faacb4d4a0ccbfbc2e74 100644
--- a/cmd/getndf.go
+++ b/cmd/getndf.go
@@ -70,8 +70,8 @@ var getNDFCmd = &cobra.Command{
 				Partial: &pb.NDFHash{
 					Hash: nil,
 				},
-				LastUpdate:  uint64(0),
-				ReceptionID: dummyID[:],
+				LastUpdate:    uint64(0),
+				ReceptionID:   dummyID[:],
 				ClientVersion: []byte(api.SEMVER),
 			}
 			resp, err := comms.SendPoll(host, pollMsg)
diff --git a/cmd/root.go b/cmd/root.go
index 1c495bae029e9a6b3251b3c6a893158280f69d5d..3dacf0e7b93ad1e30b3f0a93699fb624e599144a 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -103,7 +103,7 @@ var rootCmd = &cobra.Command{
 		client.GetHealth().AddChannel(connected)
 		waitUntilConnected(connected)
 
-		//err = client.RegisterForNotifications([]byte("dJwuGGX3KUyKldWK5PgQH8:APA91bFjuvimRc4LqOyMDiy124aLedifA8DhldtaB_b76ggphnFYQWJc_fq0hzQ-Jk4iYp2wPpkwlpE1fsOjs7XWBexWcNZoU-zgMiM0Mso9vTN53RhbXUferCbAiEylucEOacy9pniN"))
+		//err = client.RegisterForNotifications("dJwuGGX3KUyKldWK5PgQH8:APA91bFjuvimRc4LqOyMDiy124aLedifA8DhldtaB_b76ggphnFYQWJc_fq0hzQ-Jk4iYp2wPpkwlpE1fsOjs7XWBexWcNZoU-zgMiM0Mso9vTN53RhbXUferCbAiEylucEOacy9pniN")
 		//if err != nil {
 		//	jww.FATAL.Panicf("Failed to register for notifications: %+v", err)
 		//}
@@ -174,6 +174,11 @@ var rootCmd = &cobra.Command{
 				" took %d seconds", scnt)
 		}
 
+		// Delete this recipient
+		if viper.GetBool("delete-channel") {
+			deleteChannel(client, recipientID)
+		}
+
 		msg := message.Send{
 			Recipient:   recipientID,
 			Payload:     []byte(msgBody),
@@ -456,6 +461,13 @@ func acceptChannel(client *api.Client, recipientID *id.ID) {
 	}
 }
 
+func deleteChannel(client *api.Client, partnerId *id.ID) {
+	err := client.DeleteContact(partnerId)
+	if err != nil {
+		jww.FATAL.Panicf("%+v", err)
+	}
+}
+
 func printChanRequest(requestor contact.Contact, message string) {
 	msg := fmt.Sprintf("Authentication channel request from: %s\n",
 		requestor.ID)
@@ -769,6 +781,11 @@ func init() {
 	viper.BindPFlag("accept-channel",
 		rootCmd.Flags().Lookup("accept-channel"))
 
+	rootCmd.Flags().Bool("delete-channel", false,
+		"Delete the channel information for the corresponding recipient ID")
+	viper.BindPFlag("delete-channel",
+		rootCmd.Flags().Lookup("delete-channel"))
+
 	rootCmd.Flags().BoolP("send-auth-request", "", false,
 		"Send an auth request to the specified destination and wait"+
 			"for confirmation")
diff --git a/go.mod b/go.mod
index 6cf6093ebada131e619b6feba03d207332111ca6..a877a15edaf7e17febd527d37da19fb807b9955a 100644
--- a/go.mod
+++ b/go.mod
@@ -17,12 +17,12 @@ require (
 	github.com/spf13/jwalterweatherman v1.1.0
 	github.com/spf13/viper v1.7.1
 	gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228
-	gitlab.com/elixxir/comms v0.0.4-0.20210618021545-66a50a0519fe
-	gitlab.com/elixxir/crypto v0.0.7-0.20210614155844-c1e9c23a6ba7
+	gitlab.com/elixxir/comms v0.0.4-0.20210623165525-33c8222c2ce3
+	gitlab.com/elixxir/crypto v0.0.7-0.20210623165245-2bd12c6f4e39
 	gitlab.com/elixxir/ekv v0.1.5
-	gitlab.com/elixxir/primitives v0.0.3-0.20210614155726-ebcf2d47a527
-	gitlab.com/xx_network/comms v0.0.4-0.20210614155654-191473de2702
-	gitlab.com/xx_network/crypto v0.0.5-0.20210614155554-8c333814205b
+	gitlab.com/elixxir/primitives v0.0.3-0.20210623165125-c395ff3484cc
+	gitlab.com/xx_network/comms v0.0.4-0.20210623165053-57910d8f01ee
+	gitlab.com/xx_network/crypto v0.0.5-0.20210623164949-495cf892172d
 	gitlab.com/xx_network/primitives v0.0.4-0.20210617180018-6472489fd418
 	golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
 	golang.org/x/net v0.0.0-20210525063256-abc453219eb5
diff --git a/go.sum b/go.sum
index cd5748235b881f7a77471ffcaea6f05225a64a9c..fb2ae995b8ac9b86edabceb4416b6dca25c5415c 100644
--- a/go.sum
+++ b/go.sum
@@ -235,6 +235,10 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
 github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s=
 github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
+github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 h1:5u+EJUQiosu3JFX0XS0qTf5FznsMOzTjGqavBGuCbo0=
+github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2/go.mod h1:4kyMkleCiLkgY6z8gK5BkI01ChBtxR0ro3I1ZDcGM3w=
+github.com/ttacon/libphonenumber v1.2.1 h1:fzOfY5zUADkCkbIafAed11gL1sW+bJ26p6zWLBMElR4=
+github.com/ttacon/libphonenumber v1.2.1/go.mod h1:E0TpmdVMq5dyVlQ7oenAkhsLu86OkUl+yR4OAxyEg/M=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 github.com/zeebo/assert v0.0.0-20181109011804-10f827ce2ed6/go.mod h1:yssERNPivllc1yU3BvpjYI5BUW+zglcz6QWqeVRL5t0=
 github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
@@ -247,33 +251,30 @@ github.com/zeebo/pcg v1.0.0 h1:dt+dx+HvX8g7Un32rY9XWoYnd0NmKmrIzpHF7qiTDj0=
 github.com/zeebo/pcg v1.0.0/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
 gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228 h1:Gi6rj4mAlK0BJIk1HIzBVMjWNjIUfstrsXC2VqLYPcA=
 gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228/go.mod h1:H6jztdm0k+wEV2QGK/KYA+MY9nj9Zzatux/qIvDDv3k=
-gitlab.com/elixxir/comms v0.0.4-0.20210614195921-6b4a37974c50 h1:ehoUUbGelvWn2UwL9UAL4ZHKvSG3CCOe9zZ9vRD1ZyI=
-gitlab.com/elixxir/comms v0.0.4-0.20210614195921-6b4a37974c50/go.mod h1:JeCKUXRS9xP3YYGPl4+OMFdvtt7ySJIxEsL9AzgeCu0=
-gitlab.com/elixxir/comms v0.0.4-0.20210618021545-66a50a0519fe h1:ohY8eArU2yBrT2d/2cmRhRjmPBfQlA6+VJgIcxxF284=
-gitlab.com/elixxir/comms v0.0.4-0.20210618021545-66a50a0519fe/go.mod h1:JeCKUXRS9xP3YYGPl4+OMFdvtt7ySJIxEsL9AzgeCu0=
+gitlab.com/elixxir/comms v0.0.4-0.20210623165525-33c8222c2ce3 h1:oHKHY6M87Ua4O1XsD/QNXGZdkYk5yXfv029vWgXTuQE=
+gitlab.com/elixxir/comms v0.0.4-0.20210623165525-33c8222c2ce3/go.mod h1:PraQe/afDikUhDE49AvREKrVE3KrBOlcuZhBh4vMfBs=
 gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4/go.mod h1:ucm9SFKJo+K0N2GwRRpaNr+tKXMIOVWzmyUD0SbOu2c=
 gitlab.com/elixxir/crypto v0.0.3/go.mod h1:ZNgBOblhYToR4m8tj4cMvJ9UsJAUKq+p0gCp07WQmhA=
-gitlab.com/elixxir/crypto v0.0.7-0.20210614155844-c1e9c23a6ba7 h1:UBq4/xMUWkYmEzUN2F7nLw5qQeiNKoLaoX3vZ/flz1c=
-gitlab.com/elixxir/crypto v0.0.7-0.20210614155844-c1e9c23a6ba7/go.mod h1:FP848WCzyf81/Csz1lJpi3NXgIdpzJ4hoJam53xwCuo=
+gitlab.com/elixxir/crypto v0.0.7-0.20210623165245-2bd12c6f4e39 h1:Htv/pPNGy7KePcwghA2WmG2SKZwbpnZ69CnOgvBU84k=
+gitlab.com/elixxir/crypto v0.0.7-0.20210623165245-2bd12c6f4e39/go.mod h1:Sj8tbd/cp4T1dVPZM7G6ZQDAYuaxrRIsWs3UqOhWG5k=
 gitlab.com/elixxir/ekv v0.1.5 h1:R8M1PA5zRU1HVnTyrtwybdABh7gUJSCvt1JZwUSeTzk=
 gitlab.com/elixxir/ekv v0.1.5/go.mod h1:e6WPUt97taFZe5PFLPb1Dupk7tqmDCTQu1kkstqJvw4=
 gitlab.com/elixxir/primitives v0.0.0-20200731184040-494269b53b4d/go.mod h1:OQgUZq7SjnE0b+8+iIAT2eqQF+2IFHn73tOo+aV11mg=
 gitlab.com/elixxir/primitives v0.0.0-20200804170709-a1896d262cd9/go.mod h1:p0VelQda72OzoUckr1O+vPW0AiFe0nyKQ6gYcmFSuF8=
 gitlab.com/elixxir/primitives v0.0.0-20200804182913-788f47bded40/go.mod h1:tzdFFvb1ESmuTCOl1z6+yf6oAICDxH2NPUemVgoNLxc=
 gitlab.com/elixxir/primitives v0.0.1/go.mod h1:kNp47yPqja2lHSiS4DddTvFpB/4D9dB2YKnw5c+LJCE=
-gitlab.com/elixxir/primitives v0.0.3-0.20210614155726-ebcf2d47a527 h1:kBNAGFy5Ylz7F0K3DmyzuHLf1npBg7a3t4qKvfqPL3Y=
-gitlab.com/elixxir/primitives v0.0.3-0.20210614155726-ebcf2d47a527/go.mod h1:nSmBXcw4hkBLFdhu+araAPvf9szCDQF1fpRZ9/BgBec=
+gitlab.com/elixxir/primitives v0.0.3-0.20210623165125-c395ff3484cc h1:LTxjZ4Ra69sQHgusXqpaBcb8FZZA+MHq8xGRsh4N0k8=
+gitlab.com/elixxir/primitives v0.0.3-0.20210623165125-c395ff3484cc/go.mod h1:ZlS7xZMG1T/TvnwfUuVOGHbPILtCNUuT5xOPORSQxRY=
 gitlab.com/xx_network/comms v0.0.0-20200805174823-841427dd5023/go.mod h1:owEcxTRl7gsoM8c3RQ5KAm5GstxrJp5tn+6JfQ4z5Hw=
-gitlab.com/xx_network/comms v0.0.4-0.20210614155654-191473de2702 h1:ydi8FaAjFGfxMcvmIGlvnng491K2uEl3ymALC2Hh8Vw=
-gitlab.com/xx_network/comms v0.0.4-0.20210614155654-191473de2702/go.mod h1:ehwxZxcAQHkJjP5BNkwPNK8/o6avUn0j0iDDiu+nMFc=
+gitlab.com/xx_network/comms v0.0.4-0.20210623165053-57910d8f01ee h1:rsVLrqZ+us1Y/69kmP5I0pwmLpvqHxJBx8/AaFsvzsQ=
+gitlab.com/xx_network/comms v0.0.4-0.20210623165053-57910d8f01ee/go.mod h1:sKfOAJkn8bLK7IPpd0Xc1UEL6hRB4p6m25ikh/QF8Yk=
 gitlab.com/xx_network/crypto v0.0.3/go.mod h1:DF2HYvvCw9wkBybXcXAgQMzX+MiGbFPjwt3t17VRqRE=
 gitlab.com/xx_network/crypto v0.0.4/go.mod h1:+lcQEy+Th4eswFgQDwT0EXKp4AXrlubxalwQFH5O0Mk=
-gitlab.com/xx_network/crypto v0.0.5-0.20210614155554-8c333814205b h1:X2Hhg9/IYowxMdI6TTnWj6WW3pnO2vMB/7f4mnu6Muw=
-gitlab.com/xx_network/crypto v0.0.5-0.20210614155554-8c333814205b/go.mod h1:wiaQXyI9C9UGxxgLd+2lDmKyovO+PjFxaesCBgG0YDA=
+gitlab.com/xx_network/crypto v0.0.5-0.20210623164949-495cf892172d h1:dqVruaOqcWhz1oflJZGsOAMR5JDDepPjA87aImeOiLg=
+gitlab.com/xx_network/crypto v0.0.5-0.20210623164949-495cf892172d/go.mod h1:BLwPMs31pn0MNXGfhZJpRqzLWGhHS3ddDfdjZo59QSI=
 gitlab.com/xx_network/primitives v0.0.0-20200803231956-9b192c57ea7c/go.mod h1:wtdCMr7DPePz9qwctNoAUzZtbOSHSedcK++3Df3psjA=
 gitlab.com/xx_network/primitives v0.0.0-20200804183002-f99f7a7284da/go.mod h1:OK9xevzWCaPO7b1wiluVJGk7R5ZsuC7pHY5hteZFQug=
 gitlab.com/xx_network/primitives v0.0.2/go.mod h1:cs0QlFpdMDI6lAo61lDRH2JZz+3aVkHy+QogOB6F/qc=
-gitlab.com/xx_network/primitives v0.0.4-0.20210608160426-670aab2d82cf/go.mod h1:9imZHvYwNFobxueSvVtHneZLk9wTK7HQTzxPm+zhFhE=
 gitlab.com/xx_network/primitives v0.0.4-0.20210617180018-6472489fd418 h1:F52R0wvFobjkmB8YaPNHZIu0VYqwjesMBCb9T14ygW8=
 gitlab.com/xx_network/primitives v0.0.4-0.20210617180018-6472489fd418/go.mod h1:9imZHvYwNFobxueSvVtHneZLk9wTK7HQTzxPm+zhFhE=
 gitlab.com/xx_network/ring v0.0.3-0.20210527191221-ce3f170aabd5 h1:FY+4Rh1Q2rgLyv10aKJjhWApuKRCR/054XhreudfAvw=
diff --git a/interfaces/params/rounds.go b/interfaces/params/rounds.go
index 4a6ffab984f3ba309d7fdb77cf7cfb1710f8cef4..3e39ad47827e5f5f6f9dc526fcfffa200f5cf5a8 100644
--- a/interfaces/params/rounds.go
+++ b/interfaces/params/rounds.go
@@ -51,7 +51,7 @@ func GetDefaultRounds() Rounds {
 		LookupRoundsBufferLen:      2000,
 		ForceHistoricalRounds:      false,
 		MaxHistoricalRoundsRetries: 3,
-		UncheckRoundPeriod: 20 * time.Second,
-		ForceMessagePickupRetry: false,
+		UncheckRoundPeriod:         20 * time.Second,
+		ForceMessagePickupRetry:    false,
 	}
 }
diff --git a/keyExchange/confirm.go b/keyExchange/confirm.go
index ce1bec2baf28d92502c494ec94e659ba1e7c48c1..45224193f80a302ae24e4e4f01ec0f7afe647638 100644
--- a/keyExchange/confirm.go
+++ b/keyExchange/confirm.go
@@ -83,11 +83,11 @@ func unmarshalConfirm(payload []byte) (e2e.SessionID, error) {
 			"unmarshal payload: %s", err)
 	}
 
-	confimedSessionID := e2e.SessionID{}
-	if err := confimedSessionID.Unmarshal(msg.SessionID); err != nil {
+	confirmedSessionID := e2e.SessionID{}
+	if err := confirmedSessionID.Unmarshal(msg.SessionID); err != nil {
 		return e2e.SessionID{}, errors.Errorf("Failed to unmarshal"+
 			" sessionID: %s", err)
 	}
 
-	return confimedSessionID, nil
+	return confirmedSessionID, nil
 }
diff --git a/network/manager.go b/network/manager.go
index fcb20f2d77f94a57c4c2f01e581b03fca06b6178..d480f4afe6c2b23da229c4c20b0b752c3e4d936f 100644
--- a/network/manager.go
+++ b/network/manager.go
@@ -28,6 +28,8 @@ import (
 	"gitlab.com/elixxir/comms/network"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/xx_network/primitives/ndf"
+	"math"
+	"time"
 )
 
 // Manager implements the NetworkManager interface inside context. It
@@ -95,6 +97,8 @@ func NewManager(session *storage.Session, switchboard *switchboard.Switchboard,
 
 	// Set up gateway.Sender
 	poolParams := gateway.DefaultPoolParams()
+	// Client will not send KeepAlive packets
+	poolParams.HostParams.KaClientOpts.Time = time.Duration(math.MaxInt64)
 	m.sender, err = gateway.NewSender(poolParams, rng,
 		ndf, comms, session, m.NodeRegistration)
 	if err != nil {
diff --git a/network/message/parse/partition.go b/network/message/parse/partition.go
index e7fbbfd313379570d3ec522d23053fbd025456cf..ad66ba2f30e09434dc090f07e0917137973d9b00 100644
--- a/network/message/parse/partition.go
+++ b/network/message/parse/partition.go
@@ -12,6 +12,7 @@ import (
 	"gitlab.com/elixxir/client/interfaces/message"
 	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/xx_network/primitives/id"
+	"gitlab.com/xx_network/primitives/netTime"
 	"time"
 )
 
@@ -80,9 +81,9 @@ func (p Partitioner) HandlePartition(sender *id.ID, _ message.EncryptionType,
 		// Handle the message ID
 		messageID := p.session.Conversations().Get(sender).
 			ProcessReceivedMessageID(fm.GetID())
-
+		storeageTimestamp := netTime.Now()
 		return p.session.Partition().AddFirst(sender, fm.GetType(),
-			messageID, fm.GetPart(), fm.GetNumParts(), fm.GetTimestamp(),
+			messageID, fm.GetPart(), fm.GetNumParts(), fm.GetTimestamp(), storeageTimestamp,
 			fm.GetSizedContents(), relationshipFingerprint)
 	} else {
 		// If it is a subsequent message part, handle it as so
diff --git a/network/message/sendCmix.go b/network/message/sendCmix.go
index d70cd6221a32fd84d40e9b4afba0d60f22691456..1c1e7c1f3d3b0af1e55d549c156d93d82a5a6b40 100644
--- a/network/message/sendCmix.go
+++ b/network/message/sendCmix.go
@@ -74,14 +74,13 @@ func sendCmixHelper(sender *gateway.Sender, msg format.Message,
 		remainingTime := cmixParams.Timeout - elapsed
 		//find the best round to send to, excluding attempted rounds
 		bestRound, err := instance.GetWaitingRounds().GetUpcomingRealtime(remainingTime, attempted, sendTimeBuffer)
-		if err!=nil{
+		if err != nil {
 			jww.WARN.Printf("Failed to GetUpcomingRealtime (msgDigest: %s): %+v", msg.Digest(), err)
 		}
 		if bestRound == nil {
 			continue
 		}
 
-
 		//add the round on to the list of attempted so it is not tried again
 		attempted.Insert(bestRound)
 
diff --git a/permissioning/permissioning.go b/permissioning/permissioning.go
index ebe00b3c3d41c3c9fcaf844e65d87fc6033dd829..87c3b6fff40c147c59a4534f7e52f588a9ad45fd 100644
--- a/permissioning/permissioning.go
+++ b/permissioning/permissioning.go
@@ -13,6 +13,8 @@ import (
 	"gitlab.com/xx_network/comms/connect"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/ndf"
+	"math"
+	"time"
 )
 
 type Permissioning struct {
@@ -31,7 +33,8 @@ func Init(comms *client.Comms, def *ndf.NetworkDefinition) (*Permissioning, erro
 	//add the permissioning host to comms
 	hParam := connect.GetDefaultHostParams()
 	hParam.AuthEnabled = false
-
+	// Client will not send KeepAlive packets
+	hParam.KaClientOpts.Time = time.Duration(math.MaxInt64)
 	perm.host, err = comms.AddHost(&id.Permissioning, def.Registration.Address,
 		[]byte(def.Registration.TlsCertificate), hParam)
 
diff --git a/permissioning/register.go b/permissioning/register.go
index e332152573c112c5e7cf5f32608f6aa3f2a8c60b..ead58a5fcdd3856619294bab3708f1c75049487b 100644
--- a/permissioning/register.go
+++ b/permissioning/register.go
@@ -44,6 +44,6 @@ func register(comms registrationMessageSender, host *connect.Host,
 		return nil, nil, 0, errors.Errorf("sendRegistrationMessage: error handling message: %s", response.Error)
 	}
 
-	return response.ClientSignedByServer.Signature, 
-	response.ClientReceptionSignedByServer.Signature, response.Timestamp, nil
+	return response.ClientSignedByServer.Signature,
+		response.ClientReceptionSignedByServer.Signature, response.Timestamp, nil
 }
diff --git a/storage/auth/store.go b/storage/auth/store.go
index 9ce2e6154e3b5bce28f4df6c36cbffca43255fc8..341bc74c01639163b9c22666263ab23b7812b1a8 100644
--- a/storage/auth/store.go
+++ b/storage/auth/store.go
@@ -92,7 +92,7 @@ func LoadStore(kv *versioned.KV, grp *cyclic.Group, privKeys []*cyclic.Int) (*St
 		return nil, errors.WithMessagef(err, "Failed to "+
 			"unmarshal SentRequestMap")
 	}
-
+	jww.TRACE.Printf("%d found when loading AuthStore", len(requestList))
 	for _, rDisk := range requestList {
 		r := &request{
 			rt: RequestType(rDisk.T),
@@ -117,7 +117,6 @@ func LoadStore(kv *versioned.KV, grp *cyclic.Group, privKeys []*cyclic.Int) (*St
 				PrivKey: nil,
 				Request: r,
 			}
-
 			rid = sr.partner
 			r.sent = sr
 
@@ -143,7 +142,6 @@ func LoadStore(kv *versioned.KV, grp *cyclic.Group, privKeys []*cyclic.Int) (*St
 
 func (s *Store) save() error {
 	requestIDList := make([]requestDisk, len(s.requests))
-
 	index := 0
 	for pid, r := range s.requests {
 		rDisk := requestDisk{
@@ -158,7 +156,6 @@ func (s *Store) save() error {
 	if err != nil {
 		return err
 	}
-
 	obj := versioned.Object{
 		Version:   requestMapVersion,
 		Timestamp: netTime.Now(),
@@ -206,6 +203,7 @@ func (s *Store) AddSent(partner *id.ID, partnerHistoricalPubKey, myPrivKey,
 
 	jww.INFO.Printf("AddSent PUBKEY FINGERPRINT: %v", sr.fingerprint)
 	jww.INFO.Printf("AddSent PUBKEY: %v", sr.myPubKey.Bytes())
+	jww.INFO.Printf("AddSent Partner: %s", partner)
 
 	s.fingerprints[sr.fingerprint] = fingerprint{
 		Type:    Specific,
@@ -219,7 +217,7 @@ func (s *Store) AddSent(partner *id.ID, partnerHistoricalPubKey, myPrivKey,
 func (s *Store) AddReceived(c contact.Contact) error {
 	s.mux.Lock()
 	defer s.mux.Unlock()
-
+	jww.DEBUG.Printf("AddReceived new contact: %s", c.ID)
 	if _, ok := s.requests[*c.ID]; ok {
 		return errors.Errorf("Cannot add contact for partner "+
 			"%s, one already exists", c.ID)
diff --git a/storage/e2e/manager.go b/storage/e2e/manager.go
index 6d7691b2b8f402c92ea6d4615a175b0b14b4b61e..a978beeae77c2fffa723c15f495ebf1fa4925c5c 100644
--- a/storage/e2e/manager.go
+++ b/storage/e2e/manager.go
@@ -112,6 +112,25 @@ func loadManager(ctx *context, kv *versioned.KV, partnerID *id.ID) (*Manager, er
 	return m, nil
 }
 
+// clearManager removes the relationship between the partner
+// and deletes the Send and Receive sessions. This includes the
+// sessions and the key vectors
+func clearManager(m *Manager, kv *versioned.KV) error {
+	kv = kv.Prefix(fmt.Sprintf(managerPrefix, m.partner))
+
+	if err := DeleteRelationship(m); err != nil {
+		return errors.WithMessage(err,
+			"Failed to delete relationship")
+	}
+
+	if err := utility.DeleteCyclicKey(m.kv, originPartnerPubKey); err != nil {
+		jww.FATAL.Panicf("Failed to delete %s: %+v", originPartnerPubKey,
+			err)
+	}
+
+	return nil
+}
+
 // NewReceiveSession creates a new Receive session using the latest private key
 // this user has sent and the new public key received from the partner. If the
 // session already exists, then it will not be overwritten and the extant
diff --git a/storage/e2e/manager_test.go b/storage/e2e/manager_test.go
index 195b0752a603002dcb395507fc0b7d361a0b235a..114afac841407a4c4f8a0116ac452b7bd01c68cc 100644
--- a/storage/e2e/manager_test.go
+++ b/storage/e2e/manager_test.go
@@ -70,6 +70,30 @@ func TestLoadManager(t *testing.T) {
 	}
 }
 
+// Unit test for clearManager
+func TestManager_ClearManager(t *testing.T) {
+	defer func() {
+		if r := recover(); r == nil {
+			t.Fatalf("clearManager error: " +
+				"Did not panic when loading deleted manager")
+		}
+	}()
+
+	// Set up expected and test values
+	expectedM, kv := newTestManager(t)
+
+	err := clearManager(expectedM, kv)
+	if err != nil {
+		t.Fatalf("clearManager returned an error: %v", err)
+	}
+
+	// Attempt to load relationship
+	_, err = loadManager(expectedM.ctx, kv, expectedM.partner)
+	if err != nil {
+		t.Errorf("loadManager() returned an error: %v", err)
+	}
+}
+
 // Tests happy path of Manager.NewReceiveSession.
 func TestManager_NewReceiveSession(t *testing.T) {
 	// Set up test values
diff --git a/storage/e2e/relationship.go b/storage/e2e/relationship.go
index f92e12b6901b206dcdf2cae00200555eb762894b..e0e7723d6c332c36a1ac9ceae0753e3174da4ba6 100644
--- a/storage/e2e/relationship.go
+++ b/storage/e2e/relationship.go
@@ -84,6 +84,33 @@ func NewRelationship(manager *Manager, t RelationshipType,
 	return r
 }
 
+// DeleteRelationship removes all relationship and
+// relationship adjacent information from storage
+func DeleteRelationship(manager *Manager) error {
+
+	// Delete the send information
+	sendKv := manager.kv.Prefix(Send.prefix())
+	manager.send.Delete()
+	if err := deleteRelationshipFingerprint(sendKv); err != nil {
+		return err
+	}
+	if err := sendKv.Delete(relationshipKey, currentRelationshipVersion); err != nil {
+		return errors.Errorf("Could not delete send relationship: %v", err)
+	}
+
+	// Delete the receive information
+	receiveKv := manager.kv.Prefix(Receive.prefix())
+	manager.receive.Delete()
+	if err := deleteRelationshipFingerprint(receiveKv); err != nil {
+		return err
+	}
+	if err := receiveKv.Delete(relationshipKey, currentRelationshipVersion); err != nil {
+		return errors.Errorf("Could not delete receive relationship: %v", err)
+	}
+
+	return nil
+}
+
 func LoadRelationship(manager *Manager, t RelationshipType) (*relationship, error) {
 
 	kv := manager.kv.Prefix(t.prefix())
@@ -166,6 +193,16 @@ func (r *relationship) unmarshal(b []byte) error {
 	return nil
 }
 
+func (r *relationship) Delete() {
+	r.mux.Lock()
+	defer r.mux.Unlock()
+	for _, s := range r.sessions {
+		delete(r.sessionByID, s.GetID())
+		s.Delete()
+	}
+
+}
+
 func (r *relationship) AddSession(myPrivKey, partnerPubKey, baseKey *cyclic.Int,
 	trigger SessionID, negotiationStatus Negotiation,
 	e2eParams params.E2ESessionParams) *Session {
diff --git a/storage/e2e/relationshipFingerprint.go b/storage/e2e/relationshipFingerprint.go
index a3702655319ccf0f14323d31f5b32b3fe59cb825..29b80896dfc078b8ab1a7cefa348a7860498aec2 100644
--- a/storage/e2e/relationshipFingerprint.go
+++ b/storage/e2e/relationshipFingerprint.go
@@ -57,3 +57,9 @@ func loadRelationshipFingerprint(kv *versioned.KV) []byte {
 	}
 	return obj.Data
 }
+
+// deleteRelationshipFingerprint is a helper function which deletes a fingerprint from store
+func deleteRelationshipFingerprint(kv *versioned.KV) error {
+	return kv.Delete(relationshipFingerprintKey,
+		currentRelationshipVersion)
+}
diff --git a/storage/e2e/relationship_test.go b/storage/e2e/relationship_test.go
index 457e4f6dcd508abd2014248db7738f46badf947a..1ad211fcd55a389e758711a22ac8bcff24fdd76e 100644
--- a/storage/e2e/relationship_test.go
+++ b/storage/e2e/relationship_test.go
@@ -68,6 +68,64 @@ func TestLoadRelationship(t *testing.T) {
 	}
 }
 
+// Shows that a deleted Relationship can no longer be pulled from store
+func TestDeleteRelationship(t *testing.T) {
+	mgr := makeTestRelationshipManager(t)
+
+	// Generate send relationship
+	mgr.send = NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
+	if err := mgr.send.save(); err != nil {
+		t.Fatal(err)
+	}
+
+	// Generate receive relationship
+	mgr.receive = NewRelationship(mgr, Receive, params.GetDefaultE2ESessionParams())
+	if err := mgr.receive.save(); err != nil {
+		t.Fatal(err)
+	}
+
+	err := DeleteRelationship(mgr)
+	if err != nil {
+		t.Fatalf("DeleteRelationship error: Could not delete manager: %v", err)
+	}
+
+	_, err = LoadRelationship(mgr, Send)
+	if err == nil {
+		t.Fatalf("DeleteRelationship error: Should not have loaded deleted relationship: %v", err)
+	}
+
+	_, err = LoadRelationship(mgr, Receive)
+	if err == nil {
+		t.Fatalf("DeleteRelationship error: Should not have loaded deleted relationship: %v", err)
+	}
+}
+
+// Shows that a deleted relationship fingerprint can no longer be pulled from store
+func TestRelationship_deleteRelationshipFingerprint(t *testing.T) {
+	defer func() {
+		if r := recover(); r == nil {
+			t.Fatalf("deleteRelationshipFingerprint error: " +
+				"Did not panic when loading deleted fingerprint")
+		}
+	}()
+
+	mgr := makeTestRelationshipManager(t)
+	sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
+
+	err := sb.save()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = deleteRelationshipFingerprint(mgr.kv)
+	if err != nil {
+		t.Fatalf("deleteRelationshipFingerprint error: "+
+			"Could not delete fingerprint: %v", err)
+	}
+
+	loadRelationshipFingerprint(mgr.kv)
+}
+
 // Shows that Relationship returns a valid session buff
 func TestNewRelationshipBuff(t *testing.T) {
 	mgr := makeTestRelationshipManager(t)
diff --git a/storage/e2e/session.go b/storage/e2e/session.go
index 6e85d873e36768d2372b5f713c45527625233c3c..9f74ebf35efe310214237e6da36f9f4029c872be 100644
--- a/storage/e2e/session.go
+++ b/storage/e2e/session.go
@@ -201,7 +201,8 @@ func (s *Session) save() error {
 
 /*METHODS*/
 // Done all unused key fingerprints
-// delete this session and its key states from the storage
+
+// Delete removes this session and its key states from the storage
 func (s *Session) Delete() {
 	s.mux.Lock()
 	defer s.mux.Unlock()
@@ -221,7 +222,7 @@ func (s *Session) Delete() {
 	}
 }
 
-//Gets the base key.
+// GetBaseKey retrieves the base key.
 func (s *Session) GetBaseKey() *cyclic.Int {
 	// no lock is needed because this cannot be edited
 	return s.baseKey.DeepCopy()
diff --git a/storage/e2e/store.go b/storage/e2e/store.go
index b6dc289c9b83edfa42e1468a015203d67dd7c1cd..2a8006902a9adf5a94704175f55f548f61eb0d7a 100644
--- a/storage/e2e/store.go
+++ b/storage/e2e/store.go
@@ -188,6 +188,21 @@ func (s *Store) AddPartner(partnerID *id.ID, partnerPubKey, myPrivKey *cyclic.In
 	return nil
 }
 
+// DeletePartner removes the associated contact from the E2E store
+func (s *Store) DeletePartner(partnerId *id.ID) error {
+	m, ok := s.managers[*partnerId]
+	if !ok {
+		return errors.New(NoPartnerErrorStr)
+	}
+
+	if err := clearManager(m, s.kv); err != nil {
+		return errors.WithMessagef(err, "Could not remove partner %s from store", partnerId)
+	}
+
+	delete(s.managers, *partnerId)
+	return s.save()
+}
+
 func (s *Store) GetPartner(partnerID *id.ID) (*Manager, error) {
 	s.mux.RLock()
 	defer s.mux.RUnlock()
diff --git a/storage/e2e/store_test.go b/storage/e2e/store_test.go
index ef23f381f0370afec21f22c75d65dee892c93163..016184b58e803a9b92d763be3c880b8a1b4dc05e 100644
--- a/storage/e2e/store_test.go
+++ b/storage/e2e/store_test.go
@@ -98,7 +98,10 @@ func TestStore_AddPartner(t *testing.T) {
 	expectedManager := newManager(s.context, s.kv, partnerID, s.dhPrivateKey,
 		pubKey, p, p)
 
-	s.AddPartner(partnerID, pubKey, s.dhPrivateKey, p, p)
+	err := s.AddPartner(partnerID, pubKey, s.dhPrivateKey, p, p)
+	if err != nil {
+		t.Fatalf("AddPartner returned an error: %v", err)
+	}
 
 	m, exists := s.managers[*partnerID]
 	if !exists {
@@ -111,6 +114,30 @@ func TestStore_AddPartner(t *testing.T) {
 	}
 }
 
+// Unit test for DeletePartner
+func TestStore_DeletePartner(t *testing.T) {
+	s, _, _ := makeTestStore()
+	partnerID := id.NewIdFromUInt(rand.Uint64(), id.User, t)
+	pubKey := diffieHellman.GeneratePublicKey(s.dhPrivateKey, s.grp)
+	p := params.GetDefaultE2ESessionParams()
+
+	err := s.AddPartner(partnerID, pubKey, s.dhPrivateKey, p, p)
+	if err != nil {
+		t.Fatalf("DeletePartner error: Could not add partner in set up: %v", err)
+	}
+
+	err = s.DeletePartner(partnerID)
+	if err != nil {
+		t.Fatalf("DeletePartner received an error: %v", err)
+	}
+
+	_, err = s.GetPartner(partnerID)
+	if err == nil {
+		t.Errorf("DeletePartner error: Should not be able to pull deleted partner from store")
+	}
+
+}
+
 // Tests happy path of Store.GetPartner.
 func TestStore_GetPartner(t *testing.T) {
 	s, _, _ := makeTestStore()
diff --git a/storage/partition/multiPartMessage.go b/storage/partition/multiPartMessage.go
index 754c524702498c2c6586d54a42adedf3351a7cc5..3aa8cffb556c3bd23f8afb6f8730830919b3c07f 100644
--- a/storage/partition/multiPartMessage.go
+++ b/storage/partition/multiPartMessage.go
@@ -30,8 +30,11 @@ type multiPartMessage struct {
 	MessageID    uint64
 	NumParts     uint8
 	PresentParts uint8
-	Timestamp    time.Time
-	MessageType  message.Type
+	// Timestamp of message from sender
+	SenderTimestamp time.Time
+	// Timestamp in which message was stored in RAM
+	StorageTimestamp time.Time
+	MessageType      message.Type
 
 	parts [][]byte
 	kv    *versioned.KV
@@ -48,13 +51,13 @@ func loadOrCreateMultiPartMessage(sender *id.ID, messageID uint64,
 	if err != nil {
 		if !ekv.Exists(err) {
 			mpm := &multiPartMessage{
-				Sender:       sender,
-				MessageID:    messageID,
-				NumParts:     0,
-				PresentParts: 0,
-				Timestamp:    time.Time{},
-				MessageType:  0,
-				kv:           kv,
+				Sender:          sender,
+				MessageID:       messageID,
+				NumParts:        0,
+				PresentParts:    0,
+				SenderTimestamp: time.Time{},
+				MessageType:     0,
+				kv:              kv,
 			}
 			if err = mpm.save(); err != nil {
 				jww.FATAL.Panicf("Failed to save new multi part "+
@@ -119,7 +122,7 @@ func (mpm *multiPartMessage) Add(partNumber uint8, part []byte) {
 }
 
 func (mpm *multiPartMessage) AddFirst(mt message.Type, partNumber uint8,
-	numParts uint8, timestamp time.Time, part []byte) {
+	numParts uint8, senderTimestamp, storageTimestamp time.Time, part []byte) {
 	mpm.mux.Lock()
 	defer mpm.mux.Unlock()
 
@@ -129,10 +132,11 @@ func (mpm *multiPartMessage) AddFirst(mt message.Type, partNumber uint8,
 	}
 
 	mpm.NumParts = numParts
-	mpm.Timestamp = timestamp
+	mpm.SenderTimestamp = senderTimestamp
 	mpm.MessageType = mt
 	mpm.parts[partNumber] = part
 	mpm.PresentParts++
+	mpm.StorageTimestamp = storageTimestamp
 
 	if err := savePart(mpm.kv, partNumber, part); err != nil {
 		jww.FATAL.Panicf("Failed to save multi part "+
@@ -159,27 +163,8 @@ func (mpm *multiPartMessage) IsComplete(relationshipFingerprint []byte) (message
 		mpm.parts = append(mpm.parts, make([][]byte, int(mpm.NumParts)-len(mpm.parts))...)
 	}
 
-	var err error
-	lenMsg := 0
-	// Load all parts from disk, deleting files from disk as we go along
-	for i := uint8(0); i < mpm.NumParts; i++ {
-		if mpm.parts[i] == nil {
-			if mpm.parts[i], err = loadPart(mpm.kv, i); err != nil {
-				jww.FATAL.Panicf("Failed to load multi part "+
-					"message part %v from %s messageID %v: %s", i, mpm.Sender,
-					mpm.MessageID, err)
-			}
-			if err = deletePart(mpm.kv, i); err != nil {
-				jww.FATAL.Panicf("Failed to delete  multi part "+
-					"message part %v from %s messageID %v: %s", i, mpm.Sender,
-					mpm.MessageID, err)
-			}
-		}
-		lenMsg += len(mpm.parts[i])
-	}
-
 	// delete the multipart message
-	mpm.delete()
+	lenMsg := mpm.delete()
 	mpm.mux.Unlock()
 
 	// Reconstruct the message
@@ -200,7 +185,7 @@ func (mpm *multiPartMessage) IsComplete(relationshipFingerprint []byte) (message
 		Payload:     reconstructed,
 		MessageType: mpm.MessageType,
 		Sender:      mpm.Sender,
-		Timestamp:   mpm.Timestamp,
+		Timestamp:   mpm.SenderTimestamp,
 		// Encryption will be set externally
 		Encryption: 0,
 		ID:         mid,
@@ -209,7 +194,27 @@ func (mpm *multiPartMessage) IsComplete(relationshipFingerprint []byte) (message
 	return m, true
 }
 
-func (mpm *multiPartMessage) delete() {
+// deletes all parts from disk and RAM. Returns the message length for reconstruction
+func (mpm *multiPartMessage) delete() int {
+	// Load all parts from disk, deleting files from disk as we go along
+	var err error
+	lenMsg := 0
+	for i := uint8(0); i < mpm.NumParts; i++ {
+		if mpm.parts[i] == nil {
+			if mpm.parts[i], err = loadPart(mpm.kv, i); err != nil {
+				jww.FATAL.Panicf("Failed to load multi part "+
+					"message part %v from %s messageID %v: %s", i, mpm.Sender,
+					mpm.MessageID, err)
+			}
+			if err = deletePart(mpm.kv, i); err != nil {
+				jww.FATAL.Panicf("Failed to delete  multi part "+
+					"message part %v from %s messageID %v: %s", i, mpm.Sender,
+					mpm.MessageID, err)
+			}
+		}
+		lenMsg += len(mpm.parts[i])
+	}
+
 	//key := makeMultiPartMessageKey(mpm.MessageID)
 	if err := mpm.kv.Delete(messageKey,
 		currentMultiPartMessageVersion); err != nil {
@@ -217,4 +222,6 @@ func (mpm *multiPartMessage) delete() {
 			"message from %s messageID %v: %s", mpm.Sender,
 			mpm.MessageID, err)
 	}
+
+	return lenMsg
 }
diff --git a/storage/partition/multiPartMessage_test.go b/storage/partition/multiPartMessage_test.go
index dff3c0fabb41cffd20f714497b487ea8bcbd4644..752d53272bb121f566e2917d746087020f68d14b 100644
--- a/storage/partition/multiPartMessage_test.go
+++ b/storage/partition/multiPartMessage_test.go
@@ -27,13 +27,13 @@ func Test_loadOrCreateMultiPartMessage_Create(t *testing.T) {
 	// Set up expected test value
 	prng := rand.New(rand.NewSource(netTime.Now().UnixNano()))
 	expectedMpm := &multiPartMessage{
-		Sender:       id.NewIdFromUInt(prng.Uint64(), id.User, t),
-		MessageID:    prng.Uint64(),
-		NumParts:     0,
-		PresentParts: 0,
-		Timestamp:    time.Time{},
-		MessageType:  0,
-		kv:           versioned.NewKV(make(ekv.Memstore)),
+		Sender:          id.NewIdFromUInt(prng.Uint64(), id.User, t),
+		MessageID:       prng.Uint64(),
+		NumParts:        0,
+		PresentParts:    0,
+		SenderTimestamp: time.Time{},
+		MessageType:     0,
+		kv:              versioned.NewKV(make(ekv.Memstore)),
 	}
 	expectedData, err := json.Marshal(expectedMpm)
 	if err != nil {
@@ -63,13 +63,13 @@ func Test_loadOrCreateMultiPartMessage_Load(t *testing.T) {
 	// Set up expected test value
 	prng := rand.New(rand.NewSource(netTime.Now().UnixNano()))
 	expectedMpm := &multiPartMessage{
-		Sender:       id.NewIdFromUInt(prng.Uint64(), id.User, t),
-		MessageID:    prng.Uint64(),
-		NumParts:     0,
-		PresentParts: 0,
-		Timestamp:    time.Time{},
-		MessageType:  0,
-		kv:           versioned.NewKV(make(ekv.Memstore)),
+		Sender:          id.NewIdFromUInt(prng.Uint64(), id.User, t),
+		MessageID:       prng.Uint64(),
+		NumParts:        0,
+		PresentParts:    0,
+		SenderTimestamp: time.Time{},
+		MessageType:     0,
+		kv:              versioned.NewKV(make(ekv.Memstore)),
 	}
 	err := expectedMpm.save()
 	if err != nil {
@@ -85,8 +85,8 @@ func Test_loadOrCreateMultiPartMessage_Load(t *testing.T) {
 
 func CheckMultiPartMessages(expectedMpm *multiPartMessage, mpm *multiPartMessage, t *testing.T) {
 	// The kv differs because it has prefix called, so we compare fields individually
-	if expectedMpm.Timestamp != mpm.Timestamp {
-		t.Errorf("timestamps mismatch: expected %v, got %v", expectedMpm.Timestamp, mpm.Timestamp)
+	if expectedMpm.SenderTimestamp != mpm.SenderTimestamp {
+		t.Errorf("timestamps mismatch: expected %v, got %v", expectedMpm.SenderTimestamp, mpm.SenderTimestamp)
 	}
 	if expectedMpm.MessageType != mpm.MessageType {
 		t.Errorf("messagetype mismatch: expected %v, got %v", expectedMpm.MessageID, mpm.MessageID)
@@ -159,21 +159,21 @@ func TestMultiPartMessage_AddFirst(t *testing.T) {
 	// Generate test values
 	prng := rand.New(rand.NewSource(netTime.Now().UnixNano()))
 	expectedMpm := &multiPartMessage{
-		Sender:       id.NewIdFromUInt(prng.Uint64(), id.User, t),
-		MessageID:    prng.Uint64(),
-		NumParts:     uint8(prng.Uint32()),
-		PresentParts: 1,
-		Timestamp:    netTime.Now(),
-		MessageType:  message.NoType,
-		parts:        make([][]byte, 3),
-		kv:           versioned.NewKV(make(ekv.Memstore)),
+		Sender:          id.NewIdFromUInt(prng.Uint64(), id.User, t),
+		MessageID:       prng.Uint64(),
+		NumParts:        uint8(prng.Uint32()),
+		PresentParts:    1,
+		SenderTimestamp: netTime.Now(),
+		MessageType:     message.NoType,
+		parts:           make([][]byte, 3),
+		kv:              versioned.NewKV(make(ekv.Memstore)),
 	}
 	expectedMpm.parts[2] = []byte{5, 8, 78, 9}
 	npm := loadOrCreateMultiPartMessage(expectedMpm.Sender,
 		expectedMpm.MessageID, expectedMpm.kv)
 
 	npm.AddFirst(expectedMpm.MessageType, 2, expectedMpm.NumParts,
-		expectedMpm.Timestamp, expectedMpm.parts[2])
+		expectedMpm.SenderTimestamp, netTime.Now(), expectedMpm.parts[2])
 
 	CheckMultiPartMessages(expectedMpm, npm, t)
 
@@ -203,7 +203,7 @@ func TestMultiPartMessage_IsComplete(t *testing.T) {
 		t.Error("IsComplete() returned true when NumParts == 0.")
 	}
 
-	mpm.AddFirst(message.Text, partNums[0], 75, netTime.Now(), parts[0])
+	mpm.AddFirst(message.Text, partNums[0], 75, netTime.Now(), netTime.Now(), parts[0])
 	for i := range partNums {
 		if i > 0 {
 			mpm.Add(partNums[i], parts[i])
diff --git a/storage/partition/store.go b/storage/partition/store.go
index 52f7f330f06aa4887c64d991f3f384714073b3cb..f8a0e8e2c8054e6bbad61ee764c18b7664cee57f 100644
--- a/storage/partition/store.go
+++ b/storage/partition/store.go
@@ -9,9 +9,12 @@ package partition
 
 import (
 	"encoding/binary"
+	"encoding/json"
+	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/interfaces/message"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/xx_network/primitives/id"
+	"gitlab.com/xx_network/primitives/netTime"
 	"golang.org/x/crypto/blake2b"
 	"sync"
 	"time"
@@ -20,29 +23,58 @@ import (
 type multiPartID [16]byte
 
 const packagePrefix = "Partition"
+const clearPartitionThreshold = 24 * time.Hour
+const activePartitions = "activePartitions"
+const activePartitionVersion = 0
 
 type Store struct {
-	multiParts map[multiPartID]*multiPartMessage
-	kv         *versioned.KV
-	mux        sync.Mutex
+	multiParts  map[multiPartID]*multiPartMessage
+	activeParts map[*multiPartMessage]bool
+	kv          *versioned.KV
+	mux         sync.Mutex
 }
 
 func New(kv *versioned.KV) *Store {
 	return &Store{
-		multiParts: make(map[multiPartID]*multiPartMessage),
-		kv:         kv.Prefix(packagePrefix),
+		multiParts:  make(map[multiPartID]*multiPartMessage),
+		activeParts: make(map[*multiPartMessage]bool),
+		kv:          kv.Prefix(packagePrefix),
 	}
 }
 
+func Load(kv *versioned.KV) *Store {
+	partitionStore := &Store{
+		multiParts:  make(map[multiPartID]*multiPartMessage),
+		activeParts: make(map[*multiPartMessage]bool),
+		kv:          kv.Prefix(packagePrefix),
+	}
+
+	partitionStore.loadActivePartitions()
+
+	partitionStore.prune()
+
+	return partitionStore
+}
+
 func (s *Store) AddFirst(partner *id.ID, mt message.Type, messageID uint64,
-	partNum, numParts uint8, timestamp time.Time,
+	partNum, numParts uint8, senderTimestamp, storageTimestamp time.Time,
 	part []byte, relationshipFingerprint []byte) (message.Receive, bool) {
 
 	mpm := s.load(partner, messageID)
 
-	mpm.AddFirst(mt, partNum, numParts, timestamp, part)
+	mpm.AddFirst(mt, partNum, numParts, senderTimestamp, storageTimestamp, part)
+	msg, ok := mpm.IsComplete(relationshipFingerprint)
+	s.mux.Lock()
+	defer s.mux.Unlock()
+	if !ok {
+		s.activeParts[mpm] = true
+		s.saveActiveParts()
+	} else {
+		mpID := getMultiPartID(mpm.Sender, mpm.MessageID)
+		delete(s.multiParts, mpID)
+	}
 
-	return mpm.IsComplete(relationshipFingerprint)
+	return msg, ok
 }
 
 func (s *Store) Add(partner *id.ID, messageID uint64, partNum uint8,
@@ -52,7 +84,33 @@ func (s *Store) Add(partner *id.ID, messageID uint64, partNum uint8,
 
 	mpm.Add(partNum, part)
 
-	return mpm.IsComplete(relationshipFingerprint)
+	msg, ok := mpm.IsComplete(relationshipFingerprint)
+	if !ok {
+		s.activeParts[mpm] = true
+		s.saveActiveParts()
+	} else {
+		mpID := getMultiPartID(mpm.Sender, mpm.MessageID)
+		delete(s.multiParts, mpID)
+	}
+
+	return msg, ok
+}
+
+// Prune clear old messages on it's stored timestamp
+func (s *Store) prune() {
+	s.mux.Lock()
+	defer s.mux.Unlock()
+	now := netTime.Now()
+	for mpm, _ := range s.activeParts {
+		if now.Sub(mpm.StorageTimestamp) >= clearPartitionThreshold {
+			jww.INFO.Printf("prune partition: %v", mpm)
+			mpm.mux.Lock()
+			mpm.delete()
+			mpID := getMultiPartID(mpm.Sender, mpm.MessageID)
+			mpm.mux.Unlock()
+			delete(s.multiParts, mpID)
+		}
+	}
 }
 
 func (s *Store) load(partner *id.ID, messageID uint64) *multiPartMessage {
@@ -68,6 +126,56 @@ func (s *Store) load(partner *id.ID, messageID uint64) *multiPartMessage {
 	return mpm
 }
 
+func (s *Store) saveActiveParts() {
+	jww.INFO.Printf("Saving %d active partitions", len(s.activeParts))
+	activeList := make([]*multiPartMessage, 0, len(s.activeParts))
+	for mpm := range s.activeParts {
+		mpm.mux.Lock()
+		jww.INFO.Printf("saveActiveParts saving %v", mpm)
+		activeList = append(activeList, mpm)
+		mpm.mux.Unlock()
+	}
+
+	data, err := json.Marshal(&activeList)
+	if err != nil {
+		jww.FATAL.Panicf("Could not save active partitions: %v", err)
+	}
+
+	obj := versioned.Object{
+		Version:   activePartitionVersion,
+		Timestamp: netTime.Now(),
+		Data:      data,
+	}
+
+	err = s.kv.Set(activePartitions, activePartitionVersion, &obj)
+	if err != nil {
+		jww.FATAL.Panicf("Could not save active partitions: %v", err)
+	}
+}
+
+func (s *Store) loadActivePartitions() {
+	s.mux.Lock()
+	defer s.mux.Unlock()
+	obj, err := s.kv.Get(activePartitions, activePartitionVersion)
+	if err != nil {
+		jww.DEBUG.Printf("Could not load active partitions: %v", err)
+		return
+	}
+
+	activeList := make([]*multiPartMessage, 0)
+	if err := json.Unmarshal(obj.Data, &activeList); err != nil {
+		jww.FATAL.Panicf("Failed to "+
+			"unmarshal active partitions: %v", err)
+	}
+	jww.INFO.Printf("loadActivePartitions found %d active", len(activeList))
+
+	for _, activeMpm := range activeList {
+		mpm := loadOrCreateMultiPartMessage(activeMpm.Sender, activeMpm.MessageID, s.kv)
+		s.activeParts[mpm] = true
+	}
+
+}
+
 func getMultiPartID(partner *id.ID, messageID uint64) multiPartID {
 	h, _ := blake2b.New256(nil)
 
diff --git a/storage/partition/store_test.go b/storage/partition/store_test.go
index 9de6327d989d032e6ed987db0aff891d6be0fa3b..4e3d221a159be0f1fd73664c1d6d6a9e7b5097aa 100644
--- a/storage/partition/store_test.go
+++ b/storage/partition/store_test.go
@@ -22,8 +22,9 @@ import (
 func TestNew(t *testing.T) {
 	rootKv := versioned.NewKV(make(ekv.Memstore))
 	expectedStore := &Store{
-		multiParts: make(map[multiPartID]*multiPartMessage),
-		kv:         rootKv.Prefix(packagePrefix),
+		multiParts:  make(map[multiPartID]*multiPartMessage),
+		activeParts: make(map[*multiPartMessage]bool),
+		kv:          rootKv.Prefix(packagePrefix),
 	}
 
 	store := New(rootKv)
@@ -40,7 +41,7 @@ func TestStore_AddFirst(t *testing.T) {
 	s := New(versioned.NewKV(ekv.Memstore{}))
 
 	msg, complete := s.AddFirst(id.NewIdFromString("User", id.User, t),
-		message.Text, 5, 0, 1, netTime.Now(), part,
+		message.Text, 5, 0, 1, netTime.Now(), netTime.Now(), part,
 		[]byte{0})
 
 	if !complete {
@@ -60,7 +61,7 @@ func TestStore_Add(t *testing.T) {
 	s := New(versioned.NewKV(ekv.Memstore{}))
 
 	msg, complete := s.AddFirst(id.NewIdFromString("User", id.User, t),
-		message.Text, 5, 0, 2, netTime.Now(), part1,
+		message.Text, 5, 0, 2, netTime.Now(), netTime.Now(), part1,
 		[]byte{0})
 
 	if complete {
@@ -79,3 +80,44 @@ func TestStore_Add(t *testing.T) {
 			"\n\texpected: %v\n\treceived: %v", part, msg.Payload)
 	}
 }
+
+// Unit test of prune
+func TestStore_ClearMessages(t *testing.T) {
+	// Setup: Add 2 message to store: an old message past the threshold and a new message
+	part1 := []byte("Test message.")
+	part2 := []byte("Second Sentence.")
+	s := New(versioned.NewKV(ekv.Memstore{}))
+
+	partner1 := id.NewIdFromString("User", id.User, t)
+	messageId1 := uint64(5)
+	oldTimestamp := netTime.Now().Add(-2 * clearPartitionThreshold)
+	s.AddFirst(partner1,
+		message.Text, messageId1, 0, 2, netTime.Now(),
+		oldTimestamp, part1,
+		[]byte{0})
+	s.Add(partner1, messageId1, 1, part2, []byte{0})
+
+	partner2 := id.NewIdFromString("User1", id.User, t)
+	messageId2 := uint64(6)
+	newTimestamp := netTime.Now()
+	s.AddFirst(partner2, message.Text, messageId2, 0, 2, netTime.Now(),
+		newTimestamp, part1,
+		[]byte{0})
+
+	// Call clear messages
+	s.prune()
+
+	// Check if old message cleared
+	mpmId := getMultiPartID(partner1, messageId1)
+	if _, ok := s.multiParts[mpmId]; ok {
+		t.Errorf("Prune error: " +
+			"Expected old message to be cleared out of store")
+	}
+
+	// Check if new message remains
+	mpmId2 := getMultiPartID(partner2, messageId2)
+	if _, ok := s.multiParts[mpmId2]; !ok {
+		t.Errorf("Prune error: " +
+			"Expected new message to be remain in store")
+	}
+}
diff --git a/storage/session.go b/storage/session.go
index 3c4c1932baf747b080a5272b3702876abb57c652..e42cad445594e30d7b85eafa688d90b80d4d62ed 100644
--- a/storage/session.go
+++ b/storage/session.go
@@ -220,7 +220,7 @@ func Load(baseDir, password string, currentVersion version.Version,
 	}
 
 	s.conversations = conversation.NewStore(s.kv)
-	s.partition = partition.New(s.kv)
+	s.partition = partition.Load(s.kv)
 
 	s.reception = reception.LoadStore(s.kv)
 
diff --git a/storage/user.go b/storage/user.go
index a236f22d35e618d77c75277c9ece5999712832a3..975b574a2e9678a31eff7f0598b396ab6427a6af 100644
--- a/storage/user.go
+++ b/storage/user.go
@@ -14,18 +14,18 @@ func (s *Session) GetUser() user.User {
 	defer s.mux.RUnlock()
 	ci := s.user.GetCryptographicIdentity()
 	return user.User{
-		TransmissionID:   ci.GetTransmissionID().DeepCopy(),
-		TransmissionSalt: copySlice(ci.GetTransmissionSalt()),
-		TransmissionRSA:  ci.GetReceptionRSA(),
-		ReceptionID:      ci.GetReceptionID().DeepCopy(),
+		TransmissionID:        ci.GetTransmissionID().DeepCopy(),
+		TransmissionSalt:      copySlice(ci.GetTransmissionSalt()),
+		TransmissionRSA:       ci.GetReceptionRSA(),
+		ReceptionID:           ci.GetReceptionID().DeepCopy(),
 		RegistrationTimestamp: s.user.GetRegistrationTimestamp(),
-		ReceptionSalt:    copySlice(ci.GetReceptionSalt()),
-		ReceptionRSA:     ci.GetReceptionRSA(),
-		Precanned:        ci.IsPrecanned(),
-		CmixDhPrivateKey: s.cmix.GetDHPrivateKey().DeepCopy(),
-		CmixDhPublicKey:  s.cmix.GetDHPublicKey().DeepCopy(),
-		E2eDhPrivateKey:  s.e2e.GetDHPrivateKey().DeepCopy(),
-		E2eDhPublicKey:   s.e2e.GetDHPublicKey().DeepCopy(),
+		ReceptionSalt:         copySlice(ci.GetReceptionSalt()),
+		ReceptionRSA:          ci.GetReceptionRSA(),
+		Precanned:             ci.IsPrecanned(),
+		CmixDhPrivateKey:      s.cmix.GetDHPrivateKey().DeepCopy(),
+		CmixDhPublicKey:       s.cmix.GetDHPublicKey().DeepCopy(),
+		E2eDhPrivateKey:       s.e2e.GetDHPrivateKey().DeepCopy(),
+		E2eDhPublicKey:        s.e2e.GetDHPublicKey().DeepCopy(),
 	}
 
 }
diff --git a/storage/utility/dh.go b/storage/utility/dh.go
index 9b0280ed1ef4bd96e71d15fcc788b5633c51fe03..6295e446d3563127c4c1262733eb3abf8ac8b91e 100644
--- a/storage/utility/dh.go
+++ b/storage/utility/dh.go
@@ -42,3 +42,8 @@ func LoadCyclicKey(kv *versioned.KV, key string) (*cyclic.Int, error) {
 
 	return cy, cy.GobDecode(vo.Data)
 }
+
+// DeleteCyclicKey deletes a given cyclic key from storage
+func DeleteCyclicKey(kv *versioned.KV, key string) error {
+	return kv.Delete(key, currentCyclicVersion)
+}
diff --git a/storage/utility/dh_test.go b/storage/utility/dh_test.go
index 4d4a31941faee3467f029ffca4dbc57f8fa9dafe..36fb3c5734af6ea7bd29479279f01b10522b803d 100644
--- a/storage/utility/dh_test.go
+++ b/storage/utility/dh_test.go
@@ -47,3 +47,27 @@ func TestLoadCyclicKey(t *testing.T) {
 		t.Errorf("Stored int did not match received.  Stored: %v, Received: %v", x, loaded)
 	}
 }
+
+// Unit test for DeleteCyclicKey
+func TestDeleteCyclicKey(t *testing.T) {
+	kv := make(ekv.Memstore)
+	vkv := versioned.NewKV(kv)
+	grp := getTestGroup()
+	x := grp.NewInt(77)
+
+	intKey := "testKey"
+	err := StoreCyclicKey(vkv, x, intKey)
+	if err != nil {
+		t.Errorf("Failed to store cyclic key: %+v", err)
+	}
+
+	err = DeleteCyclicKey(vkv, intKey)
+	if err != nil {
+		t.Fatalf("DeleteCyclicKey returned an error: %v", err)
+	}
+
+	_, err = LoadCyclicKey(vkv, intKey)
+	if err == nil {
+		t.Errorf("DeleteCyclicKey error: Should not load deleted key: %+v", err)
+	}
+}
diff --git a/ud/manager.go b/ud/manager.go
index fecafbd904fbad0ed4e1b82c58bbbff3ef2e157e..1b80b1ad22bcb07fb94a5944a78000c2ef56f45d 100644
--- a/ud/manager.go
+++ b/ud/manager.go
@@ -15,6 +15,7 @@ import (
 	"gitlab.com/xx_network/comms/connect"
 	"gitlab.com/xx_network/crypto/signature/rsa"
 	"gitlab.com/xx_network/primitives/id"
+	"math"
 	"time"
 )
 
@@ -89,6 +90,8 @@ func NewManager(client *api.Client, single *single.Manager) (*Manager, error) {
 
 	// Create the user discovery host object
 	hp := connect.GetDefaultHostParams()
+	// Client will not send KeepAlive packets
+	hp.KaClientOpts.Time = time.Duration(math.MaxInt64)
 	hp.MaxRetries = 3
 	hp.SendTimeout = 3 * time.Second
 	m.host, err = m.comms.AddHost(&id.UDB, def.UDB.Address, []byte(def.UDB.Cert), hp)
diff --git a/ud/register.go b/ud/register.go
index c2dd6a0adc1db8f9e61495c9b989309657f6d891..b46f99a09fd6e686c2293b35a54147d7292d58cb 100644
--- a/ud/register.go
+++ b/ud/register.go
@@ -48,7 +48,7 @@ func (m *Manager) register(username string, comm registerUserComms) error {
 			DhPubKey: m.storage.E2e().GetDHPublicKey().Bytes(),
 			Salt:     cryptoUser.GetReceptionSalt(),
 		},
-		UID: cryptoUser.GetReceptionID().Marshal(),
+		UID:       cryptoUser.GetReceptionID().Marshal(),
 		Timestamp: user.GetRegistrationTimestamp().UnixNano(),
 	}