diff --git a/services/commtest/tests/identity_integration_tests.rs b/services/commtest/tests/identity_integration_tests.rs --- a/services/commtest/tests/identity_integration_tests.rs +++ b/services/commtest/tests/identity_integration_tests.rs @@ -4,7 +4,7 @@ use commtest::service_addr; use grpc_clients::identity::{ get_auth_client, get_unauthenticated_client, - protos::auth::{Identity, UserIdentityRequest}, + protos::auth::{Identity, UserIdentitiesRequest}, protos::unauthenticated::{ find_user_id_request::Identifier, FindUserIdRequest, }, @@ -54,11 +54,11 @@ .await .expect("Couldn't connect to identity service"); - let request = UserIdentityRequest { - user_id: device_info.user_id, + let request = UserIdentitiesRequest { + user_ids: vec![device_info.user_id.clone()], }; let response = client - .find_user_identity(request) + .find_user_identities(request) .await .expect("request failed") .into_inner(); @@ -66,10 +66,10 @@ let expected_username = device_info.username; assert!( matches!( - response.identity, + response.identities.get(&device_info.user_id), Some(Identity { username, .. - }) if username == expected_username + }) if *username == expected_username ), "username doesn't match" ); diff --git a/services/identity/src/database.rs b/services/identity/src/database.rs --- a/services/identity/src/database.rs +++ b/services/identity/src/database.rs @@ -720,6 +720,54 @@ .map_err(|e| Error::AwsSdk(e.into())) } + pub async fn find_db_user_identities( + &self, + user_ids: impl IntoIterator, + ) -> Result, Error> { + use comm_lib::database::batch_operations::{ + batch_get, ExponentialBackoffConfig, + }; + let primary_keys = user_ids.into_iter().map(|user_id| { + create_simple_primary_key(( + USERS_TABLE_PARTITION_KEY.to_string(), + user_id, + )) + }); + let projection_expression = [ + USERS_TABLE_PARTITION_KEY, + USERS_TABLE_USERNAME_ATTRIBUTE, + USERS_TABLE_WALLET_ADDRESS_ATTRIBUTE, + USERS_TABLE_SOCIAL_PROOF_ATTRIBUTE_NAME, + USERS_TABLE_FARCASTER_ID_ATTRIBUTE_NAME, + ] + .join(", "); + debug!( + num_requests = primary_keys.size_hint().0, + "Attempting to batch get user identifiers" + ); + + let responses = batch_get( + &self.client, + USERS_TABLE, + primary_keys, + Some(projection_expression), + ExponentialBackoffConfig::default(), + ) + .await + .map_err(Error::from)?; + debug!("Found {} matching user identifiers in DDB", responses.len()); + + let mut results = HashMap::with_capacity(responses.len()); + for response in responses { + let user_id = response.get_attr(USERS_TABLE_PARTITION_KEY)?; + // if this fails, it means that projection expression didnt have all attrs it needed + let identity = DBIdentity::try_from(response)?; + results.insert(user_id, identity); + } + + Ok(results) + } + /// Retrieves username for password users or wallet address for wallet users /// Returns `None` if user not found #[tracing::instrument(skip_all)] diff --git a/services/identity/src/grpc_services/authenticated.rs b/services/identity/src/grpc_services/authenticated.rs --- a/services/identity/src/grpc_services/authenticated.rs +++ b/services/identity/src/grpc_services/authenticated.rs @@ -25,7 +25,7 @@ PeersDeviceListsRequest, PeersDeviceListsResponse, RefreshUserPrekeysRequest, UpdateDeviceListRequest, UpdateUserPasswordFinishRequest, UpdateUserPasswordStartRequest, UpdateUserPasswordStartResponse, - UploadOneTimeKeysRequest, UserIdentityRequest, UserIdentityResponse, + UploadOneTimeKeysRequest, UserIdentitiesRequest, UserIdentitiesResponse, }; use super::protos::unauth::Empty; @@ -613,20 +613,25 @@ } #[tracing::instrument(skip_all)] - async fn find_user_identity( + async fn find_user_identities( &self, - request: tonic::Request, - ) -> Result, tonic::Status> { + request: tonic::Request, + ) -> Result, tonic::Status> { let message = request.into_inner(); - let identifier = self + + let results = self .db_client - .get_user_identity(&message.user_id) + .find_db_user_identities(message.user_ids) .await - .map_err(handle_db_error)? - .ok_or_else(|| tonic::Status::not_found("user not found"))?; + .map_err(handle_db_error)?; - let response = UserIdentityResponse { - identity: Some(identifier.into()), + let mapped_results = results + .into_iter() + .map(|(user_id, identifier)| (user_id, identifier.into())) + .collect(); + + let response = UserIdentitiesResponse { + identities: mapped_results, }; return Ok(Response::new(response)); } diff --git a/services/identity/src/grpc_utils.rs b/services/identity/src/grpc_utils.rs --- a/services/identity/src/grpc_utils.rs +++ b/services/identity/src/grpc_utils.rs @@ -255,6 +255,7 @@ DBIdentifier::Username(username) => Identity { username, eth_identity: None, + farcaster_id: value.farcaster_id, }, DBIdentifier::WalletAddress(eth_identity) => Identity { username: eth_identity.wallet_address.clone(), @@ -263,6 +264,7 @@ siwe_message: eth_identity.social_proof.message, siwe_signature: eth_identity.social_proof.signature, }), + farcaster_id: value.farcaster_id, }, } } diff --git a/shared/protos/identity_auth.proto b/shared/protos/identity_auth.proto --- a/shared/protos/identity_auth.proto +++ b/shared/protos/identity_auth.proto @@ -80,7 +80,7 @@ /* Miscellaneous actions */ - rpc FindUserIdentity(UserIdentityRequest) returns (UserIdentityResponse) {} + rpc FindUserIdentities(UserIdentitiesRequest) returns (UserIdentitiesResponse) {} } // Helper types @@ -95,6 +95,7 @@ // this is wallet address for Ethereum users string username = 1; optional EthereumIdentity eth_identity = 2; + optional string farcaster_id = 3; } // UploadOneTimeKeys @@ -258,13 +259,13 @@ string farcaster_id = 1; } -// FindUserIdentity +// FindUserIdentities -message UserIdentityRequest { - // user ID for which we want to get the identity - string user_id = 1; +message UserIdentitiesRequest { + // user IDs for which we want to get the identity + repeated string user_ids = 1; } -message UserIdentityResponse { - Identity identity = 1; +message UserIdentitiesResponse { + map identities = 1; } diff --git a/web/protobufs/identity-auth-client.cjs b/web/protobufs/identity-auth-client.cjs --- a/web/protobufs/identity-auth-client.cjs +++ b/web/protobufs/identity-auth-client.cjs @@ -1057,61 +1057,61 @@ /** * @const * @type {!grpc.web.MethodDescriptor< - * !proto.identity.auth.UserIdentityRequest, - * !proto.identity.auth.UserIdentityResponse>} + * !proto.identity.auth.UserIdentitiesRequest, + * !proto.identity.auth.UserIdentitiesResponse>} */ -const methodDescriptor_IdentityClientService_FindUserIdentity = new grpc.web.MethodDescriptor( - '/identity.auth.IdentityClientService/FindUserIdentity', +const methodDescriptor_IdentityClientService_FindUserIdentities = new grpc.web.MethodDescriptor( + '/identity.auth.IdentityClientService/FindUserIdentities', grpc.web.MethodType.UNARY, - proto.identity.auth.UserIdentityRequest, - proto.identity.auth.UserIdentityResponse, + proto.identity.auth.UserIdentitiesRequest, + proto.identity.auth.UserIdentitiesResponse, /** - * @param {!proto.identity.auth.UserIdentityRequest} request + * @param {!proto.identity.auth.UserIdentitiesRequest} request * @return {!Uint8Array} */ function(request) { return request.serializeBinary(); }, - proto.identity.auth.UserIdentityResponse.deserializeBinary + proto.identity.auth.UserIdentitiesResponse.deserializeBinary ); /** - * @param {!proto.identity.auth.UserIdentityRequest} request The + * @param {!proto.identity.auth.UserIdentitiesRequest} request The * request proto * @param {?Object} metadata User defined * call metadata - * @param {function(?grpc.web.RpcError, ?proto.identity.auth.UserIdentityResponse)} + * @param {function(?grpc.web.RpcError, ?proto.identity.auth.UserIdentitiesResponse)} * callback The callback function(error, response) - * @return {!grpc.web.ClientReadableStream|undefined} + * @return {!grpc.web.ClientReadableStream|undefined} * The XHR Node Readable Stream */ -proto.identity.auth.IdentityClientServiceClient.prototype.findUserIdentity = +proto.identity.auth.IdentityClientServiceClient.prototype.findUserIdentities = function(request, metadata, callback) { return this.client_.rpcCall(this.hostname_ + - '/identity.auth.IdentityClientService/FindUserIdentity', + '/identity.auth.IdentityClientService/FindUserIdentities', request, metadata || {}, - methodDescriptor_IdentityClientService_FindUserIdentity, + methodDescriptor_IdentityClientService_FindUserIdentities, callback); }; /** - * @param {!proto.identity.auth.UserIdentityRequest} request The + * @param {!proto.identity.auth.UserIdentitiesRequest} request The * request proto * @param {?Object=} metadata User defined * call metadata - * @return {!Promise} + * @return {!Promise} * Promise that resolves to the response */ -proto.identity.auth.IdentityClientServicePromiseClient.prototype.findUserIdentity = +proto.identity.auth.IdentityClientServicePromiseClient.prototype.findUserIdentities = function(request, metadata) { return this.client_.unaryCall(this.hostname_ + - '/identity.auth.IdentityClientService/FindUserIdentity', + '/identity.auth.IdentityClientService/FindUserIdentities', request, metadata || {}, - methodDescriptor_IdentityClientService_FindUserIdentity); + methodDescriptor_IdentityClientService_FindUserIdentities); }; diff --git a/web/protobufs/identity-auth-client.cjs.flow b/web/protobufs/identity-auth-client.cjs.flow --- a/web/protobufs/identity-auth-client.cjs.flow +++ b/web/protobufs/identity-auth-client.cjs.flow @@ -123,12 +123,12 @@ response: identityStructs.Empty) => void ): grpcWeb.ClientReadableStream; - findUserIdentity( - request: identityAuthStructs.UserIdentityRequest, + findUserIdentities( + request: identityAuthStructs.UserIdentitiesRequest, metadata: grpcWeb.Metadata | void, callback: (err: grpcWeb.RpcError, - response: identityAuthStructs.UserIdentityResponse) => void - ): grpcWeb.ClientReadableStream; + response: identityAuthStructs.UserIdentitiesResponse) => void + ): grpcWeb.ClientReadableStream; } declare export class IdentityClientServicePromiseClient { @@ -216,8 +216,9 @@ metadata?: grpcWeb.Metadata ): Promise; - findUserIdentity( - request: identityAuthStructs.UserIdentityRequest, + findUserIdentities( + request: identityAuthStructs.UserIdentitiesRequest, metadata?: grpcWeb.Metadata - ): Promise; + ): Promise; } + diff --git a/web/protobufs/identity-auth-structs.cjs b/web/protobufs/identity-auth-structs.cjs --- a/web/protobufs/identity-auth-structs.cjs +++ b/web/protobufs/identity-auth-structs.cjs @@ -47,8 +47,8 @@ goog.exportSymbol('proto.identity.auth.UpdateUserPasswordStartRequest', null, global); goog.exportSymbol('proto.identity.auth.UpdateUserPasswordStartResponse', null, global); goog.exportSymbol('proto.identity.auth.UploadOneTimeKeysRequest', null, global); -goog.exportSymbol('proto.identity.auth.UserIdentityRequest', null, global); -goog.exportSymbol('proto.identity.auth.UserIdentityResponse', null, global); +goog.exportSymbol('proto.identity.auth.UserIdentitiesRequest', null, global); +goog.exportSymbol('proto.identity.auth.UserIdentitiesResponse', null, global); /** * Generated by JsPbCodeGenerator. * @param {Array=} opt_data Optional initial data array, typically from a @@ -542,16 +542,16 @@ * @extends {jspb.Message} * @constructor */ -proto.identity.auth.UserIdentityRequest = function(opt_data) { - jspb.Message.initialize(this, opt_data, 0, -1, null, null); +proto.identity.auth.UserIdentitiesRequest = function(opt_data) { + jspb.Message.initialize(this, opt_data, 0, -1, proto.identity.auth.UserIdentitiesRequest.repeatedFields_, null); }; -goog.inherits(proto.identity.auth.UserIdentityRequest, jspb.Message); +goog.inherits(proto.identity.auth.UserIdentitiesRequest, jspb.Message); if (goog.DEBUG && !COMPILED) { /** * @public * @override */ - proto.identity.auth.UserIdentityRequest.displayName = 'proto.identity.auth.UserIdentityRequest'; + proto.identity.auth.UserIdentitiesRequest.displayName = 'proto.identity.auth.UserIdentitiesRequest'; } /** * Generated by JsPbCodeGenerator. @@ -563,16 +563,16 @@ * @extends {jspb.Message} * @constructor */ -proto.identity.auth.UserIdentityResponse = function(opt_data) { +proto.identity.auth.UserIdentitiesResponse = function(opt_data) { jspb.Message.initialize(this, opt_data, 0, -1, null, null); }; -goog.inherits(proto.identity.auth.UserIdentityResponse, jspb.Message); +goog.inherits(proto.identity.auth.UserIdentitiesResponse, jspb.Message); if (goog.DEBUG && !COMPILED) { /** * @public * @override */ - proto.identity.auth.UserIdentityResponse.displayName = 'proto.identity.auth.UserIdentityResponse'; + proto.identity.auth.UserIdentitiesResponse.displayName = 'proto.identity.auth.UserIdentitiesResponse'; } @@ -797,7 +797,8 @@ proto.identity.auth.Identity.toObject = function(includeInstance, msg) { var f, obj = { username: jspb.Message.getFieldWithDefault(msg, 1, ""), - ethIdentity: (f = msg.getEthIdentity()) && proto.identity.auth.EthereumIdentity.toObject(includeInstance, f) + ethIdentity: (f = msg.getEthIdentity()) && proto.identity.auth.EthereumIdentity.toObject(includeInstance, f), + farcasterId: jspb.Message.getFieldWithDefault(msg, 3, "") }; if (includeInstance) { @@ -843,6 +844,10 @@ reader.readMessage(value,proto.identity.auth.EthereumIdentity.deserializeBinaryFromReader); msg.setEthIdentity(value); break; + case 3: + var value = /** @type {string} */ (reader.readString()); + msg.setFarcasterId(value); + break; default: reader.skipField(); break; @@ -887,6 +892,13 @@ proto.identity.auth.EthereumIdentity.serializeBinaryToWriter ); } + f = /** @type {string} */ (jspb.Message.getField(message, 3)); + if (f != null) { + writer.writeString( + 3, + f + ); + } }; @@ -945,6 +957,42 @@ }; +/** + * optional string farcaster_id = 3; + * @return {string} + */ +proto.identity.auth.Identity.prototype.getFarcasterId = function() { + return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 3, "")); +}; + + +/** + * @param {string} value + * @return {!proto.identity.auth.Identity} returns this + */ +proto.identity.auth.Identity.prototype.setFarcasterId = function(value) { + return jspb.Message.setField(this, 3, value); +}; + + +/** + * Clears the field making it undefined. + * @return {!proto.identity.auth.Identity} returns this + */ +proto.identity.auth.Identity.prototype.clearFarcasterId = function() { + return jspb.Message.setField(this, 3, undefined); +}; + + +/** + * Returns whether this field is set. + * @return {boolean} + */ +proto.identity.auth.Identity.prototype.hasFarcasterId = function() { + return jspb.Message.getField(this, 3) != null; +}; + + /** * List of repeated fields within this message type. @@ -4715,6 +4763,13 @@ +/** + * List of repeated fields within this message type. + * @private {!Array} + * @const + */ +proto.identity.auth.UserIdentitiesRequest.repeatedFields_ = [1]; + if (jspb.Message.GENERATE_TO_OBJECT) { @@ -4730,8 +4785,8 @@ * http://goto/soy-param-migration * @return {!Object} */ -proto.identity.auth.UserIdentityRequest.prototype.toObject = function(opt_includeInstance) { - return proto.identity.auth.UserIdentityRequest.toObject(opt_includeInstance, this); +proto.identity.auth.UserIdentitiesRequest.prototype.toObject = function(opt_includeInstance) { + return proto.identity.auth.UserIdentitiesRequest.toObject(opt_includeInstance, this); }; @@ -4740,13 +4795,13 @@ * @param {boolean|undefined} includeInstance Deprecated. Whether to include * the JSPB instance for transitional soy proto support: * http://goto/soy-param-migration - * @param {!proto.identity.auth.UserIdentityRequest} msg The msg instance to transform. + * @param {!proto.identity.auth.UserIdentitiesRequest} msg The msg instance to transform. * @return {!Object} * @suppress {unusedLocalVariables} f is only used for nested messages */ -proto.identity.auth.UserIdentityRequest.toObject = function(includeInstance, msg) { +proto.identity.auth.UserIdentitiesRequest.toObject = function(includeInstance, msg) { var f, obj = { - userId: jspb.Message.getFieldWithDefault(msg, 1, "") + userIdsList: (f = jspb.Message.getRepeatedField(msg, 1)) == null ? undefined : f }; if (includeInstance) { @@ -4760,23 +4815,23 @@ /** * Deserializes binary data (in protobuf wire format). * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!proto.identity.auth.UserIdentityRequest} + * @return {!proto.identity.auth.UserIdentitiesRequest} */ -proto.identity.auth.UserIdentityRequest.deserializeBinary = function(bytes) { +proto.identity.auth.UserIdentitiesRequest.deserializeBinary = function(bytes) { var reader = new jspb.BinaryReader(bytes); - var msg = new proto.identity.auth.UserIdentityRequest; - return proto.identity.auth.UserIdentityRequest.deserializeBinaryFromReader(msg, reader); + var msg = new proto.identity.auth.UserIdentitiesRequest; + return proto.identity.auth.UserIdentitiesRequest.deserializeBinaryFromReader(msg, reader); }; /** * Deserializes binary data (in protobuf wire format) from the * given reader into the given message object. - * @param {!proto.identity.auth.UserIdentityRequest} msg The message object to deserialize into. + * @param {!proto.identity.auth.UserIdentitiesRequest} msg The message object to deserialize into. * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!proto.identity.auth.UserIdentityRequest} + * @return {!proto.identity.auth.UserIdentitiesRequest} */ -proto.identity.auth.UserIdentityRequest.deserializeBinaryFromReader = function(msg, reader) { +proto.identity.auth.UserIdentitiesRequest.deserializeBinaryFromReader = function(msg, reader) { while (reader.nextField()) { if (reader.isEndGroup()) { break; @@ -4785,7 +4840,7 @@ switch (field) { case 1: var value = /** @type {string} */ (reader.readString()); - msg.setUserId(value); + msg.addUserIds(value); break; default: reader.skipField(); @@ -4800,9 +4855,9 @@ * Serializes the message to binary data (in protobuf wire format). * @return {!Uint8Array} */ -proto.identity.auth.UserIdentityRequest.prototype.serializeBinary = function() { +proto.identity.auth.UserIdentitiesRequest.prototype.serializeBinary = function() { var writer = new jspb.BinaryWriter(); - proto.identity.auth.UserIdentityRequest.serializeBinaryToWriter(this, writer); + proto.identity.auth.UserIdentitiesRequest.serializeBinaryToWriter(this, writer); return writer.getResultBuffer(); }; @@ -4810,15 +4865,15 @@ /** * Serializes the given message to binary data (in protobuf wire * format), writing to the given BinaryWriter. - * @param {!proto.identity.auth.UserIdentityRequest} message + * @param {!proto.identity.auth.UserIdentitiesRequest} message * @param {!jspb.BinaryWriter} writer * @suppress {unusedLocalVariables} f is only used for nested messages */ -proto.identity.auth.UserIdentityRequest.serializeBinaryToWriter = function(message, writer) { +proto.identity.auth.UserIdentitiesRequest.serializeBinaryToWriter = function(message, writer) { var f = undefined; - f = message.getUserId(); + f = message.getUserIdsList(); if (f.length > 0) { - writer.writeString( + writer.writeRepeatedString( 1, f ); @@ -4827,20 +4882,39 @@ /** - * optional string user_id = 1; - * @return {string} + * repeated string user_ids = 1; + * @return {!Array} */ -proto.identity.auth.UserIdentityRequest.prototype.getUserId = function() { - return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, "")); +proto.identity.auth.UserIdentitiesRequest.prototype.getUserIdsList = function() { + return /** @type {!Array} */ (jspb.Message.getRepeatedField(this, 1)); +}; + + +/** + * @param {!Array} value + * @return {!proto.identity.auth.UserIdentitiesRequest} returns this + */ +proto.identity.auth.UserIdentitiesRequest.prototype.setUserIdsList = function(value) { + return jspb.Message.setField(this, 1, value || []); }; /** * @param {string} value - * @return {!proto.identity.auth.UserIdentityRequest} returns this + * @param {number=} opt_index + * @return {!proto.identity.auth.UserIdentitiesRequest} returns this */ -proto.identity.auth.UserIdentityRequest.prototype.setUserId = function(value) { - return jspb.Message.setProto3StringField(this, 1, value); +proto.identity.auth.UserIdentitiesRequest.prototype.addUserIds = function(value, opt_index) { + return jspb.Message.addToRepeatedField(this, 1, value, opt_index); +}; + + +/** + * Clears the list making it empty but non-null. + * @return {!proto.identity.auth.UserIdentitiesRequest} returns this + */ +proto.identity.auth.UserIdentitiesRequest.prototype.clearUserIdsList = function() { + return this.setUserIdsList([]); }; @@ -4860,8 +4934,8 @@ * http://goto/soy-param-migration * @return {!Object} */ -proto.identity.auth.UserIdentityResponse.prototype.toObject = function(opt_includeInstance) { - return proto.identity.auth.UserIdentityResponse.toObject(opt_includeInstance, this); +proto.identity.auth.UserIdentitiesResponse.prototype.toObject = function(opt_includeInstance) { + return proto.identity.auth.UserIdentitiesResponse.toObject(opt_includeInstance, this); }; @@ -4870,13 +4944,13 @@ * @param {boolean|undefined} includeInstance Deprecated. Whether to include * the JSPB instance for transitional soy proto support: * http://goto/soy-param-migration - * @param {!proto.identity.auth.UserIdentityResponse} msg The msg instance to transform. + * @param {!proto.identity.auth.UserIdentitiesResponse} msg The msg instance to transform. * @return {!Object} * @suppress {unusedLocalVariables} f is only used for nested messages */ -proto.identity.auth.UserIdentityResponse.toObject = function(includeInstance, msg) { +proto.identity.auth.UserIdentitiesResponse.toObject = function(includeInstance, msg) { var f, obj = { - identity: (f = msg.getIdentity()) && proto.identity.auth.Identity.toObject(includeInstance, f) + identitiesMap: (f = msg.getIdentitiesMap()) ? f.toObject(includeInstance, proto.identity.auth.Identity.toObject) : [] }; if (includeInstance) { @@ -4890,23 +4964,23 @@ /** * Deserializes binary data (in protobuf wire format). * @param {jspb.ByteSource} bytes The bytes to deserialize. - * @return {!proto.identity.auth.UserIdentityResponse} + * @return {!proto.identity.auth.UserIdentitiesResponse} */ -proto.identity.auth.UserIdentityResponse.deserializeBinary = function(bytes) { +proto.identity.auth.UserIdentitiesResponse.deserializeBinary = function(bytes) { var reader = new jspb.BinaryReader(bytes); - var msg = new proto.identity.auth.UserIdentityResponse; - return proto.identity.auth.UserIdentityResponse.deserializeBinaryFromReader(msg, reader); + var msg = new proto.identity.auth.UserIdentitiesResponse; + return proto.identity.auth.UserIdentitiesResponse.deserializeBinaryFromReader(msg, reader); }; /** * Deserializes binary data (in protobuf wire format) from the * given reader into the given message object. - * @param {!proto.identity.auth.UserIdentityResponse} msg The message object to deserialize into. + * @param {!proto.identity.auth.UserIdentitiesResponse} msg The message object to deserialize into. * @param {!jspb.BinaryReader} reader The BinaryReader to use. - * @return {!proto.identity.auth.UserIdentityResponse} + * @return {!proto.identity.auth.UserIdentitiesResponse} */ -proto.identity.auth.UserIdentityResponse.deserializeBinaryFromReader = function(msg, reader) { +proto.identity.auth.UserIdentitiesResponse.deserializeBinaryFromReader = function(msg, reader) { while (reader.nextField()) { if (reader.isEndGroup()) { break; @@ -4914,9 +4988,10 @@ var field = reader.getFieldNumber(); switch (field) { case 1: - var value = new proto.identity.auth.Identity; - reader.readMessage(value,proto.identity.auth.Identity.deserializeBinaryFromReader); - msg.setIdentity(value); + var value = msg.getIdentitiesMap(); + reader.readMessage(value, function(message, reader) { + jspb.Map.deserializeBinary(message, reader, jspb.BinaryReader.prototype.readString, jspb.BinaryReader.prototype.readMessage, proto.identity.auth.Identity.deserializeBinaryFromReader, "", new proto.identity.auth.Identity()); + }); break; default: reader.skipField(); @@ -4931,9 +5006,9 @@ * Serializes the message to binary data (in protobuf wire format). * @return {!Uint8Array} */ -proto.identity.auth.UserIdentityResponse.prototype.serializeBinary = function() { +proto.identity.auth.UserIdentitiesResponse.prototype.serializeBinary = function() { var writer = new jspb.BinaryWriter(); - proto.identity.auth.UserIdentityResponse.serializeBinaryToWriter(this, writer); + proto.identity.auth.UserIdentitiesResponse.serializeBinaryToWriter(this, writer); return writer.getResultBuffer(); }; @@ -4941,57 +5016,39 @@ /** * Serializes the given message to binary data (in protobuf wire * format), writing to the given BinaryWriter. - * @param {!proto.identity.auth.UserIdentityResponse} message + * @param {!proto.identity.auth.UserIdentitiesResponse} message * @param {!jspb.BinaryWriter} writer * @suppress {unusedLocalVariables} f is only used for nested messages */ -proto.identity.auth.UserIdentityResponse.serializeBinaryToWriter = function(message, writer) { +proto.identity.auth.UserIdentitiesResponse.serializeBinaryToWriter = function(message, writer) { var f = undefined; - f = message.getIdentity(); - if (f != null) { - writer.writeMessage( - 1, - f, - proto.identity.auth.Identity.serializeBinaryToWriter - ); + f = message.getIdentitiesMap(true); + if (f && f.getLength() > 0) { + f.serializeBinary(1, writer, jspb.BinaryWriter.prototype.writeString, jspb.BinaryWriter.prototype.writeMessage, proto.identity.auth.Identity.serializeBinaryToWriter); } }; /** - * optional Identity identity = 1; - * @return {?proto.identity.auth.Identity} - */ -proto.identity.auth.UserIdentityResponse.prototype.getIdentity = function() { - return /** @type{?proto.identity.auth.Identity} */ ( - jspb.Message.getWrapperField(this, proto.identity.auth.Identity, 1)); -}; - - -/** - * @param {?proto.identity.auth.Identity|undefined} value - * @return {!proto.identity.auth.UserIdentityResponse} returns this -*/ -proto.identity.auth.UserIdentityResponse.prototype.setIdentity = function(value) { - return jspb.Message.setWrapperField(this, 1, value); -}; - - -/** - * Clears the message field making it undefined. - * @return {!proto.identity.auth.UserIdentityResponse} returns this + * map identities = 1; + * @param {boolean=} opt_noLazyCreate Do not create the map if + * empty, instead returning `undefined` + * @return {!jspb.Map} */ -proto.identity.auth.UserIdentityResponse.prototype.clearIdentity = function() { - return this.setIdentity(undefined); +proto.identity.auth.UserIdentitiesResponse.prototype.getIdentitiesMap = function(opt_noLazyCreate) { + return /** @type {!jspb.Map} */ ( + jspb.Message.getMapField(this, 1, opt_noLazyCreate, + proto.identity.auth.Identity)); }; /** - * Returns whether this field is set. - * @return {boolean} + * Clears values from the map. The map will be non-null. + * @return {!proto.identity.auth.UserIdentitiesResponse} returns this */ -proto.identity.auth.UserIdentityResponse.prototype.hasIdentity = function() { - return jspb.Message.getField(this, 1) != null; +proto.identity.auth.UserIdentitiesResponse.prototype.clearIdentitiesMap = function() { + this.getIdentitiesMap().clear(); + return this; }; diff --git a/web/protobufs/identity-auth-structs.cjs.flow b/web/protobufs/identity-auth-structs.cjs.flow --- a/web/protobufs/identity-auth-structs.cjs.flow +++ b/web/protobufs/identity-auth-structs.cjs.flow @@ -42,6 +42,11 @@ hasEthIdentity(): boolean; clearEthIdentity(): Identity; + getFarcasterId(): string; + setFarcasterId(value: string): Identity; + hasFarcasterId(): boolean; + clearFarcasterId(): Identity; + serializeBinary(): Uint8Array; toObject(includeInstance?: boolean): IdentityObject; static toObject(includeInstance: boolean, msg: Identity): IdentityObject; @@ -53,6 +58,7 @@ export type IdentityObject = { username: string, ethIdentity: ?EthereumIdentityObject, + farcasterId: ?string, } declare export class UploadOneTimeKeysRequest extends Message { @@ -507,36 +513,36 @@ farcasterId: string, } -declare export class UserIdentityRequest extends Message { - getUserId(): string; - setUserId(value: string): UserIdentityRequest; +declare export class UserIdentitiesRequest extends Message { + getUserIdsList(): Array; + setUserIdsList(value: Array): UserIdentitiesRequest; + clearUserIdsList(): UserIdentitiesRequest; + addUserIds(value: string, index?: number): UserIdentitiesRequest; serializeBinary(): Uint8Array; - toObject(includeInstance?: boolean): UserIdentityRequestObject; - static toObject(includeInstance: boolean, msg: UserIdentityRequest): UserIdentityRequestObject; - static serializeBinaryToWriter(message: UserIdentityRequest, writer: BinaryWriter): void; - static deserializeBinary(bytes: Uint8Array): UserIdentityRequest; - static deserializeBinaryFromReader(message: UserIdentityRequest, reader: BinaryReader): UserIdentityRequest; + toObject(includeInstance?: boolean): UserIdentitiesRequestObject; + static toObject(includeInstance: boolean, msg: UserIdentitiesRequest): UserIdentitiesRequestObject; + static serializeBinaryToWriter(message: UserIdentitiesRequest, writer: BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): UserIdentitiesRequest; + static deserializeBinaryFromReader(message: UserIdentitiesRequest, reader: BinaryReader): UserIdentitiesRequest; } -export type UserIdentityRequestObject = { - userId: string, +export type UserIdentitiesRequestObject = { + userIdsList: Array, } -declare export class UserIdentityResponse extends Message { - getIdentity(): Identity | void; - setIdentity(value?: Identity): UserIdentityResponse; - hasIdentity(): boolean; - clearIdentity(): UserIdentityResponse; +declare export class UserIdentitiesResponse extends Message { + getIdentitiesMap(): Map; + clearIdentitiesMap(): UserIdentitiesResponse; serializeBinary(): Uint8Array; - toObject(includeInstance?: boolean): UserIdentityResponseObject; - static toObject(includeInstance: boolean, msg: UserIdentityResponse): UserIdentityResponseObject; - static serializeBinaryToWriter(message: UserIdentityResponse, writer: BinaryWriter): void; - static deserializeBinary(bytes: Uint8Array): UserIdentityResponse; - static deserializeBinaryFromReader(message: UserIdentityResponse, reader: BinaryReader): UserIdentityResponse; + toObject(includeInstance?: boolean): UserIdentitiesResponseObject; + static toObject(includeInstance: boolean, msg: UserIdentitiesResponse): UserIdentitiesResponseObject; + static serializeBinaryToWriter(message: UserIdentitiesResponse, writer: BinaryWriter): void; + static deserializeBinary(bytes: Uint8Array): UserIdentitiesResponse; + static deserializeBinaryFromReader(message: UserIdentitiesResponse, reader: BinaryReader): UserIdentitiesResponse; } -export type UserIdentityResponseObject = { - identity: ?IdentityObject, +export type UserIdentitiesResponseObject = { + identitiesMap: Array<[string, IdentityObject]>, }