diff --git a/bindings/e2e.go b/bindings/e2e.go
index beef52f655626f9fead21961f60a5aedc78df966..22438e73df9db897e20b785b871d78aadba73307 100644
--- a/bindings/e2e.go
+++ b/bindings/e2e.go
@@ -8,6 +8,7 @@
 package bindings
 
 import (
+	"gitlab.com/xx_network/primitives/id"
 	"sync"
 
 	"github.com/pkg/errors"
@@ -125,6 +126,44 @@ func (e *E2e) GetContact() []byte {
 	return e.api.GetReceptionIdentity().GetContact().Marshal()
 }
 
+// GetUdAddressFromNdf retrieve the User Discovery's network address fom the NDF.
+func (e *E2e) GetUdAddressFromNdf() string {
+	return e.api.GetCmix().GetInstance().GetPartialNdf().
+		Get().UDB.Address
+}
+
+// GetUdCertFromNdf retrieves the User Discovery's TLS certificate from the NDF.
+func (e *E2e) GetUdCertFromNdf() []byte {
+	return []byte(e.api.GetCmix().GetInstance().GetPartialNdf().Get().UDB.Cert)
+}
+
+// GetUdContactFromNdf assembles the User Discovery's contact file from the data
+// within the NDF.
+//
+// Returns
+//  - []byte - A byte marshalled contact.Contact.
+func (e *E2e) GetUdContactFromNdf() ([]byte, error) {
+	udIdData := e.api.GetCmix().GetInstance().GetPartialNdf().Get().UDB.ID
+	udId, err := id.Unmarshal(udIdData)
+	if err != nil {
+		return nil, err
+	}
+
+	udDhPubKeyData := e.api.GetCmix().GetInstance().GetPartialNdf().Get().UDB.DhPubKey
+	udDhPubKey := e.api.GetE2E().GetGroup().NewInt(1)
+	err = udDhPubKey.UnmarshalJSON(udDhPubKeyData)
+	if err != nil {
+		return nil, err
+	}
+
+	udContact := contact.Contact{
+		ID:       udId,
+		DhPubKey: udDhPubKey,
+	}
+
+	return udContact.Marshal(), nil
+}
+
 // AuthCallbacks is the bindings-specific interface for auth.Callbacks methods.
 type AuthCallbacks interface {
 	Request(contact, receptionId []byte, ephemeralId, roundId int64)
diff --git a/bindings/ud.go b/bindings/ud.go
index b4e2dc395e3e3d0fe557588f899a536fea770f9e..6ce8f8b3af073057e210675ff3203ef5ba364746 100644
--- a/bindings/ud.go
+++ b/bindings/ud.go
@@ -105,17 +105,34 @@ type UdNetworkStatus interface {
 // Manager functions                                                          //
 ////////////////////////////////////////////////////////////////////////////////
 
-// LoadOrNewUserDiscovery creates a bindings-level user discovery manager.
+// NewOrLoadUd loads an existing Manager from storage or creates a
+// new one if there is no extant storage information. Parameters need be provided
+// to specify how to connect to the User Discovery service. These parameters may be used
+// to contact either the UD server hosted by the xx network team or a custom
+// third-party operated server. For the former, all the information may be pulled from the
+// NDF using the bindings.
 //
-// Parameters:
+// Params
 //  - e2eID - e2e object ID in the tracker
 //  - follower - network follower func wrapped in UdNetworkStatus
 //  - username - the username the user wants to register with UD.
 //    If the user is already registered, this field may be blank
-//  - registrationValidationSignature - the signature provided by the xx network.
-//    This signature is optional for other consumers who deploy their own UD.
-func LoadOrNewUserDiscovery(e2eID int, follower UdNetworkStatus,
-	username string, registrationValidationSignature []byte) (
+//  - networkValidationSig is a signature provided by the network (i.e. the client registrar).
+//    This may be nil, however UD may return an error in some cases (e.g. in a production level
+//    environment).
+//  - cert is 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 is 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 is 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.
+//
+// Returns
+//  - 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) {
 
 	// Get user from singleton
@@ -124,16 +141,20 @@ func LoadOrNewUserDiscovery(e2eID int, follower UdNetworkStatus,
 		return nil, err
 	}
 
+	// Construct callback
 	UdNetworkStatusFn := func() xxdk.Status {
 		return xxdk.Status(follower.UdNetworkStatus())
 	}
 
-	u, err := ud.LoadOrNewManager(user.api, user.api.GetComms(),
-		UdNetworkStatusFn, username, registrationValidationSignature)
+	// Build manager
+	u, err := ud.NewOrLoad(user.api, user.api.GetComms(),
+		UdNetworkStatusFn, username, registrationValidationSignature,
+		cert, contactFile, address)
 	if err != nil {
 		return nil, err
 	}
 
+	// Track and return manager
 	return udTrackerSingleton.make(u), nil
 }
 
@@ -146,8 +167,15 @@ func LoadOrNewUserDiscovery(e2eID int, follower UdNetworkStatus,
 //  - follower - network follower func wrapped in UdNetworkStatus
 //  - emailFactJson - nullable JSON marshalled email fact.Fact
 //  - phoneFactJson - nullable JSON marshalled phone fact.Fact
+//  - cert is 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 is 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 is 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, emailFactJson,
-	phoneFactJson []byte) (*UserDiscovery, error) {
+	phoneFactJson []byte, cert, contactFile []byte, address string) (*UserDiscovery, error) {
 
 	// Get user from singleton
 	user, err := e2eTrackerSingleton.get(e2eID)
@@ -175,7 +203,9 @@ func NewUdManagerFromBackup(e2eID int, follower UdNetworkStatus, emailFactJson,
 	}
 
 	u, err := ud.NewManagerFromBackup(
-		user.api, user.api.GetComms(), UdNetworkStatusFn, email, phone)
+		user.api, user.api.GetComms(), UdNetworkStatusFn,
+		email, phone,
+		cert, contactFile, address)
 	if err != nil {
 		return nil, err
 	}
@@ -196,12 +226,7 @@ func (ud *UserDiscovery) GetFacts() []byte {
 // GetContact returns the marshalled bytes of the contact.Contact for UD as
 // retrieved from the NDF.
 func (ud *UserDiscovery) GetContact() ([]byte, error) {
-	c, err := ud.api.GetContact()
-	if err != nil {
-		return nil, err
-	}
-
-	return json.Marshal(c)
+	return ud.api.GetContact().Marshal(), nil
 }
 
 // ConfirmFact confirms a fact first registered via AddFact. The confirmation ID
@@ -263,22 +288,6 @@ func (ud *UserDiscovery) RemoveFact(factJson []byte) error {
 	return ud.api.RemoveFact(f)
 }
 
-// SetAlternativeUserDiscovery sets the alternativeUd object within manager.
-// Once set, any user discovery operation will go through the alternative
-// user discovery service.
-//
-// To undo this operation, use UnsetAlternativeUserDiscovery.
-func (ud *UserDiscovery) SetAlternativeUserDiscovery(
-	altCert, altAddress, contactFile []byte) error {
-	return ud.api.SetAlternativeUserDiscovery(altCert, altAddress, contactFile)
-}
-
-// UnsetAlternativeUserDiscovery clears out the information from the Manager
-// object.
-func (ud *UserDiscovery) UnsetAlternativeUserDiscovery() error {
-	return ud.api.UnsetAlternativeUserDiscovery()
-}
-
 ////////////////////////////////////////////////////////////////////////////////
 // User Discovery Lookup                                                      //
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/cmd/ud.go b/cmd/ud.go
index 10d423889ff8c1dcc2a363ad821af820db76beaa..73a47f02d60e32f588fa1e0f24395a082c23d689 100644
--- a/cmd/ud.go
+++ b/cmd/ud.go
@@ -10,6 +10,9 @@ package cmd
 
 import (
 	"fmt"
+	"gitlab.com/elixxir/client/xxdk"
+	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/xx_network/primitives/id"
 	"time"
 
 	"gitlab.com/elixxir/client/single"
@@ -60,11 +63,17 @@ var udCmd = &cobra.Command{
 
 		jww.TRACE.Printf("[UD] Connected!")
 
+		cert, contactFile, address, err := getUdContactInfo(user)
+		if err != nil {
+			jww.FATAL.Panicf("Failed to load UD contact information from NDF: %+v", err)
+		}
+
 		// Make user discovery manager
 		userToRegister := viper.GetString(udRegisterFlag)
 		jww.TRACE.Printf("[UD] Registering identity %v...", userToRegister)
-		userDiscoveryMgr, err := ud.LoadOrNewManager(user, user.GetComms(),
-			user.NetworkFollowerStatus, userToRegister, nil)
+		userDiscoveryMgr, err := ud.NewOrLoad(user, user.GetComms(),
+			user.NetworkFollowerStatus, userToRegister, nil,
+			cert, contactFile, address)
 		if err != nil {
 			jww.FATAL.Panicf("Failed to load or create new UD manager: %+v", err)
 		}
@@ -115,11 +124,7 @@ var udCmd = &cobra.Command{
 			jww.INFO.Printf("[UD] Confirmed %v", confirmID)
 		}
 
-		udContact, err := userDiscoveryMgr.GetContact()
-		if err != nil {
-			fmt.Printf("Failed to get user discovery contact object: %+v", err)
-			jww.FATAL.Printf("Failed to get user discovery contact object: %+v", err)
-		}
+		udContact := userDiscoveryMgr.GetContact()
 
 		// Handle lookup (verification) process
 		// Note: Cryptographic verification occurs above the bindings layer
@@ -243,6 +248,42 @@ var udCmd = &cobra.Command{
 	},
 }
 
+// getUdContactInfo is a helper function which retrieves the necessary information
+// to contact UD.
+func getUdContactInfo(user *xxdk.E2e) (cert, contactFile []byte, address string, err error) {
+	// Retrieve address
+	address = string([]byte(user.GetCmix().GetInstance().GetPartialNdf().
+		Get().UDB.Address))
+
+	// Retrieve certificate
+	cert = []byte(user.GetCmix().GetInstance().GetPartialNdf().Get().UDB.Cert)
+
+	// Retrieve ID
+	udIdData := user.GetCmix().GetInstance().GetPartialNdf().Get().UDB.ID
+	udId, err := id.Unmarshal(udIdData)
+	if err != nil {
+		return nil, nil, "", err
+	}
+
+	// Retrieve DH Pub Key
+	udDhPubKeyData := user.GetCmix().GetInstance().GetPartialNdf().Get().UDB.DhPubKey
+	var udDhPubKey *cyclic.Int
+	err = udDhPubKey.UnmarshalJSON(udDhPubKeyData)
+	if err != nil {
+		return nil, nil, "", err
+	}
+
+	// Construct contact
+	udContact := contact.Contact{
+		ID:       udId,
+		DhPubKey: udDhPubKey,
+	}
+
+	contactFile = udContact.Marshal()
+
+	return
+}
+
 func init() {
 	// User Discovery subcommand Options
 	udCmd.Flags().StringP(udRegisterFlag, "r", "",
diff --git a/ud/addFact.go b/ud/addFact.go
index c107636c365bfeedd449e67c9ebab426365551fd..719e7d137ab1f9c3e5ce4d414c9db08876d668a4 100644
--- a/ud/addFact.go
+++ b/ud/addFact.go
@@ -30,12 +30,6 @@ func (m *Manager) SendRegisterFact(f fact.Fact) (string, error) {
 func (m *Manager) addFact(inFact fact.Fact, myId *id.ID,
 	aFC addFactComms) (string, error) {
 
-	// get UD host
-	udHost, err := m.getOrAddUdHost()
-	if err != nil {
-		return "", err
-	}
-
 	// Create a primitives Fact so we can hash it
 	f, err := fact.NewFact(inFact.T, inFact.Fact)
 	if err != nil {
@@ -68,7 +62,7 @@ func (m *Manager) addFact(inFact fact.Fact, myId *id.ID,
 	}
 
 	// Send the message
-	response, err := aFC.SendRegisterFact(udHost, &remFactMsg)
+	response, err := aFC.SendRegisterFact(m.ud.host, &remFactMsg)
 
 	confirmationID := ""
 	if response != nil {
diff --git a/ud/alternate.go b/ud/alternate.go
deleted file mode 100644
index f53281c43470d44ed24b40f65a02c143c8d785e3..0000000000000000000000000000000000000000
--- a/ud/alternate.go
+++ /dev/null
@@ -1,64 +0,0 @@
-package ud
-
-import (
-	"github.com/pkg/errors"
-	"gitlab.com/elixxir/crypto/contact"
-	"gitlab.com/xx_network/comms/connect"
-	"gitlab.com/xx_network/primitives/id"
-)
-
-// alternateUd is an alternative user discovery service.
-// This is used for testing, so client can avoid contacting
-// the production server. This requires an alternative,
-// deployed UD service.
-type alternateUd struct {
-	host     *connect.Host
-	dhPubKey []byte
-}
-
-// SetAlternativeUserDiscovery sets the alternativeUd object within manager.
-// Once set, any user discovery operation will go through the alternative
-// user discovery service.
-//
-// To undo this operation, use UnsetAlternativeUserDiscovery.
-func (m *Manager) SetAlternativeUserDiscovery(altCert, altAddress,
-	contactFile []byte) error {
-	params := connect.GetDefaultHostParams()
-	params.AuthEnabled = false
-
-	udIdBytes, dhPubKey, err := contact.ReadContactFromFile(contactFile)
-	if err != nil {
-		return err
-	}
-
-	udID, err := id.Unmarshal(udIdBytes)
-	if err != nil {
-		return err
-	}
-
-	// Add a new host and return it if it does not already exist
-	host, err := m.comms.AddHost(udID, string(altAddress),
-		altCert, params)
-	if err != nil {
-		return errors.WithMessage(err, "User Discovery host object could "+
-			"not be constructed.")
-	}
-
-	m.alternativeUd = &alternateUd{
-		host:     host,
-		dhPubKey: dhPubKey,
-	}
-
-	return nil
-}
-
-// UnsetAlternativeUserDiscovery clears out the information from
-// the Manager object.
-func (m *Manager) UnsetAlternativeUserDiscovery() error {
-	if m.alternativeUd == nil {
-		return errors.New("Alternative User Discovery is already unset.")
-	}
-
-	m.alternativeUd = nil
-	return nil
-}
diff --git a/ud/confirmFact.go b/ud/confirmFact.go
index fb81b7a9ee78e373fb54aaa6504d22c4eb1fa35b..a55da37566945a03b5c0a276f92b7e30ec220f4d 100644
--- a/ud/confirmFact.go
+++ b/ud/confirmFact.go
@@ -19,17 +19,11 @@ func (m *Manager) ConfirmFact(confirmationID, code string) error {
 
 // confirmFact is a helper function for ConfirmFact.
 func (m *Manager) confirmFact(confirmationID, code string, comm confirmFactComm) error {
-	// get UD host
-	udHost, err := m.getOrAddUdHost()
-	if err != nil {
-		return err
-	}
-
 	msg := &pb.FactConfirmRequest{
 		ConfirmationID: confirmationID,
 		Code:           code,
 	}
-	_, err = comm.SendConfirmFact(udHost, msg)
+	_, err := comm.SendConfirmFact(m.ud.host, msg)
 	if err != nil {
 		return err
 	}
diff --git a/ud/lookup_test.go b/ud/lookup_test.go
index de7fd3f3d488bf5867d9df84a16e18ca897deea9..2b168e4a30c3b04e9840225c43b5e1aab039759c 100644
--- a/ud/lookup_test.go
+++ b/ud/lookup_test.go
@@ -37,11 +37,6 @@ func TestManager_Lookup(t *testing.T) {
 	// Set up mock manager
 	m, tnm := newTestManager(t)
 
-	udContact, err := m.GetContact()
-	if err != nil {
-		t.Fatalf("Failed to get contact: %v", err)
-	}
-
 	uid := id.NewIdFromUInt(0x500000000000000, id.User, t)
 	expectedContact := contact.Contact{
 		ID:       uid,
@@ -87,7 +82,7 @@ func TestManager_Lookup(t *testing.T) {
 	}
 
 	// Run the lookup
-	_, _, err = Lookup(m.user, udContact, callback, uid, p)
+	_, _, err = Lookup(m.user, m.GetContact(), callback, uid, p)
 	if err != nil {
 		t.Errorf("Lookup() returned an error: %+v", err)
 	}
diff --git a/ud/manager.go b/ud/manager.go
index 845d2b800d86170b19a1954a1530bff639617d52..0a4247fb809d876b4c0659639827bc2929ba3b83 100644
--- a/ud/manager.go
+++ b/ud/manager.go
@@ -1,11 +1,6 @@
 package ud
 
 import (
-	"fmt"
-	"gitlab.com/elixxir/crypto/fastRNG"
-	"sync"
-	"time"
-
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/event"
@@ -13,9 +8,9 @@ import (
 	store "gitlab.com/elixxir/client/ud/store"
 	"gitlab.com/elixxir/client/xxdk"
 	"gitlab.com/elixxir/crypto/contact"
+	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/primitives/fact"
-	"gitlab.com/xx_network/comms/connect"
-	"gitlab.com/xx_network/primitives/id"
+	"sync"
 )
 
 // Manager is the control structure for the contacting the user discovery service.
@@ -39,74 +34,56 @@ type Manager struct {
 	// may cause unexpected behaviour.
 	factMux sync.Mutex
 
-	// alternativeUd is an alternate User discovery service to circumvent
-	// production. This is for testing with a separately deployed UD service.
-	alternativeUd *alternateUd
+	// ud is the tracker for the contact information of the specified UD server.
+	// This information is specified in Manager's constructors (NewOrLoad and NewManagerFromBackup).
+	ud *userDiscovery
 }
 
-// LoadOrNewManager loads an existing Manager from storage or creates a
-// new one if there is no extant storage information.
+// NewOrLoad loads an existing Manager from storage or creates a
+// new one if there is no extant storage information. Parameters need be provided
+// to specify how to connect to the User Discovery service. These parameters may be used
+// to contact either the UD server hosted by the xx network team or a custom
+// third-party operated server.
 //
 // Params
 //  - user is an interface that adheres to the xxdk.E2e object.
 //  - comms is an interface that adheres to client.Comms object.
 //  - follower is a method off of xxdk.Cmix which returns the network follower's status.
 //  - username is the name of the user as it is registered with UD. This will be what the end user
-//  provides if through the bindings.
+//    provides if through the bindings.
 //  - networkValidationSig is a signature provided by the network (i.e. the client registrar). This may
-//  be nil, however UD may return an error in some cases (e.g. in a production level environment).
-func LoadOrNewManager(user udE2e, comms Comms, follower udNetworkStatus,
-	username string, networkValidationSig []byte) (*Manager, error) {
-	jww.INFO.Println("ud.LoadOrNewManager()")
-
-	if follower() != xxdk.Running {
-		return nil, errors.New(
-			"cannot start UD Manager when network follower is not running.")
-	}
-
-	// Initialize manager
-	m := &Manager{
-		user:  user,
-		comms: comms,
-	}
+//    be nil, however UD may return an error in some cases (e.g. in a production level environment).
+//  - cert is the TLS certificate for the UD server this call will connect with.
+//  - contactFile is the data within a marshalled contact.Contact. This represents the
+//    contact file of the server this call will connect with.
+//  - address is the IP address of the UD server this call will connect with.
+//
+// Returns
+//  - A Manager object which is registered to the specified UD service.
+func NewOrLoad(user udE2e, comms Comms, follower udNetworkStatus,
+	username string, networkValidationSig,
+	cert, contactFile []byte, address string) (*Manager, error) {
 
-	if m.isRegistered() {
-		// Load manager if already registered
-		var err error
-		m.store, err = store.NewOrLoadStore(m.getKv())
-		if err != nil {
-			return nil, errors.Errorf("Failed to initialize store: %v", err)
-		}
-		return m, nil
-	}
+	jww.INFO.Println("ud.NewOrLoad()")
 
-	// Initialize store
-	var err error
-	m.store, err = store.NewOrLoadStore(m.getKv())
+	// Construct manager
+	m, err := loadOrNewManager(user, comms, follower)
 	if err != nil {
-		return nil, errors.Errorf("Failed to initialize store: %v", err)
+		return nil, err
 	}
 
-	// Initialize/Get host
-	udHost, err := m.getOrAddUdHost()
+	// Set user discovery
+	err = m.setUserDiscovery(cert, contactFile, address)
 	if err != nil {
-		return nil, errors.WithMessage(err, "User Discovery host object could "+
-			"not be constructed.")
+		return nil, err
 	}
 
-	// Register with user discovery
-	stream := m.getRng().GetStream()
-	defer stream.Close()
-	err = m.register(username, networkValidationSig, stream, m.comms, udHost)
+	// Register manager
+	rng := m.getRng().GetStream()
+	defer rng.Close()
+	err = m.register(username, networkValidationSig, rng, comms)
 	if err != nil {
-		return nil, errors.Errorf("Failed to register: %v", err)
-	}
-
-	// Set storage to registered
-	if err = setRegistered(m.getKv()); err != nil && m.getEventReporter() != nil {
-		m.getEventReporter().Report(1, "UserDiscovery", "Registration",
-			fmt.Sprintf("User Registered with UD: %+v",
-				username))
+		return nil, err
 	}
 
 	return m, nil
@@ -115,8 +92,26 @@ func LoadOrNewManager(user udE2e, comms Comms, follower udNetworkStatus,
 // NewManagerFromBackup builds a new user discover manager from a backup.
 // It will construct a manager that is already registered and restore
 // already registered facts into store.
+//
+// Params
+//  - user is an interface that adheres to the xxdk.E2e object.
+//  - comms is an interface that adheres to client.Comms object.
+//  - follower is a method off of xxdk.Cmix which returns the network follower's status.
+//  - username is the name of the user as it is registered with UD. This will be what the end user
+//    provides if through the bindings.
+//  - networkValidationSig is a signature provided by the network (i.e. the client registrar). This may
+//    be nil, however UD may return an error in some cases (e.g. in a production level environment).
+//  - email is a fact.Fact (type Email) which has been registered with UD already.
+//  - phone is a fact.Fact (type Phone) which has been registered with UD already.
+//  - cert is the TLS certificate for the UD server this call will connect with.
+//  - contactFile is the data within a marshalled contact.Contact. This represents the
+//    contact file of the server this call will connect with.
+//  - address is the IP address of the UD server this call will connect with.
+//
+// Returns
+//  - A Manager object which is registered to the specified UD service.
 func NewManagerFromBackup(user udE2e, comms Comms, follower udNetworkStatus,
-	email, phone fact.Fact) (*Manager, error) {
+	email, phone fact.Fact, cert, contactFile []byte, address string) (*Manager, error) {
 	jww.INFO.Println("ud.NewManagerFromBackup()")
 	if follower() != xxdk.Running {
 		return nil, errors.New(
@@ -151,11 +146,9 @@ func NewManagerFromBackup(user udE2e, comms Comms, follower udNetworkStatus,
 			"registered with user discovery.")
 	}
 
-	// Create the user discovery host object
-	_, err = m.getOrAddUdHost()
+	err = m.setUserDiscovery(cert, contactFile, address)
 	if err != nil {
-		return nil, errors.WithMessage(err, "User Discovery host object could "+
-			"not be constructed.")
+		return nil, err
 	}
 
 	return m, nil
@@ -199,96 +192,44 @@ func (m *Manager) GetStringifiedFacts() []string {
 	return m.store.GetStringifiedFacts()
 }
 
-// GetContact returns the contact for UD as retrieved from the NDF.
-func (m *Manager) GetContact() (contact.Contact, error) {
-	grp, err := m.user.GetReceptionIdentity().GetGroup()
-	if err != nil {
-		return contact.Contact{}, err
-	}
-	// Return alternative User discovery contact if set
-	if m.alternativeUd != nil {
-		// Unmarshal UD DH public key
-		alternativeDhPubKey := grp.NewInt(1)
-		if err := alternativeDhPubKey.
-			UnmarshalJSON(m.alternativeUd.dhPubKey); err != nil {
-			return contact.Contact{},
-				errors.WithMessage(err, "Failed to unmarshal UD "+
-					"DH public key.")
-		}
-
-		return contact.Contact{
-			ID:             m.alternativeUd.host.GetId(),
-			DhPubKey:       alternativeDhPubKey,
-			OwnershipProof: nil,
-			Facts:          nil,
-		}, nil
-	}
-
-	netDef := m.getCmix().GetInstance().GetPartialNdf().Get()
-
-	// Unmarshal UD ID from the NDF
-	udID, err := id.Unmarshal(netDef.UDB.ID)
-	if err != nil {
-		return contact.Contact{},
-			errors.Errorf("failed to unmarshal UD ID from NDF: %+v", err)
-	}
-
-	// Unmarshal UD DH public key
-	dhPubKey := grp.NewInt(1)
-	if err = dhPubKey.UnmarshalJSON(netDef.UDB.DhPubKey); err != nil {
-		return contact.Contact{},
-			errors.WithMessage(err, "Failed to unmarshal UD DH "+
-				"public key.")
-	}
-
-	return contact.Contact{
-		ID:             udID,
-		DhPubKey:       dhPubKey,
-		OwnershipProof: nil,
-		Facts:          nil,
-	}, nil
+// GetContact returns the contact.Contact for UD.
+func (m *Manager) GetContact() contact.Contact {
+	return m.ud.contact
 }
 
-// getOrAddUdHost returns the current UD host for the UD ID found in the NDF.
-// If the host does not exist, then it is added and returned.
-func (m *Manager) getOrAddUdHost() (*connect.Host, error) {
-	// Return alternative User discovery service if it has been set
-	if m.alternativeUd != nil {
-		return m.alternativeUd.host, nil
-	}
-
-	netDef := m.getCmix().GetInstance().GetPartialNdf().Get()
-	if netDef.UDB.Cert == "" {
-		return nil, errors.New("NDF does not have User Discovery information, " +
-			"is there network access?: Cert not present.")
+// loadOrNewManager is a helper function which loads from storage or
+// creates a new Manager object.
+func loadOrNewManager(user udE2e, comms Comms,
+	follower udNetworkStatus) (*Manager, error) {
+	if follower() != xxdk.Running {
+		return nil, errors.New(
+			"cannot start UD Manager when network follower is not running.")
 	}
 
-	// Unmarshal UD ID from the NDF
-	udID, err := id.Unmarshal(netDef.UDB.ID)
-	if err != nil {
-		return nil, errors.Errorf("failed to "+
-			"unmarshal UD ID from NDF: %+v", err)
+	// Initialize manager
+	m := &Manager{
+		user:  user,
+		comms: comms,
 	}
 
-	// Return the host, if it exists
-	host, exists := m.comms.GetHost(udID)
-	if exists {
-		return host, nil
+	if m.isRegistered() {
+		// Load manager if already registered
+		var err error
+		m.store, err = store.NewOrLoadStore(m.getKv())
+		if err != nil {
+			return nil, errors.Errorf("Failed to initialize store: %v", err)
+		}
+		return m, nil
 	}
 
-	params := connect.GetDefaultHostParams()
-	params.AuthEnabled = false
-	params.SendTimeout = 20 * time.Second
-
-	// Add a new host and return it if it does not already exist
-	host, err = m.comms.AddHost(udID, netDef.UDB.Address,
-		[]byte(netDef.UDB.Cert), params)
+	// Initialize store
+	var err error
+	m.store, err = store.NewOrLoadStore(m.getKv())
 	if err != nil {
-		return nil, errors.WithMessage(err, "User Discovery host "+
-			"object could not be constructed.")
+		return nil, errors.Errorf("Failed to initialize store: %v", err)
 	}
 
-	return host, nil
+	return m, nil
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/ud/manager_test.go b/ud/manager_test.go
index 1bf18a58b4f3aa41915eddecc789c2c1f240fb4f..b214c9600302170cc0822b8806ac8c8fe6de943b 100644
--- a/ud/manager_test.go
+++ b/ud/manager_test.go
@@ -49,12 +49,12 @@ EnretBzQkeKeBwoB2u6NTiOmUjk=
 
 var testContact = `<xxc(2)LF2ccT+sdqh0AIKlFFeDOJdnxzbQQYhGStgxhOXmijIDkAZiB9kZo+Dl3bRSbBi5pXZ82rOu2IQXz9+5sspChvoccZqgC/dXGhlesmiNy/EbKxWtptTF4tcNyQxtnmCXg1p/HwKey4G2XDekTw86lq6Lpmj72jozvRWlQisqvWz/5deiPaeFGKDKC0OrrDFnIib7WnKqdYt4XyTKdmObnmbvdCbliZq0zBl7J40qKy5FypYXGlZjStIm0R1qtD4XHMZMsrMJEGxdM55zJdSzknXbR8MNahUrGMyUOTivXLHzojYLht0gFQifKMVWhrDjUoVQV43KOLPmdBwY/2Kc5KvVloDeuDXYY0i7tD63gNIp9JA3gJQUJymDdwqbS13riT1DMHHkdTzKEyGdHS+v2l7AVSlJBiTKuyM00FBNuXhhIcFR7ONFCf8cRPOPPBx3Q6iHNsvsca3KPNhwOJBgaQvHSkjIMsudiR954QbwG9rbi2vxVobIgWYMl5j6vlBS/9rfbE/uLdTEQZfNsLKDCIVCCI4I1bYZxZrDLPrfXTrN6W0sCLE7a/kRBQAAAgA7+LwJqiv9O1ogLnS4TYkSEg==xxc>`
 
-func TestManager_SetAlternativeUserDiscovery(t *testing.T) {
+func TestManager_setUserDiscovery(t *testing.T) {
 	m, _ := newTestManager(t)
 
 	altAddr := "0.0.0.0:11420"
-	err := m.SetAlternativeUserDiscovery([]byte(testCert), []byte(altAddr), []byte(testContact))
+	err := m.setUserDiscovery([]byte(testCert), []byte(testContact), string([]byte(altAddr)))
 	if err != nil {
-		t.Fatalf("Unexpected error in SetAlternativeUserDiscovery: %v", err)
+		t.Fatalf("Unexpected error in setUserDiscovery: %v", err)
 	}
 }
diff --git a/ud/mockE2e_test.go b/ud/mockE2e_test.go
index 28ddaeb0badeab3fd2eb0d18e0cacaba137927e0..c57e148fe6a63845a480bebb1aa939789b600bfc 100644
--- a/ud/mockE2e_test.go
+++ b/ud/mockE2e_test.go
@@ -29,13 +29,14 @@ import (
 ///////////////////////////////////////////////////////////////////////////////
 
 type mockE2e struct {
-	grp     *cyclic.Group
-	events  event.Reporter
-	rng     *fastRNG.StreamGenerator
-	kv      *versioned.KV
-	network cmix.Client
-	t       testing.TB
-	key     *rsa.PrivateKey
+	grp       *cyclic.Group
+	events    event.Reporter
+	rng       *fastRNG.StreamGenerator
+	kv        *versioned.KV
+	network   cmix.Client
+	mockStore mockStorage
+	t         testing.TB
+	key       *rsa.PrivateKey
 }
 
 func (m mockE2e) GetE2E() e2e.Handler {
@@ -89,8 +90,7 @@ func (m mockE2e) GetCmix() cmix.Client {
 }
 
 func (m mockE2e) GetStorage() storage.Session {
-	//TODO implement me
-	panic("implement me")
+	return m.mockStore
 }
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/ud/mockStore_test.go b/ud/mockStore_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..5031f491bbfa8b8f24ca35c9f57d3b5dd6df0575
--- /dev/null
+++ b/ud/mockStore_test.go
@@ -0,0 +1,160 @@
+package ud
+
+import (
+	"gitlab.com/elixxir/client/storage"
+	"gitlab.com/elixxir/client/storage/user"
+	"gitlab.com/elixxir/client/storage/versioned"
+	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/ekv"
+	"gitlab.com/elixxir/primitives/version"
+	"gitlab.com/xx_network/crypto/signature/rsa"
+	"gitlab.com/xx_network/primitives/id"
+	"gitlab.com/xx_network/primitives/ndf"
+	"time"
+)
+
+type mockStorage struct{}
+
+func (m mockStorage) GetKV() *versioned.KV {
+	return versioned.NewKV(ekv.MakeMemstore())
+}
+
+func (m mockStorage) GetClientVersion() version.Version {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) Get(key string) (*versioned.Object, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) Set(key string, object *versioned.Object) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) Delete(key string) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) GetCmixGroup() *cyclic.Group {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) GetE2EGroup() *cyclic.Group {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) ForwardRegistrationStatus(regStatus storage.RegistrationStatus) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) GetRegistrationStatus() storage.RegistrationStatus {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) SetRegCode(regCode string) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) GetRegCode() (string, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) SetNDF(def *ndf.NetworkDefinition) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) GetNDF() *ndf.NetworkDefinition {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) GetTransmissionID() *id.ID {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) GetTransmissionSalt() []byte {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) GetReceptionID() *id.ID {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) GetReceptionSalt() []byte {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) GetReceptionRSA() *rsa.PrivateKey {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) GetTransmissionRSA() *rsa.PrivateKey {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) IsPrecanned() bool {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) SetUsername(username string) error {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) GetUsername() (string, error) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) PortableUserInfo() user.Info {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) GetTransmissionRegistrationValidationSignature() []byte {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) GetReceptionRegistrationValidationSignature() []byte {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) GetRegistrationTimestamp() time.Time {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) SetTransmissionRegistrationValidationSignature(b []byte) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) SetReceptionRegistrationValidationSignature(b []byte) {
+	//TODO implement me
+	panic("implement me")
+}
+
+func (m mockStorage) SetRegistrationTimestamp(tsNano int64) {
+	//TODO implement me
+	panic("implement me")
+}
diff --git a/ud/register.go b/ud/register.go
index f41532bd5605ae7d45ddf90baea152293c489d3e..495d50da5e1fb51dd0e9d0e9d0211547d3314946 100644
--- a/ud/register.go
+++ b/ud/register.go
@@ -1,13 +1,13 @@
 package ud
 
 import (
+	"fmt"
 	"github.com/pkg/errors"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/elixxir/crypto/factID"
 	"gitlab.com/elixxir/crypto/hash"
 	"gitlab.com/elixxir/primitives/fact"
-	"gitlab.com/xx_network/comms/connect"
 	"gitlab.com/xx_network/crypto/csprng"
 	"gitlab.com/xx_network/crypto/signature/rsa"
 )
@@ -15,9 +15,9 @@ import (
 // register initiates registration with user discovery given a specified
 // username. Provided a comms sub-interface to facilitate testing.
 func (m *Manager) register(username string, networkSignature []byte,
-	rng csprng.Source, comm registerUserComms, udHost *connect.Host) error {
+	rng csprng.Source, comm registerUserComms) error {
 
-	var err error
+	// Retrieve data used for registration
 	identity := m.user.GetReceptionIdentity()
 	privKey, err := identity.GetRSAPrivatePem()
 	if err != nil {
@@ -63,6 +63,9 @@ func (m *Manager) register(username string, networkSignature []byte,
 	// Hash and sign fact
 	hashedFact := factID.Fingerprint(usernameFact)
 	signedFact, err := rsa.Sign(rng, privKey, hash.CMixHash, hashedFact, nil)
+	if err != nil {
+		return errors.Errorf("Failed to sign fact: %v", err)
+	}
 
 	// Add username fact register request to the user registration message
 	msg.Frs = &pb.FactRegisterRequest{
@@ -75,6 +78,17 @@ func (m *Manager) register(username string, networkSignature []byte,
 	}
 
 	// Register user with user discovery
-	_, err = comm.SendRegisterUser(udHost, msg)
+	_, err = comm.SendRegisterUser(m.ud.host, msg)
+	if err != nil {
+		return err
+	}
+
+	// Set storage to registered
+	if err = setRegistered(m.getKv()); err != nil && m.getEventReporter() != nil {
+		m.getEventReporter().Report(1, "UserDiscovery", "Registration",
+			fmt.Sprintf("User Registered with UD: %+v",
+				username))
+	}
+
 	return err
 }
diff --git a/ud/register_test.go b/ud/register_test.go
index 3a521042c31d8703e752efd439a1456ce8b789af..f5c4f57828f27826ebd025354bc91a13cb81ec49 100644
--- a/ud/register_test.go
+++ b/ud/register_test.go
@@ -26,17 +26,12 @@ func (t *testRegisterComm) SendRegisterUser(_ *connect.Host, msg *pb.UDBUserRegi
 func TestManager_register(t *testing.T) {
 	m, _ := newTestManager(t)
 
-	udHost, err := m.getOrAddUdHost()
-	if err != nil {
-		t.Fatalf("Failed to get/add ud host: %+v", err)
-	}
-
 	c := &testRegisterComm{}
 	prng := NewPrng(42)
 
 	mockSig := []byte("mock")
 
-	err = m.register("testUser", mockSig, prng, c, udHost)
+	err := m.register("testUser", mockSig, prng, c)
 	if err != nil {
 		t.Errorf("register() returned an error: %+v", err)
 	}
diff --git a/ud/remove.go b/ud/remove.go
index 5502096c716110456247c9126f7f11d6da93a642..ebb809c0022ab0bbc81237c092c106bcbf946bd2 100644
--- a/ud/remove.go
+++ b/ud/remove.go
@@ -28,12 +28,6 @@ func (m *Manager) RemoveFact(f fact.Fact) error {
 func (m *Manager) removeFact(f fact.Fact,
 	rFC removeFactComms) error {
 
-	// Get UD host
-	udHost, err := m.getOrAddUdHost()
-	if err != nil {
-		return err
-	}
-
 	// Construct the message to send
 	// Convert our Fact to a mixmessages Fact for sending
 	mmFact := mixmessages.Fact{
@@ -65,7 +59,7 @@ func (m *Manager) removeFact(f fact.Fact,
 	}
 
 	// Send the message
-	_, err = rFC.SendRemoveFact(udHost, &remFactMsg)
+	_, err = rFC.SendRemoveFact(m.ud.host, &remFactMsg)
 	if err != nil {
 		return err
 	}
@@ -83,19 +77,13 @@ func (m *Manager) PermanentDeleteAccount(f fact.Fact) error {
 		return errors.New(fmt.Sprintf("PermanentDeleteAccount must only remove "+
 			"a username. Cannot remove fact %q", f.Fact))
 	}
-
-	udHost, err := m.getOrAddUdHost()
-	if err != nil {
-		return err
-	}
-
 	identity := m.user.GetReceptionIdentity()
 	privKey, err := identity.GetRSAPrivatePem()
 	if err != nil {
 		return err
 	}
 
-	return m.permanentDeleteAccount(f, identity.ID, privKey, m.comms, udHost)
+	return m.permanentDeleteAccount(f, identity.ID, privKey, m.comms, m.ud.host)
 }
 
 // permanentDeleteAccount is a helper function for PermanentDeleteAccount.
diff --git a/ud/remove_test.go b/ud/remove_test.go
index a7cd32bc1e94347262147df7faa674d4e91aa000..53b61b3fae3070c08dad9d5d9d8c9d69503b0371 100644
--- a/ud/remove_test.go
+++ b/ud/remove_test.go
@@ -86,9 +86,9 @@ package ud
 //
 //	tRFC := testRFC{}
 //
-//	udHost, err := m.getOrAddUdHost()
+//	udHost, err := m.getHost()
 //	if err != nil {
-//		t.Fatalf("getOrAddUdHost error: %v", err)
+//		t.Fatalf("getHost error: %v", err)
 //	}
 //
 //	err = m.permanentDeleteAccount(f, mockId, &tRFC, udHost)
diff --git a/ud/search_test.go b/ud/search_test.go
index 865f09d1ecc7e27e1ebbe6aade79e82858b21562..3130e4f9b524a0cd79360a1bbcd42c4430052e8d 100644
--- a/ud/search_test.go
+++ b/ud/search_test.go
@@ -47,10 +47,8 @@ func TestManager_Search(t *testing.T) {
 	grp = getGroup()
 
 	var contacts []*Contact
-	udContact, err := m.GetContact()
-	if err != nil {
-		t.Fatalf("Failed to get ud contact: %v", err)
-	}
+	udContact := m.GetContact()
+
 	contacts = append(contacts, &Contact{
 		UserID: udContact.ID.Bytes(),
 		PubKey: udContact.DhPubKey.Bytes(),
diff --git a/ud/ud.go b/ud/ud.go
new file mode 100644
index 0000000000000000000000000000000000000000..5fb27e619de9d5196b24022b35277f1f26c37837
--- /dev/null
+++ b/ud/ud.go
@@ -0,0 +1,59 @@
+package ud
+
+import (
+	"github.com/pkg/errors"
+	"gitlab.com/elixxir/crypto/contact"
+	"gitlab.com/xx_network/comms/connect"
+	"gitlab.com/xx_network/primitives/id"
+	"time"
+)
+
+// userDiscovery is the user discovery's contact information.
+type userDiscovery struct {
+	host    *connect.Host
+	contact contact.Contact
+}
+
+// setUserDiscovery sets the ud object within Manager.
+// The specified the contact information will be used for
+// all further Manager operations which contact the UD server.
+func (m *Manager) setUserDiscovery(cert,
+	contactFile []byte, address string) error {
+	params := connect.GetDefaultHostParams()
+	params.AuthEnabled = false
+	params.SendTimeout = 20 * time.Second
+
+	udIdBytes, dhPubKeyBytes, err := contact.ReadContactFromFile(contactFile)
+	if err != nil {
+		return err
+	}
+
+	udID, err := id.Unmarshal(udIdBytes)
+	if err != nil {
+		return err
+	}
+
+	// Add a new host and return it if it does not already exist
+	host, err := m.comms.AddHost(udID, address,
+		cert, params)
+	if err != nil {
+		return errors.WithMessage(err, "User Discovery host object could "+
+			"not be constructed.")
+	}
+
+	dhPubKey := m.user.GetE2E().GetGroup().NewInt(1)
+	err = dhPubKey.UnmarshalJSON(dhPubKeyBytes)
+	if err != nil {
+		return err
+	}
+
+	m.ud = &userDiscovery{
+		host: host,
+		contact: contact.Contact{
+			ID:       udID,
+			DhPubKey: dhPubKey,
+		},
+	}
+
+	return nil
+}
diff --git a/ud/utils_test.go b/ud/utils_test.go
index c4082605b959ef94d3ab4d031970c0b370893d05..8a1fb7f826ddea93ebbaca272260a018eedef4d3 100644
--- a/ud/utils_test.go
+++ b/ud/utils_test.go
@@ -35,14 +35,6 @@ import (
 	"gitlab.com/xx_network/primitives/ndf"
 )
 
-// Base64 encoded dh private key using a pre-seeded prng
-// 	prng := NewPrng(42)
-const dhPrivKeyEnc = `U4x/lrFkvxuXu59LtHLon1sUhPJSCcnZND6SugndnVLf15tNdkKbYXoMn58NO6VbDMDWFEyIhTWEGsvgcJsHWAg/YdN1vAK0HfT5GSnhj9qeb4LlTnSOgeeeS71v40zcuoQ+6NY+jE/+HOvqVG2PrBPdGqwEzi6ih3xVec+ix44bC6+uiBuCp1EQikLtPJA8qkNGWnhiBhaXiu0M48bE8657w+BJW1cS/v2+DBAoh+EA2s0tiF9pLLYH2gChHBxwceeWotwtwlpbdLLhKXBeJz8FySMmgo4rBW44F2WOEGFJiUf980RBDtTBFgI/qONXa2/tJ/+JdLrAyv2a0FaSsTYZ5ziWTf3Hno1TQ3NmHP1m10/sHhuJSRq3I25LdSFikM8r60LDyicyhWDxqsBnzqbov0bUqytGgEAsX7KCDohdMmDx3peCg9Sgmjb5bCCUF0bj7U2mRqmui0+ntPw6ILr6GnXtMnqGuLDDmvHP0rO1EhnqeVM6v0SNLEedMmB1M5BZFMjMHPCdo54Okp0C`
-
-const searchMessageEnc = `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`
-const dhKeyEnc = `hQj4FKeaQDt34eO/BQe5OSk571WMQBu4YNqMQ0TFeuzjzCM9lLMuOsQhcyjZcIo4qanfv0egkwW7YgSAAt+WaOc6S1rzbxidb6v00KCEVkXAl3NSYk3ms8Jp0uzejOKEI6I3TCjX+71GZ6304xRKQSXDnuYG7ypvx+tYgj6EWx/sh5DsdIyT0KVxo9c/msT0cT6Fq1Hz1S3TkQc2dLcamn86gtKs4cSNuG/b7HFvyKSCK4KqQ2wrQWhiJCh0L6UhXEqTVwyoVgjH8pA/R+eTIE3QL4rDPy+gFdaZOVbr2jOOEvgYTJxWU7VPygXkPtTTHL8eD5IXoj9b46ll6CAHC5xwkCfiqO+HLE2Cg6nVmIq7eCZOLH1WnrYcjv7TQrYNCdb2hGDZznbI2wVswiIW7CilHaKH5KmiVfZG3cPKfwcTATRFR5oNVcav4wikObzB7gAmP57lGTwF1WqfLlGAxDF1R+Qiljfp1U1f0s7MBjG62gFwxpxs4AgA8lZDnvlRgeM1P0zsaypUbrHXFhu6`
-const lookupRequestEnc = `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`
-
 func newTestManager(t *testing.T) (*Manager, *testNetworkManager) {
 	kv := versioned.NewKV(ekv.MakeMemstore())
 	udStore, err := store.NewOrLoadStore(kv)
@@ -84,16 +76,33 @@ func newTestManager(t *testing.T) (*Manager, *testNetworkManager) {
 	params.SendTimeout = 20 * time.Second
 
 	// Add a new host and return it if it does not already exist
-	_, err = m.comms.AddHost(udID, netDef.UDB.Address,
+	host, err := m.comms.AddHost(udID, netDef.UDB.Address,
 		[]byte(netDef.UDB.Cert), params)
 	if err != nil {
 		t.Fatalf("User Discovery host " +
 			"object could not be constructed.")
 	}
 
-	udContact, err := m.GetContact()
+	udIdData := netDef.UDB.ID
+	udId, err := id.Unmarshal(udIdData)
+	if err != nil {
+		t.Fatalf(err.Error())
+	}
+
+	udDhPubKeyData := netDef.UDB.DhPubKey
+	udDhPubKey := getGroup().NewInt(1)
+	err = udDhPubKey.UnmarshalJSON(udDhPubKeyData)
 	if err != nil {
-		t.Fatalf("Failed to get contact: %v", err)
+		t.Fatalf(err.Error())
+	}
+
+	udContact := contact.Contact{
+		ID:       udId,
+		DhPubKey: udDhPubKey,
+	}
+	m.ud = &userDiscovery{
+		host:    host,
+		contact: udContact,
 	}
 
 	tnm.c = udContact
diff --git a/xxmutils/restoreContacts.go b/xxmutils/restoreContacts.go
index d7b842725c718a8f5f9fd5abb5cee6f5c48e0989..9f43d294e35b7f6d601ba780b93b69bb0966a002 100644
--- a/xxmutils/restoreContacts.go
+++ b/xxmutils/restoreContacts.go
@@ -42,11 +42,6 @@ func RestoreContactsFromBackup(backupPartnerIDs []byte, user *xxdk.E2e,
 	updatesCb interfaces.RestoreContactsUpdater) ([]*id.ID, []*id.ID,
 	[]error, error) {
 
-	udContact, err := udManager.GetContact()
-	if err != nil {
-		return nil, nil, nil, err
-	}
-
 	var restored, failed []*id.ID
 	var errs []error
 
@@ -99,7 +94,7 @@ func RestoreContactsFromBackup(backupPartnerIDs []byte, user *xxdk.E2e,
 	rsWg := &sync.WaitGroup{}
 	rsWg.Add(numRoutines)
 	for i := 0; i < numRoutines; i++ {
-		go LookupContacts(lookupCh, foundCh, failCh, user, udContact, lcWg)
+		go LookupContacts(lookupCh, foundCh, failCh, user, udManager.GetContact(), lcWg)
 		go ResetSessions(resetContactCh, restoredCh, failCh, user,
 			rsWg)
 	}
@@ -131,6 +126,7 @@ func RestoreContactsFromBackup(backupPartnerIDs []byte, user *xxdk.E2e,
 
 	// Event Processing
 	done := false
+	var err error
 	for !done {
 		// NOTE: Timer is reset every loop
 		timeoutTimer := time.NewTimer(restoreTimeout)