diff --git a/bindings/ud.go b/bindings/ud.go
index ac89b1e08b6b557bbc5004b4a535bed72a4d3457..df4d3c5bf2fa1ed27bad1ee66b7c9146862c4da9 100644
--- a/bindings/ud.go
+++ b/bindings/ud.go
@@ -9,6 +9,7 @@ package bindings
 
 import (
 	"fmt"
+	jww "github.com/spf13/jwalterweatherman"
 	"time"
 
 	"github.com/pkg/errors"
@@ -46,6 +47,63 @@ func NewUserDiscovery(client *Client) (*UserDiscovery, error) {
 	}
 }
 
+// NewUserDiscoveryFromBackup returns a new user discovery object. It
+// wil set up the manager with the backup data. Pass into it the backed up
+// facts, one email and phone number each. This will add the registered facts
+// to the backed Store. Any one of these fields may be empty,
+// however both fields being empty will cause an error. Any other fact that is not
+// an email or phone number will return an error. You may only add a fact for the
+// accepted types once each. If you attempt to back up a fact type that has already
+// been backed up, an error will be returned. Anytime an error is returned, it means
+// the backup was not successful.
+// NOTE: Do not use this as a direct store operation. This feature is intended to add facts
+// to a backend store that have ALREADY BEEN REGISTERED on the account.
+// THIS IS NOT FOR ADDING NEWLY REGISTERED FACTS. That is handled on the backend.
+// Only call this once. It must be called after StartNetworkFollower
+// is called and will fail if the network has never been contacted.
+// This function technically has a memory leak because it causes both sides of
+// the bindings to think the other is in charge of the client object.
+// In general this is not an issue because the client object should exist
+// for the life of the program.
+// This must be called while start network follower is running.
+func NewUserDiscoveryFromBackup(client *Client,
+	email, phone string) (*UserDiscovery, error) {
+	single, err := client.getSingle()
+	if err != nil {
+		return nil, errors.WithMessage(err, "Failed to create User Discovery Manager")
+	}
+
+	var emailFact, phoneFact fact.Fact
+	// Parse email as a fact, if it exists
+	if len(email) > 2 {
+		emailFact, err = fact.UnstringifyFact(email)
+		if err != nil {
+			return nil, errors.WithMessagef(err,
+				"Failed to parse malformed email fact: %s", email)
+		}
+	} else {
+		jww.WARN.Printf("Loading manager without a registered email")
+	}
+
+	// Parse phone number as a fact, if it exists
+	if len(phone) > 2 {
+		phoneFact, err = fact.UnstringifyFact(phone)
+		if err != nil {
+			return nil, errors.WithMessagef(err, "Failed to parse "+
+				"stringified phone fact %q", phone)
+		}
+	} else {
+		jww.WARN.Printf("Loading manager without a registered phone number")
+	}
+
+	m, err := ud.NewManagerFromBackup(&client.api, single, emailFact, phoneFact)
+	if err != nil {
+		return nil, errors.WithMessage(err, "Failed to create User Discovery Manager")
+	} else {
+		return &UserDiscovery{ud: m}, nil
+	}
+}
+
 // Register registers a user with user discovery. Will return an error if the
 // network signatures are malformed or if the username is taken. Usernames
 // cannot be changed after registration at this time. Will fail if the user is
@@ -103,37 +161,6 @@ func (ud *UserDiscovery) RemoveUser(fStr string) error {
 	return ud.ud.RemoveUser(f)
 }
 
-//BackUpMissingFacts adds a registered fact to the Store object and saves
-// it to storage. It can take in both an email or a phone number, passed into
-// the function in that order.  Any one of these fields may be empty,
-// however both fields being empty will cause an error. Any other fact that is not
-// an email or phone number will return an error. You may only add a fact for the
-// accepted types once each. If you attempt to back up a fact type that has already
-// been backed up, an error will be returned. Anytime an error is returned, it means
-// the backup was not successful.
-// NOTE: Do not use this as a direct store operation. This feature is intended to add facts
-// to a backend store that have ALREADY BEEN REGISTERED on the account.
-// THIS IS NOT FOR ADDING NEWLY REGISTERED FACTS. That is handled on the backend.
-func (ud *UserDiscovery) BackUpMissingFacts(email, phone string) error {
-	var emailFact, phoneFact fact.Fact
-	var err error
-	if len(email) > 2 {
-		emailFact, err = fact.UnstringifyFact(email)
-		if err != nil {
-			return errors.WithMessagef(err, "Failed to parse malformed email fact: %s", email)
-		}
-	}
-
-	if len(phone) > 2 {
-		phoneFact, err = fact.UnstringifyFact(phone)
-		if err != nil {
-			return errors.WithMessagef(err, "Failed to parse malformed phone fact: %s", phone)
-		}
-	}
-
-	return ud.ud.BackUpMissingFacts(emailFact, phoneFact)
-}
-
 // SearchCallback returns the result of a search
 type SearchCallback interface {
 	Callback(contacts *ContactList, error string)
diff --git a/ud/manager.go b/ud/manager.go
index 9aa0027d2d25dde78ef62d625b2c13910b762810..821718a58b2fdd29e3427e7c655f88e8288cf364 100644
--- a/ud/manager.go
+++ b/ud/manager.go
@@ -22,6 +22,7 @@ import (
 	"gitlab.com/xx_network/crypto/csprng"
 	"gitlab.com/xx_network/crypto/signature/rsa"
 	"gitlab.com/xx_network/primitives/id"
+	"math"
 	"time"
 )
 
@@ -158,6 +159,71 @@ func NewManager(services cmix.Client, e2e e2e.Handler, events event.Manager,
 	return m, nil
 }
 
+// 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.
+func NewManagerFromBackup(client *api.Client, single *single.Manager,
+	email, phone fact.Fact) (*Manager, error) {
+	jww.INFO.Println("ud.NewManagerFromBackup()")
+	if client.NetworkFollowerStatus() != api.Running {
+		return nil, errors.New(
+			"cannot start UD Manager when network follower is not running.")
+	}
+
+	registered := uint32(0)
+
+	m := &Manager{
+		client:     client,
+		comms:      client.GetComms(),
+		rng:        client.GetRng(),
+		sw:         client.GetSwitchboard(),
+		storage:    client.GetStorage(),
+		net:        client.GetNetworkInterface(),
+		single:     single,
+		registered: &registered,
+	}
+
+	err := m.client.GetStorage().GetUd().
+		BackUpMissingFacts(email, phone)
+	if err != nil {
+		return nil, errors.WithMessage(err, "Failed to restore UD store "+
+			"from backup")
+	}
+
+	// check that user discovery is available in the NDF
+	def := m.net.GetInstance().GetPartialNdf().Get()
+
+	if def.UDB.Cert == "" {
+		return nil, errors.New("NDF does not have User Discovery information, " +
+			"is there network access?: Cert not present.")
+	}
+
+	// Create the user discovery host object
+	hp := connect.GetDefaultHostParams()
+	// Client will not send KeepAlive packets
+	hp.KaClientOpts.Time = time.Duration(math.MaxInt64)
+	hp.MaxRetries = 3
+	hp.SendTimeout = 3 * time.Second
+	hp.AuthEnabled = false
+
+	m.myID = m.storage.User().GetCryptographicIdentity().GetReceptionID()
+
+	// Get the commonly used data from storage
+	m.privKey = m.storage.GetUser().ReceptionRSA
+
+	// Set as registered. Since it's from a backup,
+	// the client is already registered
+	if err = m.setRegistered(); err != nil {
+		return nil, errors.WithMessage(err, "failed to set client as "+
+			"registered with user discovery.")
+	}
+
+	// Store the pointer to the group locally for easy access
+	m.grp = m.storage.E2e().GetGroup()
+
+	return m, nil
+}
+
 func LoadManager(services cmix.Client, e2e e2e.Handler, events event.Manager,
 	comms Comms, userStore Userinfo, rng *fastRNG.StreamGenerator,
 	privKey *rsa.PrivateKey, kv *versioned.KV) (*Manager, error) {
@@ -234,18 +300,6 @@ func (m *Manager) UnsetAlternativeUserDiscovery() error {
 	return nil
 }
 
-// BackUpMissingFacts adds a registered fact to the Store object.
-// It can take in both an email and a phone number. One or the other may be nil,
-// however both is considered an error. It checks for the proper fact type for
-// the associated fact. Any other fact.FactType is not accepted and returns an
-// error and nothing is backed up. If you attempt to back up a fact type that h
-// as already been backed up, an error will be returned and nothing will be
-// backed up. Otherwise, it adds the fact and returns whether the Store saved
-// successfully.
-func (m *Manager) BackUpMissingFacts(email, phone fact.Fact) error {
-	return m.store.BackUpMissingFacts(email, phone)
-}
-
 // GetFacts returns a list of fact.Fact objects that exist within the
 // Store's registeredFacts map.
 func (m *Manager) GetFacts() []fact.Fact {
diff --git a/ud/store/facts.go b/ud/store/facts.go
index 9762bc068b915c4d5138226bf827157911508332..127e09d2bcf6287800f53e8c6496ff7e59114f0a 100644
--- a/ud/store/facts.go
+++ b/ud/store/facts.go
@@ -21,6 +21,7 @@ const (
 		"%s (%s) is non-empty but not an email. Cancelling backup operation"
 	backupMissingAllZeroesFactErr = "Cannot backup missing facts: Both email and phone facts are empty!"
 	factNotInStoreErr             = "Fact %v does not exist in store"
+	statefulStoreErr              = "cannot overwrite ud store with existing data"
 )
 
 // Store is the storage object for the higher level ud.Manager object.
@@ -48,6 +49,26 @@ func NewStore(kv *versioned.KV) (*Store, error) {
 	return s, s.save()
 }
 
+// RestoreFromBackUp initializes the confirmedFacts map
+// with the backed up fact data. This will error if
+// the store is already stateful.
+func (s *Store) RestoreFromBackUp(backupData fact.FactList) error {
+	s.mux.Lock()
+	defer s.mux.Unlock()
+
+	if len(s.confirmedFacts) != 0 || len(s.unconfirmedFacts) != 0 {
+		return errors.New(statefulStoreErr)
+	}
+
+	for _, f := range backupData {
+		if !isFactZero(f) {
+			s.confirmedFacts[f] = struct{}{}
+		}
+	}
+
+	return s.save()
+}
+
 // StoreUnconfirmedFact stores a fact that has been added to UD but has not been
 // confirmed by the user. It is keyed on the confirmation ID given by UD.
 func (s *Store) StoreUnconfirmedFact(confirmationId string, f fact.Fact) error {
@@ -94,10 +115,6 @@ func (s *Store) BackUpMissingFacts(email, phone fact.Fact) error {
 	s.mux.Lock()
 	defer s.mux.Unlock()
 
-	if isFactZero(email) && isFactZero(phone) {
-		return errors.New(backupMissingAllZeroesFactErr)
-	}
-
 	modifiedEmail, modifiedPhone := false, false
 
 	// Handle email if it is not zero (empty string)
diff --git a/ud/store/facts_test.go b/ud/store/facts_test.go
index c1f5dfc5c965d8b1bece3ab7fa3b903dc21e2b33..c4bb5ea779b2c9cf65e2b63bb520cc1a901afa57 100644
--- a/ud/store/facts_test.go
+++ b/ud/store/facts_test.go
@@ -27,6 +27,66 @@ func TestNewStore(t *testing.T) {
 
 }
 
+// Unit test
+func TestStore_RestoreFromBackUp(t *testing.T) {
+
+	kv := versioned.NewKV(make(ekv.Memstore))
+
+	s, err := NewStore(kv)
+	if err != nil {
+		t.Errorf("NewStore() produced an error: %v", err)
+	}
+
+	expected := fact.Fact{
+		Fact: "josh",
+		T:    fact.Username,
+	}
+
+	fl := fact.FactList{expected}
+
+	err = s.RestoreFromBackUp(fl)
+	if err != nil {
+		t.Fatalf("RestoreFromBackup err: %v", err)
+	}
+
+	_, exists := s.confirmedFacts[expected]
+	if !exists {
+		t.Fatalf("Fact %s does not exist in map", expected)
+	}
+
+}
+
+// Error case.
+func TestStore_RestoreFromBackUp_StatefulStore(t *testing.T) {
+
+	kv := versioned.NewKV(make(ekv.Memstore))
+
+	s, err := NewStore(kv)
+	if err != nil {
+		t.Errorf("NewStore() produced an error: %v", err)
+	}
+
+	confirmId := "confirm"
+	expected := fact.Fact{
+		Fact: "josh",
+		T:    fact.Username,
+	}
+
+	err = s.StoreUnconfirmedFact(confirmId, expected)
+	if err != nil {
+		t.Fatalf("StoreUnconfirmedFact error: %v", err)
+	}
+
+	// Expected error: should error when restoring on
+	// a stateful store.
+	fl := fact.FactList{expected}
+	err = s.RestoreFromBackUp(fl)
+	if err == nil {
+		t.Fatalf("RestoreFromBackup err: %v", err)
+	}
+
+}
+
 func TestStore_ConfirmFact(t *testing.T) {
 	kv := versioned.NewKV(make(ekv.Memstore))