diff --git a/cmd/broadcast.go b/cmd/broadcast.go
index 5d98893bd533444b459563bc22c7ed4790a67784..fc58be9a51a808ec4bad667de77b2934a0e57b77 100644
--- a/cmd/broadcast.go
+++ b/cmd/broadcast.go
@@ -48,8 +48,8 @@ var broadcastCmd = &cobra.Command{
 		/* Set up underlying crypto broadcast.Channel */
 		var channel *crypto.Channel
 		var pk *rsa.PrivateKey
-		keyPath := viper.GetString("keyPath")
-		path, err := utils.ExpandPath(viper.GetString("chanPath"))
+		keyPath := viper.GetString(broadcastKeyPathFlag)
+		path, err := utils.ExpandPath(viper.GetString(broadcastChanPathFlag))
 		if utils.Exists(path) {
 			// Load symmetric from path
 			cBytes, err := utils.ReadFile(path)
@@ -62,8 +62,8 @@ var broadcastCmd = &cobra.Command{
 			}
 		} else {
 			// Load in broadcast channel info
-			name := viper.GetString("name")
-			desc := viper.GetString("description")
+			name := viper.GetString(broadcastNameFlag)
+			desc := viper.GetString(broadcastDescriptionFlag)
 			if name == "" {
 				jww.FATAL.Panicf("Name cannot be empty")
 			} else if desc == "" {
@@ -71,7 +71,7 @@ var broadcastCmd = &cobra.Command{
 			}
 
 			var cryptChannel *crypto.Channel
-			if viper.GetBool("new") {
+			if viper.GetBool(broadcastNewFlag) {
 				// Create a new broadcast channel
 				cryptChannel, pk, err = crypto.NewChannel(name, desc, client.GetRng().GetStream())
 				if err != nil {
@@ -88,12 +88,12 @@ var broadcastCmd = &cobra.Command{
 				}
 			} else {
 				// Read rest of info from config & build object manually
-				pubKeyBytes := []byte(viper.GetString("rsaPub"))
+				pubKeyBytes := []byte(viper.GetString(broadcastRsaPubFlag))
 				pubKey, err := rsa.LoadPublicKeyFromPem(pubKeyBytes)
 				if err != nil {
 					jww.FATAL.Panicf("Failed to load public key at path: %+v", err)
 				}
-				salt := []byte(viper.GetString("salt"))
+				salt := []byte(viper.GetString(broadcastSaltFlag))
 
 				rid, err := crypto.NewChannelID(name, desc, salt, pubKeyBytes)
 				if err != nil {
@@ -154,8 +154,8 @@ var broadcastCmd = &cobra.Command{
 
 		// Select broadcast method
 		var method broadcast.Method
-		symmetric := viper.GetBool("symmetric")
-		asymmetric := viper.GetBool("asymmetric")
+		symmetric := viper.GetBool(broadcastSymmetricFlag)
+		asymmetric := viper.GetBool(broadcastAsymmetricFlag)
 		if symmetric && asymmetric {
 			jww.FATAL.Panicf("Cannot simultaneously broadcast symmetric & asymmetric")
 		}
@@ -169,7 +169,7 @@ var broadcastCmd = &cobra.Command{
 		bcl, err := broadcast.NewBroadcastChannel(*channel, cb, client.GetCmix(), client.GetRng(), broadcast.Param{Method: method})
 
 		/* Create properly sized broadcast message */
-		message := viper.GetString("broadcast")
+		message := viper.GetString(broadcastFlag)
 		fmt.Println(message)
 		var broadcastMessage []byte
 		if message != "" {
@@ -202,8 +202,8 @@ var broadcastCmd = &cobra.Command{
 		}
 
 		/* Receive broadcast messages over the channel */
-		waitSecs := viper.GetUint("waitTimeout")
-		expectedCnt := viper.GetUint("receiveCount")
+		waitSecs := viper.GetUint(waitTimeoutFlag)
+		expectedCnt := viper.GetUint(receiveCountFlag)
 		waitTimeout := time.Duration(waitSecs) * time.Second
 		receivedCount := uint(0)
 		done := false
@@ -239,45 +239,45 @@ var broadcastCmd = &cobra.Command{
 
 func init() {
 	// Single-use subcommand options
-	broadcastCmd.Flags().StringP("name", "", "",
+	broadcastCmd.Flags().StringP(broadcastNameFlag, "", "",
 		"Symmetric channel name")
-	_ = viper.BindPFlag("name", broadcastCmd.Flags().Lookup("name"))
+	bindFlagHelper(broadcastNameFlag, broadcastCmd)
 
-	broadcastCmd.Flags().StringP("rsaPub", "", "",
+	broadcastCmd.Flags().StringP(broadcastRsaPubFlag, "", "",
 		"Broadcast channel rsa pub key")
-	_ = viper.BindPFlag("rsaPub", broadcastCmd.Flags().Lookup("rsaPub"))
+	bindFlagHelper(broadcastRsaPubFlag, broadcastCmd)
 
-	broadcastCmd.Flags().StringP("salt", "", "",
+	broadcastCmd.Flags().StringP(broadcastSaltFlag, "", "",
 		"Broadcast channel salt")
-	_ = viper.BindPFlag("salt", broadcastCmd.Flags().Lookup("salt"))
+	bindFlagHelper(broadcastSaltFlag, broadcastCmd)
 
-	broadcastCmd.Flags().StringP("description", "", "",
+	broadcastCmd.Flags().StringP(broadcastDescriptionFlag, "", "",
 		"Broadcast channel description")
-	_ = viper.BindPFlag("description", broadcastCmd.Flags().Lookup("description"))
+	bindFlagHelper(broadcastDescriptionFlag, broadcastCmd)
 
-	broadcastCmd.Flags().StringP("chanPath", "", "",
+	broadcastCmd.Flags().StringP(broadcastChanPathFlag, "", "",
 		"Broadcast channel output path")
-	_ = viper.BindPFlag("chanPath", broadcastCmd.Flags().Lookup("chanPath"))
+	bindFlagHelper(broadcastChanPathFlag, broadcastCmd)
 
-	broadcastCmd.Flags().StringP("keyPath", "", "",
+	broadcastCmd.Flags().StringP(broadcastKeyPathFlag, "", "",
 		"Broadcast channel private key output path")
-	_ = viper.BindPFlag("keyPath", broadcastCmd.Flags().Lookup("keyPath"))
+	bindFlagHelper(broadcastKeyPathFlag, broadcastCmd)
 
-	broadcastCmd.Flags().BoolP("new", "", false,
+	broadcastCmd.Flags().BoolP(broadcastNewFlag, "", false,
 		"Create new broadcast channel")
-	_ = viper.BindPFlag("new", broadcastCmd.Flags().Lookup("new"))
+	bindFlagHelper(broadcastNewFlag, broadcastCmd)
 
-	broadcastCmd.Flags().StringP("broadcast", "", "",
+	broadcastCmd.Flags().StringP(broadcastFlag, "", "",
 		"Message contents for broadcast")
-	_ = viper.BindPFlag("broadcast", broadcastCmd.Flags().Lookup("broadcast"))
+	bindFlagHelper(broadcastFlag, broadcastCmd)
 
-	broadcastCmd.Flags().BoolP("symmetric", "", false,
+	broadcastCmd.Flags().BoolP(broadcastSymmetricFlag, "", false,
 		"Set broadcast method to symmetric")
-	_ = viper.BindPFlag("symmetric", broadcastCmd.Flags().Lookup("symmetric"))
+	bindFlagHelper(broadcastSymmetricFlag, broadcastCmd)
 
-	broadcastCmd.Flags().BoolP("asymmetric", "", false,
+	broadcastCmd.Flags().BoolP(broadcastAsymmetricFlag, "", false,
 		"Set broadcast method to asymmetric")
-	_ = viper.BindPFlag("asymmetric", broadcastCmd.Flags().Lookup("asymmetric"))
+	bindFlagHelper(broadcastAsymmetricFlag, broadcastCmd)
 
 	rootCmd.AddCommand(broadcastCmd)
 }
diff --git a/cmd/callbacks.go b/cmd/callbacks.go
index ec6bf4cd1760e009c9477b0d845d7a228c5f9e6f..d700147c0d3e290b86e715e0b204c7b6bca8d11c 100644
--- a/cmd/callbacks.go
+++ b/cmd/callbacks.go
@@ -48,7 +48,7 @@ func (a *authCallbacks) Request(requestor contact.Contact,
 	if a.autoConfirm {
 		jww.INFO.Printf("Channel Request: %s",
 			requestor.ID)
-		if viper.GetBool("verify-sends") { // Verify message sends were successful
+		if viper.GetBool(verifySendFlag) { // Verify message sends were successful
 			acceptChannelVerified(messenger, requestor.ID, a.params)
 		} else {
 			acceptChannel(messenger, requestor.ID)
diff --git a/cmd/deployment.go b/cmd/deployment.go
new file mode 100644
index 0000000000000000000000000000000000000000..f5350d516b2beff594fae0d0f70568c3318c2484
--- /dev/null
+++ b/cmd/deployment.go
@@ -0,0 +1,130 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2022 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+package cmd
+
+// Deployment environment constants for the download-ndf code path
+const (
+	mainnet = "mainnet"
+	release = "release"
+	dev     = "dev"
+	testnet = "testnet"
+)
+
+// URL constants pointing to the NDF of the associated deployment environment
+// requested for the download-ndf code path.
+const (
+	mainNetUrl = "https://elixxir-bins.s3.us-west-1.amazonaws.com/ndf/mainnet.json"
+	releaseUrl = "https://elixxir-bins.s3.us-west-1.amazonaws.com/ndf/release.json"
+	devUrl     = "https://elixxir-bins.s3.us-west-1.amazonaws.com/ndf/default.json"
+	testNetUrl = "https://elixxir-bins.s3.us-west-1.amazonaws.com/ndf/testnet.json"
+)
+
+// Certificates for deployment environments. Used to verify NDF signatures.
+const (
+	mainNetCert = `-----BEGIN CERTIFICATE-----
+MIIFqTCCA5GgAwIBAgIUO0qHXSeKrOMucO+Zz82Mf1Zlq4gwDQYJKoZIhvcNAQEL
+BQAwgYAxCzAJBgNVBAYTAktZMRQwEgYDVQQHDAtHZW9yZ2UgVG93bjETMBEGA1UE
+CgwKeHggbmV0d29yazEPMA0GA1UECwwGRGV2T3BzMRMwEQYDVQQDDAp4eC5uZXR3
+b3JrMSAwHgYJKoZIhvcNAQkBFhFhZG1pbnNAeHgubmV0d29yazAeFw0yMTEwMzAy
+MjI5MjZaFw0zMTEwMjgyMjI5MjZaMIGAMQswCQYDVQQGEwJLWTEUMBIGA1UEBwwL
+R2VvcmdlIFRvd24xEzARBgNVBAoMCnh4IG5ldHdvcmsxDzANBgNVBAsMBkRldk9w
+czETMBEGA1UEAwwKeHgubmV0d29yazEgMB4GCSqGSIb3DQEJARYRYWRtaW5zQHh4
+Lm5ldHdvcmswggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQD08ixnPWwz
+FtBIEWx2SnFjBsdrSWCp9NcWXRtGWeq3ACz+ixiflj/U9U4b57aULeOAvcoC7bwU
+j5w3oYxRmXIV40QSevx1z9mNcW3xbbacQ+yCgPPhhj3/c285gVVOUzURLBTNAi9I
+EA59zAb8Vy0E6zfq4HRAhH11Q/10QgDjEXuGXra1k3IlemVsouiJGNAtKojNDE1N
+x9HnraSEiXzdnV2GDplEvMHaLd3s9vs4XsiLB3VwKyHv7EH9+LOIra6pr5BWw+kD
+2qHKGmQMOQe0a7nCirW/k9axH0WiA0XWuQu3U1WfcMEfdC/xn1vtubrdYjtzpXUy
+oUEX5eHfu4OlA/zoH+trocfARDyBmTVbDy0P9imH//a6GUKDui9r3fXwEy5YPMhb
+dKaNc7QWLPHMh1n25h559z6PqxxPT6UqFFbZD2gTw1sbbpjyqhLbnYguurkxY3jZ
+ztW337hROzQ1/abbg/P59JA95Pmhkl8nqqDEf0buOmvMazq3Lwg92nuZ8gsdMKXB
+xaEtTTpxhTPOqzc1/XQgScZnc+092MBDh3C2GMxzylOIdk+yF2Gyb+VWPUe29dSa
+azzxsDXzRy8y8jaOjdSUWaLa/MgS5Dg1AfHtD55bdvqYzw3NEXIVarpMlzl+Z+6w
+jvuwz8GyoMSVe+YEGgvSDvlfY/z19aqneQIDAQABoxkwFzAVBgNVHREEDjAMggp4
+eC5uZXR3b3JrMA0GCSqGSIb3DQEBCwUAA4ICAQCp0JDub2w5vZQvFREyA+utZ/+s
+XT05j1iTgIRKMa3nofDGERYJUG7FcTd373I2baS70PGx8FF1QuXhn4DNNZlW/SZt
+pa1d0pAerqFrIzwOuWVDponYHQ8ayvsT7awCbwZEZE4RhooqS4LqnvtgFu/g7LuM
+zkFN8TER7HAUn3P7BujLvcgtqk2LMDz+AgBRszDp/Bw7+1EJDeG9d7hC/stXgDV/
+vpD1YDpxSmW4zjezFJqV6OdMOwo9RWVIktK3RXbFc6I5UJZ5kmzPe/I2oPPCBQvD
+G3VqFLQe5ik5rXP7SgAN1fL/7KuQna0s42hkV64Z2ymCX69G1ofpgpEFaQLaxLbj
+QOun0r8A3NyKvHRIh4K0dFcc3FSOF60Y6k769HKbOPmSDjSSg0qO9GEONBJ8BxAT
+IHcHoTAOQoqGehdzepXQSjHsPqTXv3ZFFwCCgO0toI0Qhqwo89X6R3k+i4Kaktr7
+mLiPO8s0nq1PZ1XrybKE9BCHkYH1JkUDA+M0pn4QAEx/BuM0QnGXoi1sImW3pEUG
+NP7fjkISrD48P8P/TLS45sx5pB8MNGEsRw0lBKmuOdWDmdfhOltB6JxmbhpstNZp
+6LVLK6SEOwE76xnHiisR2KyhTTiroUq73BgPFWkWhoJDPbmL1DHgnbdKwwstG8Qu
+UGb8k8vh6tzqYZAOKg==
+-----END CERTIFICATE-----`
+	releaseCert = `-----BEGIN CERTIFICATE-----
+MIIFtjCCA56gAwIBAgIJAJnUcpLbGSQiMA0GCSqGSIb3DQEBCwUAMIGMMQswCQYD
+VQQGEwJVUzELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCUNsYXJlbW9udDEQMA4GA1UE
+CgwHRWxpeHhpcjEUMBIGA1UECwwLRGV2ZWxvcG1lbnQxEzARBgNVBAMMCmVsaXh4
+aXIuaW8xHzAdBgkqhkiG9w0BCQEWEGFkbWluQGVsaXh4aXIuaW8wHhcNMjAxMTE3
+MTkwMTUyWhcNMjIxMTE3MTkwMTUyWjCBjDELMAkGA1UEBhMCVVMxCzAJBgNVBAgM
+AkNBMRIwEAYDVQQHDAlDbGFyZW1vbnQxEDAOBgNVBAoMB0VsaXh4aXIxFDASBgNV
+BAsMC0RldmVsb3BtZW50MRMwEQYDVQQDDAplbGl4eGlyLmlvMR8wHQYJKoZIhvcN
+AQkBFhBhZG1pbkBlbGl4eGlyLmlvMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
+CgKCAgEAvtByOoSS8SeMLvvHIuOGfnx0VgweveJHX93LUyJxr1RlVBXCgC5/QOQN
+N3dmKWzu4YwaA2jtwaAMhkgdfyOcw6kuqfvQjxv99XRIRKM4GZQkJiym2cnorNu7
+hm2/bxmj5TjpP9+vFzbjkJrpRQ80hsV7I9+NKzIhMK4YTgte/F/q9URESlMZxTbb
+MFh3s5iiBfBLRNFFsHVdy8OVH+Jv5901cLn+yowaMDLrBMOWGlRROg82ZeRAranX
+9X1s+6BclJ/cBe/LcDxGso5sco6UzrWHzpDTnOTzHoamQHYCXtAZP4XbzcqI6A5i
+GFM2akuG9Wv3XZZv/6eJRnKS2GLkvv7dtzv+nalxoBKtyIE8ICIVOrb+pVJvY1Id
+HOXkK9MEJJ6sZhddipUaQw6hD4I0dNEt30Ugq9zTgFcEnM2R7qKpIDmxrRbcl280
+TQGNYgdidzleNdZbjcTvsMVhcxPXCY+bVX1xICD1oJiZZbZFejBvPEfLYyzSdYp+
+awX5OnLVSrQtTJu9yz5q3q5pHhxJnqS/CVGLTvzLfmk7BGwRZZuK87LnSixyYfpd
+S23qI45AEUINEE0HDZsI+KBq0oVlDB0Z3AZpWauRDqY3o6JIbIOpqmZc6KntyL7j
+YCAhbB1tchS47PpbIxUgMMGoR3MBkJutPqtTWCEE3l5jvv0CknUCAwEAAaMZMBcw
+FQYDVR0RBA4wDIIKZWxpeHhpci5pbzANBgkqhkiG9w0BAQsFAAOCAgEACLoxE3nh
+3VzXH2lQo1QzjKkG/+1m75T0l9Wn9uxa2W/90qBCfim1CPfWUstGdRLBi8gjDevV
+zK5HN+Cpz2E22qByeN9fl6rJC4zd1vIdexEre5h7goWoV+qFPhOACElor1tF5UQ2
+GD+NFH+Z0ALG1u8db0hBv8NCbtD4YzcQzzINEbs9gp/Sq3cRzkz1wCufFwJwr7+R
+0YqZfPj/v/w9G9wSUys1s3i4xr2u87T/bPF68VRg6r1+kXRSRevXd99wKwap52jY
+zOwsDGZF9BHMpFVYR/yZhfzSK3F1DmvwuqOsfwSFIjrUjfRlwS28zyZ8rjBq1suD
+EAdvYCLDmBSGssNh8E20PHmk5UROYFGEEhlK5ZKj/f1HOmMiOX461XK6HODYyitq
+Six2dPi1ZlBJW83DyFqSWJaUR/CluBYmqrWoBX+chv54bU2Y9j/sA/O98wa7trsk
+ctzvAcXjhXm6ESRVVD/iZvkW5MP2mkgbDpW3RP9souK5JzbcpC7i3hEcAqPSPgzL
+94kHDpYNY7jcGQC4CjPdfBi+Tf6il/QLFRFgyHm2ze3+qrlPT6SQ4hSSH1iXyf4v
+tlqu6u77fbF9yaHtq7dvYxH1WioIUxMqbIC1CNgGC1Y/LhzgLRKPSTBCrbQyTcGc
+0b5cTzVKxdP6v6WOAXVOEkXTcBPZ4nEZxY0=
+-----END CERTIFICATE-----`
+	devCert = `-----BEGIN CERTIFICATE-----
+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
+EnretBzQkeKeBwoB2u6NTiOmUjk=
+-----END CERTIFICATE-----`
+	testNetCert = ``
+)
diff --git a/cmd/fileTransfer.go b/cmd/fileTransfer.go
index 20e8968bf9e4e2ef69556ad7cd1459984c07bee9..9540c7cabbf448d87b1b099ad66b056d9d779bb7 100644
--- a/cmd/fileTransfer.go
+++ b/cmd/fileTransfer.go
@@ -50,7 +50,7 @@ var ftCmd = &cobra.Command{
 		}
 
 		// Initialize the file transfer manager
-		maxThroughput := viper.GetInt("maxThroughput")
+		maxThroughput := viper.GetInt(fileMaxThroughputFlag)
 		m, receiveChan := initFileTransferManager(client, maxThroughput)
 
 		// Wait until connected or crash on timeout
@@ -81,13 +81,13 @@ var ftCmd = &cobra.Command{
 
 		// If set, send the file to the recipient
 		sendDone := make(chan struct{})
-		if viper.IsSet("sendFile") {
-			recipientContactPath := viper.GetString("sendFile")
-			filePath := viper.GetString("filePath")
-			fileType := viper.GetString("fileType")
-			filePreviewPath := viper.GetString("filePreviewPath")
-			filePreviewString := viper.GetString("filePreviewString")
-			retry := float32(viper.GetFloat64("retry"))
+		if viper.IsSet(fileSendFlag) {
+			recipientContactPath := viper.GetString(fileSendFlag)
+			filePath := viper.GetString(filePathFlag)
+			fileType := viper.GetString(fileTypeFlag)
+			filePreviewPath := viper.GetString(filePreviewPathFlag)
+			filePreviewString := viper.GetString(filePreviewStringFlag)
+			retry := float32(viper.GetFloat64(fileRetry))
 
 			sendFile(filePath, fileType, filePreviewPath, filePreviewString,
 				recipientContactPath, retry, m, sendDone)
@@ -348,43 +348,34 @@ func getContactFromFile(path string) contact.Contact {
 
 // init initializes commands and flags for Cobra.
 func init() {
-	ftCmd.Flags().String("sendFile", "",
+	ftCmd.Flags().String(fileSendFlag, "",
 		"Sends a file to a recipient with the contact file at this path.")
-	bindPFlagCheckErr("sendFile")
+	bindFlagHelper(fileSendFlag, ftCmd)
 
-	ftCmd.Flags().String("filePath", "",
+	ftCmd.Flags().String(filePathFlag, "",
 		"The path to the file to send. Also used as the file name.")
-	bindPFlagCheckErr("filePath")
+	bindFlagHelper(filePathFlag, ftCmd)
 
-	ftCmd.Flags().String("fileType", "txt",
+	ftCmd.Flags().String(fileTypeFlag, "txt",
 		"8-byte file type.")
-	bindPFlagCheckErr("fileType")
+	bindFlagHelper(fileTypeFlag, ftCmd)
 
-	ftCmd.Flags().String("filePreviewPath", "",
+	ftCmd.Flags().String(filePreviewPathFlag, "",
 		"The path to the file preview to send. Set either this flag or "+
 			"filePreviewString.")
-	bindPFlagCheckErr("filePreviewPath")
+	bindFlagHelper(filePreviewPathFlag, ftCmd)
 
-	ftCmd.Flags().String("filePreviewString", "",
+	ftCmd.Flags().String(filePreviewStringFlag, "",
 		"File preview data. Set either this flag or filePreviewPath.")
-	bindPFlagCheckErr("filePreviewString")
+	bindFlagHelper(filePreviewStringFlag, ftCmd)
 
-	ftCmd.Flags().Int("maxThroughput", 1000,
+	ftCmd.Flags().Int(fileMaxThroughputFlag, 1000,
 		"Maximum data transfer speed to send file parts (in bytes per second)")
-	bindPFlagCheckErr("maxThroughput")
+	bindFlagHelper(fileMaxThroughputFlag, ftCmd)
 
-	ftCmd.Flags().Float64("retry", 0.5,
+	ftCmd.Flags().Float64(fileRetry, 0.5,
 		"Retry rate.")
-	bindPFlagCheckErr("retry")
+	bindFlagHelper(fileRetry, ftCmd)
 
 	rootCmd.AddCommand(ftCmd)
 }
-
-// bindPFlagCheckErr binds the key to a pflag.Flag used by Cobra and prints an
-// error if one occurs.
-func bindPFlagCheckErr(key string) {
-	err := viper.BindPFlag(key, ftCmd.Flags().Lookup(key))
-	if err != nil {
-		jww.ERROR.Printf("viper.BindPFlag failed for %q: %+v", key, err)
-	}
-}
diff --git a/cmd/flags.go b/cmd/flags.go
new file mode 100644
index 0000000000000000000000000000000000000000..32ce750fae4f6efe97a546b60b24f7633063a52e
--- /dev/null
+++ b/cmd/flags.go
@@ -0,0 +1,150 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2022 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+package cmd
+
+// This is a comprehensive list of CLI flag name constants. Organized by
+// subcommand, with root level CLI flags at the top of the list. Newly added
+// flags for any existing or new subcommands should be listed and organized
+// here. Pulling flags using Viper should use the constants defined here.
+// todo: fill this with all existing flags, replace hardcoded references with
+//  these constants. This makes renaming them easier, as well as having
+//  a consolidated place in code for these flags.
+const (
+	//////////////// Root flags ///////////////////////////////////////////////
+
+	// Send/receive flags
+	verifySendFlag   = "verify-sends"
+	messageFlag      = "message"
+	destIdFlag       = "destid"
+	sendCountFlag    = "sendCount"
+	sendDelayFlag    = "sendDelay"
+	splitSendsFlag   = "splitSends"
+	receiveCountFlag = "receiveCount"
+	waitTimeoutFlag  = "waitTimeout"
+	unsafeFlag       = "unsafe"
+
+	// Channel flags
+	unsafeChannelCreationFlag = "unsafe-channel-creation"
+	acceptChannelFlag         = "accept-channel"
+	deleteChannelFlag         = "delete-channel"
+
+	// Request flags
+	deleteReceiveRequestsFlag = "delete-receive-requests"
+	deleteSentRequestsFlag    = "delete-sent-requests"
+	deleteAllRequestsFlag     = "delete-all-requests"
+	deleteRequestFlag         = "delete-request"
+	sendAuthRequestFlag       = "send-auth-request"
+	authTimeoutFlag           = "auth-timeout"
+
+	// Contact file flags
+	writeContactFlag = "writeContact"
+	destFileFlag     = "destfile"
+
+	// Log flags
+	logLevelFlag = "logLevel"
+	logFlag      = "log"
+
+	// Loading/establishing xxdk.E2E
+	sessionFlag       = "session"
+	passwordFlag      = "password"
+	ndfFlag           = "ndf"
+	regCodeFlag       = "regcode"
+	protoUserPathFlag = "protoUserPath"
+	protoUserOutFlag  = "protoUserOut"
+	forceLegacyFlag   = "force-legacy"
+
+	// Backup flags
+	backupOutFlag     = "backupOut"
+	backupJsonOutFlag = "backupJsonOut"
+	backupInFlag      = "backupIn"
+	backupPassFlag    = "backupPass"
+	backupIdListFlag  = "backupIdList"
+
+	// Network following/logging flags
+	verboseRoundTrackingFlag    = "verboseRoundTracking"
+	forceHistoricalRoundsFlag   = "forceHistoricalRounds"
+	slowPollingFlag             = "slowPolling"
+	forceMessagePickupRetryFlag = "forceMessagePickupRetry"
+
+	// E2E Params
+	e2eMinKeysFlag        = "e2eMinKeys"
+	e2eMaxKeysFlag        = "e2eMaxKeys"
+	e2eNumReKeysFlag      = "e2eNumReKeys"
+	e2eRekeyThresholdFlag = "e2eRekeyThreshold"
+
+	// Misc
+	sendIdFlag       = "sendid"
+	profileCpuFlag   = "profile-cpu"
+	userIdPrefixFlag = "userid-prefix"
+
+	///////////////// Broadcast subcommand flags //////////////////////////////
+	broadcastNameFlag        = "name"
+	broadcastRsaPubFlag      = "rsaPub"
+	broadcastSaltFlag        = "salt"
+	broadcastDescriptionFlag = "description"
+	broadcastChanPathFlag    = "chanPath"
+	broadcastKeyPathFlag     = "keyPath"
+	broadcastNewFlag         = "new"
+	broadcastFlag            = "broadcast"
+	broadcastSymmetricFlag   = "symmetric"
+	broadcastAsymmetricFlag  = "asymmetric"
+
+	///////////////// Connection subcommand flags /////////////////////////////
+	connectionFlag              = "connect"
+	connectionStartServerFlag   = "startServer"
+	connectionServerTimeoutFlag = "serverTimeout"
+	connectionDisconnectFlag    = "disconnect"
+	connectionAuthenticatedFlag = "authenticated"
+
+	///////////////// File Transfer subcommand flags //////////////////////////
+	fileSendFlag          = "sendFile"
+	filePathFlag          = "filePath"
+	fileTypeFlag          = "fileType"
+	filePreviewPathFlag   = "filePreviewPath"
+	filePreviewStringFlag = "filePreviewString"
+	fileMaxThroughputFlag = "maxThroughput"
+	fileRetry             = "retry"
+
+	///////////////// GetNdf subcommand flags //////////////////////////////
+	ndfGwHostFlag   = "gwhost"
+	ndfPermHostFlag = "permhost"
+	ndfCertFlag     = "cert"
+	ndfEnvFlag      = "env"
+
+	///////////////// Group subcommand flags //////////////////////////////////
+	groupCreateFlag         = "create"
+	groupNameFlag           = "name"
+	groupResendFlag         = "resend"
+	groupJoinFlag           = "join"
+	groupLeaveFlag          = "leave"
+	groupSendMessageFlag    = "sendMessage"
+	groupWaitFlag           = "wait"
+	groupReceiveTimeoutFlag = "receiveTimeout"
+	groupListFlag           = "list"
+	groupShowFlag           = "show"
+
+	///////////////// Single subcommand flags /////////////////////////////////
+	singleSendFlag        = "send"
+	singleReplyFlag       = "reply"
+	singleContactFlag     = "contact"
+	singleTagFlag         = "tag"
+	singleMaxMessagesFlag = "maxMessages"
+	singleTimeoutFlag     = "timeout"
+
+	///////////////// User Discovery subcommand flags /////////////////////////
+	udRegisterFlag       = "register"
+	udRemoveFlag         = "remove"
+	udAddPhoneFlag       = "addphone"
+	udAddEmailFlag       = "addemail"
+	udConfirmFlag        = "confirm"
+	udLookupFlag         = "lookup"
+	udSearchUsernameFlag = "searchusername"
+	udSearchEmailFlag    = "searchemail"
+	udSearchPhoneFlag    = "searchphone"
+	udBatchAddFlag       = "batchadd"
+)
diff --git a/cmd/getndf.go b/cmd/getndf.go
index 429f2238df30350497c1d0dd178fae7079847761..12299183a40d2e79b8986218f09056445abe0637 100644
--- a/cmd/getndf.go
+++ b/cmd/getndf.go
@@ -42,10 +42,10 @@ var getNDFCmd = &cobra.Command{
 		"and print it.",
 	Args: cobra.NoArgs,
 	Run: func(cmd *cobra.Command, args []string) {
-		if viper.GetString("env") != "" {
+		if viper.IsSet(ndfEnvFlag) {
 			var ndfJSON []byte
 			var err error
-			switch viper.GetString("env") {
+			switch viper.GetString(ndfEnvFlag) {
 			case mainnet:
 				ndfJSON, err = xxdk.DownloadAndVerifySignedNdfWithUrl(mainNetUrl, mainNetCert)
 				if err != nil {
@@ -69,23 +69,23 @@ var getNDFCmd = &cobra.Command{
 				}
 			default:
 				jww.FATAL.Panicf("env flag with unknown flag (%s)",
-					viper.GetString("env"))
+					viper.GetString(ndfEnvFlag))
 			}
 			// Print to stdout
 			fmt.Printf("%s", ndfJSON)
 		} else {
 
 			// Note: getndf prints to stdout, so we default to not do that
-			logLevel := viper.GetUint("logLevel")
-			logPath := viper.GetString("log")
+			logLevel := viper.GetUint(logLevelFlag)
+			logPath := viper.GetString(logFlag)
 			if logPath == "-" || logPath == "" {
 				logPath = "getndf.log"
 			}
 			initLog(logLevel, logPath)
 			jww.INFO.Printf(Version())
-			gwHost := viper.GetString("gwhost")
-			permHost := viper.GetString("permhost")
-			certPath := viper.GetString("cert")
+			gwHost := viper.GetString(ndfGwHostFlag)
+			permHost := viper.GetString(ndfPermHostFlag)
+			certPath := viper.GetString(ndfCertFlag)
 
 			// Load the certificate
 			var cert []byte
@@ -147,25 +147,22 @@ var getNDFCmd = &cobra.Command{
 }
 
 func init() {
-	getNDFCmd.Flags().StringP("gwhost", "", "",
+	getNDFCmd.Flags().StringP(ndfGwHostFlag, "", "",
 		"Poll this gateway host:port for the NDF")
-	viper.BindPFlag("gwhost",
-		getNDFCmd.Flags().Lookup("gwhost"))
-	getNDFCmd.Flags().StringP("permhost", "", "",
+	bindFlagHelper(ndfGwHostFlag, getNDFCmd)
+
+	getNDFCmd.Flags().StringP(ndfPermHostFlag, "", "",
 		"Poll this registration host:port for the NDF")
-	viper.BindPFlag("permhost",
-		getNDFCmd.Flags().Lookup("permhost"))
+	bindFlagHelper(ndfPermHostFlag, getNDFCmd)
 
-	getNDFCmd.Flags().StringP("cert", "", "",
+	getNDFCmd.Flags().StringP(ndfCertFlag, "", "",
 		"Check with the TLS certificate at this path")
-	viper.BindPFlag("cert",
-		getNDFCmd.Flags().Lookup("cert"))
+	bindFlagHelper(ndfCertFlag, getNDFCmd)
 
-	getNDFCmd.Flags().StringP("env", "", "",
+	getNDFCmd.Flags().StringP(ndfEnvFlag, "", "",
 		"Downloads and verifies a signed NDF from a specified environment. "+
 			"Accepted environment flags include mainnet, release, testnet, and dev")
-	viper.BindPFlag("env",
-		getNDFCmd.Flags().Lookup("env"))
+	bindFlagHelper(ndfEnvFlag, getNDFCmd)
 
 	rootCmd.AddCommand(getNDFCmd)
 }
diff --git a/cmd/group.go b/cmd/group.go
index 8564ded98edc282e180df484d394a136455cb1ac..783eff474813b1f3bb3c69a3b2f3212c4d56b427 100644
--- a/cmd/group.go
+++ b/cmd/group.go
@@ -70,45 +70,45 @@ var groupCmd = &cobra.Command{
 		}
 
 		// Get group message and name
-		msgBody := []byte(viper.GetString("message"))
-		name := []byte(viper.GetString("name"))
-		timeout := viper.GetDuration("receiveTimeout")
+		msgBody := []byte(viper.GetString(messageFlag))
+		name := []byte(viper.GetString(groupNameFlag))
+		timeout := viper.GetDuration(groupReceiveTimeoutFlag)
 
-		if viper.IsSet("create") {
-			filePath := viper.GetString("create")
+		if viper.IsSet(groupCreateFlag) {
+			filePath := viper.GetString(groupCreateFlag)
 			createGroup(name, msgBody, filePath, groupManager)
 		}
 
-		if viper.IsSet("resend") {
-			groupIdString := viper.GetString("resend")
+		if viper.IsSet(groupResendFlag) {
+			groupIdString := viper.GetString(groupResendFlag)
 			resendRequests(groupIdString, groupManager)
 		}
 
-		if viper.GetBool("join") {
+		if viper.GetBool(groupJoinFlag) {
 			joinGroup(reqChan, timeout, groupManager)
 		}
 
-		if viper.IsSet("leave") {
-			groupIdString := viper.GetString("leave")
+		if viper.IsSet(groupLeaveFlag) {
+			groupIdString := viper.GetString(groupLeaveFlag)
 			leaveGroup(groupIdString, groupManager)
 		}
 
-		if viper.IsSet("sendMessage") {
-			groupIdString := viper.GetString("sendMessage")
+		if viper.IsSet(groupSendMessageFlag) {
+			groupIdString := viper.GetString(groupSendMessageFlag)
 			sendGroup(groupIdString, msgBody, groupManager)
 		}
 
-		if viper.IsSet("wait") {
-			numMessages := viper.GetUint("wait")
+		if viper.IsSet(groupWaitFlag) {
+			numMessages := viper.GetUint(groupWaitFlag)
 			messageWait(numMessages, timeout, recChan)
 		}
 
-		if viper.GetBool("list") {
+		if viper.GetBool(groupListFlag) {
 			listGroups(groupManager)
 		}
 
-		if viper.IsSet("show") {
-			groupIdString := viper.GetString("show")
+		if viper.IsSet(groupShowFlag) {
+			groupIdString := viper.GetString(groupShowFlag)
 			showGroup(groupIdString, groupManager)
 		}
 	},
@@ -312,61 +312,45 @@ func ReadLines(fileName string) []string {
 }
 
 func init() {
-	groupCmd.Flags().String("create", "",
+	groupCmd.Flags().String(groupCreateFlag, "",
 		"Create a group with from the list of contact file paths.")
-	err := viper.BindPFlag("create", groupCmd.Flags().Lookup("create"))
-	checkBindErr(err, "create")
+	bindFlagHelper(groupCreateFlag, groupCmd)
 
-	groupCmd.Flags().String("name", "Group Name",
+	groupCmd.Flags().String(groupNameFlag, "Group Name",
 		"The name of the new group to create.")
-	err = viper.BindPFlag("name", groupCmd.Flags().Lookup("name"))
-	checkBindErr(err, "name")
+	bindFlagHelper(groupNameFlag, groupCmd)
 
-	groupCmd.Flags().String("resend", "",
+	groupCmd.Flags().String(groupResendFlag, "",
 		"Resend invites for all users in this group ID.")
-	err = viper.BindPFlag("resend", groupCmd.Flags().Lookup("resend"))
-	checkBindErr(err, "resend")
+	bindFlagHelper(groupResendFlag, groupCmd)
 
-	groupCmd.Flags().Bool("join", false,
+	groupCmd.Flags().Bool(groupJoinFlag, false,
 		"Waits for group request joins the group.")
-	err = viper.BindPFlag("join", groupCmd.Flags().Lookup("join"))
-	checkBindErr(err, "join")
+	bindFlagHelper(groupJoinFlag, groupCmd)
 
-	groupCmd.Flags().String("leave", "",
+	groupCmd.Flags().String(groupLeaveFlag, "",
 		"Leave this group ID.")
-	err = viper.BindPFlag("leave", groupCmd.Flags().Lookup("leave"))
-	checkBindErr(err, "leave")
+	bindFlagHelper(groupLeaveFlag, groupCmd)
 
-	groupCmd.Flags().String("sendMessage", "",
+	groupCmd.Flags().String(groupSendMessageFlag, "",
 		"Send message to this group ID.")
-	err = viper.BindPFlag("sendMessage", groupCmd.Flags().Lookup("sendMessage"))
-	checkBindErr(err, "sendMessage")
+	bindFlagHelper(groupSendMessageFlag, groupCmd)
 
-	groupCmd.Flags().Uint("wait", 0,
+	groupCmd.Flags().Uint(groupWaitFlag, 0,
 		"Waits for number of messages to be received.")
-	err = viper.BindPFlag("wait", groupCmd.Flags().Lookup("wait"))
-	checkBindErr(err, "wait")
+	bindFlagHelper(groupWaitFlag, groupCmd)
 
-	groupCmd.Flags().Duration("receiveTimeout", time.Minute,
+	groupCmd.Flags().Duration(groupReceiveTimeoutFlag, time.Minute,
 		"Amount of time to wait for a group request or message before timing out.")
-	err = viper.BindPFlag("receiveTimeout", groupCmd.Flags().Lookup("receiveTimeout"))
-	checkBindErr(err, "receiveTimeout")
+	bindFlagHelper(groupReceiveTimeoutFlag, groupCmd)
 
-	groupCmd.Flags().Bool("list", false,
+	groupCmd.Flags().Bool(groupListFlag, false,
 		"Prints list all groups to which this client belongs.")
-	err = viper.BindPFlag("list", groupCmd.Flags().Lookup("list"))
-	checkBindErr(err, "list")
+	bindFlagHelper(groupListFlag, groupCmd)
 
-	groupCmd.Flags().String("show", "",
+	groupCmd.Flags().String(groupShowFlag, "",
 		"Prints the members of this group ID.")
-	err = viper.BindPFlag("show", groupCmd.Flags().Lookup("show"))
-	checkBindErr(err, "show")
+	bindFlagHelper(groupShowFlag, groupCmd)
 
 	rootCmd.AddCommand(groupCmd)
 }
-
-func checkBindErr(err error, key string) {
-	if err != nil {
-		jww.ERROR.Printf("viper.BindPFlag failed for %s: %+v", key, err)
-	}
-}
diff --git a/cmd/init.go b/cmd/init.go
index 993ee81dba5aa347f37be1159073e9e00ff6e2bb..7854b816344b151caaa8853885b475f7c9cbc41c 100644
--- a/cmd/init.go
+++ b/cmd/init.go
@@ -64,9 +64,9 @@ var initCmd = &cobra.Command{
 }
 
 func init() {
-	initCmd.Flags().StringP("userid-prefix", "", "",
+	initCmd.Flags().StringP(userIdPrefixFlag, "", "",
 		"Desired prefix of userID to brute force when running init command. Prepend (?i) for case-insensitive. Only Base64 characters are valid.")
-	_ = viper.BindPFlag("userid-prefix", initCmd.Flags().Lookup("userid-prefix"))
+	bindFlagHelper(userIdPrefixFlag, initCmd)
 
 	rootCmd.AddCommand(initCmd)
 }
diff --git a/cmd/precan.go b/cmd/precan.go
index 84076dff5472239cd1310cab37949d16f7d29b93..3c00f106a95ca0149de171c68581b3f4ae83f618 100644
--- a/cmd/precan.go
+++ b/cmd/precan.go
@@ -30,7 +30,7 @@ func loadOrInitPrecan(precanId uint, password []byte, storeDir string,
 	// create a new client if none exist
 	if _, err := os.Stat(storeDir); errors.Is(err, fs.ErrNotExist) {
 		// Initialize from scratch
-		ndfJson, err := ioutil.ReadFile(viper.GetString("ndf"))
+		ndfJson, err := ioutil.ReadFile(viper.GetString(ndfFlag))
 		if err != nil {
 			jww.FATAL.Panicf("%+v", err)
 		}
diff --git a/cmd/proto.go b/cmd/proto.go
index b8585ca784a1751be5ec1a0be99143d81a2e82ba..6ab109c5ad15dd5dbaf1497706c0b02507c0ae6f 100644
--- a/cmd/proto.go
+++ b/cmd/proto.go
@@ -28,7 +28,7 @@ func loadOrInitProto(protoUserPath string, password []byte, storeDir string,
 	// create a new client if none exist
 	if _, err := os.Stat(storeDir); errors.Is(err, fs.ErrNotExist) {
 		// Initialize from scratch
-		ndfJson, err := ioutil.ReadFile(viper.GetString("ndf"))
+		ndfJson, err := ioutil.ReadFile(viper.GetString(ndfFlag))
 		if err != nil {
 			jww.FATAL.Panicf("%+v", err)
 		}
diff --git a/cmd/root.go b/cmd/root.go
index 4b360c8d188b767768548bf2d2904a46a1f0d5db..3456033a720c399337467a912de78f45283c951a 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -27,7 +27,6 @@ import (
 	"gitlab.com/elixxir/client/xxdk"
 
 	"gitlab.com/elixxir/client/catalog"
-	"gitlab.com/elixxir/client/cmix"
 	"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 
 	"github.com/spf13/cobra"
@@ -40,128 +39,6 @@ import (
 	"gitlab.com/xx_network/primitives/utils"
 )
 
-// Deployment environment constants for the download-ndf code path
-const (
-	mainnet = "mainnet"
-	release = "release"
-	dev     = "dev"
-	testnet = "testnet"
-)
-
-// URL constants pointing to the NDF of the associated deployment environment
-// requested for the download-ndf code path.
-const (
-	mainNetUrl = "https://elixxir-bins.s3.us-west-1.amazonaws.com/ndf/mainnet.json"
-	releaseUrl = "https://elixxir-bins.s3.us-west-1.amazonaws.com/ndf/release.json"
-	devUrl     = "https://elixxir-bins.s3.us-west-1.amazonaws.com/ndf/default.json"
-	testNetUrl = "https://elixxir-bins.s3.us-west-1.amazonaws.com/ndf/testnet.json"
-)
-
-// Certificates for deployment environments. Used to verify NDF signatures.
-const (
-	mainNetCert = `-----BEGIN CERTIFICATE-----
-MIIFqTCCA5GgAwIBAgIUO0qHXSeKrOMucO+Zz82Mf1Zlq4gwDQYJKoZIhvcNAQEL
-BQAwgYAxCzAJBgNVBAYTAktZMRQwEgYDVQQHDAtHZW9yZ2UgVG93bjETMBEGA1UE
-CgwKeHggbmV0d29yazEPMA0GA1UECwwGRGV2T3BzMRMwEQYDVQQDDAp4eC5uZXR3
-b3JrMSAwHgYJKoZIhvcNAQkBFhFhZG1pbnNAeHgubmV0d29yazAeFw0yMTEwMzAy
-MjI5MjZaFw0zMTEwMjgyMjI5MjZaMIGAMQswCQYDVQQGEwJLWTEUMBIGA1UEBwwL
-R2VvcmdlIFRvd24xEzARBgNVBAoMCnh4IG5ldHdvcmsxDzANBgNVBAsMBkRldk9w
-czETMBEGA1UEAwwKeHgubmV0d29yazEgMB4GCSqGSIb3DQEJARYRYWRtaW5zQHh4
-Lm5ldHdvcmswggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQD08ixnPWwz
-FtBIEWx2SnFjBsdrSWCp9NcWXRtGWeq3ACz+ixiflj/U9U4b57aULeOAvcoC7bwU
-j5w3oYxRmXIV40QSevx1z9mNcW3xbbacQ+yCgPPhhj3/c285gVVOUzURLBTNAi9I
-EA59zAb8Vy0E6zfq4HRAhH11Q/10QgDjEXuGXra1k3IlemVsouiJGNAtKojNDE1N
-x9HnraSEiXzdnV2GDplEvMHaLd3s9vs4XsiLB3VwKyHv7EH9+LOIra6pr5BWw+kD
-2qHKGmQMOQe0a7nCirW/k9axH0WiA0XWuQu3U1WfcMEfdC/xn1vtubrdYjtzpXUy
-oUEX5eHfu4OlA/zoH+trocfARDyBmTVbDy0P9imH//a6GUKDui9r3fXwEy5YPMhb
-dKaNc7QWLPHMh1n25h559z6PqxxPT6UqFFbZD2gTw1sbbpjyqhLbnYguurkxY3jZ
-ztW337hROzQ1/abbg/P59JA95Pmhkl8nqqDEf0buOmvMazq3Lwg92nuZ8gsdMKXB
-xaEtTTpxhTPOqzc1/XQgScZnc+092MBDh3C2GMxzylOIdk+yF2Gyb+VWPUe29dSa
-azzxsDXzRy8y8jaOjdSUWaLa/MgS5Dg1AfHtD55bdvqYzw3NEXIVarpMlzl+Z+6w
-jvuwz8GyoMSVe+YEGgvSDvlfY/z19aqneQIDAQABoxkwFzAVBgNVHREEDjAMggp4
-eC5uZXR3b3JrMA0GCSqGSIb3DQEBCwUAA4ICAQCp0JDub2w5vZQvFREyA+utZ/+s
-XT05j1iTgIRKMa3nofDGERYJUG7FcTd373I2baS70PGx8FF1QuXhn4DNNZlW/SZt
-pa1d0pAerqFrIzwOuWVDponYHQ8ayvsT7awCbwZEZE4RhooqS4LqnvtgFu/g7LuM
-zkFN8TER7HAUn3P7BujLvcgtqk2LMDz+AgBRszDp/Bw7+1EJDeG9d7hC/stXgDV/
-vpD1YDpxSmW4zjezFJqV6OdMOwo9RWVIktK3RXbFc6I5UJZ5kmzPe/I2oPPCBQvD
-G3VqFLQe5ik5rXP7SgAN1fL/7KuQna0s42hkV64Z2ymCX69G1ofpgpEFaQLaxLbj
-QOun0r8A3NyKvHRIh4K0dFcc3FSOF60Y6k769HKbOPmSDjSSg0qO9GEONBJ8BxAT
-IHcHoTAOQoqGehdzepXQSjHsPqTXv3ZFFwCCgO0toI0Qhqwo89X6R3k+i4Kaktr7
-mLiPO8s0nq1PZ1XrybKE9BCHkYH1JkUDA+M0pn4QAEx/BuM0QnGXoi1sImW3pEUG
-NP7fjkISrD48P8P/TLS45sx5pB8MNGEsRw0lBKmuOdWDmdfhOltB6JxmbhpstNZp
-6LVLK6SEOwE76xnHiisR2KyhTTiroUq73BgPFWkWhoJDPbmL1DHgnbdKwwstG8Qu
-UGb8k8vh6tzqYZAOKg==
------END CERTIFICATE-----`
-	releaseCert = `-----BEGIN CERTIFICATE-----
-MIIFtjCCA56gAwIBAgIJAJnUcpLbGSQiMA0GCSqGSIb3DQEBCwUAMIGMMQswCQYD
-VQQGEwJVUzELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCUNsYXJlbW9udDEQMA4GA1UE
-CgwHRWxpeHhpcjEUMBIGA1UECwwLRGV2ZWxvcG1lbnQxEzARBgNVBAMMCmVsaXh4
-aXIuaW8xHzAdBgkqhkiG9w0BCQEWEGFkbWluQGVsaXh4aXIuaW8wHhcNMjAxMTE3
-MTkwMTUyWhcNMjIxMTE3MTkwMTUyWjCBjDELMAkGA1UEBhMCVVMxCzAJBgNVBAgM
-AkNBMRIwEAYDVQQHDAlDbGFyZW1vbnQxEDAOBgNVBAoMB0VsaXh4aXIxFDASBgNV
-BAsMC0RldmVsb3BtZW50MRMwEQYDVQQDDAplbGl4eGlyLmlvMR8wHQYJKoZIhvcN
-AQkBFhBhZG1pbkBlbGl4eGlyLmlvMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
-CgKCAgEAvtByOoSS8SeMLvvHIuOGfnx0VgweveJHX93LUyJxr1RlVBXCgC5/QOQN
-N3dmKWzu4YwaA2jtwaAMhkgdfyOcw6kuqfvQjxv99XRIRKM4GZQkJiym2cnorNu7
-hm2/bxmj5TjpP9+vFzbjkJrpRQ80hsV7I9+NKzIhMK4YTgte/F/q9URESlMZxTbb
-MFh3s5iiBfBLRNFFsHVdy8OVH+Jv5901cLn+yowaMDLrBMOWGlRROg82ZeRAranX
-9X1s+6BclJ/cBe/LcDxGso5sco6UzrWHzpDTnOTzHoamQHYCXtAZP4XbzcqI6A5i
-GFM2akuG9Wv3XZZv/6eJRnKS2GLkvv7dtzv+nalxoBKtyIE8ICIVOrb+pVJvY1Id
-HOXkK9MEJJ6sZhddipUaQw6hD4I0dNEt30Ugq9zTgFcEnM2R7qKpIDmxrRbcl280
-TQGNYgdidzleNdZbjcTvsMVhcxPXCY+bVX1xICD1oJiZZbZFejBvPEfLYyzSdYp+
-awX5OnLVSrQtTJu9yz5q3q5pHhxJnqS/CVGLTvzLfmk7BGwRZZuK87LnSixyYfpd
-S23qI45AEUINEE0HDZsI+KBq0oVlDB0Z3AZpWauRDqY3o6JIbIOpqmZc6KntyL7j
-YCAhbB1tchS47PpbIxUgMMGoR3MBkJutPqtTWCEE3l5jvv0CknUCAwEAAaMZMBcw
-FQYDVR0RBA4wDIIKZWxpeHhpci5pbzANBgkqhkiG9w0BAQsFAAOCAgEACLoxE3nh
-3VzXH2lQo1QzjKkG/+1m75T0l9Wn9uxa2W/90qBCfim1CPfWUstGdRLBi8gjDevV
-zK5HN+Cpz2E22qByeN9fl6rJC4zd1vIdexEre5h7goWoV+qFPhOACElor1tF5UQ2
-GD+NFH+Z0ALG1u8db0hBv8NCbtD4YzcQzzINEbs9gp/Sq3cRzkz1wCufFwJwr7+R
-0YqZfPj/v/w9G9wSUys1s3i4xr2u87T/bPF68VRg6r1+kXRSRevXd99wKwap52jY
-zOwsDGZF9BHMpFVYR/yZhfzSK3F1DmvwuqOsfwSFIjrUjfRlwS28zyZ8rjBq1suD
-EAdvYCLDmBSGssNh8E20PHmk5UROYFGEEhlK5ZKj/f1HOmMiOX461XK6HODYyitq
-Six2dPi1ZlBJW83DyFqSWJaUR/CluBYmqrWoBX+chv54bU2Y9j/sA/O98wa7trsk
-ctzvAcXjhXm6ESRVVD/iZvkW5MP2mkgbDpW3RP9souK5JzbcpC7i3hEcAqPSPgzL
-94kHDpYNY7jcGQC4CjPdfBi+Tf6il/QLFRFgyHm2ze3+qrlPT6SQ4hSSH1iXyf4v
-tlqu6u77fbF9yaHtq7dvYxH1WioIUxMqbIC1CNgGC1Y/LhzgLRKPSTBCrbQyTcGc
-0b5cTzVKxdP6v6WOAXVOEkXTcBPZ4nEZxY0=
------END CERTIFICATE-----`
-	devCert = `-----BEGIN CERTIFICATE-----
-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
-EnretBzQkeKeBwoB2u6NTiOmUjk=
------END CERTIFICATE-----`
-	testNetCert = ``
-)
-
 // Key used for storing xxdk.ReceptionIdentity objects
 const identityStorageKey = "identityStorageKey"
 
@@ -183,7 +60,7 @@ var rootCmd = &cobra.Command{
 	Short: "Runs a client for cMix anonymous communication platform",
 	Args:  cobra.NoArgs,
 	Run: func(cmd *cobra.Command, args []string) {
-		profileOut := viper.GetString("profile-cpu")
+		profileOut := viper.GetString(profileCpuFlag)
 		if profileOut != "" {
 			f, err := os.Create(profileOut)
 			if err != nil {
@@ -205,9 +82,9 @@ var rootCmd = &cobra.Command{
 		var recipientContact contact.Contact
 		var recipientID *id.ID
 
-		destFile := viper.GetString("destfile")
-		destId := viper.GetString("destid")
-		sendId := viper.GetString("sendid")
+		destFile := viper.GetString(destFileFlag)
+		destId := viper.GetString(destIdFlag)
+		sendId := viper.GetString(sendIdFlag)
 		if destFile != "" {
 			recipientContact = readContact(destFile)
 			recipientID = recipientContact.ID
@@ -269,15 +146,15 @@ var rootCmd = &cobra.Command{
 		jww.INFO.Printf("Client backup triggered...")
 
 		// Send Messages
-		msgBody := viper.GetString("message")
+		msgBody := viper.GetString(messageFlag)
 		time.Sleep(10 * time.Second)
 
 		// Accept auth request for this recipient
 		authConfirmed := false
-		if viper.GetBool("accept-channel") {
+		if viper.GetBool(acceptChannelFlag) {
 			// Verify that the confirmation message makes it to the
 			// original sender
-			if viper.GetBool("verify-sends") {
+			if viper.GetBool(verifySendFlag) {
 				acceptChannelVerified(client, recipientID,
 					e2eParams)
 			} else {
@@ -301,8 +178,8 @@ var rootCmd = &cobra.Command{
 		}
 
 		// Send unsafe messages or not?
-		unsafe := viper.GetBool("unsafe")
-		sendAuthReq := viper.GetBool("send-auth-request")
+		unsafe := viper.GetBool(unsafeFlag)
+		sendAuthReq := viper.GetBool(sendAuthRequestFlag)
 		if !unsafe && !authConfirmed && !isPrecanPartner &&
 			sendAuthReq {
 			addAuthenticatedChannel(client, recipientID,
@@ -335,7 +212,7 @@ var rootCmd = &cobra.Command{
 			scnt := uint(0)
 
 			// Wait until authConfirmed
-			waitSecs := viper.GetUint("auth-timeout")
+			waitSecs := viper.GetUint(authTimeoutFlag)
 			for !authConfirmed && scnt < waitSecs {
 				time.Sleep(1 * time.Second)
 				scnt++
@@ -353,11 +230,11 @@ var rootCmd = &cobra.Command{
 		}
 
 		// DeleteFingerprint this recipient
-		if viper.GetBool("delete-channel") {
+		if viper.GetBool(deleteChannelFlag) {
 			deleteChannel(client, recipientID)
 		}
 
-		if viper.GetBool("delete-receive-requests") {
+		if viper.GetBool(deleteReceiveRequestsFlag) {
 			err = client.GetAuth().DeleteReceiveRequests()
 			if err != nil {
 				jww.FATAL.Panicf("Failed to delete received requests:"+
@@ -365,7 +242,7 @@ var rootCmd = &cobra.Command{
 			}
 		}
 
-		if viper.GetBool("delete-sent-requests") {
+		if viper.GetBool(deleteSentRequestsFlag) {
 			err = client.GetAuth().DeleteSentRequests()
 			if err != nil {
 				jww.FATAL.Panicf("Failed to delete sent requests:"+
@@ -373,7 +250,7 @@ var rootCmd = &cobra.Command{
 			}
 		}
 
-		if viper.GetBool("delete-all-requests") {
+		if viper.GetBool(deleteAllRequestsFlag) {
 			err = client.GetAuth().DeleteAllRequests()
 			if err != nil {
 				jww.FATAL.Panicf("Failed to delete all requests:"+
@@ -381,7 +258,7 @@ var rootCmd = &cobra.Command{
 			}
 		}
 
-		if viper.GetBool("delete-request") {
+		if viper.GetBool(deleteRequestFlag) {
 			err = client.GetAuth().DeleteRequest(recipientID)
 			if err != nil {
 				jww.FATAL.Panicf("Failed to delete request for %s:"+
@@ -396,10 +273,10 @@ var rootCmd = &cobra.Command{
 		jww.INFO.Printf("Client Sending messages...")
 
 		wg := &sync.WaitGroup{}
-		sendCnt := int(viper.GetUint("sendCount"))
+		sendCnt := int(viper.GetUint(sendCountFlag))
 		wg.Add(sendCnt)
 		go func() {
-			sendDelay := time.Duration(viper.GetUint("sendDelay"))
+			sendDelay := time.Duration(viper.GetUint(sendDelayFlag))
 			for i := 0; i < sendCnt; i++ {
 				go func(i int) {
 					defer wg.Done()
@@ -421,40 +298,11 @@ var rootCmd = &cobra.Command{
 							jww.FATAL.Panicf("%+v", err)
 						}
 
-						if viper.GetBool("verify-sends") { // Verify message sends were successful
-							retryChan := make(chan struct{})
-							done := make(chan struct{}, 1)
-
-							// Construct the callback function which
-							// verifies successful message send or retries
-							f := func(allRoundsSucceeded, timedOut bool,
-								rounds map[id.Round]cmix.RoundResult) {
-								printRoundResults(
-									rounds, roundIDs, payload, recipientID)
-								if !allRoundsSucceeded {
-									retryChan <- struct{}{}
-								} else {
-									done <- struct{}{}
-								}
-							}
-
-							// Monitor rounds for results
-							err = client.GetCmix().GetRoundResults(e2eParams.Base.Timeout, f, roundIDs...)
-							if err != nil {
-								jww.DEBUG.Printf("Could not verify messages were sent successfully, resending messages...")
-								continue
-							}
-
-							select {
-							case <-retryChan:
-								// On a retry, go to the top of the loop
-								jww.DEBUG.Printf("Messages were not sent successfully, resending messages...")
+						// Verify message sends were successful
+						if viper.GetBool(verifySendFlag) {
+							if !verifySendSuccess(client, e2eParams.Base,
+								roundIDs, recipientID, payload) {
 								continue
-							case <-done:
-								// Close channels on verification success
-								close(done)
-								close(retryChan)
-								break
 							}
 
 						}
@@ -468,9 +316,9 @@ var rootCmd = &cobra.Command{
 
 		// Wait until message timeout or we receive enough then exit
 		// TODO: Actually check for how many messages we've received
-		expectedCnt := viper.GetUint("receiveCount")
+		expectedCnt := viper.GetUint(receiveCountFlag)
 		receiveCnt := uint(0)
-		waitSecs := viper.GetUint("waitTimeout")
+		waitSecs := viper.GetUint(waitTimeoutFlag)
 		waitTimeout := time.Duration(waitSecs) * time.Second
 		done := false
 
@@ -546,10 +394,10 @@ var rootCmd = &cobra.Command{
 
 func initParams() (xxdk.CMIXParams, xxdk.E2EParams) {
 	e2eParams := xxdk.GetDefaultE2EParams()
-	e2eParams.Session.MinKeys = uint16(viper.GetUint("e2eMinKeys"))
-	e2eParams.Session.MaxKeys = uint16(viper.GetUint("e2eMaxKeys"))
-	e2eParams.Session.NumRekeys = uint16(viper.GetUint("e2eNumReKeys"))
-	e2eParams.Session.RekeyThreshold = viper.GetFloat64("e2eRekeyThreshold")
+	e2eParams.Session.MinKeys = uint16(viper.GetUint(e2eMinKeysFlag))
+	e2eParams.Session.MaxKeys = uint16(viper.GetUint(e2eMaxKeysFlag))
+	e2eParams.Session.NumRekeys = uint16(viper.GetUint(e2eNumReKeysFlag))
+	e2eParams.Session.RekeyThreshold = viper.GetFloat64(e2eRekeyThresholdFlag)
 
 	if viper.GetBool("splitSends") {
 		e2eParams.Base.ExcludedRounds = excludedRounds.NewSet()
@@ -557,17 +405,17 @@ func initParams() (xxdk.CMIXParams, xxdk.E2EParams) {
 
 	cmixParams := xxdk.GetDefaultCMixParams()
 	cmixParams.Network.Pickup.ForceHistoricalRounds = viper.GetBool(
-		"forceHistoricalRounds")
-	cmixParams.Network.FastPolling = !viper.GetBool("slowPolling")
+		forceHistoricalRoundsFlag)
+	cmixParams.Network.FastPolling = !viper.GetBool(slowPollingFlag)
 	cmixParams.Network.Pickup.ForceMessagePickupRetry = viper.GetBool(
-		"forceMessagePickupRetry")
+		forceMessagePickupRetryFlag)
 	if cmixParams.Network.Pickup.ForceMessagePickupRetry {
 		period := 3 * time.Second
 		jww.INFO.Printf("Setting Uncheck Round Period to %v", period)
 		cmixParams.Network.Pickup.UncheckRoundPeriod = period
 	}
 	cmixParams.Network.VerboseRoundTracking = viper.GetBool(
-		"verboseRoundTracking")
+		verboseRoundTrackingFlag)
 	return cmixParams, e2eParams
 }
 
@@ -577,20 +425,20 @@ func initE2e(cmixParams xxdk.CMIXParams, e2eParams xxdk.E2EParams) *xxdk.E2e {
 	jww.INFO.Printf(Version())
 
 	// Intake parameters for client initialization
-	precanId := viper.GetUint("sendid")
-	protoUserPath := viper.GetString("protoUserPath")
-	userIdPrefix := viper.GetString("userid-prefix")
-	backupPath := viper.GetString("backupIn")
-	backupPass := viper.GetString("backupPass")
-	storePassword := parsePassword(viper.GetString("password"))
-	storeDir := viper.GetString("session")
-	regCode := viper.GetString("regcode")
-	forceLegacy := viper.GetBool("force-legacy")
+	precanId := viper.GetUint(sendIdFlag)
+	protoUserPath := viper.GetString(protoUserPathFlag)
+	userIdPrefix := viper.GetString(userIdPrefixFlag)
+	backupPath := viper.GetString(backupInFlag)
+	backupPass := viper.GetString(backupPassFlag)
+	storePassword := parsePassword(viper.GetString(passwordFlag))
+	storeDir := viper.GetString(sessionFlag)
+	regCode := viper.GetString(regCodeFlag)
+	forceLegacy := viper.GetBool(forceLegacyFlag)
 	jww.DEBUG.Printf("sessionDir: %v", storeDir)
 
 	// TODO: This probably shouldn't be initialized globally.
 	authCbs = makeAuthCallbacks(
-		viper.GetBool("unsafe-channel-creation"), e2eParams)
+		viper.GetBool(unsafeChannelCreationFlag), e2eParams)
 
 	// Initialize the client of the proper type
 	var messenger *xxdk.E2e
@@ -607,7 +455,7 @@ func initE2e(cmixParams xxdk.CMIXParams, e2eParams xxdk.E2EParams) *xxdk.E2e {
 	}
 
 	// Handle protoUser output
-	if protoUser := viper.GetString("protoUserOut"); protoUser != "" {
+	if protoUser := viper.GetString(protoUserOutFlag); protoUser != "" {
 		jsonBytes, err := messenger.ConstructProtoUserFile()
 		if err != nil {
 			jww.FATAL.Panicf("cannot construct proto user file: %v",
@@ -622,7 +470,7 @@ func initE2e(cmixParams xxdk.CMIXParams, e2eParams xxdk.E2EParams) *xxdk.E2e {
 	}
 
 	// Handle backup output
-	if backupOut := viper.GetString("backupOut"); backupOut != "" {
+	if backupOut := viper.GetString("backupOutFlag"); backupOut != "" {
 		if !forceLegacy {
 			jww.FATAL.Panicf("Unable to make backup for non-legacy sender!")
 		}
@@ -636,7 +484,7 @@ func initE2e(cmixParams xxdk.CMIXParams, e2eParams xxdk.E2EParams) *xxdk.E2e {
 					err)
 			}
 
-			backupJsonPath := viper.GetString("backupJsonOut")
+			backupJsonPath := viper.GetString(backupJsonOutFlag)
 
 			if backupJsonPath != "" {
 				var b backupCrypto.Backup
@@ -693,7 +541,7 @@ func deleteChannel(messenger *xxdk.E2e, partnerId *id.ID) {
 func addAuthenticatedChannel(messenger *xxdk.E2e, recipientID *id.ID,
 	recipient contact.Contact, e2eParams xxdk.E2EParams) {
 	var allowed bool
-	if viper.GetBool("unsafe-channel-creation") {
+	if viper.GetBool(unsafeChannelCreationFlag) {
 		msg := "unsafe channel creation enabled\n"
 		jww.WARN.Printf(msg)
 		fmt.Printf("WARNING: %s", msg)
@@ -719,7 +567,7 @@ func addAuthenticatedChannel(messenger *xxdk.E2e, recipientID *id.ID,
 
 		// Verify that the auth request makes it to the recipient
 		// by monitoring the round result
-		if viper.GetBool("verify-sends") {
+		if viper.GetBool(verifySendFlag) {
 			requestChannelVerified(messenger, recipientContact, me, e2eParams)
 		} else {
 			// Just call Request, agnostic of round result
@@ -739,7 +587,7 @@ func addAuthenticatedChannel(messenger *xxdk.E2e, recipientID *id.ID,
 func resetAuthenticatedChannel(messenger *xxdk.E2e, recipientID *id.ID,
 	recipient contact.Contact, e2eParams xxdk.E2EParams) {
 	var allowed bool
-	if viper.GetBool("unsafe-channel-creation") {
+	if viper.GetBool(unsafeChannelCreationFlag) {
 		msg := "unsafe channel creation enabled\n"
 		jww.WARN.Printf(msg)
 		fmt.Printf("WARNING: %s", msg)
@@ -763,7 +611,7 @@ func resetAuthenticatedChannel(messenger *xxdk.E2e, recipientID *id.ID,
 			recipientID)
 		// Verify that the auth request makes it to the recipient
 		// by monitoring the round result
-		if viper.GetBool("verify-sends") {
+		if viper.GetBool(verifySendFlag) {
 			resetChannelVerified(messenger, recipientContact,
 				e2eParams)
 		} else {
@@ -896,7 +744,7 @@ func resetChannelVerified(messenger *xxdk.E2e, recipientContact contact.Contact,
 }
 
 func waitUntilConnected(connected chan bool) {
-	waitTimeout := time.Duration(viper.GetUint("waitTimeout"))
+	waitTimeout := time.Duration(viper.GetUint(waitTimeoutFlag))
 	timeoutTimer := time.NewTimer(waitTimeout * time.Second)
 	isConnected := false
 	// Wait until we connect or panic if we can't by a timeout
@@ -1034,7 +882,7 @@ func initLog(threshold uint, logPath string) {
 		jww.SetLogThreshold(jww.LevelInfo)
 	}
 
-	if viper.GetBool("verboseRoundTracking") {
+	if viper.GetBool(verboseRoundTrackingFlag) {
 		initRoundLog(logPath)
 	}
 }
@@ -1086,207 +934,210 @@ func init() {
 	// Here you will define your flags and configuration settings.
 	// Cobra supports persistent flags, which, if defined here,
 	// will be global for your application.
-	rootCmd.PersistentFlags().UintP("logLevel", "v", 0,
+	rootCmd.PersistentFlags().UintP(logLevelFlag, "v", 0,
 		"Verbose mode for debugging")
-	viper.BindPFlag("logLevel", rootCmd.PersistentFlags().Lookup("logLevel"))
+	viper.BindPFlag(logLevelFlag, rootCmd.PersistentFlags().
+		Lookup(logLevelFlag))
 
-	rootCmd.PersistentFlags().Bool("verboseRoundTracking", false,
+	rootCmd.PersistentFlags().Bool(verboseRoundTrackingFlag, false,
 		"Verbose round tracking, keeps track and prints all rounds the "+
 			"client was aware of while running. Defaults to false if not set.")
-	viper.BindPFlag("verboseRoundTracking", rootCmd.PersistentFlags().Lookup("verboseRoundTracking"))
+	viper.BindPFlag(verboseRoundTrackingFlag, rootCmd.PersistentFlags().Lookup(
+		verboseRoundTrackingFlag))
 
-	rootCmd.PersistentFlags().StringP("session", "s",
+	rootCmd.PersistentFlags().StringP(sessionFlag, "s",
 		"", "Sets the initial storage directory for "+
 			"client session data")
-	viper.BindPFlag("session", rootCmd.PersistentFlags().Lookup("session"))
+	viper.BindPFlag(sessionFlag, rootCmd.PersistentFlags().Lookup(sessionFlag))
 
-	rootCmd.PersistentFlags().StringP("writeContact", "w",
+	rootCmd.PersistentFlags().StringP(writeContactFlag, "w",
 		"-", "Write contact information, if any, to this file, "+
 			" defaults to stdout")
-	viper.BindPFlag("writeContact", rootCmd.PersistentFlags().Lookup(
-		"writeContact"))
+	viper.BindPFlag(writeContactFlag, rootCmd.PersistentFlags().Lookup(
+		writeContactFlag))
 
-	rootCmd.PersistentFlags().StringP("password", "p", "",
+	rootCmd.PersistentFlags().StringP(passwordFlag, "p", "",
 		"Password to the session file")
-	viper.BindPFlag("password", rootCmd.PersistentFlags().Lookup(
-		"password"))
+	viper.BindPFlag(passwordFlag, rootCmd.PersistentFlags().Lookup(
+		passwordFlag))
 
-	rootCmd.PersistentFlags().StringP("ndf", "n", "ndf.json",
+	rootCmd.PersistentFlags().StringP(ndfFlag, "n", "ndf.json",
 		"Path to the network definition JSON file")
-	viper.BindPFlag("ndf", rootCmd.PersistentFlags().Lookup("ndf"))
+	viper.BindPFlag(ndfFlag, rootCmd.PersistentFlags().Lookup(ndfFlag))
 
-	rootCmd.PersistentFlags().StringP("log", "l", "-",
+	rootCmd.PersistentFlags().StringP(logFlag, "l", "-",
 		"Path to the log output path (- is stdout)")
-	viper.BindPFlag("log", rootCmd.PersistentFlags().Lookup("log"))
+	viper.BindPFlag(logFlag, rootCmd.PersistentFlags().Lookup(logFlag))
 
-	rootCmd.Flags().StringP("regcode", "", "",
+	rootCmd.Flags().StringP(regCodeFlag, "", "",
 		"ReceptionIdentity code (optional)")
-	viper.BindPFlag("regcode", rootCmd.Flags().Lookup("regcode"))
+	viper.BindPFlag(regCodeFlag, rootCmd.Flags().Lookup(regCodeFlag))
 
-	rootCmd.PersistentFlags().StringP("message", "m", "",
+	rootCmd.PersistentFlags().StringP(messageFlag, "m", "",
 		"Message to send")
-	viper.BindPFlag("message", rootCmd.PersistentFlags().Lookup("message"))
+	viper.BindPFlag(messageFlag, rootCmd.PersistentFlags().Lookup(messageFlag))
 
-	rootCmd.Flags().UintP("sendid", "", 0,
+	rootCmd.Flags().UintP(sendIdFlag, "", 0,
 		"Use precanned user id (must be between 1 and 40, inclusive)")
-	viper.BindPFlag("sendid", rootCmd.Flags().Lookup("sendid"))
+	viper.BindPFlag(sendIdFlag, rootCmd.Flags().Lookup(sendIdFlag))
 
-	rootCmd.Flags().StringP("destid", "d", "0",
+	rootCmd.Flags().StringP(destIdFlag, "d", "0",
 		"ID to send message to (if below 40, will be precanned. Use "+
 			"'0x' or 'b64:' for hex and base64 representations)")
-	viper.BindPFlag("destid", rootCmd.Flags().Lookup("destid"))
+	viper.BindPFlag(destIdFlag, rootCmd.Flags().Lookup(destIdFlag))
 	rootCmd.PersistentFlags().Bool("force-legacy", false,
 		"Force client to operate using legacy identities.")
 	viper.BindPFlag("force-legacy", rootCmd.PersistentFlags().Lookup("force-legacy"))
 
-	rootCmd.Flags().StringP("destfile", "",
+	rootCmd.PersistentFlags().StringP(destFileFlag, "",
 		"", "Read this contact file for the destination id")
-	viper.BindPFlag("destfile", rootCmd.Flags().Lookup("destfile"))
+	viper.BindPFlag(destFileFlag, rootCmd.PersistentFlags().Lookup(destFileFlag))
 
-	rootCmd.Flags().UintP("sendCount",
+	rootCmd.PersistentFlags().UintP(sendCountFlag,
 		"", 1, "The number of times to send the message")
-	viper.BindPFlag("sendCount", rootCmd.Flags().Lookup("sendCount"))
-	rootCmd.Flags().UintP("sendDelay",
+	viper.BindPFlag(sendCountFlag, rootCmd.PersistentFlags().Lookup(sendCountFlag))
+	rootCmd.Flags().UintP(sendDelayFlag,
 		"", 500, "The delay between sending the messages in ms")
-	viper.BindPFlag("sendDelay", rootCmd.Flags().Lookup("sendDelay"))
-	rootCmd.Flags().BoolP("splitSends",
+	viper.BindPFlag(sendDelayFlag, rootCmd.Flags().Lookup(sendDelayFlag))
+	rootCmd.Flags().BoolP(splitSendsFlag,
 		"", false, "Force sends to go over multiple rounds if possible")
-	viper.BindPFlag("splitSends", rootCmd.Flags().Lookup("splitSends"))
+	viper.BindPFlag(splitSendsFlag, rootCmd.Flags().Lookup(splitSendsFlag))
 
-	rootCmd.Flags().BoolP("verify-sends", "", false,
+	rootCmd.Flags().BoolP(verifySendFlag, "", false,
 		"Ensure successful message sending by checking for round completion")
-	viper.BindPFlag("verify-sends", rootCmd.Flags().Lookup("verify-sends"))
+	viper.BindPFlag(verifySendFlag, rootCmd.Flags().Lookup(verifySendFlag))
 
-	rootCmd.PersistentFlags().UintP("receiveCount",
+	rootCmd.PersistentFlags().UintP(receiveCountFlag,
 		"", 1, "How many messages we should wait for before quitting")
-	viper.BindPFlag("receiveCount", rootCmd.PersistentFlags().Lookup("receiveCount"))
-	rootCmd.PersistentFlags().UintP("waitTimeout", "", 15,
+	viper.BindPFlag(receiveCountFlag, rootCmd.PersistentFlags().Lookup(receiveCountFlag))
+	rootCmd.PersistentFlags().UintP(waitTimeoutFlag, "", 15,
 		"The number of seconds to wait for messages to arrive")
-	viper.BindPFlag("waitTimeout",
-		rootCmd.PersistentFlags().Lookup("waitTimeout"))
+	viper.BindPFlag(waitTimeoutFlag,
+		rootCmd.PersistentFlags().Lookup(waitTimeoutFlag))
 
-	rootCmd.Flags().BoolP("unsafe", "", false,
+	rootCmd.Flags().BoolP(unsafeFlag, "", false,
 		"Send raw, unsafe messages without e2e encryption.")
-	viper.BindPFlag("unsafe", rootCmd.Flags().Lookup("unsafe"))
+	viper.BindPFlag(unsafeFlag, rootCmd.Flags().Lookup(unsafeFlag))
 
-	rootCmd.PersistentFlags().BoolP("unsafe-channel-creation", "", false,
+	rootCmd.PersistentFlags().BoolP(unsafeChannelCreationFlag, "", false,
 		"Turns off the user identity authenticated channel check, "+
 			"automatically approving authenticated channels")
-	viper.BindPFlag("unsafe-channel-creation",
-		rootCmd.PersistentFlags().Lookup("unsafe-channel-creation"))
+	viper.BindPFlag(unsafeChannelCreationFlag,
+		rootCmd.PersistentFlags().Lookup(unsafeChannelCreationFlag))
 
-	rootCmd.Flags().BoolP("accept-channel", "", false,
+	rootCmd.Flags().BoolP(acceptChannelFlag, "", false,
 		"Accept the channel request for the corresponding recipient ID")
-	viper.BindPFlag("accept-channel",
-		rootCmd.Flags().Lookup("accept-channel"))
+	viper.BindPFlag(acceptChannelFlag,
+		rootCmd.Flags().Lookup(acceptChannelFlag))
 
-	rootCmd.PersistentFlags().Bool("delete-channel", false,
+	rootCmd.PersistentFlags().Bool(deleteChannelFlag, false,
 		"DeleteFingerprint the channel information for the corresponding recipient ID")
-	viper.BindPFlag("delete-channel",
-		rootCmd.PersistentFlags().Lookup("delete-channel"))
+	viper.BindPFlag(deleteChannelFlag,
+		rootCmd.PersistentFlags().Lookup(deleteChannelFlag))
 
-	rootCmd.PersistentFlags().Bool("delete-receive-requests", false,
+	rootCmd.PersistentFlags().Bool(deleteReceiveRequestsFlag, false,
 		"DeleteFingerprint the all received contact requests.")
-	viper.BindPFlag("delete-receive-requests",
-		rootCmd.PersistentFlags().Lookup("delete-receive-requests"))
+	viper.BindPFlag(deleteReceiveRequestsFlag,
+		rootCmd.PersistentFlags().Lookup(deleteReceiveRequestsFlag))
 
-	rootCmd.PersistentFlags().Bool("delete-sent-requests", false,
+	rootCmd.PersistentFlags().Bool(deleteSentRequestsFlag, false,
 		"DeleteFingerprint the all sent contact requests.")
-	viper.BindPFlag("delete-sent-requests",
-		rootCmd.PersistentFlags().Lookup("delete-sent-requests"))
+	viper.BindPFlag(deleteSentRequestsFlag,
+		rootCmd.PersistentFlags().Lookup(deleteSentRequestsFlag))
 
-	rootCmd.PersistentFlags().Bool("delete-all-requests", false,
+	rootCmd.PersistentFlags().Bool(deleteAllRequestsFlag, false,
 		"DeleteFingerprint the all contact requests, both sent and received.")
-	viper.BindPFlag("delete-all-requests",
-		rootCmd.PersistentFlags().Lookup("delete-all-requests"))
+	viper.BindPFlag(deleteAllRequestsFlag,
+		rootCmd.PersistentFlags().Lookup(deleteAllRequestsFlag))
 
-	rootCmd.PersistentFlags().Bool("delete-request", false,
+	rootCmd.PersistentFlags().Bool(deleteRequestFlag, false,
 		"DeleteFingerprint the request for the specified ID given by the "+
 			"destfile flag's contact file.")
-	viper.BindPFlag("delete-request",
-		rootCmd.PersistentFlags().Lookup("delete-request"))
+	viper.BindPFlag(deleteRequestFlag,
+		rootCmd.PersistentFlags().Lookup(deleteRequestFlag))
 
-	rootCmd.Flags().BoolP("send-auth-request", "", false,
+	rootCmd.Flags().BoolP(sendAuthRequestFlag, "", false,
 		"Send an auth request to the specified destination and wait"+
 			"for confirmation")
-	viper.BindPFlag("send-auth-request",
-		rootCmd.Flags().Lookup("send-auth-request"))
-	rootCmd.Flags().UintP("auth-timeout", "", 60,
+	viper.BindPFlag(sendAuthRequestFlag,
+		rootCmd.Flags().Lookup(sendAuthRequestFlag))
+	rootCmd.Flags().UintP(authTimeoutFlag, "", 60,
 		"The number of seconds to wait for an authentication channel"+
 			"to confirm")
-	viper.BindPFlag("auth-timeout",
-		rootCmd.Flags().Lookup("auth-timeout"))
+	viper.BindPFlag(authTimeoutFlag,
+		rootCmd.Flags().Lookup(authTimeoutFlag))
 
-	rootCmd.Flags().BoolP("forceHistoricalRounds", "", false,
+	rootCmd.Flags().BoolP(forceHistoricalRoundsFlag, "", false,
 		"Force all rounds to be sent to historical round retrieval")
-	viper.BindPFlag("forceHistoricalRounds",
-		rootCmd.Flags().Lookup("forceHistoricalRounds"))
+	viper.BindPFlag(forceHistoricalRoundsFlag,
+		rootCmd.Flags().Lookup(forceHistoricalRoundsFlag))
 
 	// Network params
-	rootCmd.Flags().BoolP("slowPolling", "", false,
+	rootCmd.Flags().BoolP(slowPollingFlag, "", false,
 		"Enables polling for unfiltered network updates with RSA signatures")
-	viper.BindPFlag("slowPolling",
-		rootCmd.Flags().Lookup("slowPolling"))
-	rootCmd.Flags().Bool("forceMessagePickupRetry", false,
+	viper.BindPFlag(slowPollingFlag,
+		rootCmd.Flags().Lookup(slowPollingFlag))
+
+	rootCmd.Flags().Bool(forceMessagePickupRetryFlag, false,
 		"Enable a mechanism which forces a 50% chance of no message pickup, "+
 			"instead triggering the message pickup retry mechanism")
-	viper.BindPFlag("forceMessagePickupRetry",
-		rootCmd.Flags().Lookup("forceMessagePickupRetry"))
+	viper.BindPFlag(forceMessagePickupRetryFlag,
+		rootCmd.Flags().Lookup(forceMessagePickupRetryFlag))
 
 	// E2E Params
 	defaultE2EParams := session.GetDefaultParams()
-	rootCmd.Flags().UintP("e2eMinKeys",
+	rootCmd.Flags().UintP(e2eMinKeysFlag,
 		"", uint(defaultE2EParams.MinKeys),
 		"Minimum number of keys used before requesting rekey")
-	viper.BindPFlag("e2eMinKeys", rootCmd.Flags().Lookup("e2eMinKeys"))
-	rootCmd.Flags().UintP("e2eMaxKeys",
+	viper.BindPFlag(e2eMinKeysFlag, rootCmd.Flags().Lookup(e2eMinKeysFlag))
+	rootCmd.Flags().UintP(e2eMaxKeysFlag,
 		"", uint(defaultE2EParams.MaxKeys),
 		"Max keys used before blocking until a rekey completes")
-	viper.BindPFlag("e2eMaxKeys", rootCmd.Flags().Lookup("e2eMaxKeys"))
-	rootCmd.Flags().UintP("e2eNumReKeys",
+	viper.BindPFlag(e2eMaxKeysFlag, rootCmd.Flags().Lookup(e2eMaxKeysFlag))
+	rootCmd.Flags().UintP(e2eNumReKeysFlag,
 		"", uint(defaultE2EParams.NumRekeys),
 		"Number of rekeys reserved for rekey operations")
-	viper.BindPFlag("e2eNumReKeys", rootCmd.Flags().Lookup("e2eNumReKeys"))
-	rootCmd.Flags().Float64P("e2eRekeyThreshold",
+	viper.BindPFlag(e2eNumReKeysFlag, rootCmd.Flags().Lookup(e2eNumReKeysFlag))
+	rootCmd.Flags().Float64P(e2eRekeyThresholdFlag,
 		"", defaultE2EParams.RekeyThreshold,
 		"Number between 0 an 1. Percent of keys used before a rekey is started")
-	viper.BindPFlag("e2eRekeyThreshold", rootCmd.Flags().Lookup("e2eRekeyThreshold"))
+	viper.BindPFlag(e2eRekeyThresholdFlag, rootCmd.Flags().Lookup(e2eRekeyThresholdFlag))
 
-	rootCmd.Flags().String("profile-cpu", "",
+	rootCmd.Flags().String(profileCpuFlag, "",
 		"Enable cpu profiling to this file")
-	viper.BindPFlag("profile-cpu", rootCmd.Flags().Lookup("profile-cpu"))
+	viper.BindPFlag(profileCpuFlag, rootCmd.Flags().Lookup(profileCpuFlag))
 
 	// Proto user flags
-	rootCmd.Flags().String("protoUserPath", "",
+	rootCmd.Flags().String(protoUserPathFlag, "",
 		"Path to proto user JSON file containing cryptographic primitives "+
 			"the client will load")
-	viper.BindPFlag("protoUserPath", rootCmd.Flags().Lookup("protoUserPath"))
-	rootCmd.Flags().String("protoUserOut", "",
+	viper.BindPFlag(protoUserPathFlag, rootCmd.Flags().Lookup(protoUserPathFlag))
+	rootCmd.Flags().String(protoUserOutFlag, "",
 		"Path to which a normally constructed client "+
 			"will write proto user JSON file")
-	viper.BindPFlag("protoUserOut", rootCmd.Flags().Lookup("protoUserOut"))
+	viper.BindPFlag(protoUserOutFlag, rootCmd.Flags().Lookup(protoUserOutFlag))
 
 	// Backup flags
-	rootCmd.Flags().String("backupOut", "",
+	rootCmd.Flags().String(backupOutFlag, "",
 		"Path to output encrypted client backup. If no path is supplied, the "+
 			"backup system is not started.")
-	viper.BindPFlag("backupOut", rootCmd.Flags().Lookup("backupOut"))
+	viper.BindPFlag(backupOutFlag, rootCmd.Flags().Lookup(backupOutFlag))
 
-	rootCmd.Flags().String("backupJsonOut", "",
+	rootCmd.Flags().String(backupJsonOutFlag, "",
 		"Path to output unencrypted client JSON backup.")
-	viper.BindPFlag("backupJsonOut", rootCmd.Flags().Lookup("backupJsonOut"))
+	viper.BindPFlag(backupJsonOutFlag, rootCmd.Flags().Lookup(backupJsonOutFlag))
 
-	rootCmd.Flags().String("backupIn", "",
+	rootCmd.Flags().String(backupInFlag, "",
 		"Path to load backup client from")
-	viper.BindPFlag("backupIn", rootCmd.Flags().Lookup("backupIn"))
+	viper.BindPFlag(backupInFlag, rootCmd.Flags().Lookup(backupInFlag))
 
-	rootCmd.Flags().String("backupPass", "",
+	rootCmd.Flags().String(backupPassFlag, "",
 		"Passphrase to encrypt/decrypt backup")
-	viper.BindPFlag("backupPass", rootCmd.Flags().Lookup("backupPass"))
+	viper.BindPFlag(backupPassFlag, rootCmd.Flags().Lookup(backupPassFlag))
 
-	rootCmd.Flags().String("backupIdList", "",
+	rootCmd.Flags().String(backupIdListFlag, "",
 		"JSON file containing the backed up partner IDs")
-	viper.BindPFlag("backupIdList", rootCmd.Flags().Lookup("backupIdList"))
+	viper.BindPFlag(backupIdListFlag, rootCmd.Flags().Lookup(backupIdListFlag))
 
 }
 
diff --git a/cmd/single.go b/cmd/single.go
index 6a7e99575ff163f03c82bb2cc9799fa884e8775e..d23a5be52475b2fc3e7119c965a9c304d9518c26 100644
--- a/cmd/single.go
+++ b/cmd/single.go
@@ -55,7 +55,7 @@ var singleCmd = &cobra.Command{
 		waitUntilConnected(connected)
 
 		// get the tag
-		tag := viper.GetString("tag")
+		tag := viper.GetString(singleTagFlag)
 
 		// Register the callback
 		receiver := &Receiver{
@@ -88,14 +88,14 @@ var singleCmd = &cobra.Command{
 				numReg, total)
 		}
 
-		timeout := viper.GetDuration("timeout")
+		timeout := viper.GetDuration(singleTimeoutFlag)
 
 		// If the send flag is set, then send a message
-		if viper.GetBool("send") {
+		if viper.GetBool(singleSendFlag) {
 			// get message details
-			payload := []byte(viper.GetString("message"))
-			partner := readSingleUseContact("contact")
-			maxMessages := uint8(viper.GetUint("maxMessages"))
+			payload := []byte(viper.GetString(messageFlag))
+			partner := readSingleUseContact(singleContactFlag)
+			maxMessages := uint8(viper.GetUint(singleMaxMessagesFlag))
 
 			sendSingleUse(client.Cmix, partner, payload,
 				maxMessages, timeout, tag)
@@ -103,7 +103,7 @@ var singleCmd = &cobra.Command{
 
 		// If the reply flag is set, then start waiting for a
 		// message and reply when it is received
-		if viper.GetBool("reply") {
+		if viper.GetBool(singleReplyFlag) {
 			replySingleUse(timeout, receiver)
 		}
 		listener.Stop()
@@ -113,28 +113,28 @@ var singleCmd = &cobra.Command{
 func init() {
 	// Single-use subcommand options
 
-	singleCmd.Flags().Bool("send", false, "Sends a single-use message.")
-	_ = viper.BindPFlag("send", singleCmd.Flags().Lookup("send"))
+	singleCmd.Flags().Bool(singleSendFlag, false, "Sends a single-use message.")
+	bindFlagHelper(singleSendFlag, singleCmd)
 
-	singleCmd.Flags().Bool("reply", false,
+	singleCmd.Flags().Bool(singleReplyFlag, false,
 		"Listens for a single-use message and sends a reply.")
-	_ = viper.BindPFlag("reply", singleCmd.Flags().Lookup("reply"))
+	bindFlagHelper(singleReplyFlag, singleCmd)
 
-	singleCmd.Flags().StringP("contact", "c", "",
+	singleCmd.Flags().StringP(singleContactFlag, "c", "",
 		"Path to contact file to send message to.")
-	_ = viper.BindPFlag("contact", singleCmd.Flags().Lookup("contact"))
+	bindFlagHelper(singleContactFlag, singleCmd)
 
-	singleCmd.Flags().StringP("tag", "", "testTag",
+	singleCmd.Flags().StringP(singleTagFlag, "", "testTag",
 		"The tag that specifies the callback to trigger on reception.")
-	_ = viper.BindPFlag("tag", singleCmd.Flags().Lookup("tag"))
+	bindFlagHelper(singleTagFlag, singleCmd)
 
-	singleCmd.Flags().Uint8("maxMessages", 1,
+	singleCmd.Flags().Uint8(singleMaxMessagesFlag, 1,
 		"The max number of single-use response messages.")
-	_ = viper.BindPFlag("maxMessages", singleCmd.Flags().Lookup("maxMessages"))
+	bindFlagHelper(singleMaxMessagesFlag, singleCmd)
 
-	singleCmd.Flags().DurationP("timeout", "t", 30*time.Second,
+	singleCmd.Flags().DurationP(singleTimeoutFlag, "t", 30*time.Second,
 		"Duration before stopping to wait for single-use message.")
-	_ = viper.BindPFlag("timeout", singleCmd.Flags().Lookup("timeout"))
+	bindFlagHelper(singleTimeoutFlag, singleCmd)
 
 	rootCmd.AddCommand(singleCmd)
 }
diff --git a/cmd/ud.go b/cmd/ud.go
index d49b3d79507d30bc4f4e1469c42977549fee8020..cc9bbac169bb9faed5fcaaeaec52ac923ef28c33 100644
--- a/cmd/ud.go
+++ b/cmd/ud.go
@@ -79,7 +79,7 @@ var udCmd = &cobra.Command{
 		jww.INFO.Printf("[UD] Registered user %v", userToRegister)
 
 		var newFacts fact.FactList
-		phone := viper.GetString("addphone")
+		phone := viper.GetString(udAddPhoneFlag)
 		if phone != "" {
 			f, err := fact.NewFact(fact.Phone, phone)
 			if err != nil {
@@ -88,7 +88,7 @@ var udCmd = &cobra.Command{
 			newFacts = append(newFacts, f)
 		}
 
-		email := viper.GetString("addemail")
+		email := viper.GetString(udAddEmailFlag)
 		if email != "" {
 			f, err := fact.NewFact(fact.Email, email)
 			if err != nil {
@@ -110,7 +110,7 @@ var udCmd = &cobra.Command{
 			jww.INFO.Printf("[UD] Fact Add Response: %+v", r)
 		}
 
-		confirmID := viper.GetString("confirm")
+		confirmID := viper.GetString(udConfirmFlag)
 		if confirmID != "" {
 			jww.INFO.Printf("[UD] Confirming fact: %v", confirmID)
 			err = userDiscoveryMgr.ConfirmFact(confirmID, confirmID)
@@ -131,7 +131,7 @@ var udCmd = &cobra.Command{
 
 		// Handle lookup (verification) process
 		// Note: Cryptographic verification occurs above the bindings layer
-		lookupIDStr := viper.GetString("lookup")
+		lookupIDStr := viper.GetString(udLookupFlag)
 		if lookupIDStr != "" {
 			lookupID := parseRecipient(lookupIDStr)
 			jww.INFO.Printf("[UD] Looking up %v", lookupID)
@@ -155,8 +155,8 @@ var udCmd = &cobra.Command{
 			time.Sleep(31 * time.Second)
 		}
 
-		if viper.GetString("batchadd") != "" {
-			idListFile, err := utils.ReadFile(viper.GetString("batchadd"))
+		if viper.IsSet(udBatchAddFlag) {
+			idListFile, err := utils.ReadFile(viper.GetString(udBatchAddFlag))
 			if err != nil {
 				fmt.Printf("BATCHADD: Couldn't read file: %s\n",
 					err.Error())
@@ -176,9 +176,9 @@ var udCmd = &cobra.Command{
 				jww.INFO.Printf("[UD] Authenticated channel established for %s", uid)
 			}
 		}
-		usernameSearchStr := viper.GetString("searchusername")
-		emailSearchStr := viper.GetString("searchemail")
-		phoneSearchStr := viper.GetString("searchphone")
+		usernameSearchStr := viper.GetString(udSearchUsernameFlag)
+		emailSearchStr := viper.GetString(udSearchEmailFlag)
+		phoneSearchStr := viper.GetString(udSearchPhoneFlag)
 
 		var facts fact.FactList
 		if usernameSearchStr != "" {
@@ -203,7 +203,7 @@ var udCmd = &cobra.Command{
 			facts = append(facts, f)
 		}
 
-		userToRemove := viper.GetString("remove")
+		userToRemove := viper.GetString(udRemoveFlag)
 		if userToRemove != "" {
 			f, err := fact.NewFact(fact.Username, userToRemove)
 			if err != nil {
@@ -260,44 +260,49 @@ var udCmd = &cobra.Command{
 
 func init() {
 	// User Discovery subcommand Options
-	udCmd.Flags().StringP("register", "r", "",
+	udCmd.Flags().StringP(udRegisterFlag, "r", "",
 		"Register this user with user discovery.")
-	_ = viper.BindPFlag("register", udCmd.Flags().Lookup("register"))
+	bindFlagHelper(udRegisterFlag, udCmd)
 
-	udCmd.Flags().StringP("remove", "", "",
+	udCmd.Flags().StringP(udRemoveFlag, "", "",
 		"Remove this user with user discovery.")
-	_ = viper.BindPFlag("remove", udCmd.Flags().Lookup("remove"))
+	bindFlagHelper(udRemoveFlag, udCmd)
 
-	udCmd.Flags().String("addphone", "",
+	udCmd.Flags().String(udAddPhoneFlag, "",
 		"Add phone number to existing user registration.")
-	_ = viper.BindPFlag("addphone", udCmd.Flags().Lookup("addphone"))
+	bindFlagHelper(udAddPhoneFlag, udCmd)
 
-	udCmd.Flags().StringP("addemail", "e", "",
+	udCmd.Flags().StringP(udAddEmailFlag, "e", "",
 		"Add email to existing user registration.")
-	_ = viper.BindPFlag("addemail", udCmd.Flags().Lookup("addemail"))
+	bindFlagHelper(udAddEmailFlag, udCmd)
 
-	udCmd.Flags().String("confirm", "", "Confirm fact with confirmation ID.")
-	_ = viper.BindPFlag("confirm", udCmd.Flags().Lookup("confirm"))
+	udCmd.Flags().String(udConfirmFlag, "", "Confirm fact with confirmation ID.")
+	bindFlagHelper(udConfirmFlag, udCmd)
 
-	udCmd.Flags().StringP("lookup", "u", "",
+	udCmd.Flags().StringP(udLookupFlag, "u", "",
 		"Look up user ID. Use '0x' or 'b64:' for hex and base64 representations.")
-	_ = viper.BindPFlag("lookup", udCmd.Flags().Lookup("lookup"))
+	bindFlagHelper(udLookupFlag, udCmd)
 
-	udCmd.Flags().String("searchusername", "",
+	udCmd.Flags().String(udSearchUsernameFlag, "",
 		"Search for users with this username.")
-	_ = viper.BindPFlag("searchusername", udCmd.Flags().Lookup("searchusername"))
+	bindFlagHelper(udSearchUsernameFlag, udCmd)
 
-	udCmd.Flags().String("searchemail", "",
+	udCmd.Flags().String(udSearchEmailFlag, "",
 		"Search for users with this email address.")
-	_ = viper.BindPFlag("searchemail", udCmd.Flags().Lookup("searchemail"))
+	bindFlagHelper(udSearchEmailFlag, udCmd)
 
-	udCmd.Flags().String("searchphone", "",
+	udCmd.Flags().String(udSearchPhoneFlag, "",
 		"Search for users with this email address.")
-	_ = viper.BindPFlag("searchphone", udCmd.Flags().Lookup("searchphone"))
+	bindFlagHelper(udSearchPhoneFlag, udCmd)
 
-	udCmd.Flags().String("batchadd", "",
+	udCmd.Flags().String("udBatch", "",
 		"Path to JSON marshalled slice of partner IDs that will be looked up on UD.")
-	_ = viper.BindPFlag("batchadd", udCmd.Flags().Lookup("batchadd"))
+	err := viper.BindPFlag("udBatch", udCmd.Flags().Lookup("udBatch"))
+	if err != nil {
+		jww.ERROR.Printf("viper.BindPFlag failed for %q: %+v", "udBatch", err)
+	}
+
+	bindFlagHelper(udBatchAddFlag, udCmd)
 
 	rootCmd.AddCommand(udCmd)
 }
diff --git a/cmd/utils.go b/cmd/utils.go
index aa634f69e6495a050a24d7d904a9b79e10a2edd3..949c82b9b7a379e2f8d045766eb796cbae3e0a54 100644
--- a/cmd/utils.go
+++ b/cmd/utils.go
@@ -1,6 +1,9 @@
 package cmd
 
 import (
+	"github.com/spf13/cobra"
+	"gitlab.com/elixxir/client/e2e"
+	"gitlab.com/elixxir/client/xxdk"
 	"io/ioutil"
 	"strconv"
 	"strings"
@@ -14,6 +17,56 @@ import (
 
 // todo: go through cmd package and organize utility functions
 
+// bindFlagHelper binds the key to a pflag.Flag used by Cobra and prints an
+// error if one occurs.
+func bindFlagHelper(key string, command *cobra.Command) {
+	err := viper.BindPFlag(key, command.Flags().Lookup(key))
+	if err != nil {
+		jww.ERROR.Printf("viper.BindPFlag failed for %q: %+v", key, err)
+	}
+}
+
+func verifySendSuccess(client *xxdk.E2e, paramsE2E e2e.Params,
+	roundIDs []id.Round, partnerId *id.ID, payload []byte) bool {
+	retryChan := make(chan struct{})
+	done := make(chan struct{}, 1)
+
+	// Construct the callback function which
+	// verifies successful message send or retries
+	f := func(allRoundsSucceeded, timedOut bool,
+		rounds map[id.Round]cmix.RoundResult) {
+		printRoundResults(
+			rounds, roundIDs, payload, partnerId)
+		if !allRoundsSucceeded {
+			retryChan <- struct{}{}
+		} else {
+			done <- struct{}{}
+		}
+	}
+
+	// Monitor rounds for results
+	err := client.GetCmix().GetRoundResults(
+		paramsE2E.CMIXParams.Timeout, f, roundIDs...)
+	if err != nil {
+		jww.DEBUG.Printf("Could not verify messages were sent " +
+			"successfully, resending messages...")
+		return false
+	}
+
+	select {
+	case <-retryChan:
+		// On a retry, go to the top of the loop
+		jww.DEBUG.Printf("Messages were not sent successfully," +
+			" resending messages...")
+		return true
+	case <-done:
+		// Close channels on verification success
+		close(done)
+		close(retryChan)
+		return false
+	}
+}
+
 func parsePassword(pwStr string) []byte {
 	if strings.HasPrefix(pwStr, "0x") {
 		return getPWFromHexString(pwStr[2:])
@@ -68,7 +121,7 @@ func printRoundResults(rounds map[id.Round]cmix.RoundResult, roundIDs []id.Round
 }
 
 func writeContact(c contact.Contact) {
-	outfilePath := viper.GetString("writeContact")
+	outfilePath := viper.GetString(writeContactFlag)
 	if outfilePath == "" {
 		return
 	}
@@ -83,6 +136,7 @@ func readContact(inputFilePath string) contact.Contact {
 	if inputFilePath == "" {
 		return contact.Contact{}
 	}
+
 	data, err := ioutil.ReadFile(inputFilePath)
 	jww.INFO.Printf("Contact file size read in: %d", len(data))
 	if err != nil {