diff --git a/bindings/callback.go b/bindings/callback.go
index 1237e7fcf981f763fcf8dcb3be233d37e48741fd..34d26ecccaf4b4f105a2ab2e7b29d82fb1fe3728 100644
--- a/bindings/callback.go
+++ b/bindings/callback.go
@@ -96,3 +96,17 @@ func newRoundListUnregister(rounds []id.Round, ec []*dataStructures.EventCallbac
 type ClientError interface {
 	Report(source, message, trace string)
 }
+
+
+type LogWriter interface{
+	Log(string)
+}
+
+type writerAdapter struct{
+	lw LogWriter
+}
+
+func (wa *writerAdapter)Write(p []byte) (n int, err error){
+	wa.lw.Log(string(p))
+	return len(p), nil
+}
diff --git a/bindings/client.go b/bindings/client.go
index 80f94d247dcafc6b1a821ad317ef3ad202a488df..2ebc43897cf4daa64f420a1831167cd746ff22b8 100644
--- a/bindings/client.go
+++ b/bindings/client.go
@@ -19,9 +19,13 @@ import (
 	"gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/primitives/states"
 	"gitlab.com/xx_network/primitives/id"
+	"sync"
 	"time"
 )
 
+var extantClient bool
+var loginMux sync.Mutex
+
 // sets the log level
 func init() {
 	jww.SetLogThreshold(jww.LevelInfo)
@@ -76,6 +80,14 @@ func NewPrecannedClient(precannedID int, network, storageDir string, password []
 // Login does not block on network connection, and instead loads and
 // starts subprocesses to perform network operations.
 func Login(storageDir string, password []byte, parameters string) (*Client, error) {
+	loginMux.Lock()
+	defer loginMux.Unlock()
+
+	if extantClient{
+		return nil, errors.New("cannot login when another session " +
+			"already exists")
+	}
+	// check if a client is already logged in, refuse to login if one is
 	p, err := params.GetNetworkParameters(parameters)
 	if err != nil {
 		return nil, errors.New(fmt.Sprintf("Failed to login: %+v", err))
@@ -85,6 +97,7 @@ func Login(storageDir string, password []byte, parameters string) (*Client, erro
 	if err != nil {
 		return nil, errors.New(fmt.Sprintf("Failed to login: %+v", err))
 	}
+	extantClient=true
 	return &Client{api: *client}, nil
 }
 
@@ -127,6 +140,11 @@ func LogLevel(level int) error {
 	return nil
 }
 
+//RegisterLogWriter registers a callback on which logs are written.
+func RegisterLogWriter(writer LogWriter){
+	jww.SetLogOutput(&writerAdapter{lw:writer})
+}
+
 //Unmarshals a marshaled contact object, returns an error if it fails
 func UnmarshalContact(b []byte) (*Contact, error) {
 	c, err := contact.Unmarshal(b)
diff --git a/storage/rounds/earliestRound.go b/storage/rounds/earliestRound.go
index fea486dd93d0e718bd292fc4bc5ae35acce133f6..456e11c146e1998e45c3e9b814d5f718ddf99807 100644
--- a/storage/rounds/earliestRound.go
+++ b/storage/rounds/earliestRound.go
@@ -9,8 +9,8 @@ import (
 	"sync"
 )
 
-const unknownRoundStorageKey = "unknownRoundStorage"
-const unknownRoundStorageVersion = 0
+const earliestRoundStorageKey = "unknownRoundStorage"
+const earliestRoundStorageVersion = 0
 
 type EarliestRound struct {
 	stored bool
@@ -36,14 +36,14 @@ func LoadEarliestRound(kv *versioned.KV) *EarliestRound {
 		rid:    0,
 	}
 
-	obj, err := kv.Get(unknownRoundStorageKey, unknownRoundStorageVersion)
+	obj, err := kv.Get(earliestRoundStorageKey, earliestRoundStorageVersion)
 	if err != nil {
-		jww.FATAL.Panicf("Failed to get the unknown round: %+v", err)
+		jww.FATAL.Panicf("Failed to get the earlest round: %+v", err)
 	}
 
 	err = json.Unmarshal(obj.Data, &ur.rid)
 	if err != nil {
-		jww.FATAL.Panicf("Failed to unmarshal the unknown round: %+v", err)
+		jww.FATAL.Panicf("Failed to unmarshal the earliest round: %+v", err)
 	}
 	return ur
 }
@@ -52,20 +52,20 @@ func (ur *EarliestRound) save() {
 	if ur.stored {
 		urStr, err := json.Marshal(&ur.rid)
 		if err != nil {
-			jww.FATAL.Panicf("Failed to marshal the unknown round: %+v", err)
+			jww.FATAL.Panicf("Failed to marshal the earliest round: %+v", err)
 		}
 
 		// Create versioned object with data
 		obj := &versioned.Object{
-			Version:   unknownRoundStorageVersion,
+			Version:   earliestRoundStorageVersion,
 			Timestamp: netTime.Now(),
 			Data:      urStr,
 		}
 
-		err = ur.kv.Set(unknownRoundStorageKey,
-			unknownRoundStorageVersion, obj)
+		err = ur.kv.Set(earliestRoundStorageKey,
+			earliestRoundStorageVersion, obj)
 		if err != nil {
-			jww.FATAL.Panicf("Failed to store the unknown round: %+v", err)
+			jww.FATAL.Panicf("Failed to store the earliest round: %+v", err)
 		}
 
 	}
@@ -92,8 +92,8 @@ func (ur *EarliestRound) Get() id.Round {
 func (ur *EarliestRound) delete() {
 	ur.mux.Lock()
 	defer ur.mux.Unlock()
-	err := ur.kv.Delete(unknownRoundStorageKey, unknownRoundStorageVersion)
+	err := ur.kv.Delete(earliestRoundStorageKey, earliestRoundStorageVersion)
 	if err != nil {
-		jww.FATAL.Panicf("Failed to delete unknownRound storage: %+v", err)
+		jww.FATAL.Panicf("Failed to delete earliest storage: %+v", err)
 	}
 }