diff --git a/native/native_rust_library/src/identity.rs b/native/native_rust_library/src/identity.rs
--- a/native/native_rust_library/src/identity.rs
+++ b/native/native_rust_library/src/identity.rs
@@ -156,6 +156,7 @@
     let AuthResponse {
       user_id,
       access_token,
+      ..
     } = value;
     Self {
       user_id,
diff --git a/services/identity/src/client_service.rs b/services/identity/src/client_service.rs
--- a/services/identity/src/client_service.rs
+++ b/services/identity/src/client_service.rs
@@ -71,6 +71,7 @@
 #[derive(Clone, Serialize, Deserialize)]
 pub struct UserLoginInfo {
   pub user_id: String,
+  pub username: String,
   pub flattened_device_key_upload: FlattenedDeviceKeyUpload,
   pub opaque_server_login: comm_opaque2::server::Login,
   pub device_to_remove: Option<String>,
@@ -242,6 +243,7 @@
 
       let login_time = chrono::Utc::now();
       let device_id = state.flattened_device_key_upload.device_id_key.clone();
+      let username = state.username.clone();
       let user_id = self
         .client
         .add_password_user_to_users_table(
@@ -273,6 +275,7 @@
       let response = AuthResponse {
         user_id,
         access_token,
+        username,
       };
       Ok(Response::new(response))
     } else {
@@ -342,6 +345,7 @@
 
     let login_state = construct_user_login_info(
       user_id,
+      message.username,
       server_login,
       flattened_device_key_upload,
       maybe_device_to_remove,
@@ -419,6 +423,7 @@
       let response = AuthResponse {
         user_id: state.user_id,
         access_token,
+        username: state.username,
       };
       Ok(Response::new(response))
     } else {
@@ -504,6 +509,7 @@
     let response = AuthResponse {
       user_id,
       access_token,
+      username: wallet_address,
     };
     Ok(Response::new(response))
   }
@@ -571,7 +577,7 @@
       .client
       .add_wallet_user_to_users_table(
         flattened_device_key_upload.clone(),
-        wallet_address,
+        wallet_address.clone(),
         social_proof,
         None,
         code_version,
@@ -601,6 +607,7 @@
     let response = AuthResponse {
       user_id,
       access_token,
+      username: wallet_address,
     };
     Ok(Response::new(response))
   }
@@ -652,7 +659,7 @@
       .client
       .add_wallet_user_to_users_table(
         flattened_device_key_upload.clone(),
-        wallet_address,
+        wallet_address.clone(),
         social_proof,
         Some(user_id.clone()),
         code_version,
@@ -681,6 +688,7 @@
     let response = AuthResponse {
       user_id,
       access_token,
+      username: wallet_address,
     };
 
     Ok(Response::new(response))
@@ -729,6 +737,7 @@
 
     let login_time = chrono::Utc::now();
     let identifier = user_identity.identifier;
+    let username = identifier.username().to_string();
     let token = AccessTokenData::with_created_time(
       user_id.clone(),
       device_id,
@@ -757,6 +766,7 @@
     let response = AuthResponse {
       user_id,
       access_token,
+      username,
     };
     Ok(Response::new(response))
   }
@@ -798,6 +808,7 @@
 
     let login_time = chrono::Utc::now();
     let identifier = user_identity.identifier;
+    let username = identifier.username().to_string();
     let token = AccessTokenData::with_created_time(
       user_id.clone(),
       device_id,
@@ -815,6 +826,7 @@
     let response = AuthResponse {
       user_id,
       access_token,
+      username,
     };
     Ok(Response::new(response))
   }
@@ -1134,12 +1146,14 @@
 
 fn construct_user_login_info(
   user_id: String,
+  username: String,
   opaque_server_login: comm_opaque2::server::Login,
   flattened_device_key_upload: FlattenedDeviceKeyUpload,
   device_to_remove: Option<String>,
 ) -> Result<UserLoginInfo, tonic::Status> {
   Ok(UserLoginInfo {
     user_id,
+    username,
     flattened_device_key_upload,
     opaque_server_login,
     device_to_remove,
diff --git a/services/identity/src/ddb_utils.rs b/services/identity/src/ddb_utils.rs
--- a/services/identity/src/ddb_utils.rs
+++ b/services/identity/src/ddb_utils.rs
@@ -181,6 +181,15 @@
   WalletAddress(EthereumIdentity),
 }
 
+impl Identifier {
+  pub fn username(&self) -> &str {
+    match self {
+      Identifier::Username(username) => username,
+      Identifier::WalletAddress(eth_identity) => &eth_identity.wallet_address,
+    }
+  }
+}
+
 pub struct EthereumIdentity {
   pub wallet_address: String,
   pub social_proof: SocialProof,
diff --git a/shared/protos/identity_unauth.proto b/shared/protos/identity_unauth.proto
--- a/shared/protos/identity_unauth.proto
+++ b/shared/protos/identity_unauth.proto
@@ -177,6 +177,8 @@
   // Unique identifier for user
   string user_id = 1;
   string access_token = 2;
+  // This is wallet address for wallet users
+  string username = 3;
 }
 
 // LoginUser
diff --git a/web/protobufs/identity-unauth-structs.cjs b/web/protobufs/identity-unauth-structs.cjs
--- a/web/protobufs/identity-unauth-structs.cjs
+++ b/web/protobufs/identity-unauth-structs.cjs
@@ -2444,7 +2444,8 @@
 proto.identity.unauth.AuthResponse.toObject = function(includeInstance, msg) {
   var f, obj = {
     userId: jspb.Message.getFieldWithDefault(msg, 1, ""),
-    accessToken: jspb.Message.getFieldWithDefault(msg, 2, "")
+    accessToken: jspb.Message.getFieldWithDefault(msg, 2, ""),
+    username: jspb.Message.getFieldWithDefault(msg, 3, "")
   };
 
   if (includeInstance) {
@@ -2489,6 +2490,10 @@
       var value = /** @type {string} */ (reader.readString());
       msg.setAccessToken(value);
       break;
+    case 3:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUsername(value);
+      break;
     default:
       reader.skipField();
       break;
@@ -2532,6 +2537,13 @@
       f
     );
   }
+  f = message.getUsername();
+  if (f.length > 0) {
+    writer.writeString(
+      3,
+      f
+    );
+  }
 };
 
 
@@ -2571,6 +2583,24 @@
 };
 
 
+/**
+ * optional string username = 3;
+ * @return {string}
+ */
+proto.identity.unauth.AuthResponse.prototype.getUsername = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.identity.unauth.AuthResponse} returns this
+ */
+proto.identity.unauth.AuthResponse.prototype.setUsername = function(value) {
+  return jspb.Message.setProto3StringField(this, 3, value);
+};
+
+
 
 
 
diff --git a/web/protobufs/identity-unauth-structs.cjs.flow b/web/protobufs/identity-unauth-structs.cjs.flow
--- a/web/protobufs/identity-unauth-structs.cjs.flow
+++ b/web/protobufs/identity-unauth-structs.cjs.flow
@@ -231,6 +231,9 @@
   getAccessToken(): string;
   setAccessToken(value: string): AuthResponse;
 
+  getUsername(): string;
+  setUsername(value: string): AuthResponse;
+
   serializeBinary(): Uint8Array;
   toObject(includeInstance?: boolean): AuthResponseObject;
   static toObject(includeInstance: boolean, msg: AuthResponse): AuthResponseObject;
@@ -242,6 +245,7 @@
 export type AuthResponseObject = {
   userId: string,
   accessToken: string,
+  username: string,
 };
 
 declare export class OpaqueLoginStartRequest extends Message {