diff --git a/auth/fmt.go b/auth/fmt.go
index 015205aaacac5bc6d93870dc0083d3960dcd9526..d3cf8a29f1f0149c62a2da67ca3ee50da4809bab 100644
--- a/auth/fmt.go
+++ b/auth/fmt.go
@@ -11,7 +11,6 @@ import (
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	sidhinterface "gitlab.com/elixxir/client/v4/interfaces/sidh"
 	util "gitlab.com/elixxir/client/v4/storage/utility"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/primitives/format"
@@ -20,7 +19,7 @@ import (
 
 const requestFmtVersion = 1
 
-//Basic Format//////////////////////////////////////////////////////////////////
+// Basic Format//////////////////////////////////////////////////////////////////
 type baseFormat struct {
 	data       []byte
 	pubkey     []byte
@@ -31,14 +30,14 @@ type baseFormat struct {
 func newBaseFormat(payloadSize, pubkeySize int) baseFormat {
 	total := pubkeySize
 	// Size of sidh pubkey
-	total += sidhinterface.PubKeyByteSize + 1
+	total += util.PubKeyByteSize + 1
 	// Size of version
 	total += 1
 	if payloadSize < total {
 		jww.FATAL.Panicf("Size of baseFormat is too small (%d), must be big "+
 			"enough to contain public key (%d) and sidh key (%d)"+
 			"and version which totals to %d", payloadSize,
-			pubkeySize, sidhinterface.PubKeyByteSize+1, total)
+			pubkeySize, util.PubKeyByteSize+1, total)
 	}
 
 	jww.INFO.Printf("Empty Space RequestAuth: %d", payloadSize-total)
@@ -115,7 +114,7 @@ func (f baseFormat) SetEcrPayload(ecr []byte) {
 	copy(f.ecrPayload, ecr)
 }
 
-//Encrypted Format//////////////////////////////////////////////////////////////
+// Encrypted Format//////////////////////////////////////////////////////////////
 const ownershipSize = 32
 
 type ecrFormat struct {
@@ -126,7 +125,7 @@ type ecrFormat struct {
 }
 
 func newEcrFormat(size int) ecrFormat {
-	if size < (ownershipSize + sidhinterface.PubKeyByteSize + 1) {
+	if size < (ownershipSize + util.PubKeyByteSize + 1) {
 		jww.FATAL.Panicf("Size too small to hold")
 	}
 
@@ -146,7 +145,7 @@ func buildEcrFormat(data []byte) ecrFormat {
 	f.ownership = f.data[start:end]
 
 	start = end
-	end = start + sidhinterface.PubKeyByteSize + 1
+	end = start + util.PubKeyByteSize + 1
 	f.sidHpubkey = f.data[start:end]
 
 	start = end
@@ -206,7 +205,7 @@ func (f ecrFormat) SetPayload(p []byte) {
 	copy(f.payload, p)
 }
 
-//Request Format////////////////////////////////////////////////////////////////
+// Request Format////////////////////////////////////////////////////////////////
 type requestFormat struct {
 	ecrFormat
 	id         []byte
@@ -252,7 +251,7 @@ func (rf requestFormat) GetMsgPayload() []byte {
 	return rf.msgPayload
 }
 
-//utility functions
+// utility functions
 func handleBaseFormat(cmixMsg format.Message, grp *cyclic.Group) (baseFormat,
 	*cyclic.Int, error) {
 
diff --git a/auth/fmt_test.go b/auth/fmt_test.go
index c8215a4f533658c178d5fdce681a4447964f832b..84e7886cc66eca57a9b0a03da1196a6e67f3c7e6 100644
--- a/auth/fmt_test.go
+++ b/auth/fmt_test.go
@@ -9,11 +9,11 @@ package auth
 
 import (
 	"bytes"
+	sidhinterface "gitlab.com/elixxir/client/v4/storage/utility"
 	"math/rand"
 	"reflect"
 	"testing"
 
-	sidhinterface "gitlab.com/elixxir/client/v4/interfaces/sidh"
 	"gitlab.com/xx_network/primitives/id"
 )
 
diff --git a/auth/state.go b/auth/state.go
index a0f106952ac2d777717e6211f5a0401fa8aca53b..58fe47714f3fe2f4c26528bc6d19da416af8dd70 100644
--- a/auth/state.go
+++ b/auth/state.go
@@ -15,10 +15,10 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix"
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/message"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/v4/event"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/xx_network/primitives/id"
 )
diff --git a/auth/state_test.go b/auth/state_test.go
index dc7cca105ebc8b482e2f595a649027bfc823b49f..1276c469b25adcec3c5d3a2d2935e849051936bb 100644
--- a/auth/state_test.go
+++ b/auth/state_test.go
@@ -21,11 +21,11 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/message"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/v4/storage"
 	util "gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/fastRNG"
diff --git a/auth/store/confirmation.go b/auth/store/confirmation.go
index 4f1ca8963bd0b818d66425afe0193f0a844edfda..d28be36557427a4cbc58708f3e48dfe1a82aa8d6 100644
--- a/auth/store/confirmation.go
+++ b/auth/store/confirmation.go
@@ -10,7 +10,7 @@ package store
 import (
 	"encoding/base64"
 	"encoding/json"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/auth/store/confirmation_test.go b/auth/store/confirmation_test.go
index b60f29f0a2d8f3d9149414bd9e4a2cd7e50c06b4..dd9cb17b9093fa8a8bae00a74214e88894badbe8 100644
--- a/auth/store/confirmation_test.go
+++ b/auth/store/confirmation_test.go
@@ -13,8 +13,8 @@ import (
 	"testing"
 
 	"github.com/cloudflare/circl/dh/sidh"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/e2e/auth"
diff --git a/auth/store/previousNegotiations.go b/auth/store/previousNegotiations.go
index 5941d4d545fff7528a564214fbe58de115f7b351..c70fdb50e9a7f0ce40d4e5d6e81f3c31f12cd58b 100644
--- a/auth/store/previousNegotiations.go
+++ b/auth/store/previousNegotiations.go
@@ -15,7 +15,7 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/e2e/auth"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/auth/store/previousNegotiations_test.go b/auth/store/previousNegotiations_test.go
index 557a499113b472305fd1a76b75f53cb63e7e6063..84732a1daa547495f5d670af7b5f0a79359f6f7b 100644
--- a/auth/store/previousNegotiations_test.go
+++ b/auth/store/previousNegotiations_test.go
@@ -13,8 +13,8 @@ import (
 	"testing"
 
 	"github.com/cloudflare/circl/dh/sidh"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/e2e/auth"
diff --git a/auth/store/receivedRequest.go b/auth/store/receivedRequest.go
index 3bd07fdb3fdcc58571877812678f652dd9b782d4..f5cf95a558fe02476388dd2454c003a21cc9c9a2 100644
--- a/auth/store/receivedRequest.go
+++ b/auth/store/receivedRequest.go
@@ -14,8 +14,8 @@ import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	util "gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/xx_network/primitives/id"
 )
diff --git a/auth/store/sentRequest.go b/auth/store/sentRequest.go
index 18d9841dc70d78de081dc8433a8c5f545c20a64a..f63583d03325b6f7d832fe6c705e0b6afccc5d83 100644
--- a/auth/store/sentRequest.go
+++ b/auth/store/sentRequest.go
@@ -11,13 +11,13 @@ import (
 	"encoding/hex"
 	"encoding/json"
 	"fmt"
+	"gitlab.com/elixxir/client/v4/storage/utility"
 	"sync"
 
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	sidhinterface "gitlab.com/elixxir/client/v4/interfaces/sidh"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/primitives/id"
@@ -114,7 +114,7 @@ func loadSentRequest(kv versioned.KV, partner *id.ID, grp *cyclic.Group) (*SentR
 			"key with %s for SentRequest Auth", partner)
 	}
 
-	mySidHPrivKeyA := sidh.NewPrivateKey(sidhinterface.KeyId,
+	mySidHPrivKeyA := sidh.NewPrivateKey(utility.KeyId,
 		sidh.KeyVariantSidhA)
 	if err = mySidHPrivKeyA.Import(srd.MySidHPrivKeyA); err != nil {
 		return nil, errors.WithMessagef(err,
@@ -122,7 +122,7 @@ func loadSentRequest(kv versioned.KV, partner *id.ID, grp *cyclic.Group) (*SentR
 				"with %s for SentRequest Auth", partner)
 	}
 
-	mySidHPubKeyA := sidh.NewPublicKey(sidhinterface.KeyId,
+	mySidHPubKeyA := sidh.NewPublicKey(utility.KeyId,
 		sidh.KeyVariantSidhA)
 	if err = mySidHPubKeyA.Import(srd.MySidHPubKeyA); err != nil {
 		return nil, errors.WithMessagef(err,
@@ -184,8 +184,8 @@ func (sr *SentRequest) save() error {
 	jww.INFO.Printf("saveSentRequest fingerprint: %s",
 		hex.EncodeToString(sr.fingerprint[:]))
 
-	sidHPriv := make([]byte, sidhinterface.PrivKeyByteSize)
-	sidHPub := make([]byte, sidhinterface.PubKeyByteSize)
+	sidHPriv := make([]byte, utility.PrivKeyByteSize)
+	sidHPub := make([]byte, utility.PubKeyByteSize)
 	sr.mySidHPrivKeyA.Export(sidHPriv)
 	sr.mySidHPubKeyA.Export(sidHPub)
 
diff --git a/auth/store/store.go b/auth/store/store.go
index cca5b47abbc85b324658f27d60a312150440d93c..2485264d9ad4e158b60c4964fa555d2db16f06b8 100644
--- a/auth/store/store.go
+++ b/auth/store/store.go
@@ -15,7 +15,7 @@ import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/primitives/format"
diff --git a/auth/store/store_test.go b/auth/store/store_test.go
index b4538ee8785dd81035164d26015e5578039659b3..373bec777ee302402604db4b8cc844c0e1bac0a6 100644
--- a/auth/store/store_test.go
+++ b/auth/store/store_test.go
@@ -17,9 +17,8 @@ import (
 
 	"github.com/cloudflare/circl/dh/sidh"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
-	sidhinterface "gitlab.com/elixxir/client/v4/interfaces/sidh"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	util "gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/elixxir/crypto/cyclic"
@@ -236,9 +235,9 @@ func TestStore_GetReceivedRequest(t *testing.T) {
 			"\n\texpected: %+v\n\treceived: %+v", c, testC)
 	}
 
-	keyBytes := make([]byte, sidhinterface.PubKeyByteSize)
+	keyBytes := make([]byte, util.PubKeyByteSize)
 	sidhPubKey.Export(keyBytes)
-	expKeyBytes := make([]byte, sidhinterface.PubKeyByteSize)
+	expKeyBytes := make([]byte, util.PubKeyByteSize)
 	s.receivedByID[*c.ID].theirSidHPubKeyA.Export(expKeyBytes)
 	if !reflect.DeepEqual(keyBytes, expKeyBytes) {
 		t.Errorf("GetReceivedRequest did not send proper sidh bytes")
diff --git a/backup/backup.go b/backup/backup.go
index 4399edadf9543c202e98457fdee1b193b9725033..ca1f9c30d2d13739b718dd2ebd15309fc8af032a 100644
--- a/backup/backup.go
+++ b/backup/backup.go
@@ -12,7 +12,7 @@ import (
 	"sync"
 	"time"
 
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/primitives/fact"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/backup/backup_test.go b/backup/backup_test.go
index 858f58f87b35ff5cba46b7f4142b7a2355cbfa3e..cdd6e856278a06ab643304be165def7df46cc11e 100644
--- a/backup/backup_test.go
+++ b/backup/backup_test.go
@@ -15,8 +15,8 @@ import (
 
 	"gitlab.com/elixxir/client/v4/xxdk"
 
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/ekv"
 
 	"gitlab.com/elixxir/crypto/backup"
diff --git a/backup/jsonStorage.go b/backup/jsonStorage.go
index 3403ecb46a3d36a9f2d7a523bfaf173d8121c9a0..0bf9d6fe668a8e0b8a1cce8ea66c20080762dcf5 100644
--- a/backup/jsonStorage.go
+++ b/backup/jsonStorage.go
@@ -8,7 +8,7 @@
 package backup
 
 import (
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/netTime"
 )
 
diff --git a/backup/jsonStorage_test.go b/backup/jsonStorage_test.go
index 02588ed20909c4014a1439c89d5b4937f78ed3e1..7437474dcdd828df39036c71492efc19f198f579 100644
--- a/backup/jsonStorage_test.go
+++ b/backup/jsonStorage_test.go
@@ -10,7 +10,7 @@ package backup
 import (
 	"testing"
 
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 )
 
diff --git a/backup/keyStorage.go b/backup/keyStorage.go
index 8d96e5b85538902def0b4d6625c1907494727894..fbb7e0f994c77efa1883c2f5606564a0bdbee3bb 100644
--- a/backup/keyStorage.go
+++ b/backup/keyStorage.go
@@ -10,7 +10,7 @@ package backup
 import (
 	"bytes"
 	"github.com/pkg/errors"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/backup"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/bindings/backup.go b/bindings/backup.go
index cf0d756b010f119add99ab5a02ebac69c649303d..74d72b8dc843bdffd6751665a5c41e75cc5c3608 100644
--- a/bindings/backup.go
+++ b/bindings/backup.go
@@ -27,13 +27,14 @@ type Backup struct {
 // NewCmixFromBackup.
 //
 // Example BackupReport:
-//  {
-//    "RestoredContacts": [
-//      "U4x/lrFkvxuXu59LtHLon1sUhPJSCcnZND6SugndnVID",
-//      "15tNdkKbYXoMn58NO6VbDMDWFEyIhTWEGsvgcJsHWAgD"
-//    ],
-//    "Params": ""
-//  }
+//
+//	{
+//	  "RestoredContacts": [
+//	    "U4x/lrFkvxuXu59LtHLon1sUhPJSCcnZND6SugndnVID",
+//	    "15tNdkKbYXoMn58NO6VbDMDWFEyIhTWEGsvgcJsHWAgD"
+//	  ],
+//	  "Params": ""
+//	}
 type BackupReport struct {
 	// The list of restored E2E partner IDs
 	RestoredContacts []*id.ID
@@ -56,14 +57,14 @@ type UpdateBackupFunc interface {
 // Users of this function should call LoadCmix as normal once this call succeeds.
 //
 // Parameters:
-//  - ndfJSON - JSON of the NDF.
-//  - storageDir - directory for the storage files.
-//  - sessionPassword - password to decrypt the data in the storageDir.
-//  - backupPassphrase - backup passphrase provided by the user. Used to decrypt backup.
-//  - backupFileContents - the file contents of the backup.
+//   - ndfJSON - JSON of the NDF.
+//   - storageDir - directory for the storage files.
+//   - sessionPassword - password to decrypt the data in the storageDir.
+//   - backupPassphrase - backup passphrase provided by the user. Used to decrypt backup.
+//   - backupFileContents - the file contents of the backup.
 //
 // Returns:
-//  - []byte - the JSON marshalled bytes of the BackupReport object.
+//   - []byte - the JSON marshalled bytes of the BackupReport object.
 func NewCmixFromBackup(ndfJSON, storageDir, backupPassphrase string,
 	sessionPassword, backupFileContents []byte) ([]byte, error) {
 
@@ -93,11 +94,11 @@ func NewCmixFromBackup(ndfJSON, storageDir, backupPassphrase string,
 // InitializeBackup creates a bindings-layer Backup object.
 //
 // Parameters:
-//  - e2eID - ID of the E2e object in the e2e tracker.
-//  - udID - ID of the UserDiscovery object in the ud tracker.
-//  - backupPassPhrase - backup passphrase provided by the user. Used to decrypt
-//    backup.
-//  - cb - the callback to be called when a backup is triggered.
+//   - e2eID - ID of the E2e object in the e2e tracker.
+//   - udID - ID of the UserDiscovery object in the ud tracker.
+//   - backupPassPhrase - backup passphrase provided by the user. Used to decrypt
+//     backup.
+//   - cb - the callback to be called when a backup is triggered.
 func InitializeBackup(e2eID, udID int, backupPassPhrase string,
 	cb UpdateBackupFunc) (*Backup, error) {
 	// Retrieve the user from the tracker
@@ -131,10 +132,10 @@ func InitializeBackup(e2eID, udID int, backupPassPhrase string,
 // InitializeBackup.
 //
 // Parameters:
-//  - e2eID - ID of the E2e object in the e2e tracker.
-//  - udID - ID of the UserDiscovery object in the ud tracker.
-//  - cb - the callback to be called when a backup is triggered.
-//    This will replace any callback that has been passed into InitializeBackup.
+//   - e2eID - ID of the E2e object in the e2e tracker.
+//   - udID - ID of the UserDiscovery object in the ud tracker.
+//   - cb - the callback to be called when a backup is triggered.
+//     This will replace any callback that has been passed into InitializeBackup.
 func ResumeBackup(e2eID, udID int, cb UpdateBackupFunc) (
 	*Backup, error) {
 
@@ -176,7 +177,7 @@ func (b *Backup) IsBackupRunning() bool {
 // AddJson stores the argument within the Backup structure.
 //
 // Params
-//  - json - JSON string
+//   - json - JSON string
 func (b *Backup) AddJson(json string) {
 	b.b.AddJson(json)
 }
diff --git a/bindings/channels.go b/bindings/channels.go
index 1a713543f7e1bd0d8ce85f3f0766108e6373ddb3..9a5dd53c55a565bb210eb3e284048b3f940e25b3 100644
--- a/bindings/channels.go
+++ b/bindings/channels.go
@@ -1904,6 +1904,19 @@ func (cm *ChannelsManager) GetMutedUsers(channelIDBytes []byte) ([]byte, error)
 // Notifications                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
+// Notifications options
+const (
+	// ChannelsNotifyNone results in no notifications.
+	ChannelsNotifyNone int64 = int64(channels.NotifyNone)
+
+	// ChannelsNotifyPing results in notifications from tags, replies, and pins.
+	ChannelsNotifyPing int64 = int64(channels.NotifyPing)
+
+	// ChannelsNotifyAll results in notifications from all messages except
+	// silent ones and replays.
+	ChannelsNotifyAll = int64(channels.NotifyAll)
+)
+
 // GetNotificationLevel returns the [channels.NotificationLevel] for the given
 // channel.
 //
@@ -1949,12 +1962,14 @@ func (cm *ChannelsManager) SetMobileNotificationsLevel(
 		clientNotif.NotificationState(status))
 }
 
-// GetNotificationReportsForMe checks the notification data against the filter
+// GetChannelNotificationReportsForMe checks the notification data against the filter
 // list to determine which notifications belong to the user. A list of
 // notification reports is returned detailing all notifications for the user.
 //
 // Parameters:
 //   - notificationFilterJSON - JSON of a slice of [channels.NotificationFilter].
+//     Can optionally be the entire json return from NotificationUpdateJson
+//     Instead of just the needed subsection
 //   - notificationDataJSON - JSON of a slice of [notifications.Data].
 //
 // Example JSON of a slice of [channels.NotificationFilter]:
@@ -2014,11 +2029,16 @@ func (cm *ChannelsManager) SetMobileNotificationsLevel(
 //
 // Returns:
 //   - []byte - JSON of a slice of [channels.NotificationReport].
-func GetNotificationReportsForMe(notificationFilterJSON,
+func GetChannelNotificationReportsForMe(notificationFilterJSON,
 	notificationDataJSON []byte) ([]byte, error) {
 	var nfs []channels.NotificationFilter
 	if err := json.Unmarshal(notificationFilterJSON, &nfs); err != nil {
-		return nil, err
+		//attempt to unmarshal as the entire NotificationUpdateJson
+		nuj := &NotificationUpdateJson{}
+		if err2 := json.Unmarshal(notificationFilterJSON, &nfs); err2 != nil {
+			return nil, err
+		}
+		nfs = nuj.NotificationFilters
 	}
 
 	var notifData []*notifications.Data
@@ -2995,13 +3015,13 @@ func newChannelUICallbacksWrapper(uicb ChannelUICallbacks) *ChannelUICallbacksWr
 
 // Event Type
 const (
-	NickNameUpdate int64 = iota
-	NotificationUpdate
-	MessageReceived
-	UserMuted
-	MessageDeleted
-	AdminKeyUpdate
-	DmTokenUpdate
+	NickNameUpdate     int64 = 1000
+	NotificationUpdate int64 = 2000
+	MessageReceived    int64 = 3000
+	UserMuted          int64 = 4000
+	MessageDeleted     int64 = 5000
+	AdminKeyUpdate     int64 = 6000
+	DmTokenUpdate      int64 = 7000
 )
 
 // NickNameUpdateJson is describes when your nickname changes due to a change on a
diff --git a/bindings/cmix.go b/bindings/cmix.go
index 02f104f13455514011ffa9c3264f7607a3d70724..6ce4f7807fe115c84ebf49e07e54245e0e9096dd 100644
--- a/bindings/cmix.go
+++ b/bindings/cmix.go
@@ -13,7 +13,7 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/xxdk"
 )
 
@@ -43,7 +43,8 @@ type Cmix struct {
 // date.
 //
 // Users of this function should delete the storage directory on error.
-func NewCmix(ndfJSON, storageDir string, password []byte, registrationCode string) error {
+func NewCmix(ndfJSON, storageDir string, password []byte,
+	registrationCode string) error {
 	err := xxdk.NewCmix(ndfJSON, storageDir, password, registrationCode)
 	if err != nil {
 		return errors.Errorf("Failed to create new cmix: %+v", err)
@@ -51,6 +52,14 @@ func NewCmix(ndfJSON, storageDir string, password []byte, registrationCode strin
 	return nil
 }
 
+// NewSynchronizedCmix clones a Cmix from remote storage
+func NewSynchronizedCmix(ndfJSON, storageDir string, password []byte,
+	remote RemoteStore) error {
+	wrappedRemote := newRemoteStoreFileSystemWrapper(remote)
+	return xxdk.NewSynchronizedCmix(ndfJSON, storageDir, password,
+		wrappedRemote)
+}
+
 // LoadCmix will load an existing user storage from the storageDir using the
 // password. This will fail if the user storage does not exist or the password
 // is incorrect.
diff --git a/bindings/collective.go b/bindings/collective.go
index 9dcce0e736200404e786559231a99927e329240d..7629410328c84b1f65c0248b80f1076e5d0c1b69 100644
--- a/bindings/collective.go
+++ b/bindings/collective.go
@@ -13,7 +13,7 @@ import (
 
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/collective"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 )
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -287,14 +287,14 @@ func (r *RemoteKV) GetMapElement(mapName, element string, version int64) (
 // ListenOnRemoteKey sets up a callback listener for the object specified
 // by the key and version. It returns the current [versioned.Object] JSON
 // of the value.
+// If local events is true, you will get callback when you write to the
+// key as well
 func (r *RemoteKV) ListenOnRemoteKey(key string, version int64,
-	callback KeyChangedByRemoteCallback) ([]byte,
-	error) {
+	callback KeyChangedByRemoteCallback, localEvents bool) error {
 
 	jww.DEBUG.Printf("[RKV] ListenOnRemoteKey(%s, %d)", key, version)
 
-	bindingsCb := func(key string,
-		old, new *versioned.Object, op versioned.KeyOperation) {
+	bindingsCb := func(old, new *versioned.Object, op versioned.KeyOperation) {
 		oldJSON, err := json.Marshal(old)
 		panicOnErr(err)
 		newJSON, err := json.Marshal(new)
@@ -302,40 +302,26 @@ func (r *RemoteKV) ListenOnRemoteKey(key string, version int64,
 		callback.Callback(key, oldJSON, newJSON, int8(op))
 	}
 
-	obj, err := r.rkv.ListenOnRemoteKey(key, uint64(version), bindingsCb)
-	if err != nil {
-		return nil, err
-	}
-
-	objJSON, err := json.Marshal(obj)
-	panicOnErr(err)
-	return objJSON, nil
+	return r.rkv.ListenOnRemoteKey(key, uint64(version), bindingsCb, localEvents)
 }
 
 // ListenOnRemoteMap allows the caller to receive updates when
 // the map or map elements are updated. Returns a JSON of
 // map[string]versioned.Object of the current map value.
+// If local events is true, you will get callback when you write to the
+// key as well
 func (r *RemoteKV) ListenOnRemoteMap(mapName string, version int64,
-	callback MapChangedByRemoteCallback) ([]byte, error) {
+	callback MapChangedByRemoteCallback, localEvents bool) error {
 	jww.DEBUG.Printf("[RKV] ListenOnRemoteMap(%s, %d)", mapName, version)
 
-	bindingsCb := func(mapName string,
-		edits map[string]versioned.ElementEdit) {
+	bindingsCb := func(edits map[string]versioned.ElementEdit) {
 		editsJSON, err := json.Marshal(edits)
 		panicOnErr(err)
 		callback.Callback(mapName, editsJSON)
 	}
 
-	obj, err := r.rkv.ListenOnRemoteMap(mapName, uint64(version),
-		bindingsCb)
-	if err != nil {
-		return nil, err
-	}
-
-	objJSON, err := json.Marshal(obj)
-	panicOnErr(err)
-	return objJSON, nil
-
+	return r.rkv.ListenOnRemoteMap(mapName, uint64(version),
+		bindingsCb, localEvents)
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/bindings/collective_test.go b/bindings/collective_test.go
index 1404c0cc34f446a33f3192ffb1f91d518b04c390..bfe136fa546da94d17f56cce7c879ce2ece94510 100644
--- a/bindings/collective_test.go
+++ b/bindings/collective_test.go
@@ -12,7 +12,11 @@ import (
 	"encoding/json"
 	"fmt"
 	"math/rand"
+	"sync"
 	"testing"
+
+	"github.com/stretchr/testify/require"
+	"gitlab.com/xx_network/primitives/netTime"
 )
 
 const (
@@ -196,32 +200,52 @@ func TestGetChannelInfo(t *testing.T) {
 // 	return txLog
 // }
 
-// type mockRemote struct {
-// 	lck  sync.Mutex
-// 	data map[string][]byte
-// }
+type mockRemote struct {
+	lck  sync.Mutex
+	data map[string][]byte
+	t    *testing.T
+}
 
-// func (m *mockRemote) Read(path string) ([]byte, error) {
-// 	m.lck.Lock()
-// 	defer m.lck.Unlock()
-// 	return m.data[path], nil
-// }
+func (m *mockRemote) Read(path string) ([]byte, error) {
+	m.lck.Lock()
+	defer m.lck.Unlock()
+	return m.data[path], nil
+}
 
-// func (m *mockRemote) Write(path string, data []byte) error {
-// 	m.lck.Lock()
-// 	defer m.lck.Unlock()
-// 	m.data[path] = append(m.data[path], data...)
-// 	return nil
-// }
+func (m *mockRemote) Write(path string, data []byte) error {
+	m.lck.Lock()
+	defer m.lck.Unlock()
+	m.data[path] = append(m.data[path], data...)
+	return nil
+}
 
-// func (m *mockRemote) ReadDir(path string) ([]string, error) {
-// 	panic("unimplemented")
-// }
+func (m *mockRemote) ReadDir(path string) ([]byte, error) {
+	dirs := []string{
+		"hello",
+		"these",
+		"are",
+		"directory",
+		"names",
+	}
 
-// func (m mockRemote) GetLastModified(path string) (time.Time, error) {
-// 	return netTime.Now(), nil
-// }
+	data, err := json.Marshal(dirs)
+	m.t.Logf("Data: %s", data)
+	return data, err
+}
 
-// func (m mockRemote) GetLastWrite() (time.Time, error) {
-// 	return netTime.Now(), nil
-// }
+func (m *mockRemote) GetLastModified(path string) ([]byte, error) {
+	return netTime.Now().MarshalBinary()
+}
+
+func (m *mockRemote) GetLastWrite() ([]byte, error) {
+	return netTime.Now().MarshalBinary()
+}
+
+func TestReadDir(t *testing.T) {
+	mRemote := newRemoteStoreFileSystemWrapper(
+		&mockRemote{t: t, data: make(map[string][]byte)})
+
+	dirs, err := mRemote.ReadDir("test")
+	require.NoError(t, err)
+	t.Logf("%+v", dirs)
+}
diff --git a/bindings/connect.go b/bindings/connect.go
index 4a5a5175c69119b7b60a4334680d778cd99f998b..b34b5fd9fdd539c1b0bbae6d6af3b0d12480f703 100644
--- a/bindings/connect.go
+++ b/bindings/connect.go
@@ -46,9 +46,9 @@ func (c *Connection) GetId() int {
 // partner.Manager is confirmed.
 //
 // Parameters:
-//  - e2eId - ID of the E2E object in the e2e tracker
-//  - recipientContact - marshalled contact.Contact object
-//  - e2eParamsJSON - JSON marshalled byte of xxdk.E2EParams object
+//   - e2eId - ID of the E2E object in the e2e tracker
+//   - recipientContact - marshalled contact.Contact object
+//   - e2eParamsJSON - JSON marshalled byte of xxdk.E2EParams object
 func (c *Cmix) Connect(e2eId int, recipientContact, e2eParamsJSON []byte) (
 	*Connection, error) {
 	if len(e2eParamsJSON) == 0 {
@@ -82,8 +82,8 @@ func (c *Cmix) Connect(e2eId int, recipientContact, e2eParamsJSON []byte) (
 // partner.Manager.
 //
 // Returns:
-//  - []byte - the JSON marshalled bytes of the E2ESendReport object, which can
-//    be passed into Cmix.WaitForRoundResult to see if the send succeeded.
+//   - []byte - the JSON marshalled bytes of the E2ESendReport object, which can
+//     be passed into Cmix.WaitForRoundResult to see if the send succeeded.
 func (c *Connection) SendE2E(mt int, payload []byte) ([]byte, error) {
 	sendReport, err := c.connection.SendE2E(catalog.MessageType(mt), payload,
 		c.params.Base)
diff --git a/bindings/delivery.go b/bindings/delivery.go
index c57d548f339614e1636d4b5ea2210ee65ccb6cbd..0fde79f426001e3fc7d7a0f52dbe91b5178e867f 100644
--- a/bindings/delivery.go
+++ b/bindings/delivery.go
@@ -29,8 +29,8 @@ var dashboardBaseURL = "https://dashboard.xx.network"
 // thread-safe, and as such should only be called on setup.
 //
 // Parameters:
-//  - newURL - A valid URL that will be used for round look up on any send
-//    report.
+//   - newURL - A valid URL that will be used for round look up on any send
+//     report.
 func SetDashboardURL(newURL string) {
 	dashboardBaseURL = newURL
 }
@@ -45,7 +45,8 @@ func getRoundURL(round id.Round) string {
 // RoundsList contains a list of round IDs.
 //
 // JSON Example:
-//  [1001,1003,1006]
+//
+//	[1001,1003,1006]
 type RoundsList struct {
 	Rounds []uint64
 }
@@ -105,11 +106,11 @@ type MessageDeliveryCallback interface {
 // the same pointer.
 //
 // Parameters:
-//  - roundList - JSON marshalled bytes of RoundsList or JSON of any send report
-//    that inherits a [bindings.RoundsList] object
-//  - mdc - callback that adheres to the MessageDeliveryCallback interface
-//  - timeoutMS - timeout when the callback will return if no state update
-//    occurs, in milliseconds
+//   - roundList - JSON marshalled bytes of RoundsList or JSON of any send report
+//     that inherits a [bindings.RoundsList] object
+//   - mdc - callback that adheres to the MessageDeliveryCallback interface
+//   - timeoutMS - timeout when the callback will return if no state update
+//     occurs, in milliseconds
 func (c *Cmix) WaitForRoundResult(
 	roundList []byte, mdc MessageDeliveryCallback, timeoutMS int) error {
 	jww.INFO.Printf("WaitForRoundResult(%s, _, %d)", roundList, timeoutMS)
diff --git a/bindings/dummy.go b/bindings/dummy.go
index c56fa238fde11ad3cb78ccc3f0afb30fe1081cd8..d4831941ee6f70c819b326b87b940371f88f9099 100644
--- a/bindings/dummy.go
+++ b/bindings/dummy.go
@@ -27,14 +27,14 @@ type DummyTraffic struct {
 // given parameters below.
 //
 // Parameters:
-//  - cmixId - a Cmix object ID in the tracker.
-//  - maxNumMessages - the upper bound of the random number of messages sent
-//    each sending cycle.  Suggested value: 5.
-//  - avgSendDeltaMS - the average duration, in milliseconds, to wait between
-//    sends.  Suggested value: 60000.
-//  - randomRangeMS - the upper bound of the interval between sending cycles, in
-//    milliseconds. Sends occur every avgSendDeltaMS +/- a random duration with
-//    an upper bound of randomRangeMS.  Suggested value: 1000.
+//   - cmixId - a Cmix object ID in the tracker.
+//   - maxNumMessages - the upper bound of the random number of messages sent
+//     each sending cycle.  Suggested value: 5.
+//   - avgSendDeltaMS - the average duration, in milliseconds, to wait between
+//     sends.  Suggested value: 60000.
+//   - randomRangeMS - the upper bound of the interval between sending cycles, in
+//     milliseconds. Sends occur every avgSendDeltaMS +/- a random duration with
+//     an upper bound of randomRangeMS.  Suggested value: 1000.
 func NewDummyTrafficManager(cmixId, maxNumMessages, avgSendDeltaMS,
 	randomRangeMS int) (*DummyTraffic, error) {
 
@@ -66,8 +66,9 @@ func (dt *DummyTraffic) Pause() error {
 }
 
 // Start will start up the Manager's sending thread, meaning messages will
-//  be sent. This should be called after calling NewManager, as by default the
-//  thread is paused. This may also be called after a call to Pause.
+//
+//	be sent. This should be called after calling NewManager, as by default the
+//	thread is paused. This may also be called after a call to Pause.
 //
 // This will re-initialize the sending thread with a new randomly generated
 // interval between sending dummy messages. This means that there is zero
diff --git a/bindings/e2e.go b/bindings/e2e.go
index a5a133719406849c76f38356342bfde4149b47f3..2c3965bbb9c71691e5efc87a5250eb02220fa7d2 100644
--- a/bindings/e2e.go
+++ b/bindings/e2e.go
@@ -143,7 +143,7 @@ func (e *E2e) GetUdCertFromNdf() []byte {
 // within the NDF.
 //
 // Returns
-//  - []byte - A byte marshalled contact.Contact.
+//   - []byte - A byte marshalled contact.Contact.
 func (e *E2e) GetUdContactFromNdf() ([]byte, error) {
 	// Retrieve data from E2e
 	netDef := e.api.GetCmix().GetInstance().GetPartialNdf().Get()
diff --git a/bindings/e2eAuth.go b/bindings/e2eAuth.go
index 0576f231ad9855d5fc7e50211e0883c0ea2fe9d3..fb4b1bc95470f60e8ed715e5ce2408c0b82c44da 100644
--- a/bindings/e2eAuth.go
+++ b/bindings/e2eAuth.go
@@ -34,11 +34,11 @@ import (
 // will be auto resent by the cMix client.
 //
 // Parameters:
-//  - partnerContact - the marshalled bytes of the contact.Contact object.
-//  - factsListJson - the JSON marshalled bytes of [fact.FactList].
+//   - partnerContact - the marshalled bytes of the contact.Contact object.
+//   - factsListJson - the JSON marshalled bytes of [fact.FactList].
 //
 // Returns:
-//  - int64 - ID of the round (convert to uint64)
+//   - int64 - ID of the round (convert to uint64)
 func (e *E2e) Request(partnerContact, factsListJson []byte) (int64, error) {
 	var factsList fact.FactList
 	err := json.Unmarshal(factsListJson, &factsList)
@@ -73,10 +73,10 @@ func (e *E2e) Request(partnerContact, factsListJson []byte) (int64, error) {
 // If the confirmation must be resent, use ReplayConfirm.
 //
 // Parameters:
-//  - partnerContact - the marshalled bytes of the contact.Contact object.
+//   - partnerContact - the marshalled bytes of the contact.Contact object.
 //
 // Returns:
-//  - int64 - ID of the round (convert to uint64)
+//   - int64 - ID of the round (convert to uint64)
 func (e *E2e) Confirm(partnerContact []byte) (int64, error) {
 	partner, err := contact.Unmarshal(partnerContact)
 	if err != nil {
@@ -103,10 +103,10 @@ func (e *E2e) Confirm(partnerContact []byte) (int64, error) {
 // who is already a partner.
 //
 // Parameters:
-//  - partnerContact - the marshalled bytes of the contact.Contact object.
+//   - partnerContact - the marshalled bytes of the contact.Contact object.
 //
 // Returns:
-//  - int64 - ID of the round (convert to uint64)
+//   - int64 - ID of the round (convert to uint64)
 func (e *E2e) Reset(partnerContact []byte) (int64, error) {
 	partner, err := contact.Unmarshal(partnerContact)
 	if err != nil {
@@ -127,10 +127,10 @@ func (e *E2e) Reset(partnerContact []byte) (int64, error) {
 // This will not be useful if either side has ratcheted.
 //
 // Parameters:
-//  - partnerID - the marshalled bytes of the id.ID object.
+//   - partnerID - the marshalled bytes of the id.ID object.
 //
 // Returns:
-//  - int64 - ID of the round (convert to uint64)
+//   - int64 - ID of the round (convert to uint64)
 func (e *E2e) ReplayConfirm(partnerID []byte) (int64, error) {
 	partner, err := id.Unmarshal(partnerID)
 	if err != nil {
@@ -151,7 +151,7 @@ func (e *E2e) CallAllReceivedRequests() {
 // DeleteRequest deletes sent or received requests for a specific partner ID.
 //
 // Parameters:
-//  - partnerID - the marshalled bytes of the id.ID object.
+//   - partnerID - the marshalled bytes of the id.ID object.
 func (e *E2e) DeleteRequest(partnerID []byte) error {
 	partner, err := id.Unmarshal(partnerID)
 	if err != nil {
@@ -179,10 +179,10 @@ func (e *E2e) DeleteReceiveRequests() error {
 // GetReceivedRequest returns a contact if there is a received request for it.
 //
 // Parameters:
-//  - partnerID - the marshalled bytes of the id.ID object.
+//   - partnerID - the marshalled bytes of the id.ID object.
 //
 // Returns:
-//  - []byte - the marshalled bytes of the contact.Contact object.
+//   - []byte - the marshalled bytes of the contact.Contact object.
 func (e *E2e) GetReceivedRequest(partnerID []byte) ([]byte, error) {
 	partner, err := id.Unmarshal(partnerID)
 	if err != nil {
@@ -200,9 +200,9 @@ func (e *E2e) GetReceivedRequest(partnerID []byte) ([]byte, error) {
 // VerifyOwnership checks if the received ownership proof is valid.
 //
 // Parameters:
-//  - receivedContact, verifiedContact - the marshalled bytes of the
-//      contact.Contact object.
-//  - e2eId - ID of the e2e handler
+//   - receivedContact, verifiedContact - the marshalled bytes of the
+//     contact.Contact object.
+//   - e2eId - ID of the e2e handler
 func (e *E2e) VerifyOwnership(
 	receivedContact, verifiedContact []byte, e2eId int) (bool, error) {
 	received, err := contact.Unmarshal(receivedContact)
@@ -228,7 +228,7 @@ func (e *E2e) VerifyOwnership(
 // callback for the given partner ID.
 //
 // Parameters:
-//  - partnerID - the marshalled bytes of the id.ID object.
+//   - partnerID - the marshalled bytes of the id.ID object.
 func (e *E2e) AddPartnerCallback(partnerID []byte, cb AuthCallbacks) error {
 	partnerId, err := id.Unmarshal(partnerID)
 	if err != nil {
@@ -244,7 +244,7 @@ func (e *E2e) AddPartnerCallback(partnerID []byte, cb AuthCallbacks) error {
 // auth callback for the given partner ID.
 //
 // Parameters:
-//  - partnerID - the marshalled bytes of the id.ID object.
+//   - partnerID - the marshalled bytes of the id.ID object.
 func (e *E2e) DeletePartnerCallback(partnerID []byte) error {
 	partnerId, err := id.Unmarshal(partnerID)
 	if err != nil {
diff --git a/bindings/emoji.go b/bindings/emoji.go
index 03615bb0bc3bfa7c95206745a491d3ba6e8e818d..e788833958c80f12b9d0c5dd25d14fa874766e21 100644
--- a/bindings/emoji.go
+++ b/bindings/emoji.go
@@ -16,39 +16,39 @@ import (
 // SupportedEmojis returns a list of emojis that are supported by the backend.
 // The list includes all emojis described in [UTS #51 section A.1: Data Files].
 //
-// [UTS #51 section A.1: Data Files]: https://www.unicode.org/reports/tr51/#Data_Files
-//
 // Returns:
 //   - []byte - JSON of an array of [emoji.Emoji].
 //
 // Example JSON:
 //
-//	[
-//	  {
-//      "character": "☹️",
-//      "name": "frowning face",
-//      "comment": "E0.7",
-//      "codePoint": "2639 FE0F",
-//      "group": "Smileys \u0026 Emotion",
-//      "subgroup": "face-concerned"
-//	  },
-//	  {
-//      "character": "☺️",
-//      "name": "smiling face",
-//      "comment": "E0.6",
-//      "codePoint": "263A FE0F",
-//      "group": "Smileys \u0026 Emotion",
-//      "subgroup": "face-affection"
-//	  },
-//	  {
-//      "character": "☢️",
-//      "name": "radioactive",
-//      "comment": "E1.0",
-//      "codePoint": "2622 FE0F",
-//      "group": "Symbols",
-//      "subgroup": "warning"
-//	  }
-//	]
+//		[
+//		  {
+//	     "character": "☹️",
+//	     "name": "frowning face",
+//	     "comment": "E0.7",
+//	     "codePoint": "2639 FE0F",
+//	     "group": "Smileys \u0026 Emotion",
+//	     "subgroup": "face-concerned"
+//		  },
+//		  {
+//	     "character": "☺️",
+//	     "name": "smiling face",
+//	     "comment": "E0.6",
+//	     "codePoint": "263A FE0F",
+//	     "group": "Smileys \u0026 Emotion",
+//	     "subgroup": "face-affection"
+//		  },
+//		  {
+//	     "character": "☢️",
+//	     "name": "radioactive",
+//	     "comment": "E1.0",
+//	     "codePoint": "2622 FE0F",
+//	     "group": "Symbols",
+//	     "subgroup": "warning"
+//		  }
+//		]
+//
+// [UTS #51 section A.1: Data Files]: https://www.unicode.org/reports/tr51/#Data_Files
 func SupportedEmojis() ([]byte, error) {
 	return json.Marshal(emoji.SupportedEmojis())
 }
diff --git a/bindings/errors.go b/bindings/errors.go
index 4c15d28df9ae1fd4c6a748b3ed1b23bb317c7b4c..b2b939e828a933b5661d50df1d3eb7ce52a83201 100644
--- a/bindings/errors.go
+++ b/bindings/errors.go
@@ -57,8 +57,8 @@ const (
 //   - errStr - an error returned from the backend.
 //
 // Returns
-//  - A user-friendly error message. This should be devoid of technical speak
-//    but still be meaningful for front-end or back-end teams.
+//   - A user-friendly error message. This should be devoid of technical speak
+//     but still be meaningful for front-end or back-end teams.
 func CreateUserFriendlyErrorMessage(errStr string) string {
 	errorMux.RLock()
 	defer errorMux.RUnlock()
@@ -102,14 +102,15 @@ func CreateUserFriendlyErrorMessage(errStr string) string {
 // messages.
 //
 // Parameters:
-//  - jsonFile - contents of a JSON file whose format conforms to the example below.
+//   - jsonFile - contents of a JSON file whose format conforms to the example below.
 //
 // Example Input:
-//  {
-//    "Failed to Unmarshal Conversation": "Could not retrieve conversation",
-//    "Failed to unmarshal SentRequestMap": "Failed to pull up friend requests",
-//    "cannot create username when network is not health": "Cannot create username, unable to connect to network",
-//  }
+//
+//	{
+//	  "Failed to Unmarshal Conversation": "Could not retrieve conversation",
+//	  "Failed to unmarshal SentRequestMap": "Failed to pull up friend requests",
+//	  "cannot create username when network is not health": "Cannot create username, unable to connect to network",
+//	}
 func UpdateCommonErrors(jsonFile string) error {
 	errorMux.Lock()
 	defer errorMux.Unlock()
diff --git a/bindings/follow.go b/bindings/follow.go
index 81b1a73c0a209a171e6514846f415d32a9ff1c08..50010417812d6165e246b4b0cb665a4d7ff88b95 100644
--- a/bindings/follow.go
+++ b/bindings/follow.go
@@ -333,29 +333,29 @@ type TrackServicesCallback interface {
 //
 // Example JSON:
 //
-//	{
-//    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD": [
-//      {
-//        "Identifier": null,
-//        "Tags": ["test"],
-//        "Metadata": null
-//      }
-//    ],
-//    "AAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD": [
-//      {
-//        "Identifier": null,
-//        "Tags": ["test"],
-//        "Metadata": null
-//      }
-//    ],
-//    "AAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD": [
-//      {
-//        "Identifier": null,
-//        "Tags": ["test"],
-//        "Metadata": null
-//      }
-//    ]
-//  }
+//		{
+//	   "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD": [
+//	     {
+//	       "Identifier": null,
+//	       "Tags": ["test"],
+//	       "Metadata": null
+//	     }
+//	   ],
+//	   "AAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD": [
+//	     {
+//	       "Identifier": null,
+//	       "Tags": ["test"],
+//	       "Metadata": null
+//	     }
+//	   ],
+//	   "AAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD": [
+//	     {
+//	       "Identifier": null,
+//	       "Tags": ["test"],
+//	       "Metadata": null
+//	     }
+//	   ]
+//	 }
 type TrackCompressedServicesCallback interface {
 	Callback(marshalData []byte, err error)
 }
diff --git a/bindings/identity.go b/bindings/identity.go
index f464f71d76d9a6c0caeb8110457cbfd5e1fe1d84..e42bf04d51bd1f401d058209e4a6c97bc1c57c69 100644
--- a/bindings/identity.go
+++ b/bindings/identity.go
@@ -21,13 +21,14 @@ import (
 // ReceptionIdentity struct.
 //
 // JSON example:
-//  {
-//   "ID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
-//   "RSAPrivate":"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBNU15dTdhYjBJOS9UL1BFUUxtd2x3ejZHV3FjMUNYemVIVXhoVEc4bmg1WWRWSXMxCmJ2THpBVjNOMDJxdXN6K2s4TVFEWjBtejMzdkswUmhPczZIY0NUSFdzTEpXRkE5WWpzWWlCRi9qTDd1bmd1ckIKL2tvK1JJSnNrWGFWaEZaazRGdERoRXhTNWY4RnR0Qmk1NmNLZmdJQlVKT3ozZi9qQllTMkxzMlJ6cWV5YXM3SApjV2RaME9TclBTT3BiYlViU1FPbS9LWnlweGZHU21yZ2oxRUZuU1dZZ2xGZTdUOTRPbHF5MG14QTV5clVXbHorCk9sK3hHbXpCNUp4WUFSMU9oMFQrQTk4RWMrTUZHNm43L1MraDdzRDgybGRnVnJmbStFTzRCdmFKeTRESGZGMWgKNnp6QnVnY25NUVFGc0dLeDFYWC9COTVMdUpPVjdyeXlDbzZGbHdJREFRQUJBb0lCQVFDaUh6OGNlcDZvQk9RTAphUzBVRitHeU5VMnlVcVRNTWtTWThoUkh1c09CMmFheXoybHZVb3RLUHBPbjZRSWRWVTJrcE4vY2dtY0lSb2x5CkhBMDRUOHJBWVNaRlVqaVlRajkzKzRFREpJYXd2Z0YyVEs1bFoyb3oxVTdreStncU82V0RMR2Z0Q0wvODVQWEIKa210aXhnUXpRV3g1RWcvemtHdm03eURBalQxeDloNytsRjJwNFlBam5kT2xTS0dmQjFZeTR1RXBQd0kwc1lWdgpKQWc0MEFxbllZUmt4emJPbmQxWGNjdEJFN2Z1VDdrWXhoeSs3WXYrUTJwVy9BYmh6NGlHOEY1MW9GMGZwV0czCmlISDhsVXZFTkp2SUZEVHZ0UEpESlFZalBRN3lUbGlGZUdrMXZUQkcyQkpQNExzVzhpbDZOeUFuRktaY1hOQ24KeHVCendiSlJBb0dCQVBUK0dGTVJGRHRHZVl6NmwzZmg3UjJ0MlhrMysvUmpvR3BDUWREWDhYNERqR1pVd1RGVQpOS2tQTTNjS29ia2RBYlBDb3FpL0tOOVBibk9QVlZ3R3JkSE9vSnNibFVHYmJGamFTUzJQMFZnNUVhTC9rT2dUCmxMMUdoVFpIUWk1VUlMM0p4M1Z3T0ZRQ3RQOU1UQlQ0UEQvcEFLbDg3VTJXN3JTY1dGV1ZGbFNkQW9HQkFPOFUKVmhHWkRpVGFKTWVtSGZIdVYrNmtzaUlsam9aUVVzeGpmTGNMZ2NjV2RmTHBqS0ZWTzJNN3NqcEJEZ0w4NmFnegorVk14ZkQzZ1l0SmNWN01aMVcwNlZ6TlNVTHh3a1dRY1hXUWdDaXc5elpyYlhCUmZRNUVjMFBlblVoWWVwVzF5CkpkTC8rSlpQeDJxSzVrQytiWU5EdmxlNWdpcjlDSGVzTlR5enVyckRBb0dCQUl0cTJnN1RaazhCSVFUUVNrZ24Kb3BkRUtzRW4wZExXcXlBdENtVTlyaWpHL2l2eHlXczMveXZDQWNpWm5VVEp0QUZISHVlbXVTeXplQ2g5QmRkegoyWkRPNUdqQVBxVHlQS3NudFlNZkY4UDczZ1NES1VSWWVFbHFDejdET0c5QzRzcitPK3FoN1B3cCtqUmFoK1ZiCkNuWllNMDlBVDQ3YStJYUJmbWRkaXpLbEFvR0JBSmo1dkRDNmJIQnNISWlhNUNJL1RZaG5YWXUzMkVCYytQM0sKMHF3VThzOCtzZTNpUHBla2Y4RjVHd3RuUU4zc2tsMk1GQWFGYldmeVFZazBpUEVTb0p1cGJzNXA1enNNRkJ1bwpncUZrVnQ0RUZhRDJweTVwM2tQbDJsZjhlZXVwWkZScGE0WmRQdVIrMjZ4eWYrNEJhdlZJeld3NFNPL1V4Q3crCnhqbTNEczRkQW9HQWREL0VOa1BjU004c1BCM3JSWW9MQ2twcUV2U0MzbVZSbjNJd3c1WFAwcDRRVndhRmR1ckMKYUhtSE1EekNrNEUvb0haQVhFdGZ2S2tRaUI4MXVYM2c1aVo4amdYUVhXUHRteTVIcVVhcWJYUTlENkxWc3B0egpKL3R4SWJLMXp5c1o2bk9IY1VoUUwyVVF6SlBBRThZNDdjYzVzTThEN3kwZjJ0QURTQUZNMmN3PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQ==",
-//   "Salt":"4kk02v0NIcGtlobZ/xkxqWz8uH/ams/gjvQm14QT0dI=",
-//   "DHKeyPrivate":"eyJWYWx1ZSI6NDU2MDgzOTEzMjA0OTIyODA5Njg2MDI3MzQ0MzM3OTA0MzAyODYwMjM2NDk2NDM5NDI4NTcxMTMwNDMzOTQwMzgyMTIyMjY4OTQzNTMyMjIyMzc1MTkzNTEzMjU4MjA4MDA0NTczMDY4MjEwNzg2NDI5NjA1MjA0OTA3MjI2ODI5OTc3NTczMDkxODY0NTY3NDExMDExNjQxNCwiRmluZ2VycHJpbnQiOjE2ODAxNTQxNTExMjMzMDk4MzYzfQ=="
-//   "E2eGrp": "eyJnZW4iOiIyIiwicHJpbWUiOiJlMmVlOTgzZDAzMWRjMWRiNmYxYTdhNjdkZjBlOWE4ZTU1NjFkYjhlOGQ0OTQxMzM5NGMwNDliN2E4YWNjZWRjMjk4NzA4ZjEyMTk1MWQ5Y2Y5MjBlYzVkMTQ2NzI3YWE0YWU1MzViMDkyMmM2ODhiNTViM2RkMmFlZGY2YzAxYzk0NzY0ZGFiOTM3OTM1YWE4M2JlMzZlNjc3NjA3MTNhYjQ0YTYzMzdjMjBlNzg2MTU3NWU3NDVkMzFmOGI5ZTlhZDg0MTIxMThjNjJhM2UyZTI5ZGY0NmIwODY0ZDBjOTUxYzM5NGE1Y2JiZGM2YWRjNzE4ZGQyYTNlMDQxMDIzZGJiNWFiMjNlYmI0NzQyZGU5YzE2ODdiNWIzNGZhNDhjMzUyMTYzMmM0YTUzMGU4ZmZiMWJjNTFkYWRkZjQ1M2IwYjI3MTdjMmJjNjY2OWVkNzZiNGJkZDVjOWZmNTU4ZTg4ZjI2ZTU3ODUzMDJiZWRiY2EyM2VhYzVhY2U5MjA5NmVlOGE2MDY0MmZiNjFlOGYzZDI0OTkwYjhjYjEyZWU0NDhlZWY3OGUxODRjNzI0MmRkMTYxYzc3MzhmMzJiZjI5YTg0MTY5ODk3ODgyNWI0MTExYjRiYzNlMWUxOTg0NTUwOTU5NTgzMzNkNzc2ZDhiMmJlZWVkM2ExYTFhMjIxYTZlMzdlNjY0YTY0YjgzOTgxYzQ2ZmZkZGMxYTQ1ZTNkNTIxMWFhZjhiZmJjMDcyNzY4YzRmNTBkN2Q3ODAzZDJkNGYyNzhkZTgwMTRhNDczMjM2MzFkN2UwNjRkZTgxYzBjNmJmYTQzZWYwZTY5OTg4NjBmMTM5MGI1ZDNmZWFjYWYxNjk2MDE1Y2I3OWMzZjljMmQ5M2Q5NjExMjBjZDBlNWYxMmNiYjY4N2VhYjA0NTI0MWY5Njc4OWMzOGU4OWQ3OTYxMzhlNjMxOWJlNjJlMzVkODdiMTA0OGNhMjhiZTM4OWI1NzVlOTk0ZGNhNzU1NDcxNTg0YTA5ZWM3MjM3NDJkYzM1ODczODQ3YWVmNDlmNjZlNDM4NzMifQ=="
-// }
+//
+//	 {
+//	  "ID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+//	  "RSAPrivate":"LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBNU15dTdhYjBJOS9UL1BFUUxtd2x3ejZHV3FjMUNYemVIVXhoVEc4bmg1WWRWSXMxCmJ2THpBVjNOMDJxdXN6K2s4TVFEWjBtejMzdkswUmhPczZIY0NUSFdzTEpXRkE5WWpzWWlCRi9qTDd1bmd1ckIKL2tvK1JJSnNrWGFWaEZaazRGdERoRXhTNWY4RnR0Qmk1NmNLZmdJQlVKT3ozZi9qQllTMkxzMlJ6cWV5YXM3SApjV2RaME9TclBTT3BiYlViU1FPbS9LWnlweGZHU21yZ2oxRUZuU1dZZ2xGZTdUOTRPbHF5MG14QTV5clVXbHorCk9sK3hHbXpCNUp4WUFSMU9oMFQrQTk4RWMrTUZHNm43L1MraDdzRDgybGRnVnJmbStFTzRCdmFKeTRESGZGMWgKNnp6QnVnY25NUVFGc0dLeDFYWC9COTVMdUpPVjdyeXlDbzZGbHdJREFRQUJBb0lCQVFDaUh6OGNlcDZvQk9RTAphUzBVRitHeU5VMnlVcVRNTWtTWThoUkh1c09CMmFheXoybHZVb3RLUHBPbjZRSWRWVTJrcE4vY2dtY0lSb2x5CkhBMDRUOHJBWVNaRlVqaVlRajkzKzRFREpJYXd2Z0YyVEs1bFoyb3oxVTdreStncU82V0RMR2Z0Q0wvODVQWEIKa210aXhnUXpRV3g1RWcvemtHdm03eURBalQxeDloNytsRjJwNFlBam5kT2xTS0dmQjFZeTR1RXBQd0kwc1lWdgpKQWc0MEFxbllZUmt4emJPbmQxWGNjdEJFN2Z1VDdrWXhoeSs3WXYrUTJwVy9BYmh6NGlHOEY1MW9GMGZwV0czCmlISDhsVXZFTkp2SUZEVHZ0UEpESlFZalBRN3lUbGlGZUdrMXZUQkcyQkpQNExzVzhpbDZOeUFuRktaY1hOQ24KeHVCendiSlJBb0dCQVBUK0dGTVJGRHRHZVl6NmwzZmg3UjJ0MlhrMysvUmpvR3BDUWREWDhYNERqR1pVd1RGVQpOS2tQTTNjS29ia2RBYlBDb3FpL0tOOVBibk9QVlZ3R3JkSE9vSnNibFVHYmJGamFTUzJQMFZnNUVhTC9rT2dUCmxMMUdoVFpIUWk1VUlMM0p4M1Z3T0ZRQ3RQOU1UQlQ0UEQvcEFLbDg3VTJXN3JTY1dGV1ZGbFNkQW9HQkFPOFUKVmhHWkRpVGFKTWVtSGZIdVYrNmtzaUlsam9aUVVzeGpmTGNMZ2NjV2RmTHBqS0ZWTzJNN3NqcEJEZ0w4NmFnegorVk14ZkQzZ1l0SmNWN01aMVcwNlZ6TlNVTHh3a1dRY1hXUWdDaXc5elpyYlhCUmZRNUVjMFBlblVoWWVwVzF5CkpkTC8rSlpQeDJxSzVrQytiWU5EdmxlNWdpcjlDSGVzTlR5enVyckRBb0dCQUl0cTJnN1RaazhCSVFUUVNrZ24Kb3BkRUtzRW4wZExXcXlBdENtVTlyaWpHL2l2eHlXczMveXZDQWNpWm5VVEp0QUZISHVlbXVTeXplQ2g5QmRkegoyWkRPNUdqQVBxVHlQS3NudFlNZkY4UDczZ1NES1VSWWVFbHFDejdET0c5QzRzcitPK3FoN1B3cCtqUmFoK1ZiCkNuWllNMDlBVDQ3YStJYUJmbWRkaXpLbEFvR0JBSmo1dkRDNmJIQnNISWlhNUNJL1RZaG5YWXUzMkVCYytQM0sKMHF3VThzOCtzZTNpUHBla2Y4RjVHd3RuUU4zc2tsMk1GQWFGYldmeVFZazBpUEVTb0p1cGJzNXA1enNNRkJ1bwpncUZrVnQ0RUZhRDJweTVwM2tQbDJsZjhlZXVwWkZScGE0WmRQdVIrMjZ4eWYrNEJhdlZJeld3NFNPL1V4Q3crCnhqbTNEczRkQW9HQWREL0VOa1BjU004c1BCM3JSWW9MQ2twcUV2U0MzbVZSbjNJd3c1WFAwcDRRVndhRmR1ckMKYUhtSE1EekNrNEUvb0haQVhFdGZ2S2tRaUI4MXVYM2c1aVo4amdYUVhXUHRteTVIcVVhcWJYUTlENkxWc3B0egpKL3R4SWJLMXp5c1o2bk9IY1VoUUwyVVF6SlBBRThZNDdjYzVzTThEN3kwZjJ0QURTQUZNMmN3PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQ==",
+//	  "Salt":"4kk02v0NIcGtlobZ/xkxqWz8uH/ams/gjvQm14QT0dI=",
+//	  "DHKeyPrivate":"eyJWYWx1ZSI6NDU2MDgzOTEzMjA0OTIyODA5Njg2MDI3MzQ0MzM3OTA0MzAyODYwMjM2NDk2NDM5NDI4NTcxMTMwNDMzOTQwMzgyMTIyMjY4OTQzNTMyMjIyMzc1MTkzNTEzMjU4MjA4MDA0NTczMDY4MjEwNzg2NDI5NjA1MjA0OTA3MjI2ODI5OTc3NTczMDkxODY0NTY3NDExMDExNjQxNCwiRmluZ2VycHJpbnQiOjE2ODAxNTQxNTExMjMzMDk4MzYzfQ=="
+//	  "E2eGrp": "eyJnZW4iOiIyIiwicHJpbWUiOiJlMmVlOTgzZDAzMWRjMWRiNmYxYTdhNjdkZjBlOWE4ZTU1NjFkYjhlOGQ0OTQxMzM5NGMwNDliN2E4YWNjZWRjMjk4NzA4ZjEyMTk1MWQ5Y2Y5MjBlYzVkMTQ2NzI3YWE0YWU1MzViMDkyMmM2ODhiNTViM2RkMmFlZGY2YzAxYzk0NzY0ZGFiOTM3OTM1YWE4M2JlMzZlNjc3NjA3MTNhYjQ0YTYzMzdjMjBlNzg2MTU3NWU3NDVkMzFmOGI5ZTlhZDg0MTIxMThjNjJhM2UyZTI5ZGY0NmIwODY0ZDBjOTUxYzM5NGE1Y2JiZGM2YWRjNzE4ZGQyYTNlMDQxMDIzZGJiNWFiMjNlYmI0NzQyZGU5YzE2ODdiNWIzNGZhNDhjMzUyMTYzMmM0YTUzMGU4ZmZiMWJjNTFkYWRkZjQ1M2IwYjI3MTdjMmJjNjY2OWVkNzZiNGJkZDVjOWZmNTU4ZTg4ZjI2ZTU3ODUzMDJiZWRiY2EyM2VhYzVhY2U5MjA5NmVlOGE2MDY0MmZiNjFlOGYzZDI0OTkwYjhjYjEyZWU0NDhlZWY3OGUxODRjNzI0MmRkMTYxYzc3MzhmMzJiZjI5YTg0MTY5ODk3ODgyNWI0MTExYjRiYzNlMWUxOTg0NTUwOTU5NTgzMzNkNzc2ZDhiMmJlZWVkM2ExYTFhMjIxYTZlMzdlNjY0YTY0YjgzOTgxYzQ2ZmZkZGMxYTQ1ZTNkNTIxMWFhZjhiZmJjMDcyNzY4YzRmNTBkN2Q3ODAzZDJkNGYyNzhkZTgwMTRhNDczMjM2MzFkN2UwNjRkZTgxYzBjNmJmYTQzZWYwZTY5OTg4NjBmMTM5MGI1ZDNmZWFjYWYxNjk2MDE1Y2I3OWMzZjljMmQ5M2Q5NjExMjBjZDBlNWYxMmNiYjY4N2VhYjA0NTI0MWY5Njc4OWMzOGU4OWQ3OTYxMzhlNjMxOWJlNjJlMzVkODdiMTA0OGNhMjhiZTM4OWI1NzVlOTk0ZGNhNzU1NDcxNTg0YTA5ZWM3MjM3NDJkYzM1ODczODQ3YWVmNDlmNjZlNDM4NzMifQ=="
+//	}
 type ReceptionIdentity struct {
 	ID            []byte // User ID (base64)
 	RSAPrivatePem []byte // RSA Private key (PEM format)
@@ -104,10 +105,10 @@ func (c *Cmix) GetReceptionRegistrationValidationSignature() []byte {
 // GetIDFromContact returns the ID in the [contact.Contact] object.
 //
 // Parameters:
-//  - marshaledContact - JSON marshalled bytes of [contact.Contact]
+//   - marshaledContact - JSON marshalled bytes of [contact.Contact]
 //
 // Returns:
-//  - []byte - bytes of the [id.ID] object
+//   - []byte - bytes of the [id.ID] object
 func GetIDFromContact(marshaledContact []byte) ([]byte, error) {
 	cnt, err := contact.Unmarshal(marshaledContact)
 	if err != nil {
@@ -121,10 +122,10 @@ func GetIDFromContact(marshaledContact []byte) ([]byte, error) {
 // object.
 //
 // Parameters:
-//  - marshaledContact - JSON marshalled bytes of [contact.Contact]
+//   - marshaledContact - JSON marshalled bytes of [contact.Contact]
 //
 // Returns:
-//  - []byte - JSON marshalled bytes of the [cyclic.Int] object
+//   - []byte - JSON marshalled bytes of the [cyclic.Int] object
 func GetPubkeyFromContact(marshaledContact []byte) ([]byte, error) {
 	cnt, err := contact.Unmarshal(marshaledContact)
 	if err != nil {
@@ -142,11 +143,11 @@ func GetPubkeyFromContact(marshaledContact []byte) ([]byte, error) {
 // pass in empty facts in order to clear the facts.
 //
 // Parameters:
-//  - marshaledContact - the JSON marshalled bytes of [contact.Contact]
-//  - factListJSON - the JSON marshalled bytes of [fact.FactList]
+//   - marshaledContact - the JSON marshalled bytes of [contact.Contact]
+//   - factListJSON - the JSON marshalled bytes of [fact.FactList]
 //
 // Returns:
-//  - []byte - marshalled bytes of the modified [contact.Contact]
+//   - []byte - marshalled bytes of the modified [contact.Contact]
 func SetFactsOnContact(marshaledContact []byte, factListJSON []byte) ([]byte, error) {
 	cnt, err := contact.Unmarshal(marshaledContact)
 	if err != nil {
@@ -167,10 +168,10 @@ func SetFactsOnContact(marshaledContact []byte, factListJSON []byte) ([]byte, er
 // GetFactsFromContact returns the fact list in the [contact.Contact] object.
 //
 // Parameters:
-//  - marshaledContact - the JSON marshalled bytes of [contact.Contact]
+//   - marshaledContact - the JSON marshalled bytes of [contact.Contact]
 //
 // Returns:
-//  - []byte - the JSON marshalled bytes of [fact.FactList]
+//   - []byte - the JSON marshalled bytes of [fact.FactList]
 func GetFactsFromContact(marshaledContact []byte) ([]byte, error) {
 	cnt, err := contact.Unmarshal(marshaledContact)
 	if err != nil {
diff --git a/bindings/listener.go b/bindings/listener.go
index 4847ae85eef62bda113bff64d9286fbdbd212e29..9b4fbdafb5748940959af5ab2c15823fec78fa1d 100644
--- a/bindings/listener.go
+++ b/bindings/listener.go
@@ -40,16 +40,17 @@ type listener struct {
 // Message is the bindings' representation of a receive.Message.
 //
 // JSON example:
-//  {
-//   "MessageType":1,
-//   "ID":"EB/70R5HYEw5htZ4Hg9ondrn3+cAc/lH2G0mjQMja3w=",
-//   "Payload":"7TzZKgNphT5UooNM7mDSwtVcIs8AIu4vMKm4ld6GSR8YX5GrHirixUBAejmsgdroRJyo06TkIVef7UM9FN8YfQ==",
-//   "Sender":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
-//   "RecipientID":"amFrZXh4MzYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
-//   "EphemeralID":17,"Timestamp":1653580439357351000,
-//   "Encrypted":false,
-//   "RoundId":19
-//  }
+//
+//	{
+//	 "MessageType":1,
+//	 "ID":"EB/70R5HYEw5htZ4Hg9ondrn3+cAc/lH2G0mjQMja3w=",
+//	 "Payload":"7TzZKgNphT5UooNM7mDSwtVcIs8AIu4vMKm4ld6GSR8YX5GrHirixUBAejmsgdroRJyo06TkIVef7UM9FN8YfQ==",
+//	 "Sender":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+//	 "RecipientID":"amFrZXh4MzYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+//	 "EphemeralID":17,"Timestamp":1653580439357351000,
+//	 "Encrypted":false,
+//	 "RoundId":19
+//	}
 type Message struct {
 	MessageType int
 	ID          []byte
diff --git a/bindings/logging.go b/bindings/logging.go
index 9b609f103e8d59e79b7ac5e8e2099d5cd1056b1b..23ebffa5c752a0626d3e82c93ca9ce53d4fdd018 100644
--- a/bindings/logging.go
+++ b/bindings/logging.go
@@ -22,6 +22,7 @@ import (
 // messages will be printed).
 //
 // Log level options:
+//
 //	TRACE    - 0
 //	DEBUG    - 1
 //	INFO     - 2
diff --git a/bindings/notifications.go b/bindings/notifications.go
index cc84b2b927741a075c3cefd462fe401de2dd276f..e38c8fb3cadae94f0a0ed16b81b39d8443166750 100644
--- a/bindings/notifications.go
+++ b/bindings/notifications.go
@@ -8,6 +8,7 @@
 package bindings
 
 import (
+	"encoding/json"
 	"github.com/pkg/errors"
 	"gitlab.com/elixxir/client/v4/notifications"
 	"sync"
@@ -25,6 +26,21 @@ type Notifications struct {
 	id      int
 }
 
+// NotificationState indicates the status of notifications for an ID.
+const (
+	// NotificationsMute shows no notifications for the ID.
+	NotificationsMute int64 = int64(notifications.Mute)
+
+	// NotificationsWhenOpen shows notifications for this ID only when the app
+	// is running and open. No registration or privacy leaks occur in this
+	// state.
+	NotificationsWhenOpen int64 = int64(notifications.WhenOpen)
+
+	// NotificationsPush shows notifications for this ID as push notification
+	// on applicable devices. This state has a minor privacy loss.
+	NotificationsPush int64 = int64(notifications.Push)
+)
+
 // AddToken registers the Token with the remote server if this manager is
 // in set to register, otherwise it will return ErrRemoteRegistrationDisabled
 // This will add the token to the list of tokens which are forwarded the messages
@@ -40,6 +56,29 @@ func (n *Notifications) RemoveToken() error {
 	return n.manager.RemoveToken()
 }
 
+type GetTokenJson struct {
+	Exists bool   `json:"exists"`
+	Token  string `json:"token"`
+	App    string `json:"app"`
+}
+
+// GetToken returns the token if it exists
+//
+//	{
+//	  "exists":true,
+//	  "Token":"Z1owNo+GvizWshVW/C5IJ1izPD5oqMkCGr+PsA5If4HZ",
+//	  "App":"havenIOS"
+//	}
+func (n *Notifications) GetToken() ([]byte, error) {
+	exist, token, app := n.manager.GetToken()
+	gtj := &GetTokenJson{
+		Exists: exist,
+		Token:  token,
+		App:    app,
+	}
+	return json.Marshal(gtj)
+}
+
 // SetMaxState sets the maximum functional state of any identity
 // downstream moduals will be told to clamp any state greater than maxState
 // down to maxState. Depending on UX requirements, they may still show the
diff --git a/bindings/restlike.go b/bindings/restlike.go
index 6bd33e3e0d8e8b7b8f7450d4d0979b9a2eba69dd..1c8763c1af98214c05efaed8b501e2eb83577c53 100644
--- a/bindings/restlike.go
+++ b/bindings/restlike.go
@@ -18,14 +18,15 @@ import (
 // RestlikeMessage is the bindings' representation of a restlike.Message
 //
 // JSON example:
-//  {
-//   "Version":1,
-//   "Headers":"Y29udGVudHM6YXBwbGljYXRpb24vanNvbg==",
-//   "Content":"VGhpcyBpcyBhIHJlc3RsaWtlIG1lc3NhZ2U=",
-//   "Method":2,
-//   "URI":"xx://CmixRestlike/rest",
-//   "Error":""
-//  }
+//
+//	{
+//	 "Version":1,
+//	 "Headers":"Y29udGVudHM6YXBwbGljYXRpb24vanNvbg==",
+//	 "Content":"VGhpcyBpcyBhIHJlc3RsaWtlIG1lc3NhZ2U=",
+//	 "Method":2,
+//	 "URI":"xx://CmixRestlike/rest",
+//	 "Error":""
+//	}
 type RestlikeMessage struct {
 	Version uint32
 	Headers []byte
@@ -38,13 +39,13 @@ type RestlikeMessage struct {
 // RestlikeRequest performs a normal restlike request.
 //
 // Parameters:
-//  - cmixId - ID of the cMix object in the tracker
-//  - connectionID - ID of the connection in the tracker
-//  - request - JSON marshalled RestlikeMessage
-//  - e2eParamsJSON - JSON marshalled xxdk.E2EParams
+//   - cmixId - ID of the cMix object in the tracker
+//   - connectionID - ID of the connection in the tracker
+//   - request - JSON marshalled RestlikeMessage
+//   - e2eParamsJSON - JSON marshalled xxdk.E2EParams
 //
 // Returns:
-//  - []byte - JSON marshalled RestlikeMessage
+//   - []byte - JSON marshalled RestlikeMessage
 func RestlikeRequest(
 	cmixId, connectionID int, request, e2eParamsJSON []byte) ([]byte, error) {
 	if len(e2eParamsJSON) == 0 {
@@ -100,13 +101,13 @@ func RestlikeRequest(
 // RestlikeRequestAuth performs an authenticated restlike request.
 //
 // Parameters:
-//  - cmixId - ID of the cMix object in the tracker
-//  - authConnectionID - ID of the authenticated connection in the tracker
-//  - request - JSON marshalled RestlikeMessage
-//  - e2eParamsJSON - JSON marshalled xxdk.E2EParams
+//   - cmixId - ID of the cMix object in the tracker
+//   - authConnectionID - ID of the authenticated connection in the tracker
+//   - request - JSON marshalled RestlikeMessage
+//   - e2eParamsJSON - JSON marshalled xxdk.E2EParams
 //
 // Returns:
-//  - []byte - JSON marshalled RestlikeMessage
+//   - []byte - JSON marshalled RestlikeMessage
 func RestlikeRequestAuth(cmixId, authConnectionID int, request,
 	e2eParamsJSON []byte) ([]byte, error) {
 	if len(e2eParamsJSON) == 0 {
diff --git a/bindings/restlikeSingle.go b/bindings/restlikeSingle.go
index 3625dcc452d8cc44f39e5f7c2ec647125f79a6a3..a62dec60de167f7dbdac29090a7e1cc85fd5ce5a 100644
--- a/bindings/restlikeSingle.go
+++ b/bindings/restlikeSingle.go
@@ -19,8 +19,8 @@ import (
 // asynchronous restlike request.
 //
 // Parameters:
-//  - []byte - JSON marshalled restlike.Message
-//  - error - an error (the results of calling json.Marshal on the message)
+//   - []byte - JSON marshalled restlike.Message
+//   - error - an error (the results of calling json.Marshal on the message)
 type RestlikeCallback interface {
 	Callback([]byte, error)
 }
@@ -28,13 +28,13 @@ type RestlikeCallback interface {
 // RequestRestLike sends a restlike request to a given contact.
 //
 // Parameters:
-//  - e2eID - ID of the e2e object in the tracker
-//  - recipient - marshalled contact.Contact object
-//  - request - JSON marshalled RestlikeMessage
-//  - paramsJSON - JSON marshalled single.RequestParams
+//   - e2eID - ID of the e2e object in the tracker
+//   - recipient - marshalled contact.Contact object
+//   - request - JSON marshalled RestlikeMessage
+//   - paramsJSON - JSON marshalled single.RequestParams
 //
 // Returns:
-//  - []byte - JSON marshalled restlike.Message
+//   - []byte - JSON marshalled restlike.Message
 func RequestRestLike(e2eID int, recipient, request, paramsJSON []byte) ([]byte, error) {
 	c, err := e2eTrackerSingleton.get(e2eID)
 	if err != nil {
@@ -74,11 +74,11 @@ func RequestRestLike(e2eID int, recipient, request, paramsJSON []byte) ([]byte,
 // contact.
 //
 // Parameters:
-//  - e2eID - ID of the e2e object in the tracker
-//  - recipient - marshalled contact.Contact object
-//  - request - JSON marshalled RestlikeMessage
-//  - paramsJSON - JSON marshalled single.RequestParams
-//  - cb - RestlikeCallback callback
+//   - e2eID - ID of the e2e object in the tracker
+//   - recipient - marshalled contact.Contact object
+//   - request - JSON marshalled RestlikeMessage
+//   - paramsJSON - JSON marshalled single.RequestParams
+//   - cb - RestlikeCallback callback
 //
 // Returns an error, and the RestlikeCallback will be called with the results
 // of JSON marshalling the response when received.
diff --git a/bindings/secrets.go b/bindings/secrets.go
index 41f16598dc7b283c59bf1da2a6d1189c5b49fc94..c660d2ef7bccd7eab3605b1849fcacca4fa9dfa5 100644
--- a/bindings/secrets.go
+++ b/bindings/secrets.go
@@ -16,8 +16,8 @@ import (
 // number generator.
 //
 // Parameters:
-//  - numBytes - The size of secret. It should be set to 32, but can be set
-//   higher in certain cases.
+//   - numBytes - The size of secret. It should be set to 32, but can be set
+//     higher in certain cases.
 func GenerateSecret(numBytes int) []byte {
 	if numBytes < 32 {
 		jww.FATAL.Panic(
diff --git a/bindings/single.go b/bindings/single.go
index 50ec375d8b77802522c8becbc64096d7a31585c8..9c2201ab3ce82514cf1122059eaef780b4c23f5a 100644
--- a/bindings/single.go
+++ b/bindings/single.go
@@ -24,16 +24,16 @@ import (
 // TransmitSingleUse transmits payload to recipient via single-use.
 //
 // Parameters:
-//  - e2eID - ID of the e2e object in the tracker
-//  - recipient - marshalled contact.Contact object
-//  - tag - identifies the single-use message
-//  - payload - message contents
-//  - paramsJSON - JSON marshalled single.RequestParams
-//  - responseCB - the callback that will be called when a response is received
+//   - e2eID - ID of the e2e object in the tracker
+//   - recipient - marshalled contact.Contact object
+//   - tag - identifies the single-use message
+//   - payload - message contents
+//   - paramsJSON - JSON marshalled single.RequestParams
+//   - responseCB - the callback that will be called when a response is received
 //
 // Returns:
-//  - []byte - the JSON marshalled bytes of the SingleUseSendReport object,
-//    which can be passed into WaitForRoundResult to see if the send succeeded.
+//   - []byte - the JSON marshalled bytes of the SingleUseSendReport object,
+//     which can be passed into WaitForRoundResult to see if the send succeeded.
 func TransmitSingleUse(e2eID int, recipient []byte, tag string, payload,
 	paramsJSON []byte, responseCB SingleUseResponse) ([]byte, error) {
 	e2eCl, err := e2eTrackerSingleton.get(e2eID)
@@ -73,12 +73,12 @@ func TransmitSingleUse(e2eID int, recipient []byte, tag string, payload,
 // object and SingleUseCallback func.
 //
 // Parameters:
-//  - e2eID - ID of the e2e object in the tracker
-//  - tag - identifies the single-use message
-//  - cb - the callback that will be called when a response is received
+//   - e2eID - ID of the e2e object in the tracker
+//   - tag - identifies the single-use message
+//   - cb - the callback that will be called when a response is received
 //
 // Returns:
-//  - Stopper - an interface containing a function used to stop the listener
+//   - Stopper - an interface containing a function used to stop the listener
 func Listen(e2eID int, tag string, cb SingleUseCallback) (Stopper, error) {
 	e2eCl, err := e2eTrackerSingleton.get(e2eID)
 	if err != nil {
@@ -101,12 +101,13 @@ func Listen(e2eID int, tag string, cb SingleUseCallback) (Stopper, error) {
 // information returned by single.TransmitRequest.
 //
 // SingleUseSendReport JSON example:
-//  {
-//   "Rounds":[1,5,9],
-//   "RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true",
-//   "EphID":1655533,
-//   "ReceptionID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"}
-//  }
+//
+//	{
+//	 "Rounds":[1,5,9],
+//	 "RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true",
+//	 "EphID":1655533,
+//	 "ReceptionID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"}
+//	}
 type SingleUseSendReport struct {
 	RoundsList
 	RoundURL    string
@@ -119,14 +120,15 @@ type SingleUseSendReport struct {
 // single.TransmitRequest.
 //
 // SingleUseResponseReport JSON example:
-//  {
-//   "Rounds":[1,5,9],
-//   "RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true",
-//   "Payload":"rSuPD35ELWwm5KTR9ViKIz/r1YGRgXIl5792SF8o8piZzN6sT4Liq4rUU/nfOPvQEjbfWNh/NYxdJ72VctDnWw==",
-//   "EphID":1655533,
-//   "ReceptionID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"},
-//   "Err":"",
-//  }
+//
+//	{
+//	 "Rounds":[1,5,9],
+//	 "RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true",
+//	 "Payload":"rSuPD35ELWwm5KTR9ViKIz/r1YGRgXIl5792SF8o8piZzN6sT4Liq4rUU/nfOPvQEjbfWNh/NYxdJ72VctDnWw==",
+//	 "EphID":1655533,
+//	 "ReceptionID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"},
+//	 "Err":"",
+//	}
 type SingleUseResponseReport struct {
 	RoundsList
 	RoundURL    string
@@ -140,14 +142,15 @@ type SingleUseResponseReport struct {
 // single -use messages received by a callback passed into single.Listen.
 //
 // SingleUseCallbackReport JSON example:
-//    {
-//      "Rounds":[1,5,9],
-//      "RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true",
-//      "Payload":"rSuPD35ELWwm5KTR9ViKIz/r1YGRgXIl5792SF8o8piZzN6sT4Liq4rUU/nfOPvQEjbfWNh/NYxdJ72VctDnWw==",
-//      "Partner":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
-//      "EphID":1655533,
-//      "ReceptionID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"}
-//    }
+//
+//	{
+//	  "Rounds":[1,5,9],
+//	  "RoundURL": "https://dashboard.xx.network/rounds/25?xxmessenger=true",
+//	  "Payload":"rSuPD35ELWwm5KTR9ViKIz/r1YGRgXIl5792SF8o8piZzN6sT4Liq4rUU/nfOPvQEjbfWNh/NYxdJ72VctDnWw==",
+//	  "Partner":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD",
+//	  "EphID":1655533,
+//	  "ReceptionID":"emV6aW1hAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD"}
+//	}
 type SingleUseCallbackReport struct {
 	RoundsList
 	RoundURL    string
@@ -171,9 +174,9 @@ type Stopper interface {
 // received.
 //
 // Parameters:
-//  - callbackReport - the JSON marshalled bytes of the SingleUseCallbackReport
-//    object, which can be passed into Cmix.WaitForRoundResult to see if the
-//    send operation succeeded.
+//   - callbackReport - the JSON marshalled bytes of the SingleUseCallbackReport
+//     object, which can be passed into Cmix.WaitForRoundResult to see if the
+//     send operation succeeded.
 type SingleUseCallback interface {
 	Callback(callbackReport []byte, err error)
 }
@@ -182,9 +185,9 @@ type SingleUseCallback interface {
 // clients into TransmitSingleUse.
 //
 // Parameters:
-//  - callbackReport - the JSON marshalled bytes of the SingleUseResponseReport
-//    object, which can be passed into Cmix.WaitForRoundResult to see if the
-//    send operation succeeded.
+//   - callbackReport - the JSON marshalled bytes of the SingleUseResponseReport
+//     object, which can be passed into Cmix.WaitForRoundResult to see if the
+//     send operation succeeded.
 type SingleUseResponse interface {
 	Callback(responseReport []byte, err error)
 }
diff --git a/bindings/timeNow.go b/bindings/timeNow.go
index 6aad2298f81a9651bbd6c80eb3b70a4ac4c9966a..7c832f769befe87f3b814e488b976328c2eecc4f 100644
--- a/bindings/timeNow.go
+++ b/bindings/timeNow.go
@@ -18,8 +18,8 @@ import (
 // may result in a crash.
 //
 // Parameters:
-//  - timeNow is an object which adheres to [netTime.TimeSource]. Specifically,
-//    this object should a NowMs() method which return a 64-bit integer value.
+//   - timeNow is an object which adheres to [netTime.TimeSource]. Specifically,
+//     this object should a NowMs() method which return a 64-bit integer value.
 func SetTimeSource(timeNow netTime.TimeSource) {
 	netTime.SetTimeSource(timeNow)
 }
@@ -28,9 +28,9 @@ func SetTimeSource(timeNow netTime.TimeSource) {
 // will have this offset applied to this value.
 //
 // Parameters:
-//  - offset is a time by which netTime.Now will be offset. This value may be
-//    negative or positive. This expects a 64-bit integer value which will
-//    represent the number in microseconds this offset will be.
+//   - offset is a time by which netTime.Now will be offset. This value may be
+//     negative or positive. This expects a 64-bit integer value which will
+//     represent the number in microseconds this offset will be.
 func SetOffset(offset int64) {
 	netTime.SetOffset(time.Duration(offset) * time.Microsecond)
 }
diff --git a/bindings/ud.go b/bindings/ud.go
index dfd27b1f09a740dc77e19b748e7c8f61c0c794c1..55c81ba5103e5823ad650d7e136fe0b8d2d4d9e7 100644
--- a/bindings/ud.go
+++ b/bindings/ud.go
@@ -110,14 +110,14 @@ type UdNetworkStatus interface {
 // files to determine if a user has registered with UD in the past.
 //
 // Parameters:
-//  - e2eID -  REQUIRED. The tracked e2e object ID. This can be retrieved using [E2e.GetID].
+//   - e2eID -  REQUIRED. The tracked e2e object ID. This can be retrieved using [E2e.GetID].
 //
 // Returns:
 //   - bool - A boolean representing true if the user has been registered with UD already
-//            or false if it has not been registered already.
-//  - error - An error should only be returned if the internal tracker failed to retrieve an
-//            E2e object given the e2eId. If an error was returned, the registration state check
-//            was not performed properly, and the boolean returned should be ignored.
+//     or false if it has not been registered already.
+//   - error - An error should only be returned if the internal tracker failed to retrieve an
+//     E2e object given the e2eId. If an error was returned, the registration state check
+//     was not performed properly, and the boolean returned should be ignored.
 func IsRegisteredWithUD(e2eId int) (bool, error) {
 
 	// Get user from singleton
@@ -147,34 +147,34 @@ func IsRegisteredWithUD(e2eId int) (bool, error) {
 // methods are detailed in the parameters section.
 //
 // Params
-//  - e2eID -  REQUIRED. The tracked e2e object ID. This is returned by [E2e.GetID].
-//  - follower - REQUIRED. Network follower function. This will check if the network
-//    follower is running.
-//  - username - SEMI-REQUIRED. The username the user wants to register with UD.
-//    If the user is already registered, this field may be blank. If the user is not
-//    already registered, these field must be populated with a username that meets the
-//    requirements of the UD service. For example, in the xx network's UD service,
-//    the username must not be registered by another user.
-//  - registrationValidationSignature - SEMI-REQUIRED. A signature provided by the xx network
-//    (i.e. the client registrar). If the user is not already registered, this field is required
-//    in order to register with the xx network. This may be nil if the user is already registered
-//    or connecting to a third-party UD service unassociated with the xx network.
-//  - cert - REQUIRED. The TLS certificate for the UD server this call will connect with.
-//    If this is nil, you may not contact the UD server hosted by the xx network.
-//    Third-party services may vary.
-//    You may use the UD server run by the xx network team by using [E2e.GetUdCertFromNdf].
-//  - contactFile - REQUIRED. The data within a marshalled [contact.Contact]. This represents the
-//    contact file of the server this call will connect with.
-//    If this is nil, you may not contact the UD server hosted by the xx network.
-//    Third-party services may vary.
-//    You may use the UD server run by the xx network team by using [E2e.GetUdContactFromNdf].
-//  - address - REQUIRED. The IP address of the UD server this call will connect with.
-//    You may use the UD server run by the xx network team by using [E2e.GetUdAddressFromNdf].
-//    If this is nil, you may not contact the UD server hosted by the xx network.
-//    Third-party services may vary.
+//   - e2eID -  REQUIRED. The tracked e2e object ID. This is returned by [E2e.GetID].
+//   - follower - REQUIRED. Network follower function. This will check if the network
+//     follower is running.
+//   - username - SEMI-REQUIRED. The username the user wants to register with UD.
+//     If the user is already registered, this field may be blank. If the user is not
+//     already registered, these field must be populated with a username that meets the
+//     requirements of the UD service. For example, in the xx network's UD service,
+//     the username must not be registered by another user.
+//   - registrationValidationSignature - SEMI-REQUIRED. A signature provided by the xx network
+//     (i.e. the client registrar). If the user is not already registered, this field is required
+//     in order to register with the xx network. This may be nil if the user is already registered
+//     or connecting to a third-party UD service unassociated with the xx network.
+//   - cert - REQUIRED. The TLS certificate for the UD server this call will connect with.
+//     If this is nil, you may not contact the UD server hosted by the xx network.
+//     Third-party services may vary.
+//     You may use the UD server run by the xx network team by using [E2e.GetUdCertFromNdf].
+//   - contactFile - REQUIRED. The data within a marshalled [contact.Contact]. This represents the
+//     contact file of the server this call will connect with.
+//     If this is nil, you may not contact the UD server hosted by the xx network.
+//     Third-party services may vary.
+//     You may use the UD server run by the xx network team by using [E2e.GetUdContactFromNdf].
+//   - address - REQUIRED. The IP address of the UD server this call will connect with.
+//     You may use the UD server run by the xx network team by using [E2e.GetUdAddressFromNdf].
+//     If this is nil, you may not contact the UD server hosted by the xx network.
+//     Third-party services may vary.
 //
 // Returns
-//  - A Manager object which is registered to the specified UD service.
+//   - A Manager object which is registered to the specified UD service.
 func NewOrLoadUd(e2eID int, follower UdNetworkStatus, username string,
 	registrationValidationSignature, cert, contactFile []byte, address string) (
 	*UserDiscovery, error) {
@@ -207,18 +207,18 @@ func NewOrLoadUd(e2eID int, follower UdNetworkStatus, username string,
 // already been restored via the call NewCmixFromBackup.
 //
 // Parameters:
-//  - e2eID - e2e object ID in the tracker
-//  - follower - network follower func wrapped in UdNetworkStatus
-//  - cert - the TLS certificate for the UD server this call will connect with.
-//    You may use the UD server run by the xx network team by using
-//    [E2e.GetUdCertFromNdf].
-//  - contactFile - the data within a marshalled [contact.Contact]. This
-//    represents the contact file of the server this call will connect with. You
-//    may use the UD server run by the xx network team by using
-//    [E2e.GetUdContactFromNdf].
-//  - address - the IP address of the UD server this call will connect with. You
-//    may use the UD server run by the xx network team by using
-//    [E2e.GetUdAddressFromNdf].
+//   - e2eID - e2e object ID in the tracker
+//   - follower - network follower func wrapped in UdNetworkStatus
+//   - cert - the TLS certificate for the UD server this call will connect with.
+//     You may use the UD server run by the xx network team by using
+//     [E2e.GetUdCertFromNdf].
+//   - contactFile - the data within a marshalled [contact.Contact]. This
+//     represents the contact file of the server this call will connect with. You
+//     may use the UD server run by the xx network team by using
+//     [E2e.GetUdContactFromNdf].
+//   - address - the IP address of the UD server this call will connect with. You
+//     may use the UD server run by the xx network team by using
+//     [E2e.GetUdAddressFromNdf].
 func NewUdManagerFromBackup(e2eID int, follower UdNetworkStatus,
 	cert, contactFile []byte, address string) (*UserDiscovery, error) {
 
@@ -274,7 +274,7 @@ func (ud *UserDiscovery) ConfirmFact(confirmationID, code string) error {
 // along with the code to finalize the fact.
 //
 // Parameters:
-//  - factJson - a JSON marshalled [fact.Fact]
+//   - factJson - a JSON marshalled [fact.Fact]
 func (ud *UserDiscovery) SendRegisterFact(factJson []byte) (string, error) {
 	var f fact.Fact
 	err := json.Unmarshal(factJson, &f)
@@ -290,7 +290,7 @@ func (ud *UserDiscovery) SendRegisterFact(factJson []byte) (string, error) {
 // be associated with this user.
 //
 // Parameters:
-//  - factJson - a JSON marshalled [fact.Fact]
+//   - factJson - a JSON marshalled [fact.Fact]
 func (ud *UserDiscovery) PermanentDeleteAccount(factJson []byte) error {
 	var f fact.Fact
 	err := json.Unmarshal(factJson, &f)
@@ -305,7 +305,7 @@ func (ud *UserDiscovery) PermanentDeleteAccount(factJson []byte) error {
 // passed in is not UD service does not associate this fact with this user.
 //
 // Parameters:
-//  - factJson - a JSON marshalled [fact.Fact]
+//   - factJson - a JSON marshalled [fact.Fact]
 func (ud *UserDiscovery) RemoveFact(factJson []byte) error {
 	var f fact.Fact
 	err := json.Unmarshal(factJson, &f)
@@ -324,9 +324,9 @@ func (ud *UserDiscovery) RemoveFact(factJson []byte) error {
 // contact that matches the passed in ID.
 //
 // Parameters:
-//  - contactBytes - the marshalled bytes of contact.Contact returned from the
-//    lookup, or nil if an error occurs
-//  - err - any errors that occurred in the lookup
+//   - contactBytes - the marshalled bytes of contact.Contact returned from the
+//     lookup, or nil if an error occurs
+//   - err - any errors that occurred in the lookup
 type UdLookupCallback interface {
 	Callback(contactBytes []byte, err error)
 }
@@ -335,16 +335,16 @@ type UdLookupCallback interface {
 // discovery system or returns by the timeout.
 //
 // Parameters:
-//  - e2eID - e2e object ID in the tracker
-//  - udContact - the marshalled bytes of the contact.Contact object
-//  - lookupId - the marshalled bytes of the id.ID object for the user that
-//    LookupUD will look up.
-//  - singleRequestParams - the JSON marshalled bytes of single.RequestParams
+//   - e2eID - e2e object ID in the tracker
+//   - udContact - the marshalled bytes of the contact.Contact object
+//   - lookupId - the marshalled bytes of the id.ID object for the user that
+//     LookupUD will look up.
+//   - singleRequestParams - the JSON marshalled bytes of single.RequestParams
 //
 // Returns:
-//  - []byte - the JSON marshalled bytes of the SingleUseSendReport object,
-//    which can be passed into Cmix.WaitForRoundResult to see if the send
-//    succeeded.
+//   - []byte - the JSON marshalled bytes of the SingleUseSendReport object,
+//     which can be passed into Cmix.WaitForRoundResult to see if the send
+//     succeeded.
 func LookupUD(e2eID int, udContact []byte, cb UdLookupCallback,
 	lookupId []byte, singleRequestParamsJSON []byte) ([]byte, error) {
 
@@ -397,17 +397,20 @@ func LookupUD(e2eID int, udContact []byte, cb UdLookupCallback,
 // contacts which match the passed in IDs.
 //
 // Parameters:
-//  - contactListJSON - the JSON marshalled bytes of []contact.Contact, or nil
-//    if an error occurs.
 //
-//   JSON Example:
-//   {
-//  	"<xxc(2)F8dL9EC6gy+RMJuk3R+Au6eGExo02Wfio5cacjBcJRwDEgB7Ugdw/BAr6RkCABkWAFV1c2VybmFtZTA7c4LzV05sG+DMt+rFB0NIJg==xxc>",
-//  	"<xxc(2)eMhAi/pYkW5jCmvKE5ZaTglQb+fTo1D8NxVitr5CCFADEgB7Ugdw/BAr6RoCABkWAFV1c2VybmFtZTE7fElAa7z3IcrYrrkwNjMS2w==xxc>",
-//  	"<xxc(2)d7RJTu61Vy1lDThDMn8rYIiKSe1uXA/RCvvcIhq5Yg4DEgB7Ugdw/BAr6RsCABkWAFV1c2VybmFtZTI7N3XWrxIUpR29atpFMkcR6A==xxc>"
-//	}
-//  - failedIDs - JSON marshalled list of []*id.ID objects which failed lookup
-//  - err - any errors that occurred in the multilookup.
+//   - contactListJSON - the JSON marshalled bytes of []contact.Contact, or nil
+//     if an error occurs.
+//
+//     JSON Example:
+//     {
+//     "<xxc(2)F8dL9EC6gy+RMJuk3R+Au6eGExo02Wfio5cacjBcJRwDEgB7Ugdw/BAr6RkCABkWAFV1c2VybmFtZTA7c4LzV05sG+DMt+rFB0NIJg==xxc>",
+//     "<xxc(2)eMhAi/pYkW5jCmvKE5ZaTglQb+fTo1D8NxVitr5CCFADEgB7Ugdw/BAr6RoCABkWAFV1c2VybmFtZTE7fElAa7z3IcrYrrkwNjMS2w==xxc>",
+//     "<xxc(2)d7RJTu61Vy1lDThDMn8rYIiKSe1uXA/RCvvcIhq5Yg4DEgB7Ugdw/BAr6RsCABkWAFV1c2VybmFtZTI7N3XWrxIUpR29atpFMkcR6A==xxc>"
+//     }
+//
+//   - failedIDs - JSON marshalled list of []*id.ID objects which failed lookup
+//
+//   - err - any errors that occurred in the multilookup.
 type UdMultiLookupCallback interface {
 	Callback(contactListJSON []byte, failedIDs []byte, err error)
 }
@@ -422,16 +425,16 @@ type lookupResp struct {
 // user discovery system or returns by the timeout.
 //
 // Parameters:
-//  - e2eID - e2e object ID in the tracker
-//  - udContact - the marshalled bytes of the contact.Contact object
-//  - lookupIds - JSON marshalled list of []*id.ID object for the users that
-//    MultiLookupUD will look up.
-//  - singleRequestParams - the JSON marshalled bytes of single.RequestParams
+//   - e2eID - e2e object ID in the tracker
+//   - udContact - the marshalled bytes of the contact.Contact object
+//   - lookupIds - JSON marshalled list of []*id.ID object for the users that
+//     MultiLookupUD will look up.
+//   - singleRequestParams - the JSON marshalled bytes of single.RequestParams
 //
 // Returns:
-//  - []byte - the JSON marshalled bytes of the SingleUseSendReport object,
-//    which can be passed into Cmix.WaitForRoundResult to see if the send
-//    succeeded.
+//   - []byte - the JSON marshalled bytes of the SingleUseSendReport object,
+//     which can be passed into Cmix.WaitForRoundResult to see if the send
+//     succeeded.
 func MultiLookupUD(e2eID int, udContact []byte, cb UdMultiLookupCallback,
 	lookupIds []byte, singleRequestParamsJSON []byte) error {
 
@@ -526,16 +529,18 @@ func MultiLookupUD(e2eID int, udContact []byte, cb UdMultiLookupCallback,
 // SearchUD.
 //
 // Parameters:
-//  - contactListJSON - the JSON marshalled bytes of []contact.Contact, or nil
-//    if an error occurs.
 //
-//   JSON Example:
-//   {
-//  	"<xxc(2)F8dL9EC6gy+RMJuk3R+Au6eGExo02Wfio5cacjBcJRwDEgB7Ugdw/BAr6RkCABkWAFV1c2VybmFtZTA7c4LzV05sG+DMt+rFB0NIJg==xxc>",
-//  	"<xxc(2)eMhAi/pYkW5jCmvKE5ZaTglQb+fTo1D8NxVitr5CCFADEgB7Ugdw/BAr6RoCABkWAFV1c2VybmFtZTE7fElAa7z3IcrYrrkwNjMS2w==xxc>",
-//  	"<xxc(2)d7RJTu61Vy1lDThDMn8rYIiKSe1uXA/RCvvcIhq5Yg4DEgB7Ugdw/BAr6RsCABkWAFV1c2VybmFtZTI7N3XWrxIUpR29atpFMkcR6A==xxc>"
-//	}
-//  - err - any errors that occurred in the search.
+//   - contactListJSON - the JSON marshalled bytes of []contact.Contact, or nil
+//     if an error occurs.
+//
+//     JSON Example:
+//     {
+//     "<xxc(2)F8dL9EC6gy+RMJuk3R+Au6eGExo02Wfio5cacjBcJRwDEgB7Ugdw/BAr6RkCABkWAFV1c2VybmFtZTA7c4LzV05sG+DMt+rFB0NIJg==xxc>",
+//     "<xxc(2)eMhAi/pYkW5jCmvKE5ZaTglQb+fTo1D8NxVitr5CCFADEgB7Ugdw/BAr6RoCABkWAFV1c2VybmFtZTE7fElAa7z3IcrYrrkwNjMS2w==xxc>",
+//     "<xxc(2)d7RJTu61Vy1lDThDMn8rYIiKSe1uXA/RCvvcIhq5Yg4DEgB7Ugdw/BAr6RsCABkWAFV1c2VybmFtZTI7N3XWrxIUpR29atpFMkcR6A==xxc>"
+//     }
+//
+//   - err - any errors that occurred in the search.
 type UdSearchCallback interface {
 	Callback(contactListJSON []byte, err error)
 }
@@ -547,16 +552,16 @@ type UdSearchCallback interface {
 // where multiple pieces of information is known.
 //
 // Parameters:
-//  - e2eID - e2e object ID in the tracker
-//  - udContact - the marshalled bytes of the contact.Contact for the user
-//    discovery server
-//  - factListJSON - the JSON marshalled bytes of [fact.FactList]
-//  - singleRequestParams - the JSON marshalled bytes of single.RequestParams
+//   - e2eID - e2e object ID in the tracker
+//   - udContact - the marshalled bytes of the contact.Contact for the user
+//     discovery server
+//   - factListJSON - the JSON marshalled bytes of [fact.FactList]
+//   - singleRequestParams - the JSON marshalled bytes of single.RequestParams
 //
 // Returns:
-//  - []byte - the JSON marshalled bytes of the SingleUseSendReport object,
-//    which can be passed into Cmix.WaitForRoundResult to see if the send
-//    operation succeeded.
+//   - []byte - the JSON marshalled bytes of the SingleUseSendReport object,
+//     which can be passed into Cmix.WaitForRoundResult to see if the send
+//     operation succeeded.
 func SearchUD(e2eID int, udContact []byte, cb UdSearchCallback,
 	factListJSON, singleRequestParamsJSON []byte) ([]byte, error) {
 
diff --git a/channels/actionSaver.go b/channels/actionSaver.go
index 4cb2258db37eb6eb99c10b789f557f9b6fca940e..35ff85ca24c03a85fff8050b68c95813a58d00f1 100644
--- a/channels/actionSaver.go
+++ b/channels/actionSaver.go
@@ -17,8 +17,8 @@ import (
 	jww "github.com/spf13/jwalterweatherman"
 
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/message"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/channels/actionSaver_test.go b/channels/actionSaver_test.go
index 366f712fa17cc887c72c805e3d2363c476829e96..cbf10fa93ce1da83b45bc3dce713f0e54614593f 100644
--- a/channels/actionSaver_test.go
+++ b/channels/actionSaver_test.go
@@ -19,7 +19,7 @@ import (
 	"time"
 
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/message"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/channels/commandStore.go b/channels/commandStore.go
index 08883a424e7bf5d536c70a4e75cf5d33ae0d1310..44b699ef9cfd62fc27f28b1b3ec645c5329f22d1 100644
--- a/channels/commandStore.go
+++ b/channels/commandStore.go
@@ -13,7 +13,7 @@ import (
 	"encoding/json"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/hash"
 	"gitlab.com/elixxir/crypto/message"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/channels/commandStore_test.go b/channels/commandStore_test.go
index 4c5ff8664e7dd7a5067dfa664786151b419fe3aa..edb15ddb782cd5c581c672a474d19524924da327 100644
--- a/channels/commandStore_test.go
+++ b/channels/commandStore_test.go
@@ -11,7 +11,7 @@ import (
 	"encoding/json"
 	"github.com/stretchr/testify/require"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/crypto/message"
 	"gitlab.com/elixxir/ekv"
diff --git a/channels/eventModel.go b/channels/eventModel.go
index 5daa2433af043d3999342233101c328d2ab5d914..4e86e9ca8bbc040164f17b892d3c936333273b74 100644
--- a/channels/eventModel.go
+++ b/channels/eventModel.go
@@ -21,8 +21,8 @@ import (
 
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/emoji"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/message"
diff --git a/channels/eventModel_test.go b/channels/eventModel_test.go
index 9a184d0bbba5b6dc884712d3280be95dd4be2b86..6df51995f58088ab4efab91444700a989a62e908 100644
--- a/channels/eventModel_test.go
+++ b/channels/eventModel_test.go
@@ -20,7 +20,7 @@ import (
 	"github.com/golang/protobuf/proto"
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast"
 	cryptoChannel "gitlab.com/elixxir/crypto/channel"
 	"gitlab.com/elixxir/crypto/fastRNG"
diff --git a/channels/identityStore.go b/channels/identityStore.go
index 5a5decb68102fe319a53e19c2730ba8e4fae7810..cac1b0df73740770edc257855244c4d19250a568 100644
--- a/channels/identityStore.go
+++ b/channels/identityStore.go
@@ -1,7 +1,7 @@
 package channels
 
 import (
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	cryptoChannel "gitlab.com/elixxir/crypto/channel"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/channels/identityStore_test.go b/channels/identityStore_test.go
index 9f5b87f382f4680241e96a20a67809045a4fc233..00bdd2757ab5cd2b2cfb11da6f64d346e74b7952 100644
--- a/channels/identityStore_test.go
+++ b/channels/identityStore_test.go
@@ -9,7 +9,7 @@ package channels
 
 import (
 	"bytes"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	cryptoChannel "gitlab.com/elixxir/crypto/channel"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/crypto/csprng"
diff --git a/channels/joinedChannel.go b/channels/joinedChannel.go
index 0707d3cddb734c6d9cfe9e12ad81ee68b2d1c7ec..8b297cb18957f8af4a5aac648973d352983a19a7 100644
--- a/channels/joinedChannel.go
+++ b/channels/joinedChannel.go
@@ -12,7 +12,7 @@ import (
 	"encoding/json"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/broadcast"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast"
 	"gitlab.com/xx_network/primitives/id"
 	"time"
@@ -27,40 +27,19 @@ const (
 // for message reception.
 func (m *manager) loadChannels() {
 	m.mux.Lock()
-	defer m.mux.Unlock()
-	mapObj, err := m.remote.ListenOnRemoteMap(joinedChannelsMap, joinedChannelsMapVersion, m.mapUpdate)
+	m.channels = make(map[id.ID]*joinedChannel)
+	m.mux.Unlock()
+	err := m.remote.ListenOnRemoteMap(joinedChannelsMap, joinedChannelsMapVersion,
+		m.mapUpdate, false)
 
 	if err != nil {
 		jww.FATAL.Panicf("Failed to set up listener on remote for "+
 			"channels: %+v", err)
 	}
 
-	m.channels = make(map[id.ID]*joinedChannel)
-
-	for elementName, chObj := range mapObj {
-		channelID := &id.ID{}
-
-		if _, err = base64.StdEncoding.Decode(channelID[:], []byte(elementName)); err != nil {
-			jww.WARN.Printf("Failed to unmarshal channel ID in"+
-				"remote channel %s, skipping: %+v", elementName, err)
-			continue
-		}
-
-		if _, err := m.setUpJoinedChannel(chObj.Data); err != nil {
-			jww.WARN.Printf("Failed to set up channel %s, skipping: "+
-				"%+v", elementName, err)
-			continue
-		}
-	}
 }
 
-func (m *manager) mapUpdate(mapName string, edits map[string]versioned.ElementEdit) {
-	if mapName != joinedChannelsMap {
-		jww.ERROR.Printf("Got an update for the wrong map, "+
-			"expected: %s, got: %s", joinedChannelsMap, mapName)
-		return
-	}
-
+func (m *manager) mapUpdate(edits map[string]versioned.ElementEdit) {
 	m.mux.Lock()
 	defer m.mux.Unlock()
 
@@ -69,11 +48,14 @@ func (m *manager) mapUpdate(mapName string, edits map[string]versioned.ElementEd
 
 	for elementName, edit := range edits {
 		channelID := &id.ID{}
-		if err := channelID.UnmarshalJSON([]byte(elementName)); err != nil {
+		elementBytes, err := base64.StdEncoding.DecodeString(elementName)
+		if err != nil {
 			jww.WARN.Printf("Failed to unmarshal channel ID in"+
 				"remote channel %s, skipping: %+v", elementName, err)
 			continue
 		}
+		copy(channelID[:], elementBytes)
+
 		if edit.Operation == versioned.Deleted {
 			if err := m.removeChannelUnsafe(channelID); err != nil {
 				jww.WARN.Printf("Failed to remove "+
@@ -137,7 +119,11 @@ func (m *manager) addChannel(channel *cryptoBroadcast.Channel, dmEnabled bool) e
 		return err
 	}
 
-	return m.saveChannel(jc)
+	err = m.saveChannel(jc)
+	if err != nil {
+		return err
+	}
+	return m.notifications.addChannel(channel.ReceptionID)
 }
 
 func (m *manager) saveChannel(jc *joinedChannel) error {
@@ -184,7 +170,10 @@ func (m *manager) removeChannel(channelID *id.ID) error {
 	m.mux.Lock()
 	defer m.mux.Unlock()
 
-	return m.removeChannelUnsafe(channelID)
+	if err := m.removeChannelUnsafe(channelID); err != nil {
+		return err
+	}
+	return m.notifications.removeChannel(channelID)
 }
 
 func (m *manager) removeChannelUnsafe(channelID *id.ID) error {
diff --git a/channels/joinedChannel_test.go b/channels/joinedChannel_test.go
index d3004b233a78e46bceb22f90ccb9c2159a72b4a1..de3a4e7a15f205d3bd50b1a0a38514caf3f35f33 100644
--- a/channels/joinedChannel_test.go
+++ b/channels/joinedChannel_test.go
@@ -133,12 +133,14 @@ func Test_manager_loadChannels(t *testing.T) {
 	}
 
 	newManager := &manager{
-		channels:       make(map[id.ID]*joinedChannel),
-		local:          m.local,
-		remote:         m.remote,
-		net:            m.net,
-		rng:            m.rng,
-		events:         &events{broadcast: newProcessorList()},
+		channels: make(map[id.ID]*joinedChannel),
+		local:    m.local,
+		remote:   m.remote,
+		net:      m.net,
+		rng:      m.rng,
+		events: &events{broadcast: newProcessorList(),
+			model: &mockEventModel{},
+		},
 		broadcastMaker: m.broadcastMaker,
 	}
 
diff --git a/channels/lease.go b/channels/lease.go
index a6487e049cfa44091100f1962e8e6baab3855bc8..e9e41c14102e0f2f5825e0cadd4e894201a9a970 100644
--- a/channels/lease.go
+++ b/channels/lease.go
@@ -16,8 +16,8 @@ import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/hash"
 	"gitlab.com/elixxir/crypto/message"
diff --git a/channels/lease_test.go b/channels/lease_test.go
index cc38c56bb0c6b6bde9f931c2d63246fbc86b445c..bd6fc4171c006ddaca5d942a7495b2df53542b70 100644
--- a/channels/lease_test.go
+++ b/channels/lease_test.go
@@ -22,8 +22,8 @@ import (
 	"time"
 
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/message"
 	"gitlab.com/elixxir/ekv"
diff --git a/channels/manager.go b/channels/manager.go
index f40d1f6cbc36cc44e2c2f5312355fe95eb63dec1..bc07f444ad1180e622d9b74d41c71d65d3da91f5 100644
--- a/channels/manager.go
+++ b/channels/manager.go
@@ -25,8 +25,8 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix"
 	"gitlab.com/elixxir/client/v4/cmix/message"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	clientNotif "gitlab.com/elixxir/client/v4/notifications"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast"
 	cryptoChannel "gitlab.com/elixxir/crypto/channel"
 	"gitlab.com/elixxir/crypto/fastRNG"
diff --git a/channels/mutedUsers.go b/channels/mutedUsers.go
index 1572489034cc7cecbe49dbf85895cad4612f1997..0b7763730a3833853a1b0027ff4a0661000edc00 100644
--- a/channels/mutedUsers.go
+++ b/channels/mutedUsers.go
@@ -14,7 +14,7 @@ import (
 	"encoding/json"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
 	"sync"
diff --git a/channels/mutedUsers_test.go b/channels/mutedUsers_test.go
index b0876d8a80154727e182b370ac1da3665496fac8..bfc411e41cdc91c363aff36f1ff301aae216e156 100644
--- a/channels/mutedUsers_test.go
+++ b/channels/mutedUsers_test.go
@@ -11,7 +11,7 @@ import (
 	"bytes"
 	"crypto/ed25519"
 	"fmt"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
 	"io"
diff --git a/channels/nickname.go b/channels/nickname.go
index f46c2f2f9b86f9f81ae77e979973d3883ce26dec..33dad6ef6b7b4c2e85682a18a5030703aa738a94 100644
--- a/channels/nickname.go
+++ b/channels/nickname.go
@@ -5,7 +5,7 @@ import (
 	"encoding/json"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
 	"sync"
@@ -43,18 +43,12 @@ func loadOrNewNicknameManager(remote versioned.KV, callback func(channelId *id.I
 		callback:  callback,
 	}
 
-	nm.mux.Lock()
-	loadedMap, err := nm.remote.ListenOnRemoteMap(nicknameMapName, nicknameMapVersion,
-		nm.mapUpdate)
+	err = nm.remote.ListenOnRemoteMap(nicknameMapName, nicknameMapVersion,
+		nm.mapUpdate, false)
 	if err != nil && nm.remote.Exists(err) {
 		jww.FATAL.Panicf("[CH] Failed to load and listen to remote "+
 			"updates on nicknameManager: %+v", err)
 	}
-	err = nm.load(loadedMap)
-	if err != nil {
-		jww.FATAL.Panicf("[CH] Failed to load nicknameManager: %+v", err)
-	}
-	nm.mux.Unlock()
 
 	return nm
 }
@@ -142,15 +136,7 @@ func (nc *nicknameUpdates) AddCreatedOrEdit(nickname string, chanId id.ID) {
 
 // mapUpdate handles map updates, handles by versioned.KV's ListenOnRemoteMap
 // method.
-func (nm *nicknameManager) mapUpdate(
-	mapName string, edits map[string]versioned.ElementEdit) {
-
-	// Ensure the user is attempting to modify the correct map
-	if mapName != nicknameMapName {
-		jww.ERROR.Printf("Got an update for the wrong map, "+
-			"expected: %s, got: %s", nicknameMapName, mapName)
-		return
-	}
+func (nm *nicknameManager) mapUpdate(edits map[string]versioned.ElementEdit) {
 
 	nm.mux.Lock()
 	defer nm.mux.Unlock()
@@ -183,7 +169,9 @@ func (nm *nicknameManager) mapUpdate(
 			continue
 		}
 
-		if edit.Operation == versioned.Created || edit.Operation == versioned.Updated {
+		if edit.Operation == versioned.Created ||
+			edit.Operation == versioned.Updated ||
+			edit.Operation == versioned.Loaded {
 			updates.AddCreatedOrEdit(newUpdate, *chanId)
 		} else {
 			jww.WARN.Printf("Failed to handle nickname update %s, "+
@@ -216,28 +204,6 @@ func (nm *nicknameManager) upsertNicknameUnsafeRAM(cID *id.ID, nickname string)
 	nm.byChannel[*cID] = nickname
 }
 
-// load restores the nickname manager from disk.
-func (nm *nicknameManager) load(loadedMap map[string]*versioned.Object) error {
-
-	for elementName, obj := range loadedMap {
-		chanId, err := unmarshalChID(elementName)
-		if err != nil {
-			jww.WARN.Printf("Failed to unmarshal id in nickname "+
-				"in load of %s, skipping: %+v", elementName, err)
-			continue
-		}
-		var nickname string
-		if err := json.Unmarshal(obj.Data, &nickname); err != nil {
-			jww.WARN.Printf("Failed to unmarshal nickname "+
-				"for %s, skipping: %+v", elementName, err)
-			continue
-		}
-		nm.upsertNicknameUnsafeRAM(chanId, nickname)
-	}
-
-	return nil
-}
-
 // deleteNicknameUnsafe will remote the nickname into the remote local and into the
 // memoized map.
 func (nm *nicknameManager) deleteNicknameUnsafe(channelID *id.ID) error {
diff --git a/channels/nickname_test.go b/channels/nickname_test.go
index 56ebce9f1bfdf357d22025f4d33791f86c0abcd0..5ace4749edee3c3448afbfb991c7f0ac915d06a2 100644
--- a/channels/nickname_test.go
+++ b/channels/nickname_test.go
@@ -10,7 +10,7 @@ import (
 	"time"
 
 	"gitlab.com/elixxir/client/v4/collective"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
 )
@@ -206,7 +206,7 @@ func TestNicknameManager_mapUpdate(t *testing.T) {
 
 	nm.callback = testingCB
 
-	nm.mapUpdate(nicknameMapName, edits)
+	nm.mapUpdate(edits)
 
 	wg.Wait()
 
diff --git a/channels/privateKey.go b/channels/privateKey.go
index f93ecb3644b60b14736d6f01c476eb30bdee27dc..42e3ec84f628936dbc797432d060e4eb0de73b1e 100644
--- a/channels/privateKey.go
+++ b/channels/privateKey.go
@@ -11,7 +11,7 @@ import (
 	"bytes"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast"
 	"gitlab.com/elixxir/crypto/rsa"
 	"gitlab.com/xx_network/primitives/id"
@@ -165,8 +165,8 @@ func newAdminKeysManager(
 
 	adminMan := &adminKeysManager{remote: kvRemote, callback: cb}
 
-	_, err = adminMan.remote.ListenOnRemoteMap(
-		adminKeysMapName, adminKeysMapVersion, adminMan.mapUpdate)
+	err = adminMan.remote.ListenOnRemoteMap(
+		adminKeysMapName, adminKeysMapVersion, adminMan.mapUpdate, false)
 	if err != nil && adminMan.remote.Exists(err) {
 		jww.FATAL.Panicf("[CH] Failed to load and listen to remote "+
 			"updates on adminKeysManager: %+v", err)
@@ -230,15 +230,7 @@ func (akm *adminKeysManager) deleteChannelPrivateKey(
 
 // mapUpdate handles map updates, handles by versioned.KV's ListenOnRemoteMap
 // method.
-func (akm *adminKeysManager) mapUpdate(
-	mapName string, edits map[string]versioned.ElementEdit) {
-
-	if mapName != adminKeysMapName {
-		jww.ERROR.Printf("Got an update for the wrong map, "+
-			"expected: %s, got: %s", adminKeysMapName, mapName)
-		return
-	}
-
+func (akm *adminKeysManager) mapUpdate(edits map[string]versioned.ElementEdit) {
 	akm.mux.Lock()
 	defer akm.mux.Unlock()
 
@@ -255,7 +247,8 @@ func (akm *adminKeysManager) mapUpdate(
 		if edit.Operation == versioned.Deleted {
 			akm.callback(chanId, false)
 		} else if edit.Operation == versioned.Created ||
-			edit.Operation == versioned.Updated {
+			edit.Operation == versioned.Updated ||
+			edit.Operation == versioned.Loaded {
 			akm.callback(chanId, true)
 		} else {
 			jww.WARN.Printf("Failed to handle admin key update %s, "+
diff --git a/channels/privateKey_test.go b/channels/privateKey_test.go
index bbddfc50b5de5b6517b07659ed61244e2dda003f..89e899c1cd273046a49d37028ca46faeb4b119c5 100644
--- a/channels/privateKey_test.go
+++ b/channels/privateKey_test.go
@@ -11,7 +11,7 @@ import (
 	"github.com/stretchr/testify/require"
 	"gitlab.com/elixxir/client/v4/broadcast"
 	"gitlab.com/elixxir/client/v4/collective"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/rsa"
@@ -327,7 +327,7 @@ func Test_mapUpdate(t *testing.T) {
 
 	time.Sleep(1 * time.Second)
 
-	akm.mapUpdate(adminKeysMapName, edits)
+	akm.mapUpdate(edits)
 	wg.Wait()
 
 }
diff --git a/channels/replayBlocker.go b/channels/replayBlocker.go
index b44bd4f97f0fb33a31551806970d65617daab0d7..b4348b5f04e824fa76d2a17c825d729de19ef5a4 100644
--- a/channels/replayBlocker.go
+++ b/channels/replayBlocker.go
@@ -14,7 +14,7 @@ import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/message"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/channels/replayBlocker_test.go b/channels/replayBlocker_test.go
index c7d66d9a5635bb0a25d633fc07d7627fbcfce825..772658ae06b9093a52a6fe3de1e325e49195c561 100644
--- a/channels/replayBlocker_test.go
+++ b/channels/replayBlocker_test.go
@@ -14,7 +14,7 @@ import (
 	"fmt"
 	"github.com/stretchr/testify/require"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/message"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/channels/sendTracker.go b/channels/sendTracker.go
index 4dde35598aac7c41ec79be45e453058f9adebc53..46610a27938c8f7154e3e32777a8d045f99ef3fe 100644
--- a/channels/sendTracker.go
+++ b/channels/sendTracker.go
@@ -17,7 +17,7 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix"
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/message"
 	"gitlab.com/elixxir/primitives/states"
diff --git a/channels/sendTracker_test.go b/channels/sendTracker_test.go
index ba583989cf5d98327ae36d2022cde918930148bf..08e0d05b8ac1f1db5e1f6d157c6f0edc969fac8a 100644
--- a/channels/sendTracker_test.go
+++ b/channels/sendTracker_test.go
@@ -8,7 +8,7 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/message"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	cryptoMessage "gitlab.com/elixxir/crypto/message"
 	"gitlab.com/elixxir/ekv"
diff --git a/channels/send_test.go b/channels/send_test.go
index 40be4379459ed394d7504e6fec7afda494595beb..c4ece7080d9a365f25314e458ba6a3a91da46d49 100644
--- a/channels/send_test.go
+++ b/channels/send_test.go
@@ -19,7 +19,7 @@ import (
 	"github.com/golang/protobuf/proto"
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	cryptoChannel "gitlab.com/elixxir/crypto/channel"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/message"
diff --git a/channelsFileTransfer/callbackTracker/callbackTracker.go b/channelsFileTransfer/callbackTracker/callbackTracker.go
index 218daa2d883644a3a3bbdcc5afdc655365b8cf79..a17e591999e85bb86c4f62210a85b71e2be2a4e9 100644
--- a/channelsFileTransfer/callbackTracker/callbackTracker.go
+++ b/channelsFileTransfer/callbackTracker/callbackTracker.go
@@ -89,7 +89,7 @@ func (ct *callbackTracker) call(err error) {
 				ct.scheduled = false
 				ct.mux.Unlock()
 			}
-			
+
 			timer := time.NewTimer(ct.period - timeSinceLastCall)
 			select {
 			case <-ct.stop.Quit():
diff --git a/channelsFileTransfer/manager.go b/channelsFileTransfer/manager.go
index 77c1ca62bf56213cb52cb4dca91b4e4f5046944c..9c21a5ee3c1d627ce35b201a7bb9dd8aa1f462b0 100644
--- a/channelsFileTransfer/manager.go
+++ b/channelsFileTransfer/manager.go
@@ -25,10 +25,10 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix/identity"
 	"gitlab.com/elixxir/client/v4/cmix/message"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e"
 	"gitlab.com/elixxir/client/v4/stoppable"
 	"gitlab.com/elixxir/client/v4/storage"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/client/v4/xxdk"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/fastRNG"
diff --git a/channelsFileTransfer/send.go b/channelsFileTransfer/send.go
index 35d4c56bd55ebe66bd679cfbc18c2208e98466dc..607e9e8c3a7ca07066d4fea2c11511dadb72eb58 100644
--- a/channelsFileTransfer/send.go
+++ b/channelsFileTransfer/send.go
@@ -315,7 +315,7 @@ func (m *manager) checkedReceivedParts(st *store.SentTransfer, fl *FileLink,
 			jww.DEBUG.Printf("[FT] Completed sending and receiving file %s.",
 				st.GetFileID())
 			if err = m.closeSend(st); err != nil {
-				jww.ERROR.Printf("[FT] Failed to close file transfer send %s: " +
+				jww.ERROR.Printf("[FT] Failed to close file transfer send %s: "+
 					"%+v", st.GetFileID(), err)
 			}
 			if _, err = m.receiveFromID(rt.GetFileID()); err != nil {
diff --git a/channelsFileTransfer/store/cypher/manager.go b/channelsFileTransfer/store/cypher/manager.go
index 1a52e290c42964af5d099445f296efacecaf233e..f7cd3b9bb47459ce8a96f9dd89ad8471a33cd6c6 100644
--- a/channelsFileTransfer/store/cypher/manager.go
+++ b/channelsFileTransfer/store/cypher/manager.go
@@ -10,8 +10,8 @@ package cypher
 import (
 	"github.com/pkg/errors"
 
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/channelsFileTransfer/store/cypher/manager_test.go b/channelsFileTransfer/store/cypher/manager_test.go
index 141ce675d99238df1ae0ed338189a4bb7b456606..33d0d70d10c44b33598dbcd5256ba08442f0e485 100644
--- a/channelsFileTransfer/store/cypher/manager_test.go
+++ b/channelsFileTransfer/store/cypher/manager_test.go
@@ -16,8 +16,8 @@ import (
 	"github.com/stretchr/testify/require"
 	"gitlab.com/xx_network/crypto/csprng"
 
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/elixxir/ekv"
 )
diff --git a/channelsFileTransfer/store/received.go b/channelsFileTransfer/store/received.go
index 31dacb7aa823bca299bf6dcb46ee3fa79fc9d7dd..a3e13a16a49d082e797637392ca86604a02f5857 100644
--- a/channelsFileTransfer/store/received.go
+++ b/channelsFileTransfer/store/received.go
@@ -14,7 +14,7 @@ import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/channelsFileTransfer/store/receivedTransfer.go b/channelsFileTransfer/store/receivedTransfer.go
index 1933e1630a35c6122732b4ec9dc097dcc9b3cf82..350b0805dd05083e874ce16d391e298d0f04f420 100644
--- a/channelsFileTransfer/store/receivedTransfer.go
+++ b/channelsFileTransfer/store/receivedTransfer.go
@@ -18,8 +18,8 @@ import (
 	jww "github.com/spf13/jwalterweatherman"
 
 	"gitlab.com/elixxir/client/v4/channelsFileTransfer/store/cypher"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/channelsFileTransfer/store/receivedTransfer_test.go b/channelsFileTransfer/store/receivedTransfer_test.go
index f5e231c65cb13429c6632dc6358c3e8e2b95ee79..de30dcb9e7a0b5296452cf1e7fa2565082876fe4 100644
--- a/channelsFileTransfer/store/receivedTransfer_test.go
+++ b/channelsFileTransfer/store/receivedTransfer_test.go
@@ -21,8 +21,8 @@ import (
 	"gitlab.com/xx_network/primitives/id"
 
 	"gitlab.com/elixxir/client/v4/channelsFileTransfer/store/cypher"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/elixxir/ekv"
 )
diff --git a/channelsFileTransfer/store/received_test.go b/channelsFileTransfer/store/received_test.go
index 498a427cbf2b7a702bc4baaba954ab101fe3c1e5..c80c1708a358b1d1dcd88e1ce9b81603cb6fa882 100644
--- a/channelsFileTransfer/store/received_test.go
+++ b/channelsFileTransfer/store/received_test.go
@@ -16,7 +16,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/require"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/crypto/csprng"
diff --git a/channelsFileTransfer/store/sent.go b/channelsFileTransfer/store/sent.go
index ed1fa78db6b8c23551177cce4929ece7b0cf0ae7..00f63263373c00aa6cc7803dd268f80afcc44b65 100644
--- a/channelsFileTransfer/store/sent.go
+++ b/channelsFileTransfer/store/sent.go
@@ -14,7 +14,7 @@ import (
 
 	"github.com/pkg/errors"
 
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/channelsFileTransfer/store/sentTransfer.go b/channelsFileTransfer/store/sentTransfer.go
index 7d1ae40bcc69df43f88b85cdfc6e959ebc4b1f41..6930ef302ee586e2a163689a9e599fbaa93ee712 100644
--- a/channelsFileTransfer/store/sentTransfer.go
+++ b/channelsFileTransfer/store/sentTransfer.go
@@ -18,8 +18,8 @@ import (
 	jww "github.com/spf13/jwalterweatherman"
 
 	"gitlab.com/elixxir/client/v4/channelsFileTransfer/store/cypher"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/channelsFileTransfer/store/sentTransfer_test.go b/channelsFileTransfer/store/sentTransfer_test.go
index c4957dc57c7711ae734fc9a165698972a0dae3cc..5f4a9c5a24b4050a1b39355d0e6362571546daf7 100644
--- a/channelsFileTransfer/store/sentTransfer_test.go
+++ b/channelsFileTransfer/store/sentTransfer_test.go
@@ -20,8 +20,8 @@ import (
 
 	"gitlab.com/elixxir/client/v4/channelsFileTransfer/store/cypher"
 	"gitlab.com/elixxir/client/v4/channelsFileTransfer/store/fileMessage"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/elixxir/primitives/format"
diff --git a/channelsFileTransfer/store/sent_test.go b/channelsFileTransfer/store/sent_test.go
index 9140b27cb8e25e8f58c7ff91630a74d8dbaa3eeb..e953a0d44813ba4921a749cb76804bcdb1063f52 100644
--- a/channelsFileTransfer/store/sent_test.go
+++ b/channelsFileTransfer/store/sent_test.go
@@ -17,7 +17,7 @@ import (
 	"time"
 
 	"github.com/stretchr/testify/require"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/crypto/csprng"
diff --git a/channelsFileTransfer/store/transferStatus_test.go b/channelsFileTransfer/store/transferStatus_test.go
index 8924b0d1a188b58e9071da7fa441479a58f89948..0666e2ace619d05218f4f00a24b62c3af02cfda7 100644
--- a/channelsFileTransfer/store/transferStatus_test.go
+++ b/channelsFileTransfer/store/transferStatus_test.go
@@ -27,4 +27,4 @@ func Test_TransferStatus_String(t *testing.T) {
 				"\nexpected: %s\nreceived: %s", expected, status.String())
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/channelsFileTransfer/utils_test.go b/channelsFileTransfer/utils_test.go
index ef5aa5be583efb5f50e86419197ff0e863707134..02b1addd43ec39294e64c48b4815cc6e9677c8e5 100644
--- a/channelsFileTransfer/utils_test.go
+++ b/channelsFileTransfer/utils_test.go
@@ -11,13 +11,14 @@ import (
 	"bytes"
 	"crypto/ed25519"
 	"encoding/binary"
-	clientNotif "gitlab.com/elixxir/client/v4/notifications"
 	"io"
 	"math/rand"
 	"sync"
 	"testing"
 	"time"
 
+	clientNotif "gitlab.com/elixxir/client/v4/notifications"
+
 	jww "github.com/spf13/jwalterweatherman"
 
 	"gitlab.com/elixxir/client/v4/channels"
@@ -27,11 +28,11 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/message"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e"
 	"gitlab.com/elixxir/client/v4/stoppable"
 	"gitlab.com/elixxir/client/v4/storage"
 	userStorage "gitlab.com/elixxir/client/v4/storage/user"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/client/v4/xxdk"
 	"gitlab.com/elixxir/comms/network"
 	cryptoBroadcast "gitlab.com/elixxir/crypto/broadcast"
@@ -371,7 +372,7 @@ func (m *mockStorage) GetE2EGroup() *cyclic.Group            { panic("implement
 func (m *mockStorage) ForwardRegistrationStatus(storage.RegistrationStatus) error {
 	panic("implement me")
 }
-func (m *mockStorage) GetRegistrationStatus() storage.RegistrationStatus      { panic("implement me") }
+func (m *mockStorage) RegStatus() storage.RegistrationStatus                  { panic("implement me") }
 func (m *mockStorage) SetRegCode(string)                                      { panic("implement me") }
 func (m *mockStorage) GetRegCode() (string, error)                            { panic("implement me") }
 func (m *mockStorage) SetNDF(*ndf.NetworkDefinition)                          { panic("implement me") }
diff --git a/cmd/channelsFileTransfer.go b/cmd/channelsFileTransfer.go
index e0aa0557d4579d1ba348946175f0940c80ad1054..bf5ad4811d0b9b757f0f3e28a19a5782a485163c 100644
--- a/cmd/channelsFileTransfer.go
+++ b/cmd/channelsFileTransfer.go
@@ -98,7 +98,6 @@ var channelsFileTransferCmd = &cobra.Command{
 				"[FT] Failed to create new file transfer manager: %+v", err)
 		}
 
-
 		// Construct channels manager
 		cbs := &channelCbs{}
 		em.eventModel.api, err = channels.NewManager(chanID,
diff --git a/cmd/dm.go b/cmd/dm.go
index 602fe1df4e0aa172d83a80b3818d847d6f580e04..bdde8de9b23cc6866730c576d935b5a32bbefab7 100644
--- a/cmd/dm.go
+++ b/cmd/dm.go
@@ -19,8 +19,8 @@ import (
 
 	"gitlab.com/elixxir/client/v4/cmix"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/dm"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/codename"
 	"gitlab.com/elixxir/crypto/message"
 	"gitlab.com/elixxir/crypto/nike/ecdh"
diff --git a/cmd/sync.go b/cmd/sync.go
new file mode 100644
index 0000000000000000000000000000000000000000..afd1b6e51b93e489d43bbefe47079dff96653b36
--- /dev/null
+++ b/cmd/sync.go
@@ -0,0 +1,158 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright © 2022 xx foundation                                             //
+//                                                                            //
+// Use of this source code is governed by a license that can be found in the  //
+// LICENSE file.                                                              //
+////////////////////////////////////////////////////////////////////////////////
+
+// The group subcommand allows creation and sending messages to groups
+
+package cmd
+
+import (
+	"encoding/json"
+	"strings"
+	"time"
+
+	"gitlab.com/elixxir/client/v4/collective"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
+	"gitlab.com/elixxir/client/v4/stoppable"
+	"gitlab.com/elixxir/crypto/fastRNG"
+	"gitlab.com/elixxir/ekv"
+	"gitlab.com/xx_network/crypto/csprng"
+
+	"github.com/spf13/cobra"
+	jww "github.com/spf13/jwalterweatherman"
+	"github.com/spf13/viper"
+)
+
+// Sync Specific command line options
+const (
+	syncKey        = "key"
+	syncVal        = "value"
+	syncRemotePath = "remote"
+)
+
+var syncCmd = &cobra.Command{
+	Use:   "sync",
+	Short: "Driver for collective library, uses local fs for remote",
+	Args:  cobra.NoArgs,
+	Run: func(cmd *cobra.Command, args []string) {
+		initLog(viper.GetUint(logLevelFlag), viper.GetString(logFlag))
+		rngGen := fastRNG.NewStreamGenerator(10, 5, csprng.NewSystemRNG)
+
+		secret := parsePassword(viper.GetString(passwordFlag))
+		remotePath := viper.GetString(syncRemotePath)
+		localPath := viper.GetString(sessionFlag)
+		waitTime := time.Duration(time.Duration(
+			viper.GetUint(waitTimeoutFlag)) * time.Second)
+		// Initialize the sync kv
+		fskv, err := ekv.NewFilestore(localPath, string(secret))
+		if err != nil {
+			jww.FATAL.Panicf("%+v", err)
+		}
+		synchronizedPrefixes := []string{"synchronized"}
+		remote := collective.NewFileSystemRemoteStorage(remotePath)
+		synckv, err := collective.SynchronizedKV(remotePath, secret,
+			remote, fskv, synchronizedPrefixes, rngGen)
+		if err != nil {
+			jww.FATAL.Panicf("%+v", err)
+		}
+
+		key := viper.GetString(syncKey)
+		val := viper.GetString(syncVal)
+
+		// Set up the prefix by splitting on /
+		parts := strings.Split(key, "/")
+		jww.INFO.Printf("Parts: %v", parts)
+		var kv versioned.KV
+		kv = synckv
+		jww.INFO.Printf("Prefixing: %s", key)
+		for i := 0; i < len(parts)-1; i++ {
+			part := parts[i]
+			jww.INFO.Printf("Part: %s", part)
+			kv, err = kv.Prefix(part)
+			if err != nil {
+				jww.FATAL.Printf("prefix failure %s: %+v",
+					parts[i], err)
+			}
+			jww.INFO.Printf("Prefix Set: %s", kv.GetPrefix())
+		}
+		key = parts[len(parts)-1]
+
+		// Listen on the key
+		waitCh := make(chan bool)
+		cb := func(old, new *versioned.Object,
+			op versioned.KeyOperation) {
+			oldJSON, _ := json.Marshal(old)
+			newJSON, _ := json.Marshal(new)
+			jww.INFO.Printf("Update received for %s (%v): %s -> %s",
+				key, op, oldJSON, newJSON)
+			waitCh <- false
+		}
+		kv.ListenOnRemoteKey(parts[len(parts)-1], 0, cb, false)
+
+		// Begin synchronization
+		stopSync, err := synckv.StartProcesses()
+		if err != nil {
+			jww.FATAL.Panicf("%+v", err)
+		}
+
+		// Set the actual key if a value exists
+		if val != "" {
+			kv.Set(key, &versioned.Object{
+				Timestamp: time.Now(),
+				Version:   0,
+				Data:      []byte(val),
+			})
+			time.Sleep(6 * time.Second)
+		}
+		// Wait for updates or timeout
+		synched := synckv.WaitForRemote(waitTime)
+		if !synched {
+			jww.ERROR.Printf("synckv timed out waiting for remote")
+		}
+
+		if val == "" {
+			jww.INFO.Printf("no value, waiting for update")
+			select {
+			case <-time.After(waitTime):
+				jww.ERROR.Printf("did not get key update")
+			case <-waitCh:
+				jww.INFO.Printf("got key update")
+			}
+		}
+
+		endVal, err := kv.Get(key, 0)
+		if err != nil {
+			jww.INFO.Printf("end value error: %v", err)
+		} else {
+			evJSON, _ := json.Marshal(endVal)
+			jww.INFO.Printf("End Value for %s: %s",
+				key, evJSON)
+			jww.INFO.Printf("Data Decoded: %s",
+				string(endVal.Data))
+		}
+		stopSync.Close()
+		err = stoppable.WaitForStopped(stopSync, 2*time.Second)
+		if err != nil {
+			jww.FATAL.Panicf("timed out waiting for sync stop: %+v",
+				err)
+		}
+	},
+}
+
+func init() {
+	flags := syncCmd.Flags()
+	flags.StringP(syncRemotePath, "r", "RemoteStore",
+		"Synthetic remote storage path, directory on disk")
+	viper.BindPFlag(syncRemotePath, flags.Lookup(syncRemotePath))
+
+	flags.StringP(syncKey, "k", "DefaultKey", "Key to set or get")
+	viper.BindPFlag(syncKey, flags.Lookup(syncKey))
+
+	flags.StringP(syncVal, "", "", "Set to value, otherwise get")
+	viper.BindPFlag(syncVal, flags.Lookup(syncVal))
+
+	rootCmd.AddCommand(syncCmd)
+}
diff --git a/cmix/check_test.go b/cmix/check_test.go
index 12b72bd146baa5b10fcec22fe802ac4fa891fbac..f7c5ea12ccf495eda74e27acdb779093dc457a5d 100644
--- a/cmix/check_test.go
+++ b/cmix/check_test.go
@@ -12,7 +12,7 @@ import (
 
 	bloom "gitlab.com/elixxir/bloomfilter"
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID/store"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/cmix/cmixMessageBuffer.go b/cmix/cmixMessageBuffer.go
index cd9d54af2191bea0d40dc0881f0b2be34bcaf235..86216a9c73981dbe966b6d646e5f1bbfe5626c44 100644
--- a/cmix/cmixMessageBuffer.go
+++ b/cmix/cmixMessageBuffer.go
@@ -13,8 +13,8 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/cmix/cmixMessageBuffer_test.go b/cmix/cmixMessageBuffer_test.go
index 985b9c5cdedaf732692f307177d0275a3e57d638..d6f227ef3652f29c0f7455816d50a1ee5a04e9cc 100644
--- a/cmix/cmixMessageBuffer_test.go
+++ b/cmix/cmixMessageBuffer_test.go
@@ -13,8 +13,8 @@ import (
 	"reflect"
 	"testing"
 
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/cmix/critical.go b/cmix/critical.go
index b40bf26a3e0f1a2ddb1308ed0ded885f93e6f299..c7a4d6c31c8530dcb9ea80ae5e6e53223fcc1b95 100644
--- a/cmix/critical.go
+++ b/cmix/critical.go
@@ -14,8 +14,8 @@ import (
 
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/cmix/health"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	ds "gitlab.com/elixxir/comms/network/dataStructures"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/elixxir/primitives/states"
diff --git a/cmix/critical_test.go b/cmix/critical_test.go
index e540e46756ef1b5f492ffd922e488e7e41f0e5cd..6bf67a3eb4765a13e2ef264eaa22b7b60fe05af2 100644
--- a/cmix/critical_test.go
+++ b/cmix/critical_test.go
@@ -11,8 +11,8 @@ import (
 	"testing"
 	"time"
 
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/cmix/gateway/certChecker.go b/cmix/gateway/certChecker.go
index 6d23c0b410d42df6051f763af8fa4727b5925407..53a69248edb1bb3300b2735575f0885a03271f32 100644
--- a/cmix/gateway/certChecker.go
+++ b/cmix/gateway/certChecker.go
@@ -16,7 +16,7 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/crypto/hash"
 	"gitlab.com/xx_network/comms/connect"
diff --git a/cmix/gateway/certChecker_test.go b/cmix/gateway/certChecker_test.go
index fe0e216688fa02dbe76bc48faba8d320c884efd3..d7c3d4b98c1560e37fd1ad8bddd2b01761c1fda6 100644
--- a/cmix/gateway/certChecker_test.go
+++ b/cmix/gateway/certChecker_test.go
@@ -11,7 +11,7 @@ import (
 	"bytes"
 	"testing"
 
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/comms/testkeys"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/cmix/gateway/hostPool.go b/cmix/gateway/hostPool.go
index 71fa1860e1e63ba777864af371f9118fac2ab391..11fbb11086a2ae7c2c9e9ce006db0e607e18d1e0 100644
--- a/cmix/gateway/hostPool.go
+++ b/cmix/gateway/hostPool.go
@@ -17,9 +17,9 @@ import (
 	"github.com/golang-collections/collections/set"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
 	"gitlab.com/elixxir/client/v4/storage"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	commNetwork "gitlab.com/elixxir/comms/network"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/xx_network/comms/connect"
diff --git a/cmix/gateway/storeHostList.go b/cmix/gateway/storeHostList.go
index 65d0e25b8ada0f846ddb69174b436a8570a58b33..10b9531e7e244aaa401c99af1ce3d6a8d9a03e0c 100644
--- a/cmix/gateway/storeHostList.go
+++ b/cmix/gateway/storeHostList.go
@@ -11,7 +11,7 @@ import (
 	"bytes"
 
 	"github.com/pkg/errors"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/cmix/identity/receptionID/identity.go b/cmix/identity/receptionID/identity.go
index 8af1cd318f910ca132b6a012bc9fd66f7da5e033..c3e75a49e4749288d521f4a4598ff902821337b7 100644
--- a/cmix/identity/receptionID/identity.go
+++ b/cmix/identity/receptionID/identity.go
@@ -16,7 +16,7 @@ import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/primitives/states"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/id/ephemeral"
diff --git a/cmix/identity/receptionID/identity_test.go b/cmix/identity/receptionID/identity_test.go
index 8822a89a73a7b2ba3e85e043bf0b6ee83506caea..522cea6c04bbcf7368380bdcf9a5b0cc855b40bf 100644
--- a/cmix/identity/receptionID/identity_test.go
+++ b/cmix/identity/receptionID/identity_test.go
@@ -8,7 +8,7 @@
 package receptionID
 
 import (
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/id/ephemeral"
diff --git a/cmix/identity/receptionID/registration.go b/cmix/identity/receptionID/registration.go
index 312d5221006a4c2a30bbd13c3b7196c6f6a22fb6..099953d5fc31dccb53979bbdc678885c6abd9566 100644
--- a/cmix/identity/receptionID/registration.go
+++ b/cmix/identity/receptionID/registration.go
@@ -11,7 +11,7 @@ import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID/store"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/id/ephemeral"
 
diff --git a/cmix/identity/receptionID/registration_test.go b/cmix/identity/receptionID/registration_test.go
index 5e5ae2e3b08bbe10ddc37d170a39149a5ad07f41..e8c7684d31e7de7655eca9aa8753e0663a476558 100644
--- a/cmix/identity/receptionID/registration_test.go
+++ b/cmix/identity/receptionID/registration_test.go
@@ -8,7 +8,7 @@
 package receptionID
 
 import (
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/netTime"
 	"math/rand"
diff --git a/cmix/identity/receptionID/store.go b/cmix/identity/receptionID/store.go
index eea99ab0f1617afe84ef733cde7cd03eabc2ca01..dabb1c1a1ba5c88f2d9988280932331f865c5275 100644
--- a/cmix/identity/receptionID/store.go
+++ b/cmix/identity/receptionID/store.go
@@ -11,7 +11,7 @@ import (
 	"encoding/json"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/crypto/large"
 	"gitlab.com/xx_network/crypto/shuffle"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/cmix/identity/receptionID/store/checkedRounds.go b/cmix/identity/receptionID/store/checkedRounds.go
index 3e6629b371782768e8061b8d3c69bafa2022cd17..43ce8dcfe464725ae62eb1fc686939945d8aac73 100644
--- a/cmix/identity/receptionID/store/checkedRounds.go
+++ b/cmix/identity/receptionID/store/checkedRounds.go
@@ -12,8 +12,8 @@ import (
 	"encoding/binary"
 
 	"github.com/pkg/errors"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/xx_network/primitives/id"
 )
 
diff --git a/cmix/identity/receptionID/store/checkedRounds_test.go b/cmix/identity/receptionID/store/checkedRounds_test.go
index 924b052441da26cbd95132a9be295df13d1df8c4..d5d96e763832c117f673c3d8203c0dadc9bba61d 100644
--- a/cmix/identity/receptionID/store/checkedRounds_test.go
+++ b/cmix/identity/receptionID/store/checkedRounds_test.go
@@ -10,8 +10,8 @@ package store
 import (
 	"container/list"
 	"encoding/binary"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
 	"reflect"
diff --git a/cmix/identity/receptionID/store/earliestRound.go b/cmix/identity/receptionID/store/earliestRound.go
index 5ad3bbee960176091382ed9c18eccf2d8195a17d..a1a4387c12e567bded0f2a37099469c506751a7a 100644
--- a/cmix/identity/receptionID/store/earliestRound.go
+++ b/cmix/identity/receptionID/store/earliestRound.go
@@ -12,7 +12,7 @@ import (
 	"sync"
 
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/cmix/identity/receptionID/store/unknownRounds.go b/cmix/identity/receptionID/store/unknownRounds.go
index f59ed9df49ac587c898f1e71917ec47806069ba5..e4d09a18a9e2f858d64343d078c60b66de161be5 100644
--- a/cmix/identity/receptionID/store/unknownRounds.go
+++ b/cmix/identity/receptionID/store/unknownRounds.go
@@ -14,7 +14,7 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/cmix/identity/receptionID/store/unknownRounds_test.go b/cmix/identity/receptionID/store/unknownRounds_test.go
index 6c45ab9bfe5f80bb943e27136707d714a2f2ef37..71704461d692cc6ab30e7ac79db4f5d3ee4e7089 100644
--- a/cmix/identity/receptionID/store/unknownRounds_test.go
+++ b/cmix/identity/receptionID/store/unknownRounds_test.go
@@ -11,7 +11,7 @@ import (
 	"bytes"
 	"encoding/json"
 	"github.com/stretchr/testify/require"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
 	"reflect"
diff --git a/cmix/identity/receptionID/store_test.go b/cmix/identity/receptionID/store_test.go
index 9c477d4c2161ec1527a124b35f7653ff7f7ba7b9..85d8976d8579700205675e359b756a7225312e89 100644
--- a/cmix/identity/receptionID/store_test.go
+++ b/cmix/identity/receptionID/store_test.go
@@ -12,7 +12,7 @@ import (
 	"encoding/binary"
 	"encoding/json"
 	"github.com/stretchr/testify/require"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/hash"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/cmix/identity/tracker.go b/cmix/identity/tracker.go
index 1552c66761c4b1df48bf8795c68e279a587af3cf..af2e8a55ce523863e34a28e5daa3691197a41f95 100644
--- a/cmix/identity/tracker.go
+++ b/cmix/identity/tracker.go
@@ -19,9 +19,9 @@ import (
 
 	"gitlab.com/elixxir/client/v4/cmix/address"
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
 	"gitlab.com/elixxir/client/v4/storage"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/id/ephemeral"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/cmix/message/handler.go b/cmix/message/handler.go
index c24ab79c71c7107b2d4bc73706856122c61b950d..f8ffb59277a95df35e2645f9d13eb5b2bc52b421 100644
--- a/cmix/message/handler.go
+++ b/cmix/message/handler.go
@@ -14,8 +14,8 @@ import (
 	"sync"
 	"time"
 
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/event"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/xx_network/primitives/id"
 
 	jww "github.com/spf13/jwalterweatherman"
diff --git a/cmix/message/handler_test.go b/cmix/message/handler_test.go
index 00650bfda945f3bef048a6d329379f995b910678..d6a303bf46170faf5d1da830edb1891902d5ab74 100644
--- a/cmix/message/handler_test.go
+++ b/cmix/message/handler_test.go
@@ -13,8 +13,8 @@ import (
 
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/event"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/crypto/sih"
 	"gitlab.com/elixxir/ekv"
diff --git a/cmix/message/inProgress_test.go b/cmix/message/inProgress_test.go
index 7a61d80efe9824876fc7446451560a25288666f8..bb7d6548b76d77c95a393e4b7621d38ba55b3f4e 100644
--- a/cmix/message/inProgress_test.go
+++ b/cmix/message/inProgress_test.go
@@ -10,8 +10,8 @@ package message
 import (
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/elixxir/primitives/format"
diff --git a/cmix/message/meteredCmixMessageBuffer.go b/cmix/message/meteredCmixMessageBuffer.go
index 2e72cd9d9ed2e6a1235236aeb0215bb0cca1c297..19ad728ff417806db31f5907669457aaaec7f8d4 100644
--- a/cmix/message/meteredCmixMessageBuffer.go
+++ b/cmix/message/meteredCmixMessageBuffer.go
@@ -15,8 +15,8 @@ import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/elixxir/primitives/states"
diff --git a/cmix/message/meteredCmixMessageBuffer_test.go b/cmix/message/meteredCmixMessageBuffer_test.go
index 2002df7ad9e90c106eff0450d23ba8559507ae50..a83560ecf9d547d0070f217ccf1010faaa3bb585 100644
--- a/cmix/message/meteredCmixMessageBuffer_test.go
+++ b/cmix/message/meteredCmixMessageBuffer_test.go
@@ -11,8 +11,8 @@ import (
 	"bytes"
 	"encoding/json"
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/elixxir/primitives/format"
diff --git a/cmix/message/serviceTracker_test.go b/cmix/message/serviceTracker_test.go
index 7b16c5b0671be578de5ecc97e686d16c81c2557b..4568837f6101bc8d96769181e3f1155db877af5f 100644
--- a/cmix/message/serviceTracker_test.go
+++ b/cmix/message/serviceTracker_test.go
@@ -130,4 +130,4 @@ func TestCompressedServiceList_DeepCopy(t *testing.T) {
 			}
 		}
 	}
-}
\ No newline at end of file
+}
diff --git a/cmix/nodes/interfaces.go b/cmix/nodes/interfaces.go
index b5edce6892639ce1b744c8ad1f92c44994705628..fea5d85135f16271af199fcd02fa08d533d59dba 100644
--- a/cmix/nodes/interfaces.go
+++ b/cmix/nodes/interfaces.go
@@ -8,8 +8,8 @@
 package nodes
 
 import (
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/comms/network"
 	"gitlab.com/elixxir/crypto/cyclic"
diff --git a/cmix/nodes/registrar.go b/cmix/nodes/registrar.go
index d8ef6493a48e65bd95ffc164f0fb6a44ba62b29b..f304a88b8fba161e411e01f33595b78698c719a9 100644
--- a/cmix/nodes/registrar.go
+++ b/cmix/nodes/registrar.go
@@ -17,8 +17,8 @@ import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/cmix/gateway"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/comms/network"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/hash"
diff --git a/cmix/nodes/store.go b/cmix/nodes/store.go
index 04ef3ddf25da78c4cb21b296bbdbbd7ef12f9c4a..2867c07e3e0ec8b7e766b8c20053df862900ca29 100644
--- a/cmix/nodes/store.go
+++ b/cmix/nodes/store.go
@@ -11,7 +11,7 @@ import (
 	"encoding/json"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/cmix/nodes/storeKey.go b/cmix/nodes/storeKey.go
index a38de9c44635bd959535894377c130f41bca84c7..db7b88c5995d46506fe270ea6316c694e7282d14 100644
--- a/cmix/nodes/storeKey.go
+++ b/cmix/nodes/storeKey.go
@@ -11,7 +11,7 @@ import (
 	"bytes"
 	"encoding/binary"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/cmix/nodes/utils_test.go b/cmix/nodes/utils_test.go
index 00fd104df0ad5227647eefba4f1045f14ee23866..8e824fe3517fa4b68436657468979f62fcbb29b6 100644
--- a/cmix/nodes/utils_test.go
+++ b/cmix/nodes/utils_test.go
@@ -13,9 +13,9 @@ import (
 
 	"github.com/golang/protobuf/proto"
 	"gitlab.com/elixxir/client/v4/cmix/gateway"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
 	"gitlab.com/elixxir/client/v4/storage"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	commNetwork "gitlab.com/elixxir/comms/network"
 	"gitlab.com/elixxir/crypto/cyclic"
diff --git a/cmix/pickup/store/store.go b/cmix/pickup/store/store.go
index 8a2e17b9e9bdad8ca86eb16c843cc30ae6867e57..457e52b8de7e29a306d920320feab28d3f7b6453 100644
--- a/cmix/pickup/store/store.go
+++ b/cmix/pickup/store/store.go
@@ -15,7 +15,7 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/id/ephemeral"
diff --git a/cmix/pickup/store/uncheckedRounds.go b/cmix/pickup/store/uncheckedRounds.go
index 6d56e04dde354e1cc8f6d974eddc82139d1db023..48d99ac495755e95e29ca61d120dc2a300511acb 100644
--- a/cmix/pickup/store/uncheckedRounds.go
+++ b/cmix/pickup/store/uncheckedRounds.go
@@ -14,7 +14,7 @@ import (
 
 	"github.com/golang/protobuf/proto"
 	"github.com/pkg/errors"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/id/ephemeral"
diff --git a/cmix/pickup/store/uncheckedRounds_test.go b/cmix/pickup/store/uncheckedRounds_test.go
index 3590b9a67919801b831fe74430b1a32c8d431774..078668cd89eb218516de78e8b50130390a27b9fa 100644
--- a/cmix/pickup/store/uncheckedRounds_test.go
+++ b/cmix/pickup/store/uncheckedRounds_test.go
@@ -10,7 +10,7 @@ package store
 import (
 	"bytes"
 	"github.com/stretchr/testify/require"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/cmix/pickup/unchecked.go b/cmix/pickup/unchecked.go
index 37e3572a023d4dfd9e8632e5e1b0b8c3cce2886e..23f42a8c227caa8095b64d9b183c22a4d53b16d0 100644
--- a/cmix/pickup/unchecked.go
+++ b/cmix/pickup/unchecked.go
@@ -40,7 +40,8 @@ var backOffTable = [cappedTries]time.Duration{
 // found to be due on a periodical check, the round is sent back to
 // processMessageRetrieval.
 // TODO: Make this system know which rounds are still in progress instead of
-//  just assume by time
+//
+//	just assume by time
 func (m *pickup) processUncheckedRounds(checkInterval time.Duration,
 	backoffTable [cappedTries]time.Duration, stop *stoppable.Single) {
 	ticker := time.NewTicker(checkInterval)
diff --git a/cmix/rounds/roundStorage.go b/cmix/rounds/roundStorage.go
index 3ad31addb73774a5fdb98985496402a009555b8f..46dbcaef4a30835ff40366956268921b4f8cd4c3 100644
--- a/cmix/rounds/roundStorage.go
+++ b/cmix/rounds/roundStorage.go
@@ -9,7 +9,7 @@ package rounds
 
 import (
 	"github.com/golang/protobuf/proto"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/collective/collector.go b/collective/collector.go
index e5711dc4ef54bec80bf3daf8ddf3e5edf15126c4..5a4ac933d48a36660dc7ed3964baa35aca1e82fc 100644
--- a/collective/collector.go
+++ b/collective/collector.go
@@ -15,7 +15,7 @@ import (
 	"sync/atomic"
 	"time"
 
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
@@ -172,7 +172,7 @@ func (c *collector) IsSynched() bool {
 func (c *collector) WaitUntilSynched(timeout time.Duration) bool {
 	start := netTime.Now()
 
-	for time.Now().Sub(start) < timeout {
+	for time.Since(start) < timeout {
 		if c.IsSynched() {
 			return true
 		}
@@ -200,26 +200,31 @@ func (c *collector) notify(state bool) {
 }
 
 // collect will collect, organize and apply all changes across devices.
-func (c *collector) collect() {
-	// note this returns full device paths from the perspective of
-	// the remote
-	devicePaths, err := c.remote.ReadDir(c.syncPath)
+func (c *collector) collect() error {
+	start := netTime.Now()
+	devices, err := getDevices(c.remote, c.syncPath)
 	if err != nil {
 		c.notify(false)
-		jww.WARN.Printf("[%s] Failed to Read devices: %+v",
+		jww.ERROR.Printf("[%s] unable to get devices: %+v",
 			collectorLogHeader, err)
-		return
+		return err
 	}
 
-	start := netTime.Now()
+	if len(devices) == 0 {
+		err = errors.Errorf("[%s] no devices to collect",
+			collectorLogHeader)
+		jww.ERROR.Printf("%+v", err)
+		return err
+	}
 
-	devices := c.initDevices(devicePaths)
-	newUpdates, err := c.collectChanges(devices)
+	jww.DEBUG.Printf("[%s] initDevices: %v", collectorLogHeader,
+		devices)
+	newUpdates, err := c.collectAllChanges(devices)
 	if err != nil {
 		jww.WARN.Printf("[%s] Failed to collect updates: %+v",
 			collectorLogHeader, err)
 		c.notify(false)
-		return
+		return err
 	}
 
 	c.notify(true)
@@ -228,7 +233,7 @@ func (c *collector) collect() {
 	if err = c.applyChanges(); err != nil {
 		jww.WARN.Printf("[%s] Failed to apply updates: %+v",
 			collectorLogHeader, err)
-		return
+		return err
 	}
 
 	atomic.StoreUint32(c.synched, 1)
@@ -241,19 +246,26 @@ func (c *collector) collect() {
 		c.lastUpdateRead[k] = v
 	}
 
+	return nil
 }
 
-// collectChanges will collate all changes across all devices.
-func (c *collector) collectChanges(devices []InstanceID) (
+func (c *collector) collectAllChanges(devices []InstanceID) (
 	map[InstanceID]time.Time, error) {
-
 	newUpdates := make(map[InstanceID]time.Time, 0)
 	lck := sync.Mutex{}
-
 	wg := &sync.WaitGroup{}
-	connectionFailed := uint32(0)
-	// Iterate over devices
+	errCh := make(chan error, len(devices))
 	for i := range devices {
+		deviceID := devices[i]
+		// Set defaults for new devices
+		if _, exists := c.lastUpdateRead[deviceID]; !exists {
+			c.lastUpdateRead[deviceID] = time.Unix(0, 0).UTC()
+			c.lastMutationRead[deviceID] = time.Unix(0, 0).UTC()
+			c.devicePatchTracker[deviceID] = newPatch(deviceID)
+			jww.INFO.Printf("[%s] new device detected: %s",
+				collectorLogHeader,
+				deviceID)
+		}
 		wg.Add(1)
 		go func(deviceID InstanceID) {
 			defer wg.Done()
@@ -261,77 +273,76 @@ func (c *collector) collectChanges(devices []InstanceID) (
 			if deviceID == c.myID {
 				return
 			}
-
-			kid := c.encrypt.KeyID(deviceID)
-
-			// Get the last time the device log was written on the remote
-			logPath := getTxLogPath(c.syncPath, kid, deviceID)
-			lastRemoteUpdate, err := c.remote.GetLastModified(logPath)
-			if err != nil {
-				atomic.AddUint32(&connectionFailed, 1)
-				jww.WARN.Printf("Failed to get last modified for %s "+
-					"at %s: %+v", deviceID, logPath, err)
-				return
-			}
-
-			// determine the update timestamp we saw from the device
-			lastTrackedUpdate := c.lastUpdateRead[deviceID]
-
-			if !lastRemoteUpdate.After(lastTrackedUpdate) {
-				jww.DEBUG.Printf("last remote after tracked: "+
-					"%s != %s", lastRemoteUpdate,
-					lastTrackedUpdate)
-				return
-			}
-
-			// Read the remote log
-			patchFile, err := c.readFromDevice(logPath)
+			patch, updateTime, err := c.collectChanges(deviceID)
 			if err != nil {
-				atomic.AddUint32(&connectionFailed, 1)
-				jww.WARN.Printf("failed to Read the log from %s "+
-					"at %s %+v", deviceID, logPath, err)
+				jww.ERROR.Printf("%+v", err)
+				errCh <- err
 				return
 			}
-
-			_, patch, err := handleIncomingFile(deviceID,
-				patchFile, c.encrypt)
-			if err != nil {
-				jww.WARN.Printf("failed to handle incoming file for %s "+
-					"at %s: %+v", deviceID, logPath, err)
-				return
-			}
-
-			// preallocated
 			lck.Lock()
 			c.devicePatchTracker[deviceID] = patch
-			newUpdates[deviceID] = lastRemoteUpdate
+			newUpdates[deviceID] = updateTime
 			lck.Unlock()
-		}(devices[i])
+		}(deviceID)
+		wg.Wait()
 	}
-	wg.Wait()
 
-	if connectionFailed > 0 {
-		err := errors.Errorf("failed to read %d logs, aborting "+
-			"collection", connectionFailed)
-		return nil, err
+	done := false
+	for !done {
+		select {
+		case e := <-errCh:
+			return nil, errors.Wrapf(e, "error collecting changes")
+		default:
+			done = true
+		}
 	}
-
 	return newUpdates, nil
 }
 
-// readFromDevice is a helper function which will Read the patch from
-// the DeviceID.
-func (c *collector) readFromDevice(txLogPath string) (
-	txLog []byte, err error) {
+// collectChanges will collate all changes across all devices.
+func (c *collector) collectChanges(deviceID InstanceID) (*Patch,
+	time.Time, error) {
+	kid := c.encrypt.KeyID(deviceID)
 
-	// Retrieve device's mutate log if it is not this device
-	txLog, err = c.remote.Read(txLogPath)
+	// Get the last time the device log was written on the remote
+	logPath := getTxLogPath(c.syncPath, kid, deviceID)
+	lastRemoteUpdate, err := c.remote.GetLastModified(logPath)
 	if err != nil {
-		return nil, errors.Errorf(
-			retrieveTxLogFromDeviceErr, collectorLogHeader, err)
+		return nil, time.Time{},
+			errors.Wrapf(err, "GetLastModified(%s) ", logPath)
 	}
 
-	return txLog, nil
+	// determine the update timestamp we saw from the device
+	lastTrackedUpdate := c.lastUpdateRead[deviceID]
+
+	if !lastRemoteUpdate.After(lastTrackedUpdate) {
+		// FIXME: we warn here, because the
+		// very first thing that is done on
+		// start is to write a txLog, which
+		// means this condition is almost
+		// always true on the first run, and
+		// there may be updates to
+		// collect. Must speak w/ ben on
+		// preferences for how to addres.
+		jww.WARN.Printf("last remote after tracked: "+
+			"%s != %s", lastRemoteUpdate,
+			lastTrackedUpdate)
+	}
+
+	patchFile, err := c.remote.Read(logPath)
+	if err != nil {
+		return nil, time.Time{},
+			errors.Wrapf(err, "path: %s", logPath)
+	}
+
+	_, patch, err := handleIncomingFile(deviceID,
+		patchFile, c.encrypt)
+	if err != nil {
+		return nil, time.Time{},
+			errors.Wrapf(err, "path: %s", logPath)
+	}
+
+	return patch, lastRemoteUpdate, nil
 }
 
 // applyChanges will order the transactionChanges and apply them to the collector.
@@ -461,27 +472,6 @@ func (c *collector) loadLastMutationTime() {
 	}
 }
 
-func (c *collector) initDevices(devicePaths []string) []InstanceID {
-	devices := make([]InstanceID, 0, len(devicePaths))
-
-	for i, deviceIDStr := range devicePaths {
-		deviceID, err := NewInstanceIDFromString(deviceIDStr)
-		if err != nil {
-			jww.WARN.Printf("cannot decode device ID "+
-				"index %d: %s, %v skipping", i, deviceIDStr,
-				err)
-			continue
-		}
-		devices = append(devices, deviceID)
-		if _, exists := c.lastUpdateRead[deviceID]; !exists {
-			c.lastUpdateRead[deviceID] = time.Unix(0, 0).UTC()
-			c.lastMutationRead[deviceID] = time.Unix(0, 0).UTC()
-			c.devicePatchTracker[deviceID] = newPatch(deviceID)
-		}
-	}
-	return devices
-}
-
 func handleIncomingFile(deviceID InstanceID, patchFile []byte,
 	decrypt encryptor) (*header, *Patch, error) {
 	h, ecrPatchBytes, err := decodeFile(patchFile)
@@ -508,3 +498,23 @@ func handleIncomingFile(deviceID InstanceID, patchFile []byte,
 func makeLastMutationKey(deviceID InstanceID) string {
 	return lastMutationReadStorageKey + deviceID.String()
 }
+
+func getDevices(r RemoteStore, path string) ([]InstanceID, error) {
+	devicePaths, err := r.ReadDir(path)
+	if err != nil {
+		return nil, err
+	}
+	jww.DEBUG.Printf("[%s] device paths: %v", collectorLogHeader,
+		devicePaths)
+
+	devices := make([]InstanceID, len(devicePaths))
+	for i := range devicePaths {
+		deviceID, err := NewInstanceIDFromString(devicePaths[i])
+		if err != nil {
+			jww.WARN.Printf("deviceID decode error: %+v", err)
+		}
+		devices[i] = deviceID
+	}
+
+	return devices, nil
+}
diff --git a/collective/collector_test.go b/collective/collector_test.go
index 7f1bb8598b6921466e16324248c27eab8f2a9d03..9345813354a5bd9ff8d59a71cedf4288e853b0d5 100644
--- a/collective/collector_test.go
+++ b/collective/collector_test.go
@@ -129,7 +129,7 @@ func TestNewCollector_CollectChanges(t *testing.T) {
 	testcol := newCollector(myID, syncPath, remoteStore, remoteKv.remote,
 		crypt, txLog)
 
-	changes, err := testcol.collectChanges(devices)
+	changes, err := testcol.collectAllChanges(devices)
 	require.NoError(t, err)
 
 	// t.Logf("changes: %+v", changes)
@@ -168,9 +168,11 @@ func TestCollector_ApplyChanges(t *testing.T) {
 		encrypted := txLog.encrypt.Encrypt(serial)
 		require.NoError(t, err)
 		file := buildFile(txLog.header, encrypted)
-		err = txLog.io.Write(getTxLogPath(syncPath,
+		logPath := getTxLogPath(syncPath,
 			txLog.encrypt.KeyID(txLog.header.DeviceID),
-			txLog.header.DeviceID), file)
+			txLog.header.DeviceID)
+		t.Logf("LogPath: %s", logPath)
+		err = txLog.io.Write(logPath, file)
 		require.NoError(t, err)
 		devices = append(devices, txLog.header.DeviceID)
 	}
@@ -197,7 +199,7 @@ func TestCollector_ApplyChanges(t *testing.T) {
 	// Construct collector
 	testcol := newCollector(myID, syncPath, remoteStore, remoteKv.remote,
 		crypt, txLog)
-	_, err = testcol.collectChanges(devices)
+	_, err = testcol.collectAllChanges(devices)
 	require.NoError(t, err)
 	require.NoError(t, testcol.applyChanges())
 
diff --git a/collective/fs.go b/collective/fs.go
index 8410b0853873882c821edf55535d17b423006a8b..e3771a49917c13ddb2d6f260b4236839f5340b52 100644
--- a/collective/fs.go
+++ b/collective/fs.go
@@ -8,6 +8,7 @@
 package collective
 
 import (
+	"os"
 	"path/filepath"
 	"time"
 
@@ -80,5 +81,26 @@ func (f *FileSystemStorage) GetLastWrite() (time.Time, error) {
 
 // ReadDir implements [RemoteStore.ReadDir] and gets a file listing.
 func (f *FileSystemStorage) ReadDir(path string) ([]string, error) {
-	return utils.ReadDir(filepath.Join(f.baseDir, path))
+	jww.INFO.Printf("ReadDir: %s %s", f.baseDir, path)
+	joined := filepath.Join(f.baseDir, path)
+	jww.INFO.Printf("joined: %s", joined)
+	return readDir(joined)
+}
+
+// ReadDir reads the named directory, returning all its directory entries
+// sorted by filename.
+func readDir(path string) ([]string, error) {
+	entries, err := os.ReadDir(path)
+	if err != nil {
+		return nil, err
+	}
+
+	files := make([]string, 0)
+	for _, entry := range entries {
+		if entry.IsDir() {
+			files = append(files, entry.Name())
+		}
+	}
+
+	return files, nil
 }
diff --git a/collective/instanceID_test.go b/collective/instanceID_test.go
index 1d848d4350dd0f686b2d45281447816bcd1b8991..4bd977d28c415876428554e45257eac8ae7cad84 100644
--- a/collective/instanceID_test.go
+++ b/collective/instanceID_test.go
@@ -14,7 +14,7 @@ import (
 	"time"
 
 	"github.com/stretchr/testify/require"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 )
 
diff --git a/collective/interface.go b/collective/interface.go
index cf8b33bd4bea2be2a7a378cbf9eb03d9c0c13863..b59ec2cf12249dc9419dc7c1b303cca9506a89eb 100644
--- a/collective/interface.go
+++ b/collective/interface.go
@@ -9,8 +9,6 @@ package collective
 
 import (
 	"time"
-
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 )
 
 // FileIO is a simplified filesystem interface, providing Read and
@@ -51,17 +49,6 @@ type RemoteStore interface {
 	ReadDir(path string) ([]string, error)
 }
 
-// UpsertCallback is a custom upsert handling for specific keys. When
-// an upsert is not defined, the default is used (overwrite the
-// previous key).
-type UpsertCallback interface {
-	Callback(key string, curVal, newVal []byte)
-}
-
-// KeyUpdateCallback is the callback used to report the event.
-type KeyUpdateCallback func(key string, oldVal, newVal []byte,
-	op versioned.KeyOperation)
-
 // RemoteStoreCallback is a callback for reporting the status of
 // writing the new mutate to remote storage.
 type RemoteStoreCallback func(newTx Mutate, err error)
diff --git a/collective/kv.go b/collective/kv.go
index d98c51f37f5ce926b2c842a794676bfbdc66a31e..f14bd2afff401abd01abd8fa01eeabfc4db327fc 100644
--- a/collective/kv.go
+++ b/collective/kv.go
@@ -15,8 +15,8 @@ import (
 	"time"
 
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/ekv"
 )
 
@@ -84,8 +84,8 @@ type internalKV struct {
 	// keyUpdateListeners holds callbacks called when a key is updated
 	// by a remote
 	UpdateListenerMux  sync.RWMutex
-	keyUpdateListeners map[string]KeyUpdateCallback
-	mapUpdateListeners map[string]mapChangedByRemoteCallback
+	keyUpdateListeners map[string]keyUpdate
+	mapUpdateListeners map[string]mapUpdate
 }
 
 // newKV constructs a new remote KV. If data exists on disk, it loads
@@ -98,8 +98,8 @@ func newKV(transactionLog *remoteWriter, kv ekv.KeyValue) *internalKV {
 	rkv := &internalKV{
 		kv:                 kv,
 		txLog:              transactionLog,
-		keyUpdateListeners: make(map[string]KeyUpdateCallback),
-		mapUpdateListeners: make(map[string]mapChangedByRemoteCallback),
+		keyUpdateListeners: make(map[string]keyUpdate),
+		mapUpdateListeners: make(map[string]mapUpdate),
 		isSynchronizing:    &isSync,
 	}
 
@@ -148,7 +148,28 @@ func (r *internalKV) Delete(key string) error {
 	if err := versioned.IsValidKey(key); err != nil {
 		return err
 	}
-	return r.kv.Delete(key)
+	if updater, exists := r.keyUpdateListeners[key]; exists && updater.local {
+		var old []byte
+		var existed bool
+		op := func(files map[string]ekv.Operable, _ ekv.Extender) error {
+			file := files[key]
+			old, existed = file.Get()
+			file.Delete()
+			return file.Flush()
+		}
+
+		if err := r.kv.Transaction(op, key); err != nil {
+			return err
+		}
+
+		if existed {
+			go updater.cb(old, nil, versioned.Deleted)
+		}
+
+		return nil
+	} else {
+		return r.kv.Delete(key)
+	}
 }
 
 // SetInterface implements [ekv.KeyValue.SetInterface]. This is a LOCAL ONLY
@@ -187,7 +208,29 @@ func (r *internalKV) SetBytes(key string, data []byte) error {
 	if err := versioned.IsValidKey(key); err != nil {
 		return err
 	}
-	return r.kv.SetBytes(key, data)
+	if updater, exists := r.keyUpdateListeners[key]; exists && updater.local {
+		var old []byte
+		var existed bool
+		op := func(files map[string]ekv.Operable, _ ekv.Extender) error {
+			file := files[key]
+			old, existed = file.Get()
+			file.Set(data)
+			return file.Flush()
+		}
+
+		if err := r.kv.Transaction(op, key); err != nil {
+			return err
+		}
+
+		operation := versioned.Created
+		if existed {
+			operation = versioned.Updated
+		}
+		go updater.cb(old, data, operation)
+		return nil
+	} else {
+		return r.kv.SetBytes(key, data)
+	}
 }
 
 // GetBytes implements [ekv.KeyValue.GetBytes]
@@ -197,6 +240,7 @@ func (r *internalKV) GetBytes(key string) ([]byte, error) {
 
 // Transaction implements [ekv.KeyValue.Transaction]
 // does not filter for invalid keys
+// does not call event callbacks if they are set locally
 func (r *internalKV) Transaction(op ekv.TransactionOperation, keys ...string) error {
 	return r.kv.Transaction(op, keys...)
 }
@@ -228,12 +272,12 @@ func (r *internalKV) SetBytesFromRemote(key string, data []byte) error {
 
 	r.UpdateListenerMux.RLock()
 	defer r.UpdateListenerMux.RUnlock()
-	if cb, exists := r.keyUpdateListeners[key]; exists {
+	if updater, exists := r.keyUpdateListeners[key]; exists {
 		opp := versioned.Created
 		if existed {
 			opp = versioned.Updated
 		}
-		go cb(key, old, data, opp)
+		go updater.cb(old, data, opp)
 	}
 	return nil
 }
@@ -321,8 +365,8 @@ func (r *internalKV) MapTransactionFromRemote(mapName string,
 	r.UpdateListenerMux.RLock()
 	defer r.UpdateListenerMux.RUnlock()
 
-	if cb, exists := r.mapUpdateListeners[mapName]; exists {
-		go cb(mapName, reportedEdits)
+	if updater, exists := r.mapUpdateListeners[mapName]; exists {
+		go updater.cb(reportedEdits)
 	}
 
 	return nil
@@ -346,8 +390,8 @@ func (r *internalKV) DeleteFromRemote(key string) error {
 
 	r.UpdateListenerMux.RLock()
 	defer r.UpdateListenerMux.RUnlock()
-	if cb, exists := r.keyUpdateListeners[key]; exists {
-		go cb(key, old, nil, versioned.Deleted)
+	if updater, exists := r.keyUpdateListeners[key]; exists {
+		go updater.cb(old, nil, versioned.Deleted)
 	}
 	return nil
 }
@@ -356,21 +400,32 @@ func (r *internalKV) DeleteFromRemote(key string) error {
 // a key is updated by synching with another client.
 // Only one callback can be written per key.
 // NOTE: It may make more sense to listen for updates via the collector directly
-func (r *internalKV) ListenOnRemoteKey(key string, cb KeyUpdateCallback) ([]byte,
-	error) {
+func (r *internalKV) ListenOnRemoteKey(key string, cb keyUpdateCallback,
+	localEvents bool) error {
 	r.UpdateListenerMux.Lock()
 	defer r.UpdateListenerMux.Unlock()
 
-	if r.IsSynchronizing() {
-		jww.FATAL.Panic("cannot add listener when synchronizing")
+	r.keyUpdateListeners[key] = keyUpdate{
+		cb:    cb,
+		local: localEvents,
 	}
-
-	r.keyUpdateListeners[key] = cb
 	curData, err := r.GetBytes(key)
 	if err != nil && ekv.Exists(err) {
-		return nil, err
+		return err
 	}
-	return curData, nil
+	if curData != nil {
+		cb(nil, curData, versioned.Loaded)
+	}
+	return nil
+}
+
+// keyUpdateCallback is the callback used to report the event.
+type keyUpdateCallback func(oldVal, newVal []byte,
+	op versioned.KeyOperation)
+
+type keyUpdate struct {
+	cb    keyUpdateCallback
+	local bool
 }
 
 // ListenOnRemoteMap allows the caller to receive updates when
@@ -378,29 +433,46 @@ func (r *internalKV) ListenOnRemoteKey(key string, cb KeyUpdateCallback) ([]byte
 // Only one callback can be written per key.
 // NOTE: It may make more sense to listen for updates via the collector directly
 func (r *internalKV) ListenOnRemoteMap(mapName string,
-	cb mapChangedByRemoteCallback) (map[string][]byte, error) {
+	cb mapChangedByRemoteCallback, localEvents bool) error {
 	r.UpdateListenerMux.Lock()
 	defer r.UpdateListenerMux.Unlock()
 
-	if r.IsSynchronizing() {
-		jww.FATAL.Panic("cannot add listener when synchronizing")
+	r.mapUpdateListeners[mapName] = mapUpdate{
+		cb:    cb,
+		local: localEvents,
 	}
-
-	r.mapUpdateListeners[mapName] = cb
 	curMap, err := r.GetMap(mapName)
 	if err != nil && ekv.Exists(err) {
-		return nil, err
+		return err
+	}
+
+	if len(curMap) > 0 {
+		ee := make(map[string]elementEdit, len(curMap))
+		for key := range curMap {
+			ee[key] = elementEdit{
+				OldElement: nil,
+				NewElement: curMap[key],
+				Operation:  versioned.Loaded,
+			}
+		}
+		cb(ee)
 	}
-	return curMap, nil
+
+	return nil
 }
 
-type mapChangedByRemoteCallback func(mapName string, edits map[string]elementEdit)
+type mapChangedByRemoteCallback func(edits map[string]elementEdit)
 type elementEdit struct {
 	OldElement []byte
 	NewElement []byte
 	Operation  versioned.KeyOperation
 }
 
+type mapUpdate struct {
+	cb    mapChangedByRemoteCallback
+	local bool
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // Remote functions -- writers to the txLog
 ///////////////////////////////////////////////////////////////////////////////
@@ -511,5 +583,6 @@ func (r *internalKV) IsSynched() bool {
 
 // WaitForRemote block until timeout or remote operations complete
 func (r *internalKV) WaitForRemote(timeout time.Duration) bool {
+	// FIXME: txLog needs to wait here as well!
 	return r.col.WaitUntilSynched(timeout)
 }
diff --git a/collective/kv_test.go b/collective/kv_test.go
index 73c2ecd311cf6903f51871ec72a7b714833e7efb..c5ab2c27358c61495598ee4336d8f3421766e13f 100644
--- a/collective/kv_test.go
+++ b/collective/kv_test.go
@@ -16,8 +16,8 @@ import (
 	"time"
 
 	"github.com/stretchr/testify/require"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/crypto/csprng"
 )
@@ -46,8 +46,8 @@ func TestNewOrLoadRemoteKv(t *testing.T) {
 	expected := &internalKV{
 		kv:                 kv,
 		txLog:              txLog,
-		keyUpdateListeners: make(map[string]KeyUpdateCallback),
-		mapUpdateListeners: make(map[string]mapChangedByRemoteCallback),
+		keyUpdateListeners: make(map[string]keyUpdate),
+		mapUpdateListeners: make(map[string]mapUpdate),
 		isSynchronizing:    &isSync,
 	}
 
@@ -110,20 +110,21 @@ func TestKV_SetGet(t *testing.T) {
 	txLog2.uploadPeriod = 500 * time.Millisecond
 
 	// t.Logf("Device 1: %s, Device 2: %s", txLog.header.DeviceID,
-	// txLog2.header.DeviceID)
+	// 	txLog2.header.DeviceID)
 
 	// Construct mock update callback
 	txChan := make(chan string, numTests)
-	updateCb := KeyUpdateCallback(func(key string, oldVal, newVal []byte,
+	updateCb := keyUpdateCallback(func(oldVal, newVal []byte,
 		op versioned.KeyOperation) {
 		// t.Logf("%s: %s -> %s", key, string(oldVal), string(newVal))
 		require.Nil(t, oldVal)
-		txChan <- key
+		txChan <- string(newVal)
 	})
 
 	for i := 0; i < numTests; i++ {
 		key := "key" + strconv.Itoa(i)
-		rkv2.ListenOnRemoteKey(key, updateCb)
+		err := rkv2.ListenOnRemoteKey(key, updateCb, false)
+		require.NoError(t, err)
 	}
 
 	mStopper := stoppable.NewMulti("SetTest")
@@ -134,10 +135,10 @@ func TestKV_SetGet(t *testing.T) {
 	mStopper.Add(stop1)
 	mStopper.Add(stop2)
 
-	expected := make(map[string][]byte)
+	expected := make(map[string]string)
 	for i := 0; i < numTests; i++ {
 		key, val := "key"+strconv.Itoa(i), []byte("val"+strconv.Itoa(i))
-		expected[key] = val
+		expected[string(val)] = key
 		// t.Logf("SetRemote: %s: %s", key, string(val))
 		require.NoError(t, rkv.SetRemote(key, val))
 	}
@@ -147,7 +148,7 @@ func TestKV_SetGet(t *testing.T) {
 			t.Fatalf("Failed to receive from callback %d", i)
 		case txKey := <-txChan:
 			_, ok := expected[txKey]
-			require.True(t, ok, txKey)
+			require.Truef(t, ok, "failed on reception %d, %s", i, txKey)
 		}
 	}
 
@@ -160,7 +161,8 @@ func TestKV_SetGet(t *testing.T) {
 	require.NoError(t, err)
 
 	// Verify everything is synchronized between both instances
-	for k, v := range expected {
+	for vStr, k := range expected {
+		v := []byte(vStr)
 		v1, err := rkv.GetBytes(k)
 		require.NoError(t, err)
 		require.Equal(t, v, v1, k)
diff --git a/collective/map.go b/collective/map.go
index fb3bfc37a30a0e1f6bd5907418e74b4528f33a34..29bed14da0efab87a4eb72552742b2de00191898 100644
--- a/collective/map.go
+++ b/collective/map.go
@@ -4,7 +4,7 @@ import (
 	"encoding/json"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"os"
 )
@@ -23,7 +23,28 @@ func (r *internalKV) StoreMapElement(mapName, element string,
 	value []byte) error {
 	elementsMap := make(map[string][]byte)
 	elementsMap[element] = value
-	_, err := r.txLog.WriteMap(mapName, elementsMap, nil)
+	oldMap, err := r.txLog.WriteMap(mapName, elementsMap, nil)
+
+	if updater, existed := r.mapUpdateListeners[mapName]; existed && updater.local {
+		old := oldMap[element]
+
+		op := versioned.Created
+		if old != nil {
+			op = versioned.Updated
+		}
+
+		ee := elementEdit{
+			OldElement: old,
+			NewElement: value,
+			Operation:  op,
+		}
+
+		edits := make(map[string]elementEdit)
+		edits[element] = ee
+
+		go updater.cb(edits)
+	}
+
 	return err
 }
 
@@ -34,23 +55,59 @@ func (r *internalKV) StoreMapElement(mapName, element string,
 func (r *internalKV) DeleteMapElement(mapName, element string) ([]byte, error) {
 	elementsMap := make(map[string]struct{})
 	elementsMap[element] = struct{}{}
-	old, err := r.txLog.WriteMap(mapName, nil, elementsMap)
+	oldMap, err := r.txLog.WriteMap(mapName, nil, elementsMap)
 	if err != nil {
 		return nil, err
 	}
 
-	oldData, exists := old[element]
-	if !exists {
-		return nil, nil
+	old, _ := oldMap[element]
+
+	if updater, existed := r.mapUpdateListeners[mapName]; existed && updater.local {
+
+		ee := elementEdit{
+			OldElement: old,
+			NewElement: nil,
+			Operation:  versioned.Deleted,
+		}
+
+		edits := make(map[string]elementEdit)
+		edits[element] = ee
+
+		go updater.cb(edits)
 	}
-	return oldData, nil
+
+	return old, nil
 }
 
 // StoreMap saves each element of the map, then updates the map structure
 // and deletes no longer used keys in the map.
 // All Map storage functions update the remote.
 func (r *internalKV) StoreMap(mapName string, value map[string][]byte) error {
-	_, err := r.txLog.WriteMap(mapName, value, nil)
+	oldMap, err := r.txLog.WriteMap(mapName, value, nil)
+	if updater, existed := r.mapUpdateListeners[mapName]; existed && updater.local {
+
+		edits := make(map[string]elementEdit)
+
+		for element := range value {
+			old := oldMap[element]
+
+			op := versioned.Created
+			if old != nil {
+				op = versioned.Updated
+			}
+
+			ee := elementEdit{
+				OldElement: old,
+				NewElement: value[element],
+				Operation:  op,
+			}
+
+			edits[element] = ee
+		}
+
+		go updater.cb(edits)
+	}
+
 	return err
 }
 
diff --git a/collective/patches.go b/collective/patches.go
index 48ff7f1c664f3b4c252039d33e7d936fb62bb650..f959e01bfe28c539b6a6c79c15753cfab897bb84 100644
--- a/collective/patches.go
+++ b/collective/patches.go
@@ -3,6 +3,8 @@ package collective
 import (
 	"encoding/json"
 	"time"
+
+	jww "github.com/spf13/jwalterweatherman"
 )
 
 // Patch is the structure which stores both local and remote patches,
@@ -31,11 +33,22 @@ func (p *Patch) AddUnsafe(key string, m *Mutate) {
 }
 
 func (p *Patch) Serialize() ([]byte, error) {
-	return json.Marshal(&p.keys)
+	for k, v := range p.keys {
+		d, _ := json.Marshal(v)
+		jww.DEBUG.Printf("Serializing %s: %s->%s",
+			p.myID, k, d)
+	}
+	return json.Marshal(p.keys)
 }
 
 func (p *Patch) Deserialize(b []byte) error {
-	return json.Unmarshal(b, &p.keys)
+	err := json.Unmarshal(b, &p.keys)
+	for k, v := range p.keys {
+		d, _ := json.Marshal(v)
+		jww.DEBUG.Printf("Deserializing %s: %s->%s",
+			p.myID, k, d)
+	}
+	return err
 }
 
 func (p *Patch) get(key string) (*Mutate, bool) {
diff --git a/collective/synckv.go b/collective/synckv.go
index 2dc3f86bcca0d69ea69e88434db19c36f44a31bd..9775bdbdc1746b60360d1f504cc87e0189ea2ed4 100644
--- a/collective/synckv.go
+++ b/collective/synckv.go
@@ -14,8 +14,8 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/ekv"
 )
@@ -50,12 +50,26 @@ type versionedKV struct {
 	local versioned.KV
 }
 
+// CloneFromRemoteStorage copies state from RemoteStore and
+// instantiates a SynchronizedKV
+func CloneFromRemoteStorage(path string, deviceSecret []byte,
+	remote RemoteStore, kv ekv.KeyValue,
+	rng *fastRNG.StreamGenerator) (*versionedKV, error) {
+
+	rkv, err := SynchronizedKV(path, deviceSecret, remote, kv, nil, rng)
+	if err != nil {
+		return nil, err
+	}
+
+	return rkv, rkv.remote.col.collect()
+}
+
 // SynchronizedKV loads or creates a synchronized remote KV that uses
 // a remote RemoteStore to store defined synchronization prefixes to the
 // network.
 func SynchronizedKV(path string, deviceSecret []byte,
 	remote RemoteStore, kv ekv.KeyValue, synchedPrefixes []string,
-	rng *fastRNG.StreamGenerator) (SyncKV, error) {
+	rng *fastRNG.StreamGenerator) (*versionedKV, error) {
 
 	rngStream := rng.GetStream()
 	defer rngStream.Close()
@@ -179,6 +193,7 @@ func (r *versionedKV) Delete(key string, version uint64) error {
 func (r *versionedKV) Set(key string, object *versioned.Object) error {
 	if r.inSynchronizedPrefix {
 		k := r.local.GetFullKey(key, object.Version)
+		jww.INFO.Printf("Setting Remote: %s", k)
 		return r.remote.SetRemote(k, object.Marshal())
 	}
 	return r.local.Set(key, object)
@@ -309,19 +324,18 @@ func (r *versionedKV) DeleteMapElement(mapName, elementName string,
 // a key is updated by synching with another client.
 // Only one callback can be written per key.
 func (r *versionedKV) ListenOnRemoteKey(key string, version uint64,
-	callback versioned.KeyChangedByRemoteCallback) (*versioned.Object,
-	error) {
+	callback versioned.KeyChangedByRemoteCallback, localEvents bool) error {
 
 	versionedKey := r.local.GetFullKey(key, version)
 
-	wrap := func(key string, old, new []byte, op versioned.KeyOperation) {
+	wrap := func(old, new []byte, op versioned.KeyOperation) {
 		var oldObj *versioned.Object
-		if old != nil {
+		if old != nil && len(old) > 0 {
 			oldObj = &versioned.Object{}
 			err := oldObj.Unmarshal(old)
 			if err != nil {
 				jww.WARN.Printf("Failed to unmarshal old versioned object "+
-					"for listener on key %s", key)
+					"for listener on key %s: %+v", key, err)
 			}
 		}
 
@@ -335,27 +349,20 @@ func (r *versionedKV) ListenOnRemoteKey(key string, version uint64,
 			}
 		}
 
-		cleanedKey := cleanKey(key)
-
-		callback(cleanedKey, oldObj, newObj, op)
+		callback(oldObj, newObj, op)
 	}
 
-	cur := &versioned.Object{}
-	val, err := r.remote.ListenOnRemoteKey(versionedKey, wrap)
-	if err == nil && val != nil {
-		err = cur.Unmarshal(val)
-	}
-	return cur, err
+	return r.remote.ListenOnRemoteKey(versionedKey, wrap, localEvents)
 }
 
 // ListenOnRemoteMap allows the caller to receive updates when
 // the map or map elements are updated
 func (r *versionedKV) ListenOnRemoteMap(mapName string, version uint64,
-	callback versioned.MapChangedByRemoteCallback) (map[string]*versioned.Object, error) {
+	callback versioned.MapChangedByRemoteCallback, localEvents bool) error {
 
 	versionedMap := r.local.GetFullKey(mapName, version)
 
-	wrap := func(mapName string, edits map[string]elementEdit) {
+	wrap := func(edits map[string]elementEdit) {
 		versionedEdits := make(map[string]versioned.ElementEdit, len(edits))
 
 		for key, edit := range edits {
@@ -364,10 +371,11 @@ func (r *versionedKV) ListenOnRemoteMap(mapName string, version uint64,
 				NewElement: &versioned.Object{},
 				Operation:  edit.Operation,
 			}
-
-			if err := versionedEdit.OldElement.Unmarshal(edit.OldElement); err != nil {
-				jww.WARN.Printf("Failed to unmarshal old versioned object "+
-					"for listener on map %s element %s", mapName, key)
+			if edit.OldElement != nil && len(edit.OldElement) > 0 {
+				if err := versionedEdit.OldElement.Unmarshal(edit.OldElement); err != nil {
+					jww.WARN.Printf("Failed to unmarshal old versioned object "+
+						"for listener on map %s element %s: %+v", mapName, key, err)
+				}
 			}
 
 			if err := versionedEdit.NewElement.Unmarshal(edit.NewElement); err != nil {
@@ -382,16 +390,10 @@ func (r *versionedKV) ListenOnRemoteMap(mapName string, version uint64,
 			versionedEdits[key] = versionedEdit
 		}
 
-		cleanedMapName := cleanKey(mapName)
-		callback(cleanedMapName, versionedEdits)
+		callback(versionedEdits)
 	}
 
-	var cur map[string]*versioned.Object
-	rMap, err := r.remote.ListenOnRemoteMap(versionedMap, wrap)
-	if err == nil {
-		cur, err = mapBytesToVersioned(rMap)
-	}
-	return cur, err
+	return r.remote.ListenOnRemoteMap(versionedMap, wrap, localEvents)
 }
 
 // GetPrefix implements [storage.versioned.KV.GetPrefix]
diff --git a/collective/synckv_test.go b/collective/synckv_test.go
index a6729f213240f3e03fe2c4a3e01506e86ee0436c..78d1f2ec6dec337f426f7af7c65fd7c6d35d284c 100644
--- a/collective/synckv_test.go
+++ b/collective/synckv_test.go
@@ -15,8 +15,8 @@ import (
 	"math/rand"
 
 	"github.com/stretchr/testify/require"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/shuffle"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/crypto/randomness"
diff --git a/collective/testing.go b/collective/testing.go
index 72cbb6f7762cbb4571b59f489d2a8ca9094b25d1..f0b1bc8e64af1f9eca3f77726911e644582e1b8a 100644
--- a/collective/testing.go
+++ b/collective/testing.go
@@ -10,7 +10,7 @@ import (
 
 	jww "github.com/spf13/jwalterweatherman"
 	"github.com/stretchr/testify/require"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/crypto/csprng"
diff --git a/collective/transactionLog.go b/collective/transactionLog.go
index 800fae397948af85639b601732937b5a88279a4e..49828fad8c0f32f0c7c03718f246353a5a391fc7 100644
--- a/collective/transactionLog.go
+++ b/collective/transactionLog.go
@@ -15,8 +15,8 @@ import (
 	"sync/atomic"
 	"time"
 
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/netTime"
 
@@ -165,6 +165,7 @@ func (rw *remoteWriter) Runner(s *stoppable.Single) {
 	for {
 		select {
 		case t := <-rw.adds:
+			jww.INFO.Printf("Adding change for %s", t.Key)
 			rw.state.AddUnsafe(t.Key, t.Mutate)
 
 			// batch writes
@@ -209,7 +210,7 @@ func (rw *remoteWriter) Runner(s *stoppable.Single) {
 				return
 			}
 			if !running {
-				timer.Reset(rw.uploadPeriod)
+				timer = time.NewTimer(rw.uploadPeriod)
 				running = true
 			}
 
@@ -224,7 +225,7 @@ func (rw *remoteWriter) Runner(s *stoppable.Single) {
 				jww.ERROR.Printf("Failed to update collective state, "+
 					"last update %s, will auto retry in %s: %+v", ts,
 					uploadPeriod, err)
-				timer.Reset(uploadPeriod)
+				timer = time.NewTimer(rw.uploadPeriod)
 				running = true
 			} else {
 				rw.notify(true)
@@ -262,6 +263,7 @@ func (rw *remoteWriter) Write(key string, value []byte) error {
 		return err
 	}
 
+	jww.INFO.Printf("Sending transaction for %s", key)
 	rw.adds <- transaction{
 		Mutate: &Mutate{
 			Timestamp: ts.UTC().UnixNano(),
diff --git a/storage/versioned/kv.go b/collective/versioned/kv.go
similarity index 88%
rename from storage/versioned/kv.go
rename to collective/versioned/kv.go
index 3f12058352043020096ee20c795a9302c9e67755..f3a4cd984d420889e184a2775264fadf7d48b15d 100644
--- a/storage/versioned/kv.go
+++ b/collective/versioned/kv.go
@@ -14,6 +14,7 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/v4/stoppable"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
 )
@@ -88,21 +89,26 @@ type KV interface {
 	// ListenOnRemoteKey allows the caller to receive updates when
 	// a key is updated by synching with another client.
 	// Only one callback can be written per key.
-	// returns the object for the key such that callbacks will be updates on
-	// that state. The object will be nil if it doesn't exist yet.
-	// You cannot add listeners when network processor for
-	// synchronization is active.
+	// On call, a state update will be created on the callback containing
+	// the current state of the key as a creation event. This call will occur
+	// in the go routine that ListenOnRemoteKey is called from, blocking its
+	// return until the callback returns.
+	// If local Events is true, the callback will also trigger when
+	// setting this key locally
 	ListenOnRemoteKey(key string, version uint64,
-		callback KeyChangedByRemoteCallback) (*Object, error)
+		callback KeyChangedByRemoteCallback, localEvents bool) error
 
 	// ListenOnRemoteMap allows the caller to receive updates when
 	// the map or map elements are updated
-	// returns the map such that callbacks will be updates on
-	// that state. The Map will be nil if it doesn't exist yet.
-	// You cannot add listeners when network processor for
-	// synchronization is active.
+	// Only one callback can be written per map.
+	// On call, a state update will be created on the callback containing
+	// the entire state of the map as a creation event. This call will occur
+	// in the go routine that ListenOnRemoteMap is called from, blocking its
+	// return until the callback returns.
+	// If local Events is true, the callback will also trigger when
+	// modifying this map locally
 	ListenOnRemoteMap(mapName string, version uint64,
-		callback MapChangedByRemoteCallback) (map[string]*Object, error)
+		callback MapChangedByRemoteCallback, localEvents bool) error
 
 	// GetPrefix returns the full Prefix of the KV
 	GetPrefix() string
@@ -125,15 +131,18 @@ type KV interface {
 	// Exists returns if the error indicates a KV error showing
 	// the key exists.
 	Exists(err error) bool
+
+	// StartProcesses starts any applicable networking processes
+	StartProcesses() (stoppable.Stoppable, error)
 }
 
 // KeyChangedByRemoteCallback is the callback used to report local updates caused
 // by a remote client editing their EKV
-type KeyChangedByRemoteCallback func(key string, old, new *Object, op KeyOperation)
+type KeyChangedByRemoteCallback func(old, new *Object, op KeyOperation)
 
 // MapChangedByRemoteCallback is the callback used to report local updates caused
 // by a remote client editing their EKV
-type MapChangedByRemoteCallback func(mapName string, edits map[string]ElementEdit)
+type MapChangedByRemoteCallback func(edits map[string]ElementEdit)
 
 type ElementEdit struct {
 	OldElement *Object
@@ -147,6 +156,7 @@ const (
 	Created KeyOperation = iota
 	Updated
 	Deleted
+	Loaded
 )
 
 func (ko KeyOperation) String() string {
@@ -410,14 +420,17 @@ func (v *kv) Transaction(key string, op TransactionOperation, version uint64) (
 
 // ListenOnRemoteKey is not implemented for local KVs
 func (v *kv) ListenOnRemoteKey(key string, version uint64,
-	callback KeyChangedByRemoteCallback) (*Object, error) {
-	return nil, errors.Wrapf(UnimplementedErr,
-		"ListenOnRemoteMap")
+	callback KeyChangedByRemoteCallback, localEvents bool) error {
+	return errors.Wrapf(UnimplementedErr, "ListenOnRemoteMap")
 }
 
 // ListenOnRemoteMap is not implemented for local KVs
 func (v *kv) ListenOnRemoteMap(mapName string, version uint64,
-	callback MapChangedByRemoteCallback) (map[string]*Object, error) {
-	return nil, errors.Wrapf(UnimplementedErr,
-		"ListenOnRemoteMap")
+	callback MapChangedByRemoteCallback, localEvents bool) error {
+	return errors.Wrapf(UnimplementedErr, "ListenOnRemoteMap")
+}
+
+// StartProcesses doesn't do anything for local KVs
+func (v *kv) StartProcesses() (stoppable.Stoppable, error) {
+	return stoppable.NewSingle("nil"), nil
 }
diff --git a/storage/versioned/kv_test.go b/collective/versioned/kv_test.go
similarity index 100%
rename from storage/versioned/kv_test.go
rename to collective/versioned/kv_test.go
diff --git a/storage/versioned/mapSyntax.go b/collective/versioned/mapSyntax.go
similarity index 100%
rename from storage/versioned/mapSyntax.go
rename to collective/versioned/mapSyntax.go
diff --git a/storage/versioned/object.go b/collective/versioned/object.go
similarity index 100%
rename from storage/versioned/object.go
rename to collective/versioned/object.go
diff --git a/storage/versioned/object_test.go b/collective/versioned/object_test.go
similarity index 100%
rename from storage/versioned/object_test.go
rename to collective/versioned/object_test.go
diff --git a/connect/authCallbacks.go b/connect/authCallbacks.go
index 84fd39d33e1a882b175a6c62b8c9431af119186a..d96781fd0823b0c7c0c1ae9c2b424d31c818b3fd 100644
--- a/connect/authCallbacks.go
+++ b/connect/authCallbacks.go
@@ -76,7 +76,7 @@ func (a clientAuthCallback) Reset(contact.Contact,
 
 // serverAuthCallback provides callback functionality for interfacing between
 // auth.State and Connection. This is used for building new Connection
-//objects when an auth Request is received.
+// objects when an auth Request is received.
 type serverAuthCallback struct {
 	// Used for signaling confirmation of E2E partnership
 	requestCallback Callback
diff --git a/connect/server.go b/connect/server.go
index cf71b41e6b5bf2f1cf5c397c11acbbc1e3aa4229..695c56f4004c8bf5551ce9e6b1a9488dbff72722 100644
--- a/connect/server.go
+++ b/connect/server.go
@@ -16,7 +16,7 @@ import (
 )
 
 // authenticatedServerListenerName is the name of the client's
-//listener interface.
+// listener interface.
 const authenticatedServerListenerName = "AuthenticatedServerListener"
 
 // server is an interface that wraps receive.Listener. This handles
diff --git a/dm/client.go b/dm/client.go
index a7d0c21cf995ced5cab16aaf90eb7bac38a481d6..bc7091174ada347a0ba370d44ce6201ad22a287b 100644
--- a/dm/client.go
+++ b/dm/client.go
@@ -20,7 +20,7 @@ import (
 	"gitlab.com/xx_network/primitives/id"
 
 	"gitlab.com/elixxir/client/v4/cmix/identity"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/nike"
 	"gitlab.com/elixxir/crypto/nike/ecdh"
 )
diff --git a/dm/client_test.go b/dm/client_test.go
index 72f161721d66bd3f6ae3a7d43c30cebfa398c8e5..ad4cbe2cde7f244c0a769371a4d65822c4abf75e 100644
--- a/dm/client_test.go
+++ b/dm/client_test.go
@@ -12,7 +12,7 @@ import (
 
 	"github.com/stretchr/testify/require"
 	"gitlab.com/elixxir/client/v4/cmix"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/codename"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/nike/ecdh"
diff --git a/dm/dm_test.go b/dm/dm_test.go
index bbdf6ac43a4035cfba6ddc3b3e822073b5ae1e85..3256468cdfd2a87f88393d890efb605c1a40d24a 100644
--- a/dm/dm_test.go
+++ b/dm/dm_test.go
@@ -17,7 +17,7 @@ import (
 	jww "github.com/spf13/jwalterweatherman"
 	"github.com/stretchr/testify/require"
 	"gitlab.com/elixxir/client/v4/cmix"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/codename"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/ekv"
diff --git a/dm/sendTracker.go b/dm/sendTracker.go
index 22dd5600f5a021d0ea92c6396874c97c34637d42..70b9b4af2f78efa4852c3e18bd6a7c6092262f6c 100644
--- a/dm/sendTracker.go
+++ b/dm/sendTracker.go
@@ -21,7 +21,7 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix"
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/message"
 	"gitlab.com/elixxir/primitives/states"
diff --git a/dm/sendTracker_test.go b/dm/sendTracker_test.go
index ad9a6804592dcbbf2d159cb87dce20e8f030e1c5..2dcca67e53a93335b53e7b4542b60f0d573b7d79 100644
--- a/dm/sendTracker_test.go
+++ b/dm/sendTracker_test.go
@@ -17,7 +17,7 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix"
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/codename"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/message"
diff --git a/dummy/random.go b/dummy/random.go
index 64deddd4f178ff7e82b8e885fee356e217ba2521..62cc8d90a1d822168c748bbf776de1418bed740b 100644
--- a/dummy/random.go
+++ b/dummy/random.go
@@ -29,13 +29,13 @@ const (
 // newRandomCmixMessage returns random format.Message data.
 //
 // Returns in order a:
-//  - Recipient (id.ID)
-//  - Message fingerprint (format.Fingerprint)
-//  - Message service (message.Service)
-//  - Payload ([]byte)
-//  - MAC ([]byte)
-//  - Error if there was an issue randomly generating any of the above data.
-//    The error will specify which of the above failed to be randomly generated.
+//   - Recipient (id.ID)
+//   - Message fingerprint (format.Fingerprint)
+//   - Message service (message.Service)
+//   - Payload ([]byte)
+//   - MAC ([]byte)
+//   - Error if there was an issue randomly generating any of the above data.
+//     The error will specify which of the above failed to be randomly generated.
 func (m *Manager) newRandomCmixMessage(rng csprng.Source) (
 	recipient *id.ID, fingerprint format.Fingerprint,
 	service message.Service,
diff --git a/e2e/critical.go b/e2e/critical.go
index e027b9a1b954054fdb69761f6e127f3497705e24..b343063580b0c7dab36625f7c4d37509be45a373 100644
--- a/e2e/critical.go
+++ b/e2e/critical.go
@@ -14,8 +14,8 @@ import (
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/catalog"
 	"gitlab.com/elixxir/client/v4/cmix"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	ds "gitlab.com/elixxir/comms/network/dataStructures"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/elixxir/primitives/states"
diff --git a/e2e/e2eMessageBuffer.go b/e2e/e2eMessageBuffer.go
index 0427753d91aab7965977980dc69d24de5ad0c129..a64ae6c7f5e0771d960f15e46571fc3f71a214d4 100644
--- a/e2e/e2eMessageBuffer.go
+++ b/e2e/e2eMessageBuffer.go
@@ -13,8 +13,8 @@ import (
 
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/catalog"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
 	"golang.org/x/crypto/blake2b"
diff --git a/e2e/e2eMessageBuffer_test.go b/e2e/e2eMessageBuffer_test.go
index e2166aa25b6b0b1a987401ba6cc8198c37c3e43e..6a15693619e333d2cfa14deb553bb4cedcd2a8cd 100644
--- a/e2e/e2eMessageBuffer_test.go
+++ b/e2e/e2eMessageBuffer_test.go
@@ -11,8 +11,8 @@ import (
 	"encoding/json"
 	"gitlab.com/elixxir/client/v4/catalog"
 	"gitlab.com/elixxir/client/v4/cmix"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
 	"reflect"
diff --git a/e2e/fpGenerator_test.go b/e2e/fpGenerator_test.go
index 3389fda02f17364f5290f11b5224a7ca0e01f6c3..c3e64d4c6900412448e4db0a5f2a8c3afc2db51b 100644
--- a/e2e/fpGenerator_test.go
+++ b/e2e/fpGenerator_test.go
@@ -188,14 +188,14 @@ func (m *mockFpgCmix) TrackServices(message.ServicesTracker)
 func (m *mockFpgCmix) GetServices() (message.ServiceList, message.CompressedServiceList) {
 	return message.ServiceList{}, message.CompressedServiceList{}
 }
-func (m *mockFpgCmix) CheckInProgressMessages()                                 {}
-func (m *mockFpgCmix) IsHealthy() bool                                          { return false }
-func (m *mockFpgCmix) WasHealthy() bool                                         { return false }
-func (m *mockFpgCmix) AddHealthCallback(func(bool)) uint64                      { return 0 }
-func (m *mockFpgCmix) RemoveHealthCallback(uint64)                              {}
-func (m *mockFpgCmix) HasNode(*id.ID) bool                                      { return false }
-func (m *mockFpgCmix) NumRegisteredNodes() int                                  { return 0 }
-func (m *mockFpgCmix) TriggerNodeRegistration(*id.ID)                           {}
+func (m *mockFpgCmix) CheckInProgressMessages()            {}
+func (m *mockFpgCmix) IsHealthy() bool                     { return false }
+func (m *mockFpgCmix) WasHealthy() bool                    { return false }
+func (m *mockFpgCmix) AddHealthCallback(func(bool)) uint64 { return 0 }
+func (m *mockFpgCmix) RemoveHealthCallback(uint64)         {}
+func (m *mockFpgCmix) HasNode(*id.ID) bool                 { return false }
+func (m *mockFpgCmix) NumRegisteredNodes() int             { return 0 }
+func (m *mockFpgCmix) TriggerNodeRegistration(*id.ID)      {}
 func (m *mockFpgCmix) GetRoundResults(time.Duration, cmix.RoundEventCallback, ...id.Round) {
 }
 func (m *mockFpgCmix) LookupHistoricalRound(id.Round, rounds.RoundResultCallback) error { return nil }
diff --git a/e2e/manager.go b/e2e/manager.go
index 13f1d9ea309360b87ac1c7e15ced325bb46aa477..46107a9c4bafcd8431faa9b48a0693d797dc369e 100644
--- a/e2e/manager.go
+++ b/e2e/manager.go
@@ -22,13 +22,13 @@ import (
 	"gitlab.com/elixxir/client/v4/catalog"
 	"gitlab.com/elixxir/client/v4/cmix"
 	"gitlab.com/elixxir/client/v4/cmix/message"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/parse"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet"
 	"gitlab.com/elixxir/client/v4/e2e/receive"
 	"gitlab.com/elixxir/client/v4/e2e/rekey"
 	"gitlab.com/elixxir/client/v4/event"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/e2e/parse/conversation/partner.go b/e2e/parse/conversation/partner.go
index 01485bfec6695a41d0ad8e77386826c2fb6fad42..1c6714d5d67e8abfcbc6897fbabb0f26eb4caaa0 100644
--- a/e2e/parse/conversation/partner.go
+++ b/e2e/parse/conversation/partner.go
@@ -14,7 +14,7 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/e2e/parse/conversation/partner_test.go b/e2e/parse/conversation/partner_test.go
index e9368961d0586f0fc50ed2aa1063229232d4258d..491a04911ff293c916b862e0592d0da20140f7aa 100644
--- a/e2e/parse/conversation/partner_test.go
+++ b/e2e/parse/conversation/partner_test.go
@@ -12,7 +12,7 @@ import (
 	"reflect"
 	"testing"
 
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
 )
diff --git a/e2e/parse/conversation/ring.go b/e2e/parse/conversation/ring.go
index 3a7a815ec82a8818fe3af511ec658c583b9050d3..91006953ba439ff0e6b6f0a626089a911c4f7d04 100644
--- a/e2e/parse/conversation/ring.go
+++ b/e2e/parse/conversation/ring.go
@@ -15,7 +15,7 @@ import (
 	"time"
 
 	"github.com/pkg/errors"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/netTime"
 )
 
diff --git a/e2e/parse/conversation/ring_test.go b/e2e/parse/conversation/ring_test.go
index 63ac30d3622c0b819b7be4142915fe74952f8890..0f001a3116c6130abbbfcf77b2dad0716b86cd36 100644
--- a/e2e/parse/conversation/ring_test.go
+++ b/e2e/parse/conversation/ring_test.go
@@ -9,7 +9,7 @@ package conversation
 
 import (
 	"github.com/stretchr/testify/require"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"reflect"
 	"strconv"
diff --git a/e2e/parse/conversation/store.go b/e2e/parse/conversation/store.go
index a6dd7d22703a1580e2e4fa4f4d5ad41c275a2bdb..3927ee8bc689b130c7aa22a642798b13bf1b5aec 100644
--- a/e2e/parse/conversation/store.go
+++ b/e2e/parse/conversation/store.go
@@ -11,7 +11,7 @@ import (
 	"sync"
 
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/id"
 )
 
diff --git a/e2e/parse/conversation/store_test.go b/e2e/parse/conversation/store_test.go
index 68ee8e2ba1b73b550d55244afce6715e7a19d612..aebaa12a314652f01a9f185b5380f1e2a1898617 100644
--- a/e2e/parse/conversation/store_test.go
+++ b/e2e/parse/conversation/store_test.go
@@ -8,7 +8,7 @@
 package conversation
 
 import (
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
 	"math/rand"
diff --git a/e2e/parse/partition.go b/e2e/parse/partition.go
index bb44609c9ca4f402a975f3df7ab67a8d9ddbdd18..f9134df696c4dc70b5cfa9f44b37d9c4e98aedc2 100644
--- a/e2e/parse/partition.go
+++ b/e2e/parse/partition.go
@@ -13,10 +13,10 @@ import (
 
 	"github.com/pkg/errors"
 	"gitlab.com/elixxir/client/v4/catalog"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/parse/conversation"
 	"gitlab.com/elixxir/client/v4/e2e/parse/partition"
 	"gitlab.com/elixxir/client/v4/e2e/receive"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/e2e/parse/partition/multiPartMessage.go b/e2e/parse/partition/multiPartMessage.go
index 96840192f297aa5acb1ba879fdc4ec372bca6f0c..a2d99433aab0ba02fa495a51d00fd51a358358a8 100644
--- a/e2e/parse/partition/multiPartMessage.go
+++ b/e2e/parse/partition/multiPartMessage.go
@@ -16,8 +16,8 @@ import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/catalog"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/receive"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/e2e/parse/partition/multiPartMessage_test.go b/e2e/parse/partition/multiPartMessage_test.go
index 182137a7cd164befb19c2abf89c6f063f21db81e..5ded9d207d477eeb4423cd3be18e96c57da9d049 100644
--- a/e2e/parse/partition/multiPartMessage_test.go
+++ b/e2e/parse/partition/multiPartMessage_test.go
@@ -11,8 +11,8 @@ import (
 	"bytes"
 	"encoding/json"
 	"gitlab.com/elixxir/client/v4/catalog"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/receive"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/e2e/parse/partition/part.go b/e2e/parse/partition/part.go
index 215c4019b50a3fdb599a0a981d27aef45ba17d80..53c00924f2e19ee37b25c4919893569deabb2d83 100644
--- a/e2e/parse/partition/part.go
+++ b/e2e/parse/partition/part.go
@@ -8,7 +8,7 @@
 package partition
 
 import (
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/netTime"
 	"strconv"
 )
diff --git a/e2e/parse/partition/part_test.go b/e2e/parse/partition/part_test.go
index 5d4a5889fe495ac2d966d0ce782f9982f361bdf8..710dd488921526e3e8854177976e2438de06e729 100644
--- a/e2e/parse/partition/part_test.go
+++ b/e2e/parse/partition/part_test.go
@@ -9,7 +9,7 @@ package partition
 
 import (
 	"bytes"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/netTime"
 	"math/rand"
diff --git a/e2e/parse/partition/store.go b/e2e/parse/partition/store.go
index 19a9626520d2bfd186b5c1af9cb9797effebf8ae..2d578730fcc70f6cbfff49cb5ae841bcd879968d 100644
--- a/e2e/parse/partition/store.go
+++ b/e2e/parse/partition/store.go
@@ -16,8 +16,8 @@ import (
 
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/catalog"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/receive"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/e2e/parse/partition/store_test.go b/e2e/parse/partition/store_test.go
index d91b51936450da67b2fc6d7f2b547b060e990bf8..f6d7bc6b8c963ebddb15d29935bbfe6ba8bd7bf1 100644
--- a/e2e/parse/partition/store_test.go
+++ b/e2e/parse/partition/store_test.go
@@ -11,7 +11,7 @@ import (
 	"bytes"
 	"github.com/stretchr/testify/require"
 	"gitlab.com/elixxir/client/v4/catalog"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/e2e"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/e2e/parse/partition_test.go b/e2e/parse/partition_test.go
index cf9900e5aa335554c9f51da399b1d7319ff69281..a4276e28090d8a2a3afe5aed00d24d91d5de0516 100644
--- a/e2e/parse/partition_test.go
+++ b/e2e/parse/partition_test.go
@@ -12,7 +12,7 @@ import (
 	"testing"
 
 	"gitlab.com/elixxir/client/v4/catalog"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/e2e/ratchet/partner/manager.go b/e2e/ratchet/partner/manager.go
index f55b2645c6a2cca7d632ceb065bfcac61b75056a..dd164ef17b6a12d08c9b334a68e369eb95815ad0 100644
--- a/e2e/ratchet/partner/manager.go
+++ b/e2e/ratchet/partner/manager.go
@@ -16,9 +16,9 @@ import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/cmix/message"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/fastRNG"
diff --git a/e2e/ratchet/partner/manager_test.go b/e2e/ratchet/partner/manager_test.go
index dfa88ec2584598b512242d123ee873d67cf1f766..f15b04426f0aef733f07f081ce8f8fdd1d41d312 100644
--- a/e2e/ratchet/partner/manager_test.go
+++ b/e2e/ratchet/partner/manager_test.go
@@ -169,7 +169,7 @@ func TestManager_NewSendSession(t *testing.T) {
 	}
 }
 
-//Tests happy path of Manager.GetKeyForSending.
+// Tests happy path of Manager.GetKeyForSending.
 func TestManager_GetKeyForSending(t *testing.T) {
 	// Set up test values
 	m, _ := newTestManager(t)
diff --git a/e2e/ratchet/partner/relationship.go b/e2e/ratchet/partner/relationship.go
index 3a533136209b33873e75e85d7ae7344c08871f90..dd177ae02068038922858ed3208cce05e4da58b7 100644
--- a/e2e/ratchet/partner/relationship.go
+++ b/e2e/ratchet/partner/relationship.go
@@ -14,8 +14,8 @@ import (
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/e2e/ratchet/partner/relationshipFingerprint.go b/e2e/ratchet/partner/relationshipFingerprint.go
index dd651545cc2bfbe1a1fc2cfd74a2f2d667ddda69..0ba355f32d54583faefb1305a1a548abc60e8706 100644
--- a/e2e/ratchet/partner/relationshipFingerprint.go
+++ b/e2e/ratchet/partner/relationshipFingerprint.go
@@ -9,8 +9,8 @@ package partner
 
 import (
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	session2 "gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/e2e"
diff --git a/e2e/ratchet/partner/relationship_test.go b/e2e/ratchet/partner/relationship_test.go
index 2fc5f85fbca0bca703ffe238e79aaaccc161883c..26df47aa615bcf0babcbd4ab52e8580edec710ff 100644
--- a/e2e/ratchet/partner/relationship_test.go
+++ b/e2e/ratchet/partner/relationship_test.go
@@ -12,9 +12,9 @@ import (
 	"testing"
 
 	"github.com/cloudflare/circl/dh/sidh"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
 	util "gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	dh "gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/fastRNG"
diff --git a/e2e/ratchet/partner/session/negotiation.go b/e2e/ratchet/partner/session/negotiation.go
index 1f8b4ffec5043249e59d6d19cf2a0874fd7d4edc..c57aabee10235ad5c449c52aa96b1fedb1918ca3 100644
--- a/e2e/ratchet/partner/session/negotiation.go
+++ b/e2e/ratchet/partner/session/negotiation.go
@@ -25,7 +25,7 @@ const (
 	NewSessionCreated
 )
 
-//Adherence to stringer interface
+// Adherence to stringer interface
 func (c Negotiation) String() string {
 	switch c {
 	case Unconfirmed:
diff --git a/e2e/ratchet/partner/session/session.go b/e2e/ratchet/partner/session/session.go
index e951652160c1beda1d206b7e3526a7ebeeaa020d..653eb0d2cfeba70e7edcf12915a56f2285ccd675 100644
--- a/e2e/ratchet/partner/session/session.go
+++ b/e2e/ratchet/partner/session/session.go
@@ -19,8 +19,8 @@ import (
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	dh "gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/fastRNG"
diff --git a/e2e/ratchet/partner/session/testUtils.go b/e2e/ratchet/partner/session/testUtils.go
index d5ac95c117a504a187912134de69158ada15c6d7..09d2b7d420af6cb04ac192c69794ada71aba6b11 100644
--- a/e2e/ratchet/partner/session/testUtils.go
+++ b/e2e/ratchet/partner/session/testUtils.go
@@ -13,8 +13,8 @@ import (
 
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/pkg/errors"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	util "gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	dh "gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/fastRNG"
diff --git a/e2e/ratchet/partner/utils_test.go b/e2e/ratchet/partner/utils_test.go
index 6af81d3f80b3440bebba4d1dfee588ff15b50a2e..935cf17f47f9e5d71faf3ace6bbdbdf9e6817a94 100644
--- a/e2e/ratchet/partner/utils_test.go
+++ b/e2e/ratchet/partner/utils_test.go
@@ -13,9 +13,9 @@ import (
 	"testing"
 
 	"github.com/cloudflare/circl/dh/sidh"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
 	util "gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	dh "gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/fastRNG"
diff --git a/e2e/ratchet/ratchet.go b/e2e/ratchet/ratchet.go
index 573eab3f0d8a0bf78ec0ac0f1395de03268856ca..458142b670324ef1fcc0c5d6f507d649d2b18f2f 100644
--- a/e2e/ratchet/ratchet.go
+++ b/e2e/ratchet/ratchet.go
@@ -14,10 +14,10 @@ import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/cmix/message"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
 	util "gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/fastRNG"
diff --git a/e2e/ratchet/ratchet_test.go b/e2e/ratchet/ratchet_test.go
index 8e9f228759b4b83e72a881f384a103ceb1208239..84e95083359f6b930498e933bba170783c29b194 100644
--- a/e2e/ratchet/ratchet_test.go
+++ b/e2e/ratchet/ratchet_test.go
@@ -16,9 +16,9 @@ import (
 	"testing"
 
 	"github.com/cloudflare/circl/dh/sidh"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/ekv"
diff --git a/e2e/ratchet/storage.go b/e2e/ratchet/storage.go
index 5de0a8e2f0cafbf7653f11f0bacb7f26a9593e72..efd801d20cacece09fba70736dc9be71ef26c180 100644
--- a/e2e/ratchet/storage.go
+++ b/e2e/ratchet/storage.go
@@ -13,10 +13,10 @@ import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/cmix/message"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
 	util "gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/e2e/ratchet/utils_test.go b/e2e/ratchet/utils_test.go
index 125023fea0cb54e36832bee3de801657eab8884d..da3e0e4669d4c38de8dd0d5b6206262053805eb6 100644
--- a/e2e/ratchet/utils_test.go
+++ b/e2e/ratchet/utils_test.go
@@ -18,10 +18,10 @@ import (
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/pkg/errors"
 	"gitlab.com/elixxir/client/v4/cmix/message"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
 	util "gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/ekv"
diff --git a/e2e/receive/any.go b/e2e/receive/any.go
index ffa7ca18c6901270e1941efa3ccec1f8dba35a91..28dea55260394a595bd34a855ccf095eae0e63b4 100644
--- a/e2e/receive/any.go
+++ b/e2e/receive/any.go
@@ -15,7 +15,7 @@ import (
 // ID to respond to any message type
 const AnyType = catalog.NoType
 
-//ID to respond to any user
+// ID to respond to any user
 func AnyUser() *id.ID {
 	return &id.ZeroUser
 }
diff --git a/e2e/receive/any_test.go b/e2e/receive/any_test.go
index 3cadcbffd7ec987140bcb52aa0f946abe15b46d1..e5ace81f02ca61a7ab8577e576be6979a41cc2cb 100644
--- a/e2e/receive/any_test.go
+++ b/e2e/receive/any_test.go
@@ -12,7 +12,7 @@ import (
 	"testing"
 )
 
-//tests that AnyUser returns the correct user
+// tests that AnyUser returns the correct user
 func TestAnyUser(t *testing.T) {
 	au := AnyUser()
 	if !au.Cmp(&id.ZeroUser) {
diff --git a/e2e/receive/byID_test.go b/e2e/receive/byID_test.go
index da58460a099e80f324f16096a176419abf55023c..7e3d327d79481afdf89362685c11009b4a0c8cd3 100644
--- a/e2e/receive/byID_test.go
+++ b/e2e/receive/byID_test.go
@@ -47,7 +47,7 @@ func TestById_Get_Empty(t *testing.T) {
 	}
 }
 
-//tests that getting a set for a specific ID returns that set
+// tests that getting a set for a specific ID returns that set
 func TestById_Get_Selected(t *testing.T) {
 	nbi := newById()
 
diff --git a/e2e/receive/listener.go b/e2e/receive/listener.go
index bbf5d5b02ce4102c273c5ed611e485a72fcbab9b..11b9793ac88b37c19ef92fa89dee1cc9a8e9d022 100644
--- a/e2e/receive/listener.go
+++ b/e2e/receive/listener.go
@@ -15,7 +15,7 @@ import (
 	"strings"
 )
 
-//Listener interface for a listener adhere to
+// Listener interface for a listener adhere to
 type Listener interface {
 	// the Hear function is called to exercise the listener, passing in the
 	// data as an item
@@ -67,13 +67,14 @@ func (lid ListenerID) String() string {
 
 /*internal listener implementations*/
 
-//listener based off of a function
+// listener based off of a function
 type funcListener struct {
 	listener ListenerFunc
 	name     string
 }
 
-//  newFuncListener creates a new FuncListener Adhereing to the listener interface out of the
+//	newFuncListener creates a new FuncListener Adhereing to the listener interface out of the
+//
 // passed function and name, returns a pointer to the result
 func newFuncListener(listener ListenerFunc, name string) *funcListener {
 	return &funcListener{
@@ -94,7 +95,7 @@ func (fl *funcListener) Name() string {
 	return fl.name
 }
 
-//listener based off of a channel
+// listener based off of a channel
 type chanListener struct {
 	listener chan Message
 	name     string
diff --git a/e2e/receive/listener_test.go b/e2e/receive/listener_test.go
index 07aec52fc940820d918b86efa7b0f510185a8f12..189c54b0cbeb9d36b235ab48358838e6e852f2a4 100644
--- a/e2e/receive/listener_test.go
+++ b/e2e/receive/listener_test.go
@@ -14,13 +14,13 @@ import (
 	"time"
 )
 
-//verify func listener adheres to the listener interface
+// verify func listener adheres to the listener interface
 var _ Listener = &funcListener{}
 
-//verify chan listener adheres to the listener interface
+// verify chan listener adheres to the listener interface
 var _ Listener = &chanListener{}
 
-//test listenerID returns the userID
+// test listenerID returns the userID
 func TestListenerID_GetUserID(t *testing.T) {
 	lid := ListenerID{
 		userID:      id.NewIdFromUInt(42, id.User, t),
@@ -33,7 +33,7 @@ func TestListenerID_GetUserID(t *testing.T) {
 	}
 }
 
-//test listenerID returns the messageType
+// test listenerID returns the messageType
 func TestListenerID_GetMessageType(t *testing.T) {
 	lid := ListenerID{
 		userID:      id.NewIdFromUInt(42, id.User, t),
@@ -46,7 +46,7 @@ func TestListenerID_GetMessageType(t *testing.T) {
 	}
 }
 
-//test listenerID returns the name
+// test listenerID returns the name
 func TestListenerID_GetName(t *testing.T) {
 	name := "test"
 
@@ -61,7 +61,7 @@ func TestListenerID_GetName(t *testing.T) {
 	}
 }
 
-//tests new function listener creates the funcListener properly
+// tests new function listener creates the funcListener properly
 func TestNewFuncListener(t *testing.T) {
 	f := func(item Message) {}
 	name := "test"
@@ -76,7 +76,7 @@ func TestNewFuncListener(t *testing.T) {
 	}
 }
 
-//tests FuncListener Hear works
+// tests FuncListener Hear works
 func TestFuncListener_Hear(t *testing.T) {
 	m := Message{
 		Payload:     []byte{0, 1, 2, 3},
@@ -114,7 +114,7 @@ func TestFuncListener_Name(t *testing.T) {
 	}
 }
 
-//tests new chan listener creates the chanListener properly
+// tests new chan listener creates the chanListener properly
 func TestNewChanListener(t *testing.T) {
 	c := make(chan Message)
 	name := "test"
@@ -129,7 +129,7 @@ func TestNewChanListener(t *testing.T) {
 	}
 }
 
-//tests ChanListener Hear works
+// tests ChanListener Hear works
 func TestChanListener_Hear(t *testing.T) {
 	m := Message{
 		Payload:     []byte{0, 1, 2, 3},
diff --git a/e2e/rekey/confirm_test.go b/e2e/rekey/confirm_test.go
index 114a82ddb33ac2ecf206ea02a511f4ce0a50baf0..0de5a0807839feab0a2f3e7414c873c6a704dfb3 100644
--- a/e2e/rekey/confirm_test.go
+++ b/e2e/rekey/confirm_test.go
@@ -14,11 +14,11 @@ import (
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/golang/protobuf/proto"
 	"gitlab.com/elixxir/client/v4/catalog"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/v4/e2e/receive"
 	util "gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	dh "gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/ekv"
diff --git a/e2e/rekey/exchange_test.go b/e2e/rekey/exchange_test.go
index b65f9fac8c502fda36be004a6452028d693eab71..b80ef3d6c7cf63b4cafeca0dd6c36d5206d62d48 100644
--- a/e2e/rekey/exchange_test.go
+++ b/e2e/rekey/exchange_test.go
@@ -16,11 +16,11 @@ import (
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/golang/protobuf/proto"
 	"gitlab.com/elixxir/client/v4/catalog"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/v4/e2e/receive"
 	util "gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	dh "gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/ekv"
diff --git a/e2e/rekey/trigger_test.go b/e2e/rekey/trigger_test.go
index 8cf5888ebdb5cd3e2b6194c91a1f6221cd238733..94b4321b90ca73fad0bb507558f60be62ddce022 100644
--- a/e2e/rekey/trigger_test.go
+++ b/e2e/rekey/trigger_test.go
@@ -15,12 +15,12 @@ import (
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/golang/protobuf/proto"
 	"gitlab.com/elixxir/client/v4/catalog"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet"
 	session2 "gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/v4/e2e/receive"
 	"gitlab.com/elixxir/client/v4/stoppable"
 	util "gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	dh "gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/ekv"
diff --git a/e2e/sendE2E_test.go b/e2e/sendE2E_test.go
index 7f6b0c593ad75f41f2778508da1fb7bea03cc56b..b145669f131cc41f65c6cd3de7a381538ba7c30c 100644
--- a/e2e/sendE2E_test.go
+++ b/e2e/sendE2E_test.go
@@ -12,6 +12,7 @@ import (
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/pkg/errors"
 	"gitlab.com/elixxir/client/v4/catalog"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/parse"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
@@ -19,7 +20,6 @@ import (
 	"gitlab.com/elixxir/client/v4/e2e/rekey"
 	"gitlab.com/elixxir/client/v4/stoppable"
 	util "gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	dh "gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/e2e"
diff --git a/e2e/sendUnsafe_test.go b/e2e/sendUnsafe_test.go
index b9d87c15f0343f5b59ce734a1e69932df45f85a8..25dbb005cd0e96118b0adec250eb10ad2e6155cd 100644
--- a/e2e/sendUnsafe_test.go
+++ b/e2e/sendUnsafe_test.go
@@ -9,11 +9,11 @@ package e2e
 
 import (
 	"gitlab.com/elixxir/client/v4/catalog"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/parse"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet"
 	"gitlab.com/elixxir/client/v4/e2e/receive"
 	"gitlab.com/elixxir/client/v4/e2e/rekey"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	dh "gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/ekv"
diff --git a/e2e/utils_test.go b/e2e/utils_test.go
index 424ec285543b92327572038715c89c09bdb6b7de..c2ddbd63e6ac5dd24526012f9a4d204ad3ab4a6e 100644
--- a/e2e/utils_test.go
+++ b/e2e/utils_test.go
@@ -266,14 +266,14 @@ func (m *mockCmix) TrackServices(message.ServicesTracker)                    {}
 func (m *mockCmix) GetServices() (message.ServiceList, message.CompressedServiceList) {
 	return message.ServiceList{}, message.CompressedServiceList{}
 }
-func (m *mockCmix) CheckInProgressMessages()                                 {}
-func (m *mockCmix) IsHealthy() bool                                          { return m.health }
-func (m *mockCmix) WasHealthy() bool                                         { return true }
-func (m *mockCmix) AddHealthCallback(func(bool)) uint64                      { return 0 }
-func (m *mockCmix) RemoveHealthCallback(uint64)                              {}
-func (m *mockCmix) HasNode(*id.ID) bool                                      { return true }
-func (m *mockCmix) NumRegisteredNodes() int                                  { return 0 }
-func (m *mockCmix) TriggerNodeRegistration(*id.ID)                           {}
+func (m *mockCmix) CheckInProgressMessages()            {}
+func (m *mockCmix) IsHealthy() bool                     { return m.health }
+func (m *mockCmix) WasHealthy() bool                    { return true }
+func (m *mockCmix) AddHealthCallback(func(bool)) uint64 { return 0 }
+func (m *mockCmix) RemoveHealthCallback(uint64)         {}
+func (m *mockCmix) HasNode(*id.ID) bool                 { return true }
+func (m *mockCmix) NumRegisteredNodes() int             { return 0 }
+func (m *mockCmix) TriggerNodeRegistration(*id.ID)      {}
 func (m *mockCmix) GetRoundResults(time.Duration, cmix.RoundEventCallback, ...id.Round) {
 }
 func (m *mockCmix) LookupHistoricalRound(id.Round, rounds.RoundResultCallback) error { return nil }
diff --git a/emoji/data.go b/emoji/data.go
index 9d8de41123abfdc272094347536b89b614000642..a931ee0f2a7f74547fc7780dd2cba1251d192234 100644
--- a/emoji/data.go
+++ b/emoji/data.go
@@ -13,7 +13,7 @@ var emojiFile = File{
 	Date:         "2022-08-12, 20:24:39 GMT",
 	DateAccessed: "2023-04-03, 16:36:15 UTC",
 	Version:      "15.0",
-	Map: Map{ 
+	Map: Map{
 		"#⃣": {
 			Character: "#⃣",
 			Name:      "keycap: #",
diff --git a/fileTransfer/connect/utils_test.go b/fileTransfer/connect/utils_test.go
index 48ec5436c6e7bf5cefaf40e68d415082602cc731..d3423fcd40743c60c323692b17313b30e302c1ef 100644
--- a/fileTransfer/connect/utils_test.go
+++ b/fileTransfer/connect/utils_test.go
@@ -20,13 +20,13 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/message"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner"
 	"gitlab.com/elixxir/client/v4/e2e/receive"
 	"gitlab.com/elixxir/client/v4/stoppable"
 	"gitlab.com/elixxir/client/v4/storage"
 	"gitlab.com/elixxir/client/v4/storage/user"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/client/v4/xxdk"
 	"gitlab.com/elixxir/comms/network"
 	"gitlab.com/elixxir/crypto/cyclic"
@@ -187,9 +187,9 @@ func (m *mockCmix) TrackServices(message.ServicesTracker)                    { p
 func (m *mockCmix) GetServices() (message.ServiceList, message.CompressedServiceList) {
 	panic("implement me")
 }
-func (m *mockCmix) CheckInProgressMessages()                                 {}
-func (m *mockCmix) IsHealthy() bool                                          { return m.health }
-func (m *mockCmix) WasHealthy() bool                                         { return true }
+func (m *mockCmix) CheckInProgressMessages() {}
+func (m *mockCmix) IsHealthy() bool          { return m.health }
+func (m *mockCmix) WasHealthy() bool         { return true }
 
 func (m *mockCmix) AddHealthCallback(f func(bool)) uint64 {
 	m.Lock()
@@ -334,13 +334,15 @@ type mockStorage struct {
 
 func newMockStorage() *mockStorage {
 	b := make([]byte, 768)
-	rng := fastRNG.NewStreamGenerator(1000, 10, csprng.NewSystemRNG).GetStream()
+	rng := fastRNG.NewStreamGenerator(1000, 10,
+		csprng.NewSystemRNG).GetStream()
 	_, _ = rng.Read(b)
 	rng.Close()
 
 	return &mockStorage{
-		kv:        versioned.NewKV(ekv.MakeMemstore()),
-		cmixGroup: cyclic.NewGroup(large.NewIntFromBytes(b), large.NewInt(2)),
+		kv: versioned.NewKV(ekv.MakeMemstore()),
+		cmixGroup: cyclic.NewGroup(large.NewIntFromBytes(b),
+			large.NewInt(2)),
 	}
 }
 
@@ -348,13 +350,13 @@ func (m *mockStorage) GetClientVersion() version.Version     { panic("implement
 func (m *mockStorage) Get(string) (*versioned.Object, error) { panic("implement me") }
 func (m *mockStorage) Set(string, *versioned.Object) error   { panic("implement me") }
 func (m *mockStorage) Delete(string) error                   { panic("implement me") }
-func (m *mockStorage) GetKV() versioned.KV                  { return m.kv }
+func (m *mockStorage) GetKV() versioned.KV                   { return m.kv }
 func (m *mockStorage) GetCmixGroup() *cyclic.Group           { return m.cmixGroup }
 func (m *mockStorage) GetE2EGroup() *cyclic.Group            { panic("implement me") }
 func (m *mockStorage) ForwardRegistrationStatus(storage.RegistrationStatus) error {
 	panic("implement me")
 }
-func (m *mockStorage) GetRegistrationStatus() storage.RegistrationStatus      { panic("implement me") }
+func (m *mockStorage) RegStatus() storage.RegistrationStatus                  { panic("implement me") }
 func (m *mockStorage) SetRegCode(string)                                      { panic("implement me") }
 func (m *mockStorage) GetRegCode() (string, error)                            { panic("implement me") }
 func (m *mockStorage) SetNDF(*ndf.NetworkDefinition)                          { panic("implement me") }
diff --git a/fileTransfer/e2e/utils_test.go b/fileTransfer/e2e/utils_test.go
index 2df02e848c0a411672b7eae6e0aff554a8398ad7..f1f0a7cd12c1038fffdf05159144f55920ca31c5 100644
--- a/fileTransfer/e2e/utils_test.go
+++ b/fileTransfer/e2e/utils_test.go
@@ -20,6 +20,7 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/message"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
@@ -27,7 +28,6 @@ import (
 	"gitlab.com/elixxir/client/v4/stoppable"
 	"gitlab.com/elixxir/client/v4/storage"
 	userStorage "gitlab.com/elixxir/client/v4/storage/user"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/client/v4/xxdk"
 	"gitlab.com/elixxir/comms/network"
 	"gitlab.com/elixxir/crypto/cyclic"
@@ -191,9 +191,9 @@ func (m *mockCmix) TrackServices(message.ServicesTracker)                    { p
 func (m *mockCmix) GetServices() (message.ServiceList, message.CompressedServiceList) {
 	panic("implement me")
 }
-func (m *mockCmix) CheckInProgressMessages()                                 {}
-func (m *mockCmix) IsHealthy() bool                                          { return m.health }
-func (m *mockCmix) WasHealthy() bool                                         { return true }
+func (m *mockCmix) CheckInProgressMessages() {}
+func (m *mockCmix) IsHealthy() bool          { return m.health }
+func (m *mockCmix) WasHealthy() bool         { return true }
 
 func (m *mockCmix) AddHealthCallback(f func(bool)) uint64 {
 	m.Lock()
@@ -359,13 +359,15 @@ type mockStorage struct {
 
 func newMockStorage() *mockStorage {
 	b := make([]byte, 768)
-	rng := fastRNG.NewStreamGenerator(1000, 10, csprng.NewSystemRNG).GetStream()
+	rng := fastRNG.NewStreamGenerator(1000, 10,
+		csprng.NewSystemRNG).GetStream()
 	_, _ = rng.Read(b)
 	rng.Close()
 
 	return &mockStorage{
-		kv:        versioned.NewKV(ekv.MakeMemstore()),
-		cmixGroup: cyclic.NewGroup(large.NewIntFromBytes(b), large.NewInt(2)),
+		kv: versioned.NewKV(ekv.MakeMemstore()),
+		cmixGroup: cyclic.NewGroup(large.NewIntFromBytes(b),
+			large.NewInt(2)),
 	}
 }
 
@@ -373,13 +375,13 @@ func (m *mockStorage) GetClientVersion() version.Version     { panic("implement
 func (m *mockStorage) Get(string) (*versioned.Object, error) { panic("implement me") }
 func (m *mockStorage) Set(string, *versioned.Object) error   { panic("implement me") }
 func (m *mockStorage) Delete(string) error                   { panic("implement me") }
-func (m *mockStorage) GetKV() versioned.KV                  { return m.kv }
+func (m *mockStorage) GetKV() versioned.KV                   { return m.kv }
 func (m *mockStorage) GetCmixGroup() *cyclic.Group           { return m.cmixGroup }
 func (m *mockStorage) GetE2EGroup() *cyclic.Group            { panic("implement me") }
 func (m *mockStorage) ForwardRegistrationStatus(storage.RegistrationStatus) error {
 	panic("implement me")
 }
-func (m *mockStorage) GetRegistrationStatus() storage.RegistrationStatus      { panic("implement me") }
+func (m *mockStorage) RegStatus() storage.RegistrationStatus                  { panic("implement me") }
 func (m *mockStorage) SetRegCode(string)                                      { panic("implement me") }
 func (m *mockStorage) GetRegCode() (string, error)                            { panic("implement me") }
 func (m *mockStorage) SetNDF(*ndf.NetworkDefinition)                          { panic("implement me") }
diff --git a/fileTransfer/groupChat/utils_test.go b/fileTransfer/groupChat/utils_test.go
index 3a71e34eaca8c6f73aa81ffaf40d7b680bc3d9ed..10ddf6278e310b400981bdc0837632830cf820b6 100644
--- a/fileTransfer/groupChat/utils_test.go
+++ b/fileTransfer/groupChat/utils_test.go
@@ -18,12 +18,12 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/message"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e"
 	"gitlab.com/elixxir/client/v4/groupChat"
 	"gitlab.com/elixxir/client/v4/stoppable"
 	"gitlab.com/elixxir/client/v4/storage"
 	"gitlab.com/elixxir/client/v4/storage/user"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/client/v4/xxdk"
 	"gitlab.com/elixxir/comms/network"
 	"gitlab.com/elixxir/crypto/cyclic"
@@ -310,13 +310,13 @@ func (m *mockStorage) GetClientVersion() version.Version     { panic("implement
 func (m *mockStorage) Get(string) (*versioned.Object, error) { panic("implement me") }
 func (m *mockStorage) Set(string, *versioned.Object) error   { panic("implement me") }
 func (m *mockStorage) Delete(string) error                   { panic("implement me") }
-func (m *mockStorage) GetKV() versioned.KV                  { return m.kv }
+func (m *mockStorage) GetKV() versioned.KV                   { return m.kv }
 func (m *mockStorage) GetCmixGroup() *cyclic.Group           { return m.cmixGroup }
 func (m *mockStorage) GetE2EGroup() *cyclic.Group            { panic("implement me") }
 func (m *mockStorage) ForwardRegistrationStatus(storage.RegistrationStatus) error {
 	panic("implement me")
 }
-func (m *mockStorage) GetRegistrationStatus() storage.RegistrationStatus      { panic("implement me") }
+func (m *mockStorage) RegStatus() storage.RegistrationStatus                  { panic("implement me") }
 func (m *mockStorage) SetRegCode(string)                                      { panic("implement me") }
 func (m *mockStorage) GetRegCode() (string, error)                            { panic("implement me") }
 func (m *mockStorage) SetNDF(*ndf.NetworkDefinition)                          { panic("implement me") }
diff --git a/fileTransfer/manager.go b/fileTransfer/manager.go
index 28f0876c8f45ffd03ec4720a696b8be2f93debc0..f17f7c165498c0065af07b9fb01d7b8e22943fed 100644
--- a/fileTransfer/manager.go
+++ b/fileTransfer/manager.go
@@ -14,13 +14,13 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix"
 	"gitlab.com/elixxir/client/v4/cmix/message"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e"
 	"gitlab.com/elixxir/client/v4/fileTransfer/callbackTracker"
 	"gitlab.com/elixxir/client/v4/fileTransfer/store"
 	"gitlab.com/elixxir/client/v4/fileTransfer/store/fileMessage"
 	"gitlab.com/elixxir/client/v4/stoppable"
 	"gitlab.com/elixxir/client/v4/storage"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/client/v4/xxdk"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/fastRNG"
diff --git a/fileTransfer/store/cypher/manager.go b/fileTransfer/store/cypher/manager.go
index ad32184625b45024393470711c3b6d9ec2228a6c..1e392772ec4656763249bc2f96ec8c5cbc2d49e1 100644
--- a/fileTransfer/store/cypher/manager.go
+++ b/fileTransfer/store/cypher/manager.go
@@ -9,8 +9,8 @@ package cypher
 
 import (
 	"github.com/pkg/errors"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/fileTransfer/store/cypher/manager_test.go b/fileTransfer/store/cypher/manager_test.go
index 4d34d0e2c9612818ec5f635addbf38fe050e0b8c..8f28a5df34af4e6bbd8364722a5c26c86a949c38 100644
--- a/fileTransfer/store/cypher/manager_test.go
+++ b/fileTransfer/store/cypher/manager_test.go
@@ -13,8 +13,8 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/require"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/crypto/csprng"
diff --git a/fileTransfer/store/received.go b/fileTransfer/store/received.go
index b252f90818f5a95fea68b60bc909a4f3a0d047a2..169528be593de35517b7b099efdfaf03058813cc 100644
--- a/fileTransfer/store/received.go
+++ b/fileTransfer/store/received.go
@@ -13,7 +13,7 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/fileTransfer/store/receivedTransfer.go b/fileTransfer/store/receivedTransfer.go
index 5f2ced9cc5f49dc793c3f881c8592f91baaa38c6..3119e93383f0393cf7b7b3c91f5809b0ec0c1740 100644
--- a/fileTransfer/store/receivedTransfer.go
+++ b/fileTransfer/store/receivedTransfer.go
@@ -16,9 +16,9 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/fileTransfer/store/cypher"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/fileTransfer/store/receivedTransfer_test.go b/fileTransfer/store/receivedTransfer_test.go
index 6b4d3beae6c4b6f3aad4bc8a2c9500fa53b9b9c2..a996dd83594e49d82bd4a3bdff5a4451a2c08605 100644
--- a/fileTransfer/store/receivedTransfer_test.go
+++ b/fileTransfer/store/receivedTransfer_test.go
@@ -14,9 +14,9 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/require"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/fileTransfer/store/cypher"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/crypto/csprng"
diff --git a/fileTransfer/store/received_test.go b/fileTransfer/store/received_test.go
index cf2ccaa7bc1680387d2b4001a615f513ad890256..83b28e0e5d6b003cc1220e64f837bdb000086618 100644
--- a/fileTransfer/store/received_test.go
+++ b/fileTransfer/store/received_test.go
@@ -11,7 +11,7 @@ import (
 	"bytes"
 	"fmt"
 	"github.com/stretchr/testify/require"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/crypto/csprng"
diff --git a/fileTransfer/store/sent.go b/fileTransfer/store/sent.go
index f3f7d3395b6d3dc630e643e0d2a4ff6148f492d0..9e8087a7dd03650b8360078dd10e145bafffb498 100644
--- a/fileTransfer/store/sent.go
+++ b/fileTransfer/store/sent.go
@@ -13,7 +13,7 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/fileTransfer/store/sentTransfer.go b/fileTransfer/store/sentTransfer.go
index dfe4b0fa118b1a5847ee15c5f8e711e813939538..1cd323a412028820c506faf69dc2ec1d1057aad1 100644
--- a/fileTransfer/store/sentTransfer.go
+++ b/fileTransfer/store/sentTransfer.go
@@ -15,9 +15,9 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/fileTransfer/store/cypher"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/fileTransfer/store/sentTransfer_test.go b/fileTransfer/store/sentTransfer_test.go
index 5aad2267da9dc3d48dc5a3cb9f544b1f8e0b168a..eb883b6302df6d30b30d4df3449dfcfe3622496b 100644
--- a/fileTransfer/store/sentTransfer_test.go
+++ b/fileTransfer/store/sentTransfer_test.go
@@ -11,10 +11,10 @@ import (
 	"bytes"
 	"fmt"
 	"github.com/stretchr/testify/require"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/fileTransfer/store/cypher"
 	"gitlab.com/elixxir/client/v4/fileTransfer/store/fileMessage"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/elixxir/primitives/format"
diff --git a/fileTransfer/store/sent_test.go b/fileTransfer/store/sent_test.go
index 246d069cf25a52176cae2d6a3e759b4d493bb5aa..1a23159ed799afbc9ee3c99da1027a02a64a0b4e 100644
--- a/fileTransfer/store/sent_test.go
+++ b/fileTransfer/store/sent_test.go
@@ -11,7 +11,7 @@ import (
 	"bytes"
 	"fmt"
 	"github.com/stretchr/testify/require"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	ftCrypto "gitlab.com/elixxir/crypto/fileTransfer"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/crypto/csprng"
diff --git a/fileTransfer/utils_test.go b/fileTransfer/utils_test.go
index fe2a8197aefc123d6f85536b7387eeea73695d95..ddb16fb948814cc236530ba393bd09532e553e73 100644
--- a/fileTransfer/utils_test.go
+++ b/fileTransfer/utils_test.go
@@ -23,11 +23,11 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/message"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e"
 	"gitlab.com/elixxir/client/v4/stoppable"
 	"gitlab.com/elixxir/client/v4/storage"
 	userStorage "gitlab.com/elixxir/client/v4/storage/user"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/client/v4/xxdk"
 	"gitlab.com/elixxir/comms/network"
 	"gitlab.com/elixxir/crypto/cyclic"
@@ -308,13 +308,15 @@ type mockStorage struct {
 
 func newMockStorage() *mockStorage {
 	b := make([]byte, 768)
-	rng := fastRNG.NewStreamGenerator(1000, 10, csprng.NewSystemRNG).GetStream()
+	rng := fastRNG.NewStreamGenerator(1000, 10,
+		csprng.NewSystemRNG).GetStream()
 	_, _ = rng.Read(b)
 	rng.Close()
 
 	return &mockStorage{
-		kv:        versioned.NewKV(ekv.MakeMemstore()),
-		cmixGroup: cyclic.NewGroup(large.NewIntFromBytes(b), large.NewInt(2)),
+		kv: versioned.NewKV(ekv.MakeMemstore()),
+		cmixGroup: cyclic.NewGroup(large.NewIntFromBytes(b),
+			large.NewInt(2)),
 	}
 }
 
@@ -322,13 +324,13 @@ func (m *mockStorage) GetClientVersion() version.Version     { panic("implement
 func (m *mockStorage) Get(string) (*versioned.Object, error) { panic("implement me") }
 func (m *mockStorage) Set(string, *versioned.Object) error   { panic("implement me") }
 func (m *mockStorage) Delete(string) error                   { panic("implement me") }
-func (m *mockStorage) GetKV() versioned.KV                  { return m.kv }
+func (m *mockStorage) GetKV() versioned.KV                   { return m.kv }
 func (m *mockStorage) GetCmixGroup() *cyclic.Group           { return m.cmixGroup }
 func (m *mockStorage) GetE2EGroup() *cyclic.Group            { panic("implement me") }
 func (m *mockStorage) ForwardRegistrationStatus(storage.RegistrationStatus) error {
 	panic("implement me")
 }
-func (m *mockStorage) GetRegistrationStatus() storage.RegistrationStatus      { panic("implement me") }
+func (m *mockStorage) RegStatus() storage.RegistrationStatus                  { panic("implement me") }
 func (m *mockStorage) SetRegCode(string)                                      { panic("implement me") }
 func (m *mockStorage) GetRegCode() (string, error)                            { panic("implement me") }
 func (m *mockStorage) SetNDF(*ndf.NetworkDefinition)                          { panic("implement me") }
diff --git a/groupChat/groupStore/group.go b/groupChat/groupStore/group.go
index 4d551f7fa6967b671f40fa89b252cdeaf7dab176..58006c0073faa282189d0f2476135e4083c4bc08 100644
--- a/groupChat/groupStore/group.go
+++ b/groupChat/groupStore/group.go
@@ -15,7 +15,7 @@ import (
 	"time"
 
 	"github.com/pkg/errors"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/group"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/groupChat/groupStore/group_test.go b/groupChat/groupStore/group_test.go
index c311fb3451ac38ecefa925801226a4d0d2216ce5..87ecd7ba9a31f98059e3512f2413ffa1060ac62b 100644
--- a/groupChat/groupStore/group_test.go
+++ b/groupChat/groupStore/group_test.go
@@ -8,7 +8,7 @@
 package groupStore
 
 import (
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/group"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/groupChat/groupStore/store.go b/groupChat/groupStore/store.go
index 25923f0946b5e18dfbf59961ff9bdb1183ddf9ff..4993a8210efa76d543640f5bd6714fab59da7af9 100644
--- a/groupChat/groupStore/store.go
+++ b/groupChat/groupStore/store.go
@@ -14,7 +14,7 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/group"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/groupChat/groupStore/store_test.go b/groupChat/groupStore/store_test.go
index a13d98cf44d1915f4980f0938259d39479c78ec1..5c6310c5f56631f77fafeb531d6753a316b24b7c 100644
--- a/groupChat/groupStore/store_test.go
+++ b/groupChat/groupStore/store_test.go
@@ -11,7 +11,7 @@ import (
 	"bytes"
 	"fmt"
 	"github.com/stretchr/testify/require"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/group"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
diff --git a/groupChat/manager_test.go b/groupChat/manager_test.go
index b4cd58cb7c05d3ac6912330ffd0c3d987bfae180..6fb75747e7b188ee6049e28c5756aa8127fd96dc 100644
--- a/groupChat/manager_test.go
+++ b/groupChat/manager_test.go
@@ -11,9 +11,9 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix"
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	e2eImport "gitlab.com/elixxir/client/v4/e2e"
 	gs "gitlab.com/elixxir/client/v4/groupChat/groupStore"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/group"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/elixxir/primitives/format"
diff --git a/groupChat/messenger_test.go b/groupChat/messenger_test.go
index 7fd78bb97984a2a774636a2c1f13697f7491b10b..e3d8e0840d7834e669d3245acc73a22697503691 100644
--- a/groupChat/messenger_test.go
+++ b/groupChat/messenger_test.go
@@ -9,10 +9,10 @@ package groupChat
 
 import (
 	"gitlab.com/elixxir/client/v4/cmix"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	clientE2E "gitlab.com/elixxir/client/v4/e2e"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner"
 	"gitlab.com/elixxir/client/v4/storage"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/client/v4/xxdk"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/fastRNG"
diff --git a/groupChat/session_test.go b/groupChat/session_test.go
index 5d8e485a38619862135f8d81e6400b8db2a5c8f1..d73682d14932d689e1622fdadaccc250fbbcd2b1 100644
--- a/groupChat/session_test.go
+++ b/groupChat/session_test.go
@@ -8,16 +8,17 @@
 package groupChat
 
 import (
+	"time"
+
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage"
 	"gitlab.com/elixxir/client/v4/storage/user"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/rsa"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/elixxir/primitives/version"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/ndf"
-	"time"
 )
 
 // mockSession is a storage.Session implementation for testing.
@@ -75,7 +76,7 @@ func (m mockSession) ForwardRegistrationStatus(regStatus storage.RegistrationSta
 	panic("implement me")
 }
 
-func (m mockSession) GetRegistrationStatus() storage.RegistrationStatus {
+func (m mockSession) RegStatus() storage.RegistrationStatus {
 	//TODO implement me
 	panic("implement me")
 }
diff --git a/groupChat/utils_test.go b/groupChat/utils_test.go
index 3fcfc3d1caf5bfee792127609d80dce965216128..8b69540d1d811b8e38796ef8f8619c28ac9fb96c 100644
--- a/groupChat/utils_test.go
+++ b/groupChat/utils_test.go
@@ -9,10 +9,10 @@ package groupChat
 
 import (
 	"encoding/base64"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner"
 	"gitlab.com/elixxir/client/v4/event"
 	gs "gitlab.com/elixxir/client/v4/groupChat/groupStore"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/group"
diff --git a/interfaces/auth.go b/interfaces/auth.go
deleted file mode 100644
index fe022dfe471a8696adc56f765ff6a6e96db2418b..0000000000000000000000000000000000000000
--- a/interfaces/auth.go
+++ /dev/null
@@ -1,14 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// Copyright © 2022 xx foundation                                             //
-//                                                                            //
-// Use of this source code is governed by a license that can be found in the  //
-// LICENSE file.                                                              //
-////////////////////////////////////////////////////////////////////////////////
-
-package interfaces
-
-import (
-	"gitlab.com/elixxir/crypto/contact"
-)
-
-type RequestCallback func(requestor contact.Contact)
diff --git a/interfaces/clientError.go b/interfaces/clientError.go
deleted file mode 100644
index 86b55ac9f959abc6bef07c5870c71a94a78fa0a8..0000000000000000000000000000000000000000
--- a/interfaces/clientError.go
+++ /dev/null
@@ -1,16 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// Copyright © 2022 xx foundation                                             //
-//                                                                            //
-// Use of this source code is governed by a license that can be found in the  //
-// LICENSE file.                                                              //
-////////////////////////////////////////////////////////////////////////////////
-
-package interfaces
-
-type ClientError struct {
-	Source  string
-	Message string
-	Trace   string
-}
-
-type ClientErrorReport func(source, message, trace string)
diff --git a/interfaces/ephemeral.go b/interfaces/ephemeral.go
deleted file mode 100644
index 57523cb5e123322a41f551d4d6aab3c68b00f042..0000000000000000000000000000000000000000
--- a/interfaces/ephemeral.go
+++ /dev/null
@@ -1,11 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// Copyright © 2022 xx foundation                                             //
-//                                                                            //
-// Use of this source code is governed by a license that can be found in the  //
-// LICENSE file.                                                              //
-////////////////////////////////////////////////////////////////////////////////
-
-package interfaces
-
-// DefaultExtraChecks is the default value for ExtraChecks on reception.Identity
-const DefaultExtraChecks = 10
diff --git a/interfaces/restoreContacts.go b/interfaces/restoreContacts.go
deleted file mode 100644
index 82ca65b825d5081baff773519d6d0c0eced6a39c..0000000000000000000000000000000000000000
--- a/interfaces/restoreContacts.go
+++ /dev/null
@@ -1,19 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// Copyright © 2022 xx foundation                                             //
-//                                                                            //
-// Use of this source code is governed by a license that can be found in the  //
-// LICENSE file.                                                              //
-////////////////////////////////////////////////////////////////////////////////
-
-package interfaces
-
-// RestoreContactsUpdater interface provides a callback function
-// for receiving update information from RestoreContactsFromBackup.
-type RestoreContactsUpdater interface {
-	// RestoreContactsCallback is called to report the current # of contacts
-	// that have been found and how many have been restored
-	// against the total number that need to be
-	// processed. If an error occurs it it set on the err variable as a
-	// plain string.
-	RestoreContactsCallback(numFound, numRestored, total int, err string)
-}
diff --git a/interfaces/roundEvents.go b/interfaces/roundEvents.go
deleted file mode 100644
index a2113d6f5fe86959aa365729eac5c8ae2bd8f3e1..0000000000000000000000000000000000000000
--- a/interfaces/roundEvents.go
+++ /dev/null
@@ -1,39 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// Copyright © 2022 xx foundation                                             //
-//                                                                            //
-// Use of this source code is governed by a license that can be found in the  //
-// LICENSE file.                                                              //
-////////////////////////////////////////////////////////////////////////////////
-
-package interfaces
-
-import (
-	ds "gitlab.com/elixxir/comms/network/dataStructures"
-	"gitlab.com/elixxir/primitives/states"
-	"gitlab.com/xx_network/primitives/id"
-	"time"
-)
-
-// The round events interface allows the registration of an event which triggers
-// when a round reaches one or more states
-
-type RoundEvents interface {
-	// designates a callback to call on the specified event
-	// rid is the id of the round the event occurs on
-	// callback is the callback the event is triggered on
-	// timeout is the amount of time before an error event is returned
-	// valid states are the states which the event should trigger on
-	AddRoundEvent(rid id.Round, callback ds.RoundEventCallback,
-		timeout time.Duration, validStates ...states.Round) *ds.EventCallback
-
-	// designates a go channel to signal the specified event
-	// rid is the id of the round the event occurs on
-	// eventChan is the channel the event is triggered on
-	// timeout is the amount of time before an error event is returned
-	// valid states are the states which the event should trigger on
-	AddRoundEventChan(rid id.Round, eventChan chan ds.EventReturn,
-		timeout time.Duration, validStates ...states.Round) *ds.EventCallback
-
-	//Allows the un-registration of a round event before it triggers
-	Remove(rid id.Round, e *ds.EventCallback)
-}
diff --git a/notifications/interface.go b/notifications/interface.go
index 66bd3646b17112e49af16fc1366e019b8dc63df0..9ce901a3d5edbf80d53637176b5fbd664b88f222 100644
--- a/notifications/interface.go
+++ b/notifications/interface.go
@@ -97,6 +97,9 @@ type Manager interface {
 	// It will remove all registered identities if it is the last Token.
 	RemoveToken() error
 
+	// GetToken returns the token if it is registered
+	GetToken() (has bool, token, app string)
+
 	// RegisterUpdateCallback registers a callback to be used to receive updates
 	// to changes in notifications. Because this is being called after
 	// initialization, a poll of state via the get function will be necessary
diff --git a/notifications/manager.go b/notifications/manager.go
index 74fec1a5edeb2de6fe6c3ff1e1e11522ad289edd..3048d81231fc0eaac6e756ee3e90c5f150080d3f 100644
--- a/notifications/manager.go
+++ b/notifications/manager.go
@@ -6,7 +6,7 @@ import (
 	"fmt"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/collective"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/xxdk"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/rsa"
@@ -55,7 +55,8 @@ type manager struct {
 	local  versioned.KV
 	remote versioned.KV
 
-	maxState NotificationState
+	maxState       NotificationState
+	initialization bool
 }
 
 type registration struct {
@@ -110,24 +111,25 @@ func NewOrLoadManager(identity xxdk.TransmissionIdentity, regSig []byte,
 		notifications:                               make(map[id.ID]registration),
 		group:                                       make(map[string]Group),
 		maxState:                                    Push,
+		initialization:                              true,
 	}
 
 	// lock so that an update cannot run while we are loading the basic
 	// notifications structure from disk into ram
-	m.mux.Lock()
-	loadedMap, err := m.remote.ListenOnRemoteMap(notificationsMap,
-		notificationsMapVersion, m.mapUpdate)
-	if err != nil {
-		jww.FATAL.Panicf("Could not load notifications map: %+v", err)
-	}
-	m.loadNotificationsUnsafe(loadedMap)
-	loadedMaxState, err := m.remote.ListenOnRemoteKey(maxStateKey,
-		maxStateKetVersion, m.maxStateUpdate)
+
+	err = m.remote.ListenOnRemoteKey(maxStateKey,
+		maxStateKetVersion, m.maxStateUpdate, false)
 	if err != nil && ekv.Exists(err) {
 		jww.FATAL.Panicf("Could not load notifications state key: %+v", err)
 	}
-	m.loadMaxStateUnsafe(loadedMaxState)
+	err = m.remote.ListenOnRemoteMap(notificationsMap,
+		notificationsMapVersion, m.mapUpdate, false)
+	if err != nil {
+		jww.FATAL.Panicf("Could not load notifications map: %+v", err)
+	}
+	m.mux.Lock()
 	m.loadTokenUnsafe()
+	m.initialization = false
 	m.mux.Unlock()
 
 	return m
@@ -137,16 +139,14 @@ func (m *manager) RegisterUpdateCallback(group string, nu Update) {
 	m.mux.Lock()
 	defer m.mux.Unlock()
 	m.callbacks[group] = nu
+	if g, ok := m.group[group]; ok {
+		nu(g, nil, nil, nil, m.maxState)
+	}
 }
 
 // mapUpdate is the listener function which is called whenever the notifications
 // data is updated based upon a remote sync
-func (m *manager) mapUpdate(mapName string, edits map[string]versioned.ElementEdit) {
-	if mapName != notificationsMap {
-		jww.ERROR.Printf("Got an update for the wrong map, "+
-			"expected: %s, got: %s", notificationsMap, mapName)
-		return
-	}
+func (m *manager) mapUpdate(edits map[string]versioned.ElementEdit) {
 
 	updates := make(groupChanges)
 
@@ -182,7 +182,8 @@ func (m *manager) mapUpdate(mapName string, edits map[string]versioned.ElementEd
 			continue
 		}
 
-		if edit.Operation == versioned.Created {
+		if edit.Operation == versioned.Created ||
+			edit.Operation == versioned.Loaded {
 			updates.AddCreated(newUpdate.Group, nID)
 		} else if edit.Operation == versioned.Updated {
 			updates.AddEdit(newUpdate.Group, nID)
@@ -229,13 +230,7 @@ func (m *manager) loadNotificationsUnsafe(mapObj map[string]*versioned.Object) {
 	}
 }
 
-func (m *manager) maxStateUpdate(key string, old, new *versioned.Object, op versioned.KeyOperation) {
-	if key != maxStateKey {
-		jww.ERROR.Printf("Got an update for the wrong key, "+
-			"expected: %s, got: %s", maxStateKey, key)
-		return
-	}
-
+func (m *manager) maxStateUpdate(old, new *versioned.Object, op versioned.KeyOperation) {
 	if op == versioned.Deleted {
 		jww.FATAL.Panicf("Notifications max state key cannot be deleted")
 	}
@@ -248,11 +243,16 @@ func (m *manager) maxStateUpdate(key string, old, new *versioned.Object, op vers
 			maxStateKey, err)
 		return
 	}
-
-	for g := range m.callbacks {
-		cb := m.callbacks[g]
-		go cb(m.group[g].DeepCopy(), nil, nil, nil, m.maxState)
+	if !m.initialization {
+		for g := range m.callbacks {
+			cb := m.callbacks[g]
+			go cb(m.group[g].DeepCopy(), nil, nil, nil, m.maxState)
+		}
+	} else {
+		jww.DEBUG.Printf("Skipping callback on masStateUpdate to %s, "+
+			"in initialization", m.maxState)
 	}
+
 }
 
 func (m *manager) loadMaxStateUnsafe(obj *versioned.Object) {
@@ -308,10 +308,11 @@ func (m *manager) addToGroupUnsafeRAM(nID *id.ID, reg registration) {
 // deleteNotificationUnsafeRAM removes the given notification registration from
 // the in ram storage, both to notification and groups
 // must be called under the lock
-func (m *manager) deleteNotificationUnsafeRAM(nid *id.ID) {
+// returns the group becasue it may be nesseary
+func (m *manager) deleteNotificationUnsafeRAM(nid *id.ID) string {
 	reg, exists := m.notifications[*nid]
 	if !exists {
-		return
+		return ""
 	}
 
 	groupList := m.group[reg.Group]
@@ -323,6 +324,8 @@ func (m *manager) deleteNotificationUnsafeRAM(nid *id.ID) {
 	}
 
 	delete(m.notifications, *nid)
+
+	return reg.Group
 }
 
 // setTokenUnsafe sets the token in ram and on disk, locally only. Returns true
diff --git a/notifications/manager_test.go b/notifications/manager_test.go
index 1dab4e4d187970407a8cccc0d1296375b18a1890..30c3c3354bc7af25ca299cfbe37eb8666cc0d6ef 100644
--- a/notifications/manager_test.go
+++ b/notifications/manager_test.go
@@ -5,7 +5,7 @@ import (
 	"fmt"
 	"github.com/stretchr/testify/require"
 	"gitlab.com/elixxir/client/v4/collective"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/xxdk"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/crypto/fastRNG"
@@ -229,7 +229,7 @@ func TestManager_mapUpdate(t *testing.T) {
 	}
 
 	// run the map update
-	mInternal.mapUpdate(notificationsMap, edits)
+	mInternal.mapUpdate(edits)
 
 	wg.Wait()
 
@@ -400,9 +400,22 @@ func getGroup(i, numGroups int) int {
 func TestManager_maxStateUpdate(t *testing.T) {
 	m, _, _ := buildTestingManager(t)
 	mInternal := m.(*manager)
+	resultCh := make(chan bool, 1)
 
-	mInternal.maxStateUpdate("blah", nil, nil, versioned.Deleted)
-	// key check worked becasue we didnt crash from the delete panic
+	go func() {
+		defer func() {
+			if r := recover(); r != nil {
+				resultCh <- true
+			}
+		}()
+		mInternal.maxStateUpdate(nil, nil, versioned.Deleted)
+		resultCh <- false
+	}()
+
+	result := <-resultCh
+	if result == false {
+		t.Errorf("Failed to get panic on delete")
+	}
 
 	numGroups := 4
 	numCB := numGroups / 2
@@ -413,14 +426,18 @@ func TestManager_maxStateUpdate(t *testing.T) {
 
 	var setMax NotificationState
 
+	skip := true
 	for i := 0; i < numGroups; i++ {
 		groupName := fmt.Sprintf("grp_%d", i)
 		nid := id.NewIdFromUInt(uint64(i), id.User, t)
-		m.Set(nid, groupName, []byte{0}, NotificationState(i%3))
 		if i%2 == 0 {
+
 			localI := i
 			cb := func(group Group, created, edits, deletions []*id.ID,
 				maxState NotificationState) {
+				if skip {
+					return
+				}
 				if created != nil || edits != nil || deletions != nil {
 					t.Errorf("actions are not nil")
 				}
@@ -433,11 +450,13 @@ func TestManager_maxStateUpdate(t *testing.T) {
 			}
 			m.RegisterUpdateCallback(groupName, cb)
 		}
+		m.Set(nid, groupName, []byte{0}, NotificationState(i%3))
 	}
+	skip = false
 
 	for i := Mute; i <= Push; i++ {
 		setMax = i
-		for j := versioned.Created; j <= versioned.Deleted; j++ {
+		for j := versioned.Created; j <= versioned.Loaded; j++ {
 			ch := make(chan bool)
 			didRun = make([]bool, numGroups)
 			if j != versioned.Deleted {
@@ -450,8 +469,7 @@ func TestManager_maxStateUpdate(t *testing.T) {
 						ch <- false
 					}
 				}()
-				mInternal.maxStateUpdate(maxStateKey, nil,
-					makeMaxStateObj(i, t), j)
+				mInternal.maxStateUpdate(nil, makeMaxStateObj(i, t), j)
 				ch <- true
 			}()
 			result := <-ch
@@ -610,10 +628,13 @@ func TestManager_deleteNotificationUnsafeRAM(t *testing.T) {
 	// some groups and partially from other
 	for i := 0; i < numTests; i++ {
 		if (i%2) == 1 || i < numTests/2 {
-			mInternal.deleteNotificationUnsafeRAM(nids[i])
+			grp := mInternal.deleteNotificationUnsafeRAM(nids[i])
 			if _, exists := mInternal.notifications[*nids[i]]; exists {
 				t.Errorf("Failed to delete %s", nids[i])
 			}
+			if grp != regs[i].Group {
+				t.Errorf("group does not match, %s vs %s", grp, regs[i].Group)
+			}
 		}
 
 	}
diff --git a/notifications/notifications.go b/notifications/notifications.go
index a86a25ad362259451eae8cb88ad459a66324ae01..e363f8563b6ab21b22cf3c978fe8a7f34a3b69a3 100644
--- a/notifications/notifications.go
+++ b/notifications/notifications.go
@@ -4,7 +4,7 @@ import (
 	"bytes"
 	"encoding/json"
 	"errors"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	notifCrypto "gitlab.com/elixxir/crypto/notifications"
 	"gitlab.com/xx_network/primitives/id"
@@ -63,6 +63,19 @@ func (m *manager) Set(toBeNotifiedOn *id.ID, group string, metadata []byte,
 	// update in ram storage
 	m.upsertNotificationUnsafeRAM(toBeNotifiedOn, reg)
 
+	// call the callback if it exists to notify that an update exists
+	if cb, cbExists := m.callbacks[group]; cbExists {
+		// can be nil if the last element was deleted
+		g, _ := m.group[group]
+		var created, updated []*id.ID
+		if exists {
+			updated = []*id.ID{toBeNotifiedOn}
+		} else {
+			created = []*id.ID{toBeNotifiedOn}
+		}
+		go cb(g.DeepCopy(), created, updated, nil, m.maxState)
+	}
+
 	return nil
 }
 
@@ -97,7 +110,14 @@ func (m *manager) Delete(toBeNotifiedOn *id.ID) error {
 
 	_, err := m.remote.DeleteMapElement(notificationsMap, elementName,
 		notificationsMapVersion)
-	m.deleteNotificationUnsafeRAM(toBeNotifiedOn)
+	group := m.deleteNotificationUnsafeRAM(toBeNotifiedOn)
+
+	// call the callback if it exists to notify that an update exists
+	if cb, cbExists := m.callbacks[group]; cbExists {
+		// can be nil if the last element was deleted
+		g, _ := m.group[group]
+		go cb(g.DeepCopy(), nil, nil, []*id.ID{toBeNotifiedOn}, m.maxState)
+	}
 	return err
 }
 
diff --git a/notifications/token.go b/notifications/token.go
index c0e437f30bf989169af1fbf3523e481ba8cb9299..64f5e65b5acfa500d4c19c820712188e54a23def 100644
--- a/notifications/token.go
+++ b/notifications/token.go
@@ -86,3 +86,15 @@ func (m *manager) RemoveToken() error {
 	m.deleteTokenUnsafe()
 	return nil
 }
+
+// GetToken returns the token if it is registered
+func (m *manager) GetToken() (has bool, token, app string) {
+	m.mux.RLock()
+	defer m.mux.RUnlock()
+	if m.token.Token != "" {
+		return true, m.token.Token, m.token.App
+	} else {
+		return false, "", ""
+	}
+
+}
diff --git a/notifications/token_test.go b/notifications/token_test.go
index 81927e8fb37ec531dea29c3a42070e2f13d12d6f..4ca9da9b62dbc53c3dffa2ca56b69cd5c7d3954b 100644
--- a/notifications/token_test.go
+++ b/notifications/token_test.go
@@ -90,3 +90,52 @@ func TestManager_RemoveToken_Smoke(t *testing.T) {
 			err)
 	}
 }
+
+func TestManager_GetToken_Smoke(t *testing.T) {
+
+	m, _, _ := buildTestingManager(t)
+
+	testToken := "mickey"
+	testApp := "mouse"
+
+	exist1, token1, app1 := m.GetToken()
+
+	if exist1 {
+		t.Errorf("token exists when it shouldnt")
+	}
+
+	if token1 != "" || app1 != "" {
+		t.Errorf("token values are set exists when they shouldnt be")
+	}
+
+	err := m.AddToken(testToken, testApp)
+	if err != nil {
+		t.Errorf("Failed to add token when it should be "+
+			"possible: %+v", err)
+	}
+
+	exist2, token2, app2 := m.GetToken()
+
+	if !exist2 {
+		t.Errorf("token doesnt exists when it shouldnt")
+	}
+
+	if token2 != testToken || app2 != testApp {
+		t.Errorf("token values are not set correctly")
+	}
+
+	err = m.RemoveToken()
+	if err != nil {
+		t.Errorf("remove token errored when it shouldnt have: %+v", err)
+	}
+
+	exist3, token3, app3 := m.GetToken()
+
+	if exist3 {
+		t.Errorf("token  exists when it shouldnt")
+	}
+
+	if token3 != "" || app3 != "" {
+		t.Errorf("token values are not set correctly")
+	}
+}
diff --git a/registration/register.go b/registration/register.go
index 0fbe6b240afef04165e5b44277f6e3faab8f1875..378e517bbded8a472bb5043ecff365d5497f5094 100644
--- a/registration/register.go
+++ b/registration/register.go
@@ -26,7 +26,7 @@ type registrationMessageSender interface {
 	SendRegistrationMessage(host *connect.Host, message *pb.ClientRegistration) (*pb.SignedClientRegistrationConfirmations, error)
 }
 
-//register registers the user with optional registration code
+// register registers the user with optional registration code
 // Returns an error if registration fails.
 func register(comms registrationMessageSender, host *connect.Host,
 	transmissionPublicKey, receptionPublicKey rsa.PublicKey,
diff --git a/storage/clientVersion/store.go b/storage/clientVersion/store.go
index edc0e4da0bce5999a4a45419b17c80a9573e8f43..9de13b1b29bf477f00dc4cffac7977dce43f01c8 100644
--- a/storage/clientVersion/store.go
+++ b/storage/clientVersion/store.go
@@ -12,7 +12,7 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/primitives/version"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/storage/clientVersion/store_test.go b/storage/clientVersion/store_test.go
index eee5f3e9ce2ed5bfb3ebd65ae6e457d98e366d7e..44e9a3f1a900239daf6018e1a30f53c41c335a5c 100644
--- a/storage/clientVersion/store_test.go
+++ b/storage/clientVersion/store_test.go
@@ -9,7 +9,7 @@ package clientVersion
 
 import (
 	"github.com/stretchr/testify/require"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/elixxir/primitives/version"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/storage/ndf.go b/storage/ndf.go
index 1cf5225962402d122e44980a83133712e163e52a..a22d144000e5e3aea25d6db636773ab708f1becc 100644
--- a/storage/ndf.go
+++ b/storage/ndf.go
@@ -9,6 +9,7 @@ package storage
 
 import (
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
 	"gitlab.com/xx_network/primitives/ndf"
 )
@@ -16,7 +17,7 @@ import (
 const ndfKey = "ndf"
 
 func (s *session) SetNDF(def *ndf.NetworkDefinition) {
-	err := utility.SaveNDF(s.kv, ndfKey, def)
+	err := SaveNDF(s.kv, def)
 	if err != nil {
 		jww.FATAL.Printf("Failed to dave the NDF: %+v", err)
 	}
@@ -35,3 +36,7 @@ func (s *session) GetNDF() *ndf.NetworkDefinition {
 	s.ndf = def
 	return def
 }
+
+func SaveNDF(kv versioned.KV, def *ndf.NetworkDefinition) error {
+	return utility.SaveNDF(kv, ndfKey, def)
+}
diff --git a/storage/regCode.go b/storage/regCode.go
index 7bd67cb37cb7be8a653f0f657d237c3007026c49..f58fe42018f14a7dcab90fb6becbc8a12ef1a775 100644
--- a/storage/regCode.go
+++ b/storage/regCode.go
@@ -10,7 +10,7 @@ package storage
 import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/netTime"
 )
 
@@ -19,7 +19,7 @@ const regCodeVersion = 0
 
 // SetNDF stores a network definition json file
 func (s *session) SetRegCode(regCode string) {
-	if err := s.Set(regCodeKey,
+	if err := s.syncKV.Set(regCodeKey,
 		&versioned.Object{
 			Version:   regCodeVersion,
 			Data:      []byte(regCode),
@@ -31,7 +31,7 @@ func (s *session) SetRegCode(regCode string) {
 
 // Returns the stored network definition json file
 func (s *session) GetRegCode() (string, error) {
-	regCode, err := s.Get(regCodeKey)
+	regCode, err := s.syncKV.Get(regCodeKey, regCodeVersion)
 	if err != nil {
 		return "", errors.WithMessage(err, "Failed to load the regcode")
 	}
diff --git a/storage/regStatus.go b/storage/regStatus.go
index 49a506c62095e721c76a86b36b8e872136a0df68..f1b3ad9fbd50031e5930b67b8f709a2f56a89dd8 100644
--- a/storage/regStatus.go
+++ b/storage/regStatus.go
@@ -10,8 +10,11 @@ package storage
 import (
 	"encoding/binary"
 	"fmt"
+
+	jww "github.com/spf13/jwalterweatherman"
+
 	"github.com/pkg/errors"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/netTime"
 )
 
@@ -55,19 +58,33 @@ func (rs RegistrationStatus) marshalBinary() []byte {
 	return b
 }
 
+// RegStatus returns the registration status as stored in the
+// kv
+func (s *session) RegStatus() RegistrationStatus {
+	var status RegistrationStatus
+	obj, err := s.syncKV.Get(registrationStatusKey,
+		currentRegistrationStatusVersion)
+	if err == nil {
+		status = regStatusUnmarshalBinary(obj.Data)
+	} else {
+		jww.FATAL.Panicf("could not load RegStatus: %+v", err)
+	}
+	return status
+}
+
 // creates a new registration status and stores it
 func (s *session) newRegStatus() error {
-	s.regStatus = NotStarted
+	regStatus := NotStarted
 
 	now := netTime.Now()
 
 	obj := versioned.Object{
 		Version:   currentRegistrationStatusVersion,
 		Timestamp: now,
-		Data:      s.regStatus.marshalBinary(),
+		Data:      regStatus.marshalBinary(),
 	}
 
-	err := s.Set(registrationStatusKey, &obj)
+	err := s.syncKV.Set(registrationStatusKey, &obj)
 	if err != nil {
 		return errors.WithMessagef(err, "Failed to store new "+
 			"registration status")
@@ -76,26 +93,18 @@ func (s *session) newRegStatus() error {
 	return nil
 }
 
-// loads registration status from disk.
-func (s *session) loadRegStatus() error {
-	obj, err := s.Get(registrationStatusKey)
-	if err != nil {
-		return errors.WithMessage(err, "Failed to load registration status")
-	}
-	s.regStatus = regStatusUnmarshalBinary(obj.Data)
-	return nil
-}
-
 // sets the registration status to the passed status if it is greater than the
 // current stats, otherwise returns an error
-func (s *session) ForwardRegistrationStatus(regStatus RegistrationStatus) error {
+func (s *session) ForwardRegistrationStatus(
+	regStatus RegistrationStatus) error {
 	s.mux.Lock()
 	defer s.mux.Unlock()
 
-	if regStatus <= s.regStatus {
+	oldStatus := s.RegStatus()
+	if regStatus <= oldStatus {
 		return errors.Errorf("Cannot set registration status to a "+
 			"status before the current stats: Current: %s, New: %s",
-			s.regStatus, regStatus)
+			oldStatus, regStatus)
 	}
 
 	now := netTime.Now()
@@ -105,20 +114,10 @@ func (s *session) ForwardRegistrationStatus(regStatus RegistrationStatus) error
 		Timestamp: now,
 		Data:      regStatus.marshalBinary(),
 	}
-
-	err := s.Set(registrationStatusKey, &obj)
+	err := s.syncKV.Set(registrationStatusKey, &obj)
 	if err != nil {
-		return errors.WithMessagef(err, "Failed to store registration status")
+		return errors.Wrapf(err, "Failed to store registration status")
 	}
 
-	s.regStatus = regStatus
 	return nil
 }
-
-// sets the registration status to the passed status if it is greater than the
-// current stats, otherwise returns an error
-func (s *session) GetRegistrationStatus() RegistrationStatus {
-	s.mux.RLock()
-	defer s.mux.RUnlock()
-	return s.regStatus
-}
diff --git a/storage/session.go b/storage/session.go
index 3197c82223b34c85cdd327a0ff43d919a210102a..604c0d017ac69eec7e9d6367b2de4bf8e7742d01 100644
--- a/storage/session.go
+++ b/storage/session.go
@@ -17,14 +17,15 @@ import (
 
 	"gitlab.com/elixxir/crypto/diffieHellman"
 
+	"gitlab.com/elixxir/client/v4/collective"
 	"gitlab.com/elixxir/client/v4/storage/utility"
 	"gitlab.com/xx_network/crypto/large"
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/clientVersion"
 	"gitlab.com/elixxir/client/v4/storage/user"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/rsa"
 	"gitlab.com/elixxir/ekv"
@@ -50,7 +51,7 @@ type Session interface {
 	GetCmixGroup() *cyclic.Group
 	GetE2EGroup() *cyclic.Group
 	ForwardRegistrationStatus(regStatus RegistrationStatus) error
-	GetRegistrationStatus() RegistrationStatus
+	RegStatus() RegistrationStatus
 	SetRegCode(regCode string)
 	GetRegCode() (string, error)
 	SetNDF(def *ndf.NetworkDefinition)
@@ -74,12 +75,12 @@ type Session interface {
 }
 
 type session struct {
-	kv versioned.KV
+	kv     versioned.KV
+	syncKV versioned.KV
 
 	// memoized data
-	mux       sync.RWMutex
-	regStatus RegistrationStatus
-	ndf       *ndf.NetworkDefinition
+	mux sync.RWMutex
+	ndf *ndf.NetworkDefinition
 
 	// network parameters
 	cmixGroup *cyclic.Group
@@ -95,16 +96,23 @@ func New(storage versioned.KV, u user.Info,
 	currentVersion version.Version,
 	cmixGrp, e2eGrp *cyclic.Group) (Session, error) {
 
+	remote, err := storage.Prefix(collective.StandardRemoteSyncPrefix)
+	if err != nil {
+		return nil, errors.Wrapf(err, "create new session")
+	}
+
 	s := &session{
-		kv: storage,
+		kv:     storage,
+		syncKV: remote,
 	}
 
-	err := s.newRegStatus()
+	err = s.newRegStatus()
 	if err != nil {
 		return nil, errors.WithMessage(err,
 			"Create new session")
 	}
 
+	// Note: user does it's own prefixing
 	s.User, err = user.NewUser(s.kv, u.TransmissionID, u.ReceptionID,
 		u.TransmissionSalt, u.ReceptionSalt, u.TransmissionRSA,
 		u.ReceptionRSA, u.Precanned, u.E2eDhPrivateKey,
@@ -114,6 +122,9 @@ func New(storage versioned.KV, u user.Info,
 	}
 
 	s.clientVersion, err = clientVersion.NewStore(currentVersion, s.kv)
+	if err != nil {
+		return nil, err
+	}
 
 	if err = utility.StoreGroup(s.kv, cmixGrp, cmixGroupKey); err != nil {
 		return nil, err
@@ -128,21 +139,39 @@ func New(storage versioned.KV, u user.Info,
 	return s, nil
 }
 
+// InitFromRemote sets local data for a session variable
+func InitFromRemote(storage versioned.KV,
+	currentVersion version.Version,
+	cmixGrp, e2eGrp *cyclic.Group) error {
+	_, err := clientVersion.NewStore(currentVersion, storage)
+	if err != nil {
+		return err
+	}
+
+	if err = utility.StoreGroup(storage, cmixGrp, cmixGroupKey); err != nil {
+		return err
+	}
+
+	if err = utility.StoreGroup(storage, e2eGrp, e2eGroupKey); err != nil {
+		return err
+	}
+
+	_, err = Load(storage, currentVersion)
+	return err
+}
+
 // Load existing user data into the session
 func Load(storage versioned.KV,
 	currentVersion version.Version) (Session, error) {
 
-	s := &session{
-		kv: storage,
+	remote, err := storage.Prefix(collective.StandardRemoteSyncPrefix)
+	if err != nil {
+		return nil, errors.Wrapf(err, "create new session")
 	}
 
-	err := s.loadRegStatus()
-	if err != nil {
-		if !ekv.Exists(err) {
-			return nil, errors.Errorf(
-				"uninitialized cMix, call 'NewCmix' first")
-		}
-		return nil, errors.WithMessage(err, "Failed to load Session")
+	s := &session{
+		kv:     storage,
+		syncKV: remote,
 	}
 
 	s.clientVersion, err = clientVersion.LoadStore(s.kv)
@@ -158,19 +187,20 @@ func Load(storage versioned.KV,
 			"Failed to load client version store.")
 	}
 
+	// Note: User does it's own prefixing
 	s.User, err = user.LoadUser(s.kv)
 	if err != nil {
-		return nil, errors.WithMessage(err, "Failed to load Session")
+		return nil, errors.WithMessage(err, "failed to load user")
 	}
 
 	s.cmixGroup, err = utility.LoadGroup(s.kv, cmixGroupKey)
 	if err != nil {
-		return nil, errors.WithMessage(err, "Failed to load Session")
+		return nil, errors.WithMessage(err, "failed to load group")
 	}
 
 	s.e2eGroup, err = utility.LoadGroup(s.kv, e2eGroupKey)
 	if err != nil {
-		return nil, errors.WithMessage(err, "Failed to load Session")
+		return nil, errors.WithMessage(err, "failed to load e2e group")
 	}
 
 	return s, nil
diff --git a/storage/user/cryptographic.go b/storage/user/cryptographic.go
index ade79f20e359fb2d39ce63d7f4676c126476422d..6a4499ac0b6d968736214f6940b54a612529d29d 100644
--- a/storage/user/cryptographic.go
+++ b/storage/user/cryptographic.go
@@ -14,8 +14,8 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/utility"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/rsa"
 	oldRsa "gitlab.com/xx_network/crypto/signature/rsa"
diff --git a/storage/user/cryptographic_test.go b/storage/user/cryptographic_test.go
index f8769e96288ce3e8b7a5d653d521cc6d4a317948..a14fc6000d7eef9c31e1a33a1fd87124d12e63d3 100644
--- a/storage/user/cryptographic_test.go
+++ b/storage/user/cryptographic_test.go
@@ -12,7 +12,7 @@ import (
 	"crypto/rand"
 	"testing"
 
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/rsa"
diff --git a/storage/user/registation.go b/storage/user/registation.go
index 5900f82a188303ab9a2e162c2328f5e07761fa29..3e07dd8c0104ece2e16aa42ee7a703eb92fc676a 100644
--- a/storage/user/registation.go
+++ b/storage/user/registation.go
@@ -10,7 +10,7 @@ package user
 import (
 	"encoding/binary"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/netTime"
 	"time"
 )
diff --git a/storage/user/registation_test.go b/storage/user/registation_test.go
index 5b9069a651aedd0c22af4e0e9a5d63da8f7f28d3..de80fbb5f69e7171e39f0f10bfbc1f9820e03e40 100644
--- a/storage/user/registation_test.go
+++ b/storage/user/registation_test.go
@@ -14,7 +14,7 @@ import (
 	"testing"
 	"time"
 
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/rsa"
@@ -152,7 +152,7 @@ func TestUser_loadRegistrationValidationSignature(t *testing.T) {
 	}
 
 	sig := []byte("transmissionsignature")
-	err = kv.Set(transmissionRegValidationSigKey,
+	err = u.kv.Set(transmissionRegValidationSigKey,
 		&versioned.Object{
 			Version:   currentRegValidationSigVersion,
 			Timestamp: netTime.Now(),
@@ -168,7 +168,7 @@ func TestUser_loadRegistrationValidationSignature(t *testing.T) {
 	}
 
 	sig = []byte("receptionsignature")
-	err = kv.Set(receptionRegValidationSigKey,
+	err = u.kv.Set(receptionRegValidationSigKey,
 		&versioned.Object{
 			Version:   currentRegValidationSigVersion,
 			Timestamp: netTime.Now(),
@@ -283,7 +283,7 @@ func TestUser_loadRegistrationTimestamp(t *testing.T) {
 		Data:      data,
 	}
 
-	err = kv.Set(registrationTimestampKey, vo)
+	err = u.kv.Set(registrationTimestampKey, vo)
 	if err != nil {
 		t.Errorf("Failed to set reg validation sig key in kv store: %+v", err)
 	}
diff --git a/storage/user/user.go b/storage/user/user.go
index 235905983f209930bbf68ac132efe8dcdf83d745..2b977b87def83b791c193ca1125029518dc80577 100644
--- a/storage/user/user.go
+++ b/storage/user/user.go
@@ -12,7 +12,8 @@ import (
 	"time"
 
 	"github.com/pkg/errors"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/rsa"
 	"gitlab.com/xx_network/primitives/id"
@@ -38,20 +39,32 @@ func NewUser(kv versioned.KV, transmissionID, receptionID *id.ID, transmissionSa
 	receptionSalt []byte, transmissionRsa, receptionRsa rsa.PrivateKey, isPrecanned bool,
 	e2eDhPrivateKey, e2eDhPublicKey *cyclic.Int) (*User, error) {
 
-	ci := newCryptographicIdentity(transmissionID, receptionID, transmissionSalt,
-		receptionSalt, transmissionRsa, receptionRsa, isPrecanned, e2eDhPrivateKey, e2eDhPublicKey, kv)
+	remote, err := kv.Prefix(collective.StandardRemoteSyncPrefix)
+	if err != nil {
+		return nil, err
+	}
+
+	ci := newCryptographicIdentity(transmissionID, receptionID,
+		transmissionSalt, receptionSalt, transmissionRsa,
+		receptionRsa, isPrecanned,
+		e2eDhPrivateKey, e2eDhPublicKey, remote)
 
-	return &User{CryptographicIdentity: ci, kv: kv}, nil
+	return &User{CryptographicIdentity: ci, kv: remote}, nil
 }
 
 func LoadUser(kv versioned.KV) (*User, error) {
-	ci, err := loadCryptographicIdentity(kv)
+	remote, err := kv.Prefix(collective.StandardRemoteSyncPrefix)
+	if err != nil {
+		return nil, err
+	}
+
+	ci, err := loadCryptographicIdentity(remote)
 	if err != nil {
 		return nil, errors.WithMessage(err, "Failed to load user "+
 			"due to failure to load cryptographic identity")
 	}
 
-	u := &User{CryptographicIdentity: ci, kv: kv}
+	u := &User{CryptographicIdentity: ci, kv: remote}
 	u.loadTransmissionRegistrationValidationSignature()
 	u.loadReceptionRegistrationValidationSignature()
 	u.loadUsername()
diff --git a/storage/user/user_test.go b/storage/user/user_test.go
index 4220d1900ef664af50a8b94b2b7cf4b4969eb96a..a19125a845bba3dc42c2874a129e91f417052653 100644
--- a/storage/user/user_test.go
+++ b/storage/user/user_test.go
@@ -8,10 +8,11 @@
 package user
 
 import (
+	"gitlab.com/elixxir/client/v4/collective"
 	"math/rand"
 	"testing"
 
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/rsa"
@@ -43,9 +44,11 @@ func TestLoadUser(t *testing.T) {
 	transmission, _ := sch.Generate(prng, 256)
 	reception, _ := sch.Generate(prng, 256)
 
+	remote, err := kv.Prefix(collective.StandardRemoteSyncPrefix)
+
 	ci := newCryptographicIdentity(uid, uid, salt, salt, transmission,
-		reception, false, dhPrivKey, dhPubKey, kv)
-	err = ci.save(kv)
+		reception, false, dhPrivKey, dhPubKey, remote)
+	err = ci.save(remote)
 	if err != nil {
 		t.Errorf("Failed to save ci to kv: %+v", err)
 	}
diff --git a/storage/user/username.go b/storage/user/username.go
index 636f4e3d3b4c0305fc3a3c151c55e05fab2706b7..6c654b7d8cdfb5cb2290510f1b593f5ac3bc8c8e 100644
--- a/storage/user/username.go
+++ b/storage/user/username.go
@@ -10,7 +10,7 @@ package user
 import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/netTime"
 )
 
diff --git a/storage/user/username_test.go b/storage/user/username_test.go
index 4824424ad80fe7f1f9fdedaf6b533bdd2ee79192..49439c2b083f423fea41b51dbfaf4f7ed78c5aef 100644
--- a/storage/user/username_test.go
+++ b/storage/user/username_test.go
@@ -11,7 +11,7 @@ import (
 	"math/rand"
 	"testing"
 
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/rsa"
diff --git a/storage/utility/NDF.go b/storage/utility/NDF.go
index 7830e9c146f67d3ee97a8213a3d512f16660bd8e..7f05e9247a84c7c63fa6cded1ce0c9e10925540f 100644
--- a/storage/utility/NDF.go
+++ b/storage/utility/NDF.go
@@ -11,7 +11,7 @@
 package utility
 
 import (
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/ndf"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/storage/utility/NDF_js.go b/storage/utility/NDF_js.go
index 9de986cd0568c4f4ff3508c463703cccc6bb1d3c..29ee77c001ecf71679a34629a5abf370f88c4f36 100644
--- a/storage/utility/NDF_js.go
+++ b/storage/utility/NDF_js.go
@@ -8,7 +8,7 @@
 package utility
 
 import (
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/ndf"
 )
 
diff --git a/storage/utility/blockStore.go b/storage/utility/blockStore.go
index 9665917af61fcb6f3234f7504462d8200a3bce60..05d6edb71e7c793bddc87abee45f73572354ef71 100644
--- a/storage/utility/blockStore.go
+++ b/storage/utility/blockStore.go
@@ -15,7 +15,7 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/netTime"
 )
 
diff --git a/storage/utility/blockStore_test.go b/storage/utility/blockStore_test.go
index b519eda92517768f9e360677341cbb8b5b486e22..c2794f950acf84fe521f7dd18a1820f6bb382d8f 100644
--- a/storage/utility/blockStore_test.go
+++ b/storage/utility/blockStore_test.go
@@ -11,7 +11,7 @@ import (
 	"bytes"
 	"encoding/binary"
 	"fmt"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/netTime"
 	"math/rand"
diff --git a/storage/utility/bucket.go b/storage/utility/bucket.go
index 05b1da34d3230d86fab5c2e5d87e91234c0a09fb..eb3d906df817e707558bc9df915c156469b15304 100644
--- a/storage/utility/bucket.go
+++ b/storage/utility/bucket.go
@@ -12,7 +12,7 @@ import (
 	"time"
 
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/netTime"
 	"gitlab.com/xx_network/primitives/rateLimiting"
 )
diff --git a/storage/utility/bucketParams.go b/storage/utility/bucketParams.go
index e518f45ed4e161471fa766bd465940d984b99972..9d060c4742d33af0155db4f71050eb40f3c1092c 100644
--- a/storage/utility/bucketParams.go
+++ b/storage/utility/bucketParams.go
@@ -15,7 +15,7 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/netTime"
 	"gitlab.com/xx_network/primitives/rateLimiting"
 )
diff --git a/storage/utility/bucketParams_test.go b/storage/utility/bucketParams_test.go
index bfd4aa727893e798758d0cb18edbc04ab78c3693..afbe3f3914c438c00da5e365ed9c0200ec62403b 100644
--- a/storage/utility/bucketParams_test.go
+++ b/storage/utility/bucketParams_test.go
@@ -9,7 +9,7 @@ package utility
 
 import (
 	"github.com/stretchr/testify/require"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"reflect"
 	"testing"
diff --git a/storage/utility/contact.go b/storage/utility/contact.go
index f7fefe1b7aa56c9b4b64892326b33b0c8bb7e9e3..3e324d9c2c9c0aa9c13540d913788b05cea97be9 100644
--- a/storage/utility/contact.go
+++ b/storage/utility/contact.go
@@ -10,7 +10,7 @@ package utility
 import (
 	"fmt"
 
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
diff --git a/storage/utility/dh.go b/storage/utility/dh.go
index 403e8f1335c2191fc2f25318b2ac8c4078e941cb..2f4f279608c04af8f1c5d0099bb6926fd1a77fea 100644
--- a/storage/utility/dh.go
+++ b/storage/utility/dh.go
@@ -8,7 +8,7 @@
 package utility
 
 import (
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/storage/utility/dh_test.go b/storage/utility/dh_test.go
index d106c6d906227c1418d48b887dd95ee3d8271874..00adad4a439ab5986bc4820285120aa3bec6daa5 100644
--- a/storage/utility/dh_test.go
+++ b/storage/utility/dh_test.go
@@ -8,7 +8,7 @@
 package utility
 
 import (
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"testing"
 )
diff --git a/storage/utility/encryptionSalt.go b/storage/utility/encryptionSalt.go
index c0c7c0accaabae59169e0cb60e3cee7477cba3b0..f4db315d09e097eaf4d7d334f602a08fda7c423e 100644
--- a/storage/utility/encryptionSalt.go
+++ b/storage/utility/encryptionSalt.go
@@ -4,7 +4,7 @@ import (
 	"io"
 
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/netTime"
 )
 
diff --git a/storage/utility/encryptionSalt_test.go b/storage/utility/encryptionSalt_test.go
index 2701362339a77609b4de2d812ddd327ae8bc69d9..8231371becb381696514a498146b008ada702fcd 100644
--- a/storage/utility/encryptionSalt_test.go
+++ b/storage/utility/encryptionSalt_test.go
@@ -2,7 +2,7 @@ package utility
 
 import (
 	"bytes"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/crypto/csprng"
 	"testing"
diff --git a/storage/utility/group.go b/storage/utility/group.go
index 1aeca4ee2c07ebf0f65a3bbf47f1fa6ba898f20e..95b351c4e50236b8f0e16fccc60c4eb0182bc7a3 100644
--- a/storage/utility/group.go
+++ b/storage/utility/group.go
@@ -8,7 +8,7 @@
 package utility
 
 import (
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/storage/utility/group_test.go b/storage/utility/group_test.go
index ecc9f3cffa516804227ef665836e5615321d0d16..4e6acfaee2b89e8a64fbe37e41a78efe2060b4bd 100644
--- a/storage/utility/group_test.go
+++ b/storage/utility/group_test.go
@@ -8,7 +8,7 @@
 package utility
 
 import (
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/crypto/large"
diff --git a/storage/utility/id.go b/storage/utility/id.go
index 0e1c2a8829269a9bb146535b3c3863d2833e8ce9..fdb60b1d767cdd140d45dd06c0aac28a09d7dce5 100644
--- a/storage/utility/id.go
+++ b/storage/utility/id.go
@@ -8,7 +8,7 @@
 package utility
 
 import (
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/storage/utility/messageBuffer.go b/storage/utility/messageBuffer.go
index b4c7f598a4e34c8486280842a99a1deb5295c362..69925487193a732e4ed00a9e664f86851432016c 100644
--- a/storage/utility/messageBuffer.go
+++ b/storage/utility/messageBuffer.go
@@ -13,7 +13,7 @@ import (
 	"sync"
 
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/storage/utility/messageBuffer_test.go b/storage/utility/messageBuffer_test.go
index 02ac0e2f64bb9549e7c7cad8c501d6ab6062fcdf..32b9b81b3fcf679daa34da86f97ecfb5b79f4caf 100644
--- a/storage/utility/messageBuffer_test.go
+++ b/storage/utility/messageBuffer_test.go
@@ -10,7 +10,7 @@ package utility
 import (
 	"bytes"
 	"encoding/json"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/netTime"
 	"golang.org/x/crypto/blake2b"
diff --git a/storage/utility/multiStateVector.go b/storage/utility/multiStateVector.go
index 908a0b24158a4b13227b506dfcf2efbad0ff4910..b17a3c3c8bbc54c4aed4b8a10faf8d85d02c0ad1 100644
--- a/storage/utility/multiStateVector.go
+++ b/storage/utility/multiStateVector.go
@@ -15,7 +15,7 @@ import (
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/netTime"
 )
 
diff --git a/storage/utility/multiStateVector_test.go b/storage/utility/multiStateVector_test.go
index 813861e3c903597fc45f68324e9fde410e53233a..7c0830c2e5fe2c7ee83318a46761c6f35906b758 100644
--- a/storage/utility/multiStateVector_test.go
+++ b/storage/utility/multiStateVector_test.go
@@ -11,7 +11,7 @@ import (
 	"bytes"
 	"encoding/base64"
 	"fmt"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/netTime"
 	"math"
diff --git a/storage/utility/sidh.go b/storage/utility/sidh.go
index 6e55b5b5e5f36a6160f6c0d0039ff779b7a2536e..6dad894b7f0cf0c28ffb2238fc6156784bb6dfdb 100644
--- a/storage/utility/sidh.go
+++ b/storage/utility/sidh.go
@@ -14,8 +14,7 @@ import (
 
 	"github.com/cloudflare/circl/dh/sidh"
 	jww "github.com/spf13/jwalterweatherman"
-	sidhinterface "gitlab.com/elixxir/client/v4/interfaces/sidh"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
 )
@@ -25,13 +24,13 @@ const currentSIDHVersion = 0
 // NewSIDHPUblicKey is a helper which returns a proper new SIDH public key
 // Right now this is set to Fp434 but it could change.
 func NewSIDHPublicKey(variant sidh.KeyVariant) *sidh.PublicKey {
-	return sidh.NewPublicKey(sidhinterface.KeyId, variant)
+	return sidh.NewPublicKey(KeyId, variant)
 }
 
 // NewSIDHPUblicKey is a helper which returns a proper new SIDH public key
 // Right now this is set to Fp434 but it could change.
 func NewSIDHPrivateKey(variant sidh.KeyVariant) *sidh.PrivateKey {
-	return sidh.NewPrivateKey(sidhinterface.KeyId, variant)
+	return sidh.NewPrivateKey(KeyId, variant)
 }
 
 // GetSIDHVariant returns the variant opposite the otherVariant
diff --git a/interfaces/sidh/sidh.go b/storage/utility/sidhParams.go
similarity index 97%
rename from interfaces/sidh/sidh.go
rename to storage/utility/sidhParams.go
index ff1ad9c4f63a063ce54bf67e2759e56b374054d8..422553ea0a1a9311f72cbfb4c169f473cf575dda 100644
--- a/interfaces/sidh/sidh.go
+++ b/storage/utility/sidhParams.go
@@ -5,7 +5,7 @@
 // LICENSE file.                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
-package interfaces
+package utility
 
 import "github.com/cloudflare/circl/dh/sidh"
 
diff --git a/storage/utility/sidh_test.go b/storage/utility/sidh_test.go
index 14bc958367def52672dd72e9d0a22c9ccc3e9c30..be98a6c72b5ffe536b8f82b49e0d91864a73e823 100644
--- a/storage/utility/sidh_test.go
+++ b/storage/utility/sidh_test.go
@@ -9,7 +9,7 @@ package utility
 
 import (
 	"github.com/cloudflare/circl/dh/sidh"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/crypto/csprng"
diff --git a/storage/utility/stateVector.go b/storage/utility/stateVector.go
index 6940130b21f97c95d6c4d86c949cfa24ca812600..cdbd103b4bb70d46333900a247753cd2ed793adf 100644
--- a/storage/utility/stateVector.go
+++ b/storage/utility/stateVector.go
@@ -18,7 +18,7 @@ import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/netTime"
 )
 
diff --git a/storage/utility/stateVector_test.go b/storage/utility/stateVector_test.go
index af697007e58d0298fab54ac98346c9fa3b3d2449..c66e160d6bb0e49a7545adce31c142b82f5ee265 100644
--- a/storage/utility/stateVector_test.go
+++ b/storage/utility/stateVector_test.go
@@ -18,7 +18,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/require"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/ud/channelIDTracking.go b/ud/channelIDTracking.go
index 03173f68ebef5b3a820f3900cb1cf3fa70bb136c..31d25d1983b91339d509971643c2ede688ae6c65 100644
--- a/ud/channelIDTracking.go
+++ b/ud/channelIDTracking.go
@@ -11,8 +11,8 @@ import (
 	jww "github.com/spf13/jwalterweatherman"
 
 	"gitlab.com/elixxir/client/v4/channels"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/stoppable"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/client/v4/xxdk"
 	"gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/crypto/channel"
diff --git a/ud/channelIDTracking_test.go b/ud/channelIDTracking_test.go
index a0ae578436648f5b0bcdad5dff159b817ea2f25e..9bf020ff6c3565aac82212bd607eef2a6b3bd014 100644
--- a/ud/channelIDTracking_test.go
+++ b/ud/channelIDTracking_test.go
@@ -13,8 +13,8 @@ import (
 	"gitlab.com/xx_network/crypto/csprng"
 	"gitlab.com/xx_network/primitives/id"
 
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/event"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	store "gitlab.com/elixxir/client/v4/ud/store"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/ekv"
diff --git a/ud/manager.go b/ud/manager.go
index 063ff6271d9fdeacf5ab7e00cef50fa254f1c8b3..004193aa997e044f5445b638d70019060a18d392 100644
--- a/ud/manager.go
+++ b/ud/manager.go
@@ -10,8 +10,8 @@ package ud
 import (
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/event"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	store "gitlab.com/elixxir/client/v4/ud/store"
 	"gitlab.com/elixxir/client/v4/xxdk"
 	"gitlab.com/elixxir/crypto/contact"
diff --git a/ud/mockE2e_test.go b/ud/mockE2e_test.go
index 763d8c05189f729da5f5fdbb1ca0289b8b9c9b9b..f955c594baddea3fff1babb292f7cbdada251c04 100644
--- a/ud/mockE2e_test.go
+++ b/ud/mockE2e_test.go
@@ -12,6 +12,7 @@ import (
 	"gitlab.com/elixxir/client/v4/catalog"
 	"gitlab.com/elixxir/client/v4/cmix"
 	"gitlab.com/elixxir/client/v4/cmix/message"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner"
 	"gitlab.com/elixxir/client/v4/e2e/ratchet/partner/session"
@@ -19,7 +20,6 @@ import (
 	"gitlab.com/elixxir/client/v4/event"
 	"gitlab.com/elixxir/client/v4/stoppable"
 	"gitlab.com/elixxir/client/v4/storage"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/client/v4/xxdk"
 	"gitlab.com/elixxir/crypto/cyclic"
 	cryptoE2e "gitlab.com/elixxir/crypto/e2e"
diff --git a/ud/mockStore_test.go b/ud/mockStore_test.go
index 229358d43eb3890c3665ad1e764b77eb2451eb97..c686b60e1d9eb168e8bf265b8c6a2373a5b0cdda 100644
--- a/ud/mockStore_test.go
+++ b/ud/mockStore_test.go
@@ -8,16 +8,17 @@
 package ud
 
 import (
+	"time"
+
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage"
 	"gitlab.com/elixxir/client/v4/storage/user"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/rsa"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/elixxir/primitives/version"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/ndf"
-	"time"
 )
 
 type mockStorage struct{}
@@ -61,7 +62,7 @@ func (m mockStorage) ForwardRegistrationStatus(regStatus storage.RegistrationSta
 	panic("implement me")
 }
 
-func (m mockStorage) GetRegistrationStatus() storage.RegistrationStatus {
+func (m mockStorage) RegStatus() storage.RegistrationStatus {
 	//TODO implement me
 	panic("implement me")
 }
diff --git a/ud/registered.go b/ud/registered.go
index 6d766a477d20655fe9b4558f0a713f354eae01c5..b19670d311bf34139162ad8895580782b14c94b5 100644
--- a/ud/registered.go
+++ b/ud/registered.go
@@ -11,7 +11,7 @@ import (
 	"encoding/binary"
 
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/xx_network/primitives/netTime"
 )
 
diff --git a/ud/store/facts_test.go b/ud/store/facts_test.go
index fe3e2a85fbb2a1436e23352c2bc06f159f4c345a..f5946eafc8c06a0a1af1b1255dbe82dcf36cd802 100644
--- a/ud/store/facts_test.go
+++ b/ud/store/facts_test.go
@@ -8,7 +8,7 @@
 package ud
 
 import (
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/elixxir/primitives/fact"
 	"reflect"
diff --git a/ud/store/store.go b/ud/store/store.go
index 4b1a0b3c6daddfcd4894b0a2bd64bc76df581024..a7a47796007139d7e09e726da982052914600282 100644
--- a/ud/store/store.go
+++ b/ud/store/store.go
@@ -14,7 +14,7 @@ import (
 	"sync"
 
 	"github.com/pkg/errors"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/primitives/fact"
 	"gitlab.com/xx_network/primitives/netTime"
 )
diff --git a/ud/store/store_test.go b/ud/store/store_test.go
index 3102149ff4b5e22a0d0673c06b6b3ae0054dc973..b0a9d2096ae2574953c346e1a4d9f44383951238 100644
--- a/ud/store/store_test.go
+++ b/ud/store/store_test.go
@@ -10,7 +10,7 @@ package ud
 import (
 	"bytes"
 	"github.com/stretchr/testify/require"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/elixxir/primitives/fact"
 	"reflect"
diff --git a/ud/utils_test.go b/ud/utils_test.go
index 9152dbec17fcbc50965a5b2829e57e6aec1ac9c8..c7962c3415228db3d0dbaa15b50cc27ffd3cf12d 100644
--- a/ud/utils_test.go
+++ b/ud/utils_test.go
@@ -12,10 +12,10 @@ import (
 	"gitlab.com/elixxir/client/v4/cmix"
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/event"
 	"gitlab.com/elixxir/client/v4/single"
 	"gitlab.com/elixxir/client/v4/storage/user"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	store "gitlab.com/elixxir/client/v4/ud/store"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/elixxir/crypto/cyclic"
diff --git a/xxdk/backup.go b/xxdk/backup.go
index 301bb48ba0c64368ad4fba0b64b7777f7dccb1d1..4f949fefb8fa3f88f42ba8b54b792edd9a366960 100644
--- a/xxdk/backup.go
+++ b/xxdk/backup.go
@@ -25,6 +25,7 @@ type Container struct {
 // The passed in reason will be printed to the log when the backup is sent. It
 // should be in the paste tense. For example, if a contact is deleted, the
 // reason can be "contact deleted" and the log will show:
+//
 //	Triggering backup: contact deleted
 func (bc *Container) TriggerBackup(reason string) {
 	bc.mux.RLock()
diff --git a/xxdk/cmix.go b/xxdk/cmix.go
index 4a5841365f64e51e435309589573f68fe055bb65..a15a21ab1c52644ec891758f1a804cf6bef0b5bf 100644
--- a/xxdk/cmix.go
+++ b/xxdk/cmix.go
@@ -8,6 +8,8 @@
 package xxdk
 
 import (
+	ds "gitlab.com/elixxir/comms/network/dataStructures"
+	"gitlab.com/elixxir/primitives/states"
 	"math"
 	"time"
 
@@ -17,16 +19,16 @@ import (
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/v4/cmix"
 	"gitlab.com/elixxir/client/v4/collective"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/event"
-	"gitlab.com/elixxir/client/v4/interfaces"
 	"gitlab.com/elixxir/client/v4/registration"
 	"gitlab.com/elixxir/client/v4/stoppable"
 	"gitlab.com/elixxir/client/v4/storage"
 	"gitlab.com/elixxir/client/v4/storage/user"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/comms/client"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/fastRNG"
+	"gitlab.com/elixxir/ekv"
 	"gitlab.com/elixxir/primitives/version"
 	"gitlab.com/xx_network/comms/connect"
 	"gitlab.com/xx_network/crypto/csprng"
@@ -60,7 +62,7 @@ type Cmix struct {
 
 	// Services system to track running threads
 	followerServices   *services
-	clientErrorChannel chan interfaces.ClientError
+	clientErrorChannel chan ClientError
 
 	// Event reporting in event.go
 	events *event.Manager
@@ -70,8 +72,8 @@ type Cmix struct {
 // with the network. Note that this does not register a username/identity, but
 // merely creates a new cryptographic identity for adding such information at a
 // later date.
-func NewCmix(
-	ndfJSON, storageDir string, password []byte, registrationCode string) error {
+func NewCmix(ndfJSON, storageDir string, password []byte,
+	registrationCode string) error {
 	jww.INFO.Printf("NewCmix(dir: %s)", storageDir)
 	rngStreamGen := fastRNG.NewStreamGenerator(12, 1024, csprng.NewSystemRNG)
 
@@ -131,6 +133,45 @@ func NewVanityCmix(ndfJSON, storageDir string, password []byte,
 	return nil
 }
 
+// NewSynchronizedCmix clones a Cmix from remote storage
+func NewSynchronizedCmix(ndfJSON, storageDir string, password []byte,
+	remote collective.RemoteStore) error {
+	jww.INFO.Printf("NewSynchronizedCmix(dir: %s)", storageDir)
+	rngStreamGen := fastRNG.NewStreamGenerator(12, 1024,
+		csprng.NewSystemRNG)
+
+	def, err := ParseNDF(ndfJSON)
+	if err != nil {
+		return errors.Wrapf(err, "ParseNDF")
+	}
+
+	kv, err := ekv.NewFilestore(storageDir, string(password))
+	if err != nil {
+		return errors.Wrapf(err, "NewFilestore")
+	}
+
+	rkv, err := collective.CloneFromRemoteStorage(storageDir, password,
+		remote, kv, rngStreamGen)
+	if err != nil {
+		return errors.Wrapf(err, "CloneFromRemoteStorage")
+	}
+
+	cmixGrp, e2eGrp := DecodeGroups(def)
+	currentVersion, err := version.ParseVersion(SEMVER)
+	if err != nil {
+		return errors.Wrapf(err, "Could not parse version string.")
+	}
+
+	err = storage.InitFromRemote(rkv, currentVersion, cmixGrp, e2eGrp)
+	if err != nil {
+		return err
+	}
+
+	// NOTE: UserInfo, RegCode, and Registration State is synchronized,
+	// so we don't need to set it.
+	return err
+}
+
 // OpenCmix creates client storage but does not connect to the network or login.
 // Note that this is a helper function that, in most applications, should not be
 // used on its own. Consider using LoadCmix instead, which calls this function
@@ -178,7 +219,7 @@ func openCmix(storageKV versioned.KV, rngStreamGen *fastRNG.StreamGenerator) (
 		comms:              nil,
 		network:            nil,
 		followerServices:   newServices(),
-		clientErrorChannel: make(chan interfaces.ClientError, 1000),
+		clientErrorChannel: make(chan ClientError, 1000),
 		events:             event.NewEventManager(),
 	}
 
@@ -187,6 +228,10 @@ func openCmix(storageKV versioned.KV, rngStreamGen *fastRNG.StreamGenerator) (
 		return nil, err
 	}
 
+	// NOTE: Open is the only place where we have the reference to
+	// add the service
+	c.AddService(storageKV.StartProcesses)
+
 	return c, nil
 }
 
@@ -336,7 +381,8 @@ func (c *Cmix) initPermissioning(def *ndf.NetworkDefinition) error {
 	}
 
 	// Register with registration if necessary
-	if c.storage.GetRegistrationStatus() == storage.KeyGenComplete {
+	regStatus := c.storage.RegStatus()
+	if regStatus == storage.KeyGenComplete {
 		jww.INFO.Printf("Cmix has not registered yet, attempting registration")
 		err = c.registerWithPermissioning()
 		if err != nil {
@@ -355,7 +401,7 @@ func (c *Cmix) registerFollower() error {
 	// Build the error callback
 	cer := func(source, message, trace string) {
 		select {
-		case c.clientErrorChannel <- interfaces.ClientError{
+		case c.clientErrorChannel <- ClientError{
 			Source:  source,
 			Message: message,
 			Trace:   trace,
@@ -388,7 +434,7 @@ func (c *Cmix) registerFollower() error {
 
 // GetErrorsChannel returns a channel that passes errors from the long-running
 // threads controlled by StartNetworkFollower and StopNetworkFollower.
-func (c *Cmix) GetErrorsChannel() <-chan interfaces.ClientError {
+func (c *Cmix) GetErrorsChannel() <-chan ClientError {
 	return c.clientErrorChannel
 }
 
@@ -481,8 +527,32 @@ func (c *Cmix) GetRunningProcesses() []string {
 	return c.followerServices.stoppable.GetRunningProcesses()
 }
 
+// The round events interface allows the registration of an event which triggers
+// when a round reaches one or more states
+
+type RoundEvents interface {
+	// AddRoundEvent designates a callback to call on the specified event
+	// rid is the id of the round the event occurs on
+	// callback is the callback the event is triggered on
+	// timeout is the amount of time before an error event is returned
+	// valid states are the states which the event should trigger on
+	AddRoundEvent(rid id.Round, callback ds.RoundEventCallback,
+		timeout time.Duration, validStates ...states.Round) *ds.EventCallback
+
+	// AddRoundEventChan designates a go channel to signal the specified event
+	// rid is the id of the round the event occurs on
+	// eventChan is the channel the event is triggered on
+	// timeout is the amount of time before an error event is returned
+	// valid states are the states which the event should trigger on
+	AddRoundEventChan(rid id.Round, eventChan chan ds.EventReturn,
+		timeout time.Duration, validStates ...states.Round) *ds.EventCallback
+
+	// Remove Allows the un-registration of a round event before it triggers
+	Remove(rid id.Round, e *ds.EventCallback)
+}
+
 // GetRoundEvents registers a callback for round events.
-func (c *Cmix) GetRoundEvents() interfaces.RoundEvents {
+func (c *Cmix) GetRoundEvents() RoundEvents {
 	jww.INFO.Printf("GetRoundEvents()")
 	jww.WARN.Printf("GetRoundEvents does not handle Cmix Errors edge case!")
 	return c.network.GetInstance().GetRoundEvents()
@@ -693,9 +763,6 @@ func CheckVersionAndSetupStorage(def *ndf.NetworkDefinition,
 	// Store the registration code for later use
 	storageSess.SetRegCode(registrationCode)
 
-	rngStream := rng.GetStream()
-	defer rngStream.Close()
-
 	// Move the registration state to keys generated
 	err = storageSess.ForwardRegistrationStatus(storage.KeyGenComplete)
 
diff --git a/interfaces/healthTracker.go b/xxdk/cmixInterfaces.go
similarity index 81%
rename from interfaces/healthTracker.go
rename to xxdk/cmixInterfaces.go
index 995df5ce21933c8228becc225a8fcd800a6511cf..be8e5f65071dcb5b2aab6159e1ee7c52d0f2b668 100644
--- a/interfaces/healthTracker.go
+++ b/xxdk/cmixInterfaces.go
@@ -5,7 +5,15 @@
 // LICENSE file.                                                              //
 ////////////////////////////////////////////////////////////////////////////////
 
-package interfaces
+package xxdk
+
+type ClientError struct {
+	Source  string
+	Message string
+	Trace   string
+}
+
+type ClientErrorReport func(source, message, trace string)
 
 type HealthTracker interface {
 	AddChannel(chan bool) uint64
diff --git a/xxdk/e2e.go b/xxdk/e2e.go
index db1abc6728f4e71fe55823fde35fd5196e9cbdd5..babf5a4434b5a7f6024b80125f849d6969a9ad59 100644
--- a/xxdk/e2e.go
+++ b/xxdk/e2e.go
@@ -16,10 +16,10 @@ import (
 	"gitlab.com/elixxir/client/v4/auth"
 	"gitlab.com/elixxir/client/v4/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/v4/cmix/rounds"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/e2e"
 	"gitlab.com/elixxir/client/v4/e2e/rekey"
 	"gitlab.com/elixxir/client/v4/storage/user"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/crypto/xx"
diff --git a/xxdk/identity.go b/xxdk/identity.go
index 29a3ad17d8fa67533ee192bbe3a48b99c579e90c..f260b843cfb6213873464b73bd8a82e197c9f361 100644
--- a/xxdk/identity.go
+++ b/xxdk/identity.go
@@ -11,8 +11,8 @@ import (
 	"encoding/json"
 	"gitlab.com/elixxir/primitives/fact"
 
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage/user"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/diffieHellman"
diff --git a/xxdk/kv.go b/xxdk/kv.go
index 5d8a5e7ccf9bea821d4ec6c0f0485819ffd71b65..a6544c1e8b27567df94d361235ccacc52f6b2e99 100644
--- a/xxdk/kv.go
+++ b/xxdk/kv.go
@@ -10,7 +10,7 @@ package xxdk
 import (
 	"github.com/pkg/errors"
 	"gitlab.com/elixxir/client/v4/collective"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/ekv"
 )
diff --git a/xxmutils/restoreContacts.go b/xxmutils/restoreContacts.go
index 57861126578c613972f8504d9361a872fcf49d39..d2926085597eeb5c29be99eb8c31e5685bdd46b4 100644
--- a/xxmutils/restoreContacts.go
+++ b/xxmutils/restoreContacts.go
@@ -21,14 +21,24 @@ import (
 
 	jww "github.com/spf13/jwalterweatherman"
 
-	"gitlab.com/elixxir/client/v4/interfaces"
+	"gitlab.com/elixxir/client/v4/collective/versioned"
 	"gitlab.com/elixxir/client/v4/storage"
-	"gitlab.com/elixxir/client/v4/storage/versioned"
 	"gitlab.com/elixxir/client/v4/ud"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/xx_network/primitives/id"
 )
 
+// RestoreContactsUpdater interface provides a callback function
+// for receiving update information from RestoreContactsFromBackup.
+type RestoreContactsUpdater interface {
+	// RestoreContactsCallback is called to report the current # of contacts
+	// that have been found and how many have been restored
+	// against the total number that need to be
+	// processed. If an error occurs it it set on the err variable as a
+	// plain string.
+	RestoreContactsCallback(numFound, numRestored, total int, err string)
+}
+
 // RestoreContactsFromBackup takes as input the jason output of the
 // `NewClientFromBackup` function, unmarshals it into IDs, looks up
 // each ID in user discovery, and initiates a session reset request.
@@ -39,7 +49,7 @@ import (
 // should be treated as internal functions specific to the phone apps.
 func RestoreContactsFromBackup(backupPartnerIDs []byte, user *xxdk.E2e,
 	udManager *ud.Manager,
-	updatesCb interfaces.RestoreContactsUpdater) ([]*id.ID, []*id.ID,
+	updatesCb RestoreContactsUpdater) ([]*id.ID, []*id.ID,
 	[]error, error) {
 
 	var restored, failed []*id.ID
@@ -263,11 +273,11 @@ type failure struct {
 	Err error
 }
 
-////
+// //
 // stateStore wraps a kv and stores contact state for the restoration
 // TODO: Right now, it uses 1 contact-per-key approach, but it might make sense
 // to wrap this in a mutex and load/store a whole list
-////
+// //
 const stateStoreFmt = "restoreContactsFromBackup/v1/%s"
 
 type stateStore struct {