diff --git a/README.md b/README.md
index e494e57d83614256744b08ea2adf0af371103f4d..26fc33259e9795344bb0477e1fcb97c94e287c05 100644
--- a/README.md
+++ b/README.md
@@ -160,7 +160,10 @@ Available Commands:
 Flags:
       --accept-channel            Accept the channel request for the corresponding recipient ID
       --auth-timeout uint         The number of seconds to wait for an authentication channelto confirm (default 120)
+      --delete-all-requests       Delete the all contact requests, both sent and received.
       --delete-channel            Delete the channel information for the corresponding recipient ID
+      --delete-receive-requests   Delete the all received contact requests.
+      --delete-sent-requests      Delete the all sent contact requests.
       --destfile string           Read this contact file for the destination id
   -d, --destid string             ID to send message to (if below 40, will be precanned. Use '0x' or 'b64:' for hex and base64 representations) (default "0")
       --e2eMaxKeys uint           Max keys used before blocking until a rekey completes (default 800)
diff --git a/api/client.go b/api/client.go
index 0aee60d576cae5301f0e7d5e48f0d91e68f50a21..a289fea1e030118346df4011ef5601e49438fe6d 100644
--- a/api/client.go
+++ b/api/client.go
@@ -684,6 +684,24 @@ func (c *Client) GetNodeRegistrationStatus() (int, int, error) {
 	return numRegistered, len(nodes) - numStale, nil
 }
 
+// DeleteAllRequests clears all requests from client's auth storage.
+func (c *Client) DeleteAllRequests() error {
+	jww.DEBUG.Printf("Deleting all requests")
+	return c.GetStorage().Auth().DeleteAllRequests()
+}
+
+// DeleteSentRequests clears sent requests from client's auth storage.
+func (c *Client) DeleteSentRequests() error {
+	jww.DEBUG.Printf("Deleting all sent requests")
+	return c.GetStorage().Auth().DeleteSentRequests()
+}
+
+// DeleteReceiveRequests clears receive requests from client's auth storage.
+func (c *Client) DeleteReceiveRequests() error {
+	jww.DEBUG.Printf("Deleting all received requests")
+	return c.GetStorage().Auth().DeleteReceiveRequests()
+}
+
 // DeleteContact is a function which removes a partner from Client's storage
 func (c *Client) DeleteContact(partnerId *id.ID) error {
 	jww.DEBUG.Printf("Deleting contact with ID %s", partnerId)
@@ -742,8 +760,8 @@ func (c *Client) DeleteContact(partnerId *id.ID) error {
 	//delete conversations
 	c.storage.Conversations().Delete(partnerId)
 
-	// call delete requests to make sure nothing is lingering. 
-	// this is for saftey to ensure the contact can be readded 
+	// call delete requests to make sure nothing is lingering.
+	// this is for saftey to ensure the contact can be readded
 	// in the future
 	_ = c.storage.Auth().Delete(partnerId)
 
diff --git a/auth/callback.go b/auth/callback.go
index 7d3f262165df1f8cb5eb1f30a5c3283a99da9150..7ae57d144bfb2a3c6e0b7b8cd02cb610d4694553 100644
--- a/auth/callback.go
+++ b/auth/callback.go
@@ -9,6 +9,8 @@ package auth
 
 import (
 	"fmt"
+	"strings"
+
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
@@ -26,7 +28,6 @@ import (
 	"gitlab.com/elixxir/primitives/fact"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/xx_network/crypto/csprng"
-	"strings"
 )
 
 func (m *Manager) StartProcesses() (stoppable.Stoppable, error) {
@@ -185,7 +186,7 @@ func (m *Manager) handleRequest(cmixMsg format.Message,
 				events.Report(5, "Auth", "DuplicateRequest", em)
 				// if the caller of the API wants requests replayed,
 				// replay the duplicate request
-				if m.replayRequests{
+				if m.replayRequests {
 					cbList := m.requestCallbacks.Get(c.ID)
 					for _, cb := range cbList {
 						rcb := cb.(interfaces.RequestCallback)
@@ -229,12 +230,28 @@ func (m *Manager) handleRequest(cmixMsg format.Message,
 				}
 
 				// If I do, delete my request on disk
-				_, _, partnerContact, _ := m.storage.Auth().GetRequest(partnerID)
 				m.storage.Auth().Delete(partnerID)
 
-				// Use the public key sent to me, not the one I
-				// first retrieved to initiate the auth request
-				partnerContact.DhPubKey = partnerPubKey
+				//process the inner payload
+				facts, _, err := fact.UnstringifyFactList(
+					string(requestFmt.msgPayload))
+				if err != nil {
+					em := fmt.Sprintf("failed to parse facts and message "+
+						"from Auth Request: %s", err)
+					jww.WARN.Print(em)
+					events.Report(10, "Auth", "RequestError", em)
+					return
+				}
+
+				// create the contact, note that we use the data
+				// sent in the request and not any data we had
+				// already
+				partnerContact := contact.Contact{
+					ID:             partnerID,
+					DhPubKey:       partnerPubKey,
+					OwnershipProof: copySlice(ownership),
+					Facts:          facts,
+				}
 
 				// add a confirmation to disk
 				if err = m.storage.Auth().AddReceived(partnerContact,
diff --git a/bindings/client.go b/bindings/client.go
index 47e4b34a34943c09a740eaec61ef9c6f26965538..1996507cbc0a005ae20006763f6596fe1ca25834 100644
--- a/bindings/client.go
+++ b/bindings/client.go
@@ -265,6 +265,7 @@ func (c *Client) WaitForNetwork(timeoutMS int) bool {
 func (c *Client) NetworkFollowerStatus() int {
 	return int(c.api.NetworkFollowerStatus())
 }
+
 // HasRunningProcessies checks if any background threads are running.
 // returns true if none are running. This is meant to be
 // used when NetworkFollowerStatus() returns Stopping.
@@ -449,6 +450,21 @@ func (c *Client) GetNodeRegistrationStatus() (*NodeRegistrationsStatus, error) {
 	return &NodeRegistrationsStatus{registered, total}, err
 }
 
+// DeleteAllRequests clears all requests from Client's auth storage.
+func (c *Client) DeleteAllRequests() error {
+	return c.api.DeleteAllRequests()
+}
+
+// DeleteSentRequests clears sent requests from Client's auth storage.
+func (c *Client) DeleteSentRequests() error {
+	return c.api.DeleteSentRequests()
+}
+
+// DeleteReceiveRequests clears receive requests from Client's auth storage.
+func (c *Client) DeleteReceiveRequests() error {
+	return c.api.DeleteReceiveRequests()
+}
+
 // DeleteContact is a function which removes a contact from Client's storage
 func (c *Client) DeleteContact(b []byte) error {
 	contactObj, err := UnmarshalContact(b)
diff --git a/bindings/ud.go b/bindings/ud.go
index 727f4118333c2813c8acd227000deffab78ad6e3..d3883fb973a1f0a44f55efce797f367772a9f0a1 100644
--- a/bindings/ud.go
+++ b/bindings/ud.go
@@ -293,3 +293,18 @@ func (ud UserDiscovery) MultiLookup(ids *IdList, callback MultiLookupCallback,
 
 	return nil
 }
+
+// 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.
+// The contact file is the already read in bytes, not the file path for the contact file.
+func (ud *UserDiscovery) SetAlternativeUserDiscovery(address, cert, contactFile []byte) error {
+	return ud.ud.SetAlternativeUserDiscovery(cert, address, contactFile)
+}
+
+// UnsetAlternativeUserDiscovery clears out the information from
+// the Manager object.
+func (ud *UserDiscovery) UnsetAlternativeUserDiscovery() error {
+	return ud.ud.UnsetAlternativeUserDiscovery()
+}
diff --git a/cmd/root.go b/cmd/root.go
index 7f38db02a83e6cbcd869637e9c5a6fbec920cd14..a3ce0ce3bad8f8188e3a24dad103d75b138dcfbc 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -304,6 +304,18 @@ var rootCmd = &cobra.Command{
 			deleteChannel(client, recipientID)
 		}
 
+		if viper.GetBool("delete-receive-requests") {
+			client.DeleteReceiveRequests()
+		}
+
+		if viper.GetBool("delete-sent-requests") {
+			client.DeleteSentRequests()
+		}
+
+		if viper.GetBool("delete-all-requests") {
+			client.DeleteAllRequests()
+		}
+
 		msg := message.Send{
 			Recipient:   recipientID,
 			Payload:     []byte(msgBody),
@@ -1030,6 +1042,21 @@ func init() {
 	viper.BindPFlag("delete-channel",
 		rootCmd.PersistentFlags().Lookup("delete-channel"))
 
+	rootCmd.PersistentFlags().Bool("delete-receive-requests", false,
+		"Delete the all received contact requests.")
+	viper.BindPFlag("delete-receive-requests",
+		rootCmd.PersistentFlags().Lookup("delete-receive-requests"))
+
+	rootCmd.PersistentFlags().Bool("delete-sent-requests", false,
+		"Delete the all sent contact requests.")
+	viper.BindPFlag("delete-sent-requests",
+		rootCmd.PersistentFlags().Lookup("delete-sent-requests"))
+
+	rootCmd.PersistentFlags().Bool("delete-all-requests", false,
+		"Delete the all contact requests, both sent and received.")
+	viper.BindPFlag("delete-all-requests",
+		rootCmd.PersistentFlags().Lookup("delete-all-requests"))
+
 	rootCmd.Flags().BoolP("send-auth-request", "", false,
 		"Send an auth request to the specified destination and wait"+
 			"for confirmation")
diff --git a/go.mod b/go.mod
index 921d2bfee5931c88e34fc37897d4142f8612b1eb..318963950867ca0e6bbc8182c251de29b19c227e 100644
--- a/go.mod
+++ b/go.mod
@@ -1,19 +1,26 @@
 module gitlab.com/elixxir/client
 
-go 1.17
+go 1.13
 
 require (
 	github.com/cloudflare/circl v1.0.1-0.20211008185751-59b49bc148ce
 	github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3
 	github.com/golang/protobuf v1.5.2
+	github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
+	github.com/magiconair/properties v1.8.4 // indirect
+	github.com/mitchellh/mapstructure v1.4.0 // indirect
 	github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
+	github.com/pelletier/go-toml v1.8.1 // indirect
 	github.com/pkg/errors v0.9.1
+	github.com/smartystreets/assertions v1.0.1 // indirect
+	github.com/spf13/afero v1.5.1 // indirect
+	github.com/spf13/cast v1.3.1 // indirect
 	github.com/spf13/cobra v1.1.1
 	github.com/spf13/jwalterweatherman v1.1.0
 	github.com/spf13/viper v1.7.1
 	gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228
-	gitlab.com/elixxir/comms v0.0.4-0.20220128193157-34178165415d
-	gitlab.com/elixxir/crypto v0.0.7-0.20220209170739-af304c494917
+	gitlab.com/elixxir/comms v0.0.4-0.20220128144348-f01dc3227d76
+	gitlab.com/elixxir/crypto v0.0.7-0.20220208232308-f2bee37935e3
 	gitlab.com/elixxir/ekv v0.1.6
 	gitlab.com/elixxir/primitives v0.0.3-0.20220104173924-275cb9d7834f
 	gitlab.com/xx_network/comms v0.0.4-0.20220126231737-fe2338016cce
@@ -21,35 +28,9 @@ require (
 	gitlab.com/xx_network/primitives v0.0.4-0.20211222205802-03e9d7d835b0
 	golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed
 	golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2
+	google.golang.org/genproto v0.0.0-20210105202744-fe13368bc0e1 // indirect
 	google.golang.org/grpc v1.42.0
 	google.golang.org/protobuf v1.27.1
-)
-
-require (
-	github.com/badoux/checkmail v1.2.1 // indirect
-	github.com/elliotchance/orderedmap v1.4.0 // indirect
-	github.com/fsnotify/fsnotify v1.4.9 // indirect
-	github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
-	github.com/hashicorp/hcl v1.0.0 // indirect
-	github.com/inconshreveable/mousetrap v1.0.0 // indirect
-	github.com/magiconair/properties v1.8.4 // indirect
-	github.com/mitchellh/go-homedir v1.1.0 // indirect
-	github.com/mitchellh/mapstructure v1.4.0 // indirect
-	github.com/pelletier/go-toml v1.8.1 // indirect
-	github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
-	github.com/smartystreets/assertions v1.0.1 // indirect
-	github.com/spf13/afero v1.5.1 // indirect
-	github.com/spf13/cast v1.3.1 // indirect
-	github.com/spf13/pflag v1.0.5 // indirect
-	github.com/subosito/gotenv v1.2.0 // indirect
-	github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 // indirect
-	github.com/ttacon/libphonenumber v1.2.1 // indirect
-	github.com/tyler-smith/go-bip39 v1.1.0 // indirect
-	github.com/zeebo/blake3 v0.1.1 // indirect
-	gitlab.com/xx_network/ring v0.0.3-0.20210527191221-ce3f170aabd5 // indirect
-	golang.org/x/sys v0.0.0-20210902050250-f475640dd07b // indirect
-	golang.org/x/text v0.3.6 // indirect
-	google.golang.org/genproto v0.0.0-20210105202744-fe13368bc0e1 // indirect
 	gopkg.in/ini.v1 v1.62.0 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 )
diff --git a/go.sum b/go.sum
index efda6eaa2973185c4a8cf86bb1d9851d901fa215..f16443fe952c3a180666f891be363b848b077587 100644
--- a/go.sum
+++ b/go.sum
@@ -272,13 +272,20 @@ github.com/zeebo/pcg v1.0.0 h1:dt+dx+HvX8g7Un32rY9XWoYnd0NmKmrIzpHF7qiTDj0=
 github.com/zeebo/pcg v1.0.0/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
 gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228 h1:Gi6rj4mAlK0BJIk1HIzBVMjWNjIUfstrsXC2VqLYPcA=
 gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228/go.mod h1:H6jztdm0k+wEV2QGK/KYA+MY9nj9Zzatux/qIvDDv3k=
+gitlab.com/elixxir/comms v0.0.4-0.20220128144348-f01dc3227d76 h1:bmc/tvLJOIciHRCcRhkZqYKDcH4F503BKUitocEcQk0=
+gitlab.com/elixxir/comms v0.0.4-0.20220128144348-f01dc3227d76/go.mod h1:pj1TXrpHKytF68y53BtCBRYhaiMJWquuVBk4iEN7wkk=
 gitlab.com/elixxir/comms v0.0.4-0.20220128193157-34178165415d h1:207Okb8+amKnRzsKE/4ehl3eb6ZHkWXevq9TimOehzw=
 gitlab.com/elixxir/comms v0.0.4-0.20220128193157-34178165415d/go.mod h1:pj1TXrpHKytF68y53BtCBRYhaiMJWquuVBk4iEN7wkk=
 gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4/go.mod h1:ucm9SFKJo+K0N2GwRRpaNr+tKXMIOVWzmyUD0SbOu2c=
 gitlab.com/elixxir/crypto v0.0.3/go.mod h1:ZNgBOblhYToR4m8tj4cMvJ9UsJAUKq+p0gCp07WQmhA=
+gitlab.com/elixxir/crypto v0.0.7-0.20220110170041-7e42f2e8b062 h1:6LLdEX2U/jA3RakJh/cKtjckMYBBjrjyowoBEtIF9L4=
 gitlab.com/elixxir/crypto v0.0.7-0.20220110170041-7e42f2e8b062/go.mod h1:qmW0OGPB21GcaGg1Jvt527/qUw7ke6W8DKCiYBfsx48=
-gitlab.com/elixxir/crypto v0.0.7-0.20220209170739-af304c494917 h1:tXphTxkgKdJbO9lNh+EmMGaaH8NNklfmHyIdZVoGdng=
-gitlab.com/elixxir/crypto v0.0.7-0.20220209170739-af304c494917/go.mod h1:WyLFCxOOgaCHElpH0Ha893tfjxg3HXYU7lSJz2M4JUE=
+gitlab.com/elixxir/crypto v0.0.7-0.20220208225325-dbdeafce872f h1:pYw+i7SHvRtE7r5PKf738eZ4MVE0JpdCCUvfITj6cEY=
+gitlab.com/elixxir/crypto v0.0.7-0.20220208225325-dbdeafce872f/go.mod h1:WyLFCxOOgaCHElpH0Ha893tfjxg3HXYU7lSJz2M4JUE=
+gitlab.com/elixxir/crypto v0.0.7-0.20220208225807-4ca94bd92105 h1:nuYixTwkX6rAw+9RJ6HBk+8bHVrSbV16vxVOexCyK6s=
+gitlab.com/elixxir/crypto v0.0.7-0.20220208225807-4ca94bd92105/go.mod h1:WyLFCxOOgaCHElpH0Ha893tfjxg3HXYU7lSJz2M4JUE=
+gitlab.com/elixxir/crypto v0.0.7-0.20220208232308-f2bee37935e3 h1:n6CgqQLrYkIWxgbxuDxjE7qNHIeB0EUEnakisf6C0Ng=
+gitlab.com/elixxir/crypto v0.0.7-0.20220208232308-f2bee37935e3/go.mod h1:WyLFCxOOgaCHElpH0Ha893tfjxg3HXYU7lSJz2M4JUE=
 gitlab.com/elixxir/ekv v0.1.6 h1:M2hUSNhH/ChxDd+s8xBqSEKgoPtmE6hOEBqQ73KbN6A=
 gitlab.com/elixxir/ekv v0.1.6/go.mod h1:e6WPUt97taFZe5PFLPb1Dupk7tqmDCTQu1kkstqJvw4=
 gitlab.com/elixxir/primitives v0.0.0-20200731184040-494269b53b4d/go.mod h1:OQgUZq7SjnE0b+8+iIAT2eqQF+2IFHn73tOo+aV11mg=
@@ -321,6 +328,7 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed h1:YoWVYYAfvQ4ddHv3OKmIvX7NCAhFGTj62VP2l2kfBbA=
 golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
@@ -359,6 +367,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20210525063256-abc453219eb5 h1:wjuX4b5yYQnEQHzd+CBcrcC6OVR2J1CN6mUy0oSxIPo=
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
 golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
diff --git a/storage/auth/store.go b/storage/auth/store.go
index 2bb90faf774bb777b28b33799934d89f9a966fe9..fb9aa2b04be8875bae32de4c74752db3dd80ddee 100644
--- a/storage/auth/store.go
+++ b/storage/auth/store.go
@@ -403,7 +403,7 @@ func (s *Store) Done(partner *id.ID) {
 	r.mux.Unlock()
 }
 
-// delete is one of two calls after using a request. This one is to be used when
+// Delete is one of two calls after using a request. This one is to be used when
 // the use is unsuccessful. It deletes all references to the request associated
 // with the passed partner, if it exists. It will allow any thread waiting on
 // access to continue. They should fail due to the deletion of the structure.
@@ -418,16 +418,9 @@ func (s *Store) Delete(partner *id.ID) error {
 
 	switch r.rt {
 	case Sent:
-		delete(s.fingerprints, r.sent.fingerprint)
-		if err := r.sent.delete(); err != nil {
-			jww.FATAL.Panicf("Failed to delete sent request: %+v", err)
-		}
-
+		s.deleteSentRequest(r)
 	case Receive:
-		if err := util.DeleteContact(s.kv, r.receive.ID); err != nil {
-			jww.FATAL.Panicf("Failed to delete recieved request "+
-				"contact: %+v", err)
-		}
+		s.deleteReceiveRequest(r)
 	}
 
 	delete(s.requests, *partner)
@@ -438,3 +431,91 @@ func (s *Store) Delete(partner *id.ID) error {
 
 	return nil
 }
+
+// DeleteAllRequests clears the request map and all associated storage objects
+// containing request data.
+func (s *Store) DeleteAllRequests() error {
+	s.mux.Lock()
+	defer s.mux.Unlock()
+
+	for partnerId, req := range s.requests {
+		switch req.rt {
+		case Sent:
+			s.deleteSentRequest(req)
+			delete(s.requests, partnerId)
+		case Receive:
+			s.deleteReceiveRequest(req)
+			delete(s.requests, partnerId)
+		}
+
+	}
+
+	if err := s.save(); err != nil {
+		jww.FATAL.Panicf("Failed to store updated request map after "+
+			"deleting all requests: %+v", err)
+	}
+
+	return nil
+}
+
+// DeleteSentRequests deletes all Sent requests from Store.
+func (s *Store) DeleteSentRequests() error {
+	s.mux.Lock()
+	defer s.mux.Unlock()
+
+	for partnerId, req := range s.requests {
+		switch req.rt {
+		case Sent:
+			s.deleteSentRequest(req)
+			delete(s.requests, partnerId)
+		case Receive:
+			continue
+		}
+	}
+
+	if err := s.save(); err != nil {
+		jww.FATAL.Panicf("Failed to store updated request map after "+
+			"deleting all sent requests: %+v", err)
+	}
+
+	return nil
+}
+
+// DeleteReceiveRequests deletes all Receive requests from Store.
+func (s *Store) DeleteReceiveRequests() error {
+	s.mux.Lock()
+	defer s.mux.Unlock()
+
+	for partnerId, req := range s.requests {
+		switch req.rt {
+		case Sent:
+			continue
+		case Receive:
+			s.deleteReceiveRequest(req)
+			delete(s.requests, partnerId)
+		}
+	}
+
+	if err := s.save(); err != nil {
+		jww.FATAL.Panicf("Failed to store updated request map after "+
+			"deleting all receive requests: %+v", err)
+	}
+
+	return nil
+}
+
+// deleteSentRequest is a helper function which deletes a Sent request from storage.
+func (s *Store) deleteSentRequest(r *request) {
+	delete(s.fingerprints, r.sent.fingerprint)
+	if err := r.sent.delete(); err != nil {
+		jww.FATAL.Panicf("Failed to delete sent request: %+v", err)
+	}
+}
+
+// deleteReceiveRequest is a helper function which deletes a Receive request from storage.
+func (s *Store) deleteReceiveRequest(r *request) {
+	if err := util.DeleteContact(s.kv, r.receive.ID); err != nil {
+		jww.FATAL.Panicf("Failed to delete recieved request "+
+			"contact: %+v", err)
+	}
+}
diff --git a/storage/auth/store_test.go b/storage/auth/store_test.go
index 6568cd75540f7633b711d64380e106435b50d359..f1f10414836eb6c37596593322d112dbcfcc9394 100644
--- a/storage/auth/store_test.go
+++ b/storage/auth/store_test.go
@@ -905,6 +905,170 @@ func TestStore_GetAllReceived_MixSentReceived(t *testing.T) {
 
 }
 
+// Unit test.
+func TestStore_DeleteReceiveRequests(t *testing.T) {
+	s, _, _ := makeTestStore(t)
+	c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)}
+	rng := csprng.NewSystemRNG()
+	_, sidhPubKey := genSidhAKeys(rng)
+	if err := s.AddReceived(c, sidhPubKey); err != nil {
+		t.Fatalf("AddReceived() returned an error: %+v", err)
+	}
+	if _, _, err := s.GetReceivedRequest(c.ID); err != nil {
+		t.Fatalf("GetReceivedRequest() returned an error: %+v", err)
+	}
+
+	err := s.DeleteReceiveRequests()
+	if err != nil {
+		t.Fatalf("DeleteReceiveRequests returned an error: %+v", err)
+	}
+
+	if s.requests[*c.ID] != nil {
+		t.Errorf("delete() failed to delete request for user %s.", c.ID)
+	}
+}
+
+// Unit test.
+func TestStore_DeleteSentRequests(t *testing.T) {
+	s, _, _ := makeTestStore(t)
+	partnerID := id.NewIdFromUInt(rand.Uint64(), id.User, t)
+	rng := csprng.NewSystemRNG()
+	sidhPrivKey, sidhPubKey := genSidhAKeys(rng)
+	sr := &SentRequest{
+		kv:                      s.kv,
+		partner:                 partnerID,
+		partnerHistoricalPubKey: s.grp.NewInt(1),
+		myPrivKey:               s.grp.NewInt(2),
+		myPubKey:                s.grp.NewInt(3),
+		mySidHPrivKeyA:          sidhPrivKey,
+		mySidHPubKeyA:           sidhPubKey,
+		fingerprint:             format.Fingerprint{5},
+	}
+	if err := s.AddSent(sr.partner, sr.partnerHistoricalPubKey,
+		sr.myPrivKey, sr.myPubKey, sr.mySidHPrivKeyA,
+		sr.mySidHPubKeyA, sr.fingerprint); err != nil {
+		t.Fatalf("AddSent() returned an error: %+v", err)
+	}
+
+	err := s.DeleteSentRequests()
+	if err != nil {
+		t.Fatalf("DeleteSentRequests returned an error: %+v", err)
+	}
+
+	if s.requests[*sr.partner] != nil {
+		t.Errorf("delete() failed to delete request for user %s.",
+			sr.partner)
+	}
+
+	if _, exists := s.fingerprints[sr.fingerprint]; exists {
+		t.Errorf("delete() failed to delete fingerprint for fp %v.",
+			sr.fingerprint)
+	}
+}
+
+// Tests that DeleteSentRequests does not affect receive requests in map
+func TestStore_DeleteSentRequests_ReceiveInMap(t *testing.T) {
+	s, _, _ := makeTestStore(t)
+	c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)}
+	rng := csprng.NewSystemRNG()
+	_, sidhPubKey := genSidhAKeys(rng)
+	if err := s.AddReceived(c, sidhPubKey); err != nil {
+		t.Fatalf("AddReceived() returned an error: %+v", err)
+	}
+
+	err := s.DeleteSentRequests()
+	if err != nil {
+		t.Fatalf("DeleteSentRequests returned an error: %+v", err)
+	}
+
+	if s.requests[*c.ID] == nil {
+		t.Fatalf("DeleteSentRequests removes receive requests!")
+	}
+
+}
+
+// Tests that DeleteReceiveRequests does not affect sent requests in map
+func TestStore_DeleteReceiveRequests_SentInMap(t *testing.T) {
+	s, _, _ := makeTestStore(t)
+	partnerID := id.NewIdFromUInt(rand.Uint64(), id.User, t)
+	rng := csprng.NewSystemRNG()
+	sidhPrivKey, sidhPubKey := genSidhAKeys(rng)
+	sr := &SentRequest{
+		kv:                      s.kv,
+		partner:                 partnerID,
+		partnerHistoricalPubKey: s.grp.NewInt(1),
+		myPrivKey:               s.grp.NewInt(2),
+		myPubKey:                s.grp.NewInt(3),
+		mySidHPrivKeyA:          sidhPrivKey,
+		mySidHPubKeyA:           sidhPubKey,
+		fingerprint:             format.Fingerprint{5},
+	}
+	if err := s.AddSent(sr.partner, sr.partnerHistoricalPubKey,
+		sr.myPrivKey, sr.myPubKey, sr.mySidHPrivKeyA,
+		sr.mySidHPubKeyA, sr.fingerprint); err != nil {
+		t.Fatalf("AddSent() returned an error: %+v", err)
+	}
+
+	err := s.DeleteReceiveRequests()
+	if err != nil {
+		t.Fatalf("DeleteSentRequests returned an error: %+v", err)
+	}
+
+	if s.requests[*partnerID] == nil {
+		t.Fatalf("DeleteReceiveRequests removes sent requests!")
+	}
+
+}
+
+// Unit test.
+func TestStore_DeleteAllRequests(t *testing.T) {
+	s, _, _ := makeTestStore(t)
+	partnerID := id.NewIdFromUInt(rand.Uint64(), id.User, t)
+	rng := csprng.NewSystemRNG()
+	sidhPrivKey, sidhPubKey := genSidhAKeys(rng)
+	sr := &SentRequest{
+		kv:                      s.kv,
+		partner:                 partnerID,
+		partnerHistoricalPubKey: s.grp.NewInt(1),
+		myPrivKey:               s.grp.NewInt(2),
+		myPubKey:                s.grp.NewInt(3),
+		mySidHPrivKeyA:          sidhPrivKey,
+		mySidHPubKeyA:           sidhPubKey,
+		fingerprint:             format.Fingerprint{5},
+	}
+	if err := s.AddSent(sr.partner, sr.partnerHistoricalPubKey,
+		sr.myPrivKey, sr.myPubKey, sr.mySidHPrivKeyA,
+		sr.mySidHPubKeyA, sr.fingerprint); err != nil {
+		t.Fatalf("AddSent() returned an error: %+v", err)
+	}
+
+	c := contact.Contact{ID: id.NewIdFromUInt(rand.Uint64(), id.User, t)}
+	_, sidhPubKey = genSidhAKeys(rng)
+	if err := s.AddReceived(c, sidhPubKey); err != nil {
+		t.Fatalf("AddReceived() returned an error: %+v", err)
+	}
+
+	err := s.DeleteAllRequests()
+	if err != nil {
+		t.Fatalf("DeleteAllRequests returned an error: %+v", err)
+	}
+
+	if s.requests[*sr.partner] != nil {
+		t.Errorf("delete() failed to delete request for user %s.",
+			sr.partner)
+	}
+
+	if _, exists := s.fingerprints[sr.fingerprint]; exists {
+		t.Errorf("delete() failed to delete fingerprint for fp %v.",
+			sr.fingerprint)
+	}
+
+	if s.requests[*c.ID] != nil {
+		t.Errorf("delete() failed to delete request for user %s.", c.ID)
+	}
+
+}
+
 func makeTestStore(t *testing.T) (*Store, *versioned.KV, []*cyclic.Int) {
 	kv := versioned.NewKV(make(ekv.Memstore))
 	grp := cyclic.NewGroup(large.NewInt(173), large.NewInt(0))
diff --git a/ud/manager.go b/ud/manager.go
index 1b9de113a558afc451e2acabfb5dabde096a4f88..b271c0d90a635e3927728a9337b2902bb8a58be4 100644
--- a/ud/manager.go
+++ b/ud/manager.go
@@ -42,9 +42,20 @@ type Manager struct {
 	single SingleInterface
 	myID   *id.ID
 
+	// alternate User discovery service to circumvent production
+	alternativeUd *alternateUd
+
 	registered *uint32
 }
 
+// alternateUd is an alternative user discovery service.
+// This is used for testing, so client can avoid using
+// the production server.
+type alternateUd struct {
+	host     *connect.Host
+	dhPubKey []byte
+}
+
 // NewManager builds a new user discovery manager. It requires that an updated
 // NDF is available and will error if one is not.
 func NewManager(client *api.Client, single *single.Manager) (*Manager, error) {
@@ -94,11 +105,60 @@ func NewManager(client *api.Client, single *single.Manager) (*Manager, error) {
 	return m, nil
 }
 
+// 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
+}
+
 // getHost 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) getHost() (*connect.Host, error) {
-	netDef := m.net.GetInstance().GetPartialNdf().Get()
+	// Return alternative User discovery service if it has been set
+	if m.alternativeUd != nil {
+		return m.alternativeUd.host, nil
+	}
 
+	netDef := m.net.GetInstance().GetPartialNdf().Get()
 	// Unmarshal UD ID from the NDF
 	udID, err := id.Unmarshal(netDef.UDB.ID)
 	if err != nil {
@@ -113,6 +173,7 @@ func (m *Manager) getHost() (*connect.Host, error) {
 
 	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,
@@ -127,6 +188,23 @@ func (m *Manager) getHost() (*connect.Host, error) {
 
 // getContact returns the contact for UD as retrieved from the NDF.
 func (m *Manager) getContact() (contact.Contact, error) {
+	// Return alternative User discovery contact if set
+	if m.alternativeUd != nil {
+		// Unmarshal UD DH public key
+		alternativeDhPubKey := m.storage.E2e().GetGroup().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.net.GetInstance().GetPartialNdf().Get()
 
 	// Unmarshal UD ID from the NDF
diff --git a/ud/manager_test.go b/ud/manager_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..1dcb6c273df1c6ec7ed92980b15fc8990cfab01a
--- /dev/null
+++ b/ud/manager_test.go
@@ -0,0 +1,83 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+package ud
+
+import (
+	"gitlab.com/elixxir/comms/client"
+	"gitlab.com/xx_network/crypto/csprng"
+	"gitlab.com/xx_network/crypto/signature/rsa"
+	"testing"
+)
+
+var testCert = `-----BEGIN CERTIFICATE-----
+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
+EnretBzQkeKeBwoB2u6NTiOmUjk=
+-----END CERTIFICATE-----
+`
+
+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) {
+	isReg := uint32(1)
+
+	// Create a new Private Key to use for signing the Fact
+	rng := csprng.NewSystemRNG()
+	cpk, err := rsa.GenerateKey(rng, 2048)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	comms, err := client.NewClientComms(nil, nil, nil, nil)
+	if err != nil {
+		t.Errorf("Failed to start client comms: %+v", err)
+	}
+
+	// Create our Manager object
+	m := Manager{
+		comms:      comms,
+		net:        newTestNetworkManager(t),
+		privKey:    cpk,
+		registered: &isReg,
+	}
+
+	altAddr := "0.0.0.0:11420"
+	err = m.SetAlternativeUserDiscovery([]byte(testCert), []byte(altAddr), []byte(testContact))
+	if err != nil {
+		t.Fatalf("Unexpected error in SetAlternativeUserDiscovery: %v", err)
+	}
+}