diff --git a/web/protobufs/identity-auth-client.cjs b/web/protobufs/identity-auth-client.cjs
new file mode 100644
--- /dev/null
+++ b/web/protobufs/identity-auth-client.cjs
@@ -0,0 +1,263 @@
+/**
+ * @fileoverview gRPC-Web generated client stub for identity.authenticated
+ * @enhanceable
+ * @public
+ * @generated
+ */
+
+// Code generated by protoc-gen-grpc-web. DO NOT EDIT.
+// versions:
+// 	protoc-gen-grpc-web v1.4.2
+// 	protoc              v3.21.12
+// source: identity_authenticated.proto
+
+/* eslint-disable */
+// @ts-nocheck
+
+
+
+const grpc = {};
+grpc.web = require('grpc-web');
+
+
+var identity_client_pb = require('./identity-structs.cjs')
+const proto = {};
+proto.identity = {};
+proto.identity.authenticated = require('./identity-auth-structs.cjs');
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?grpc.web.ClientOptions} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.identity.authenticated.IdentityClientServiceClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options.format = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname.replace(/\/+$/, '');
+
+};
+
+
+/**
+ * @param {string} hostname
+ * @param {?Object} credentials
+ * @param {?grpc.web.ClientOptions} options
+ * @constructor
+ * @struct
+ * @final
+ */
+proto.identity.authenticated.IdentityClientServicePromiseClient =
+    function(hostname, credentials, options) {
+  if (!options) options = {};
+  options.format = 'text';
+
+  /**
+   * @private @const {!grpc.web.GrpcWebClientBase} The client
+   */
+  this.client_ = new grpc.web.GrpcWebClientBase(options);
+
+  /**
+   * @private @const {string} The hostname
+   */
+  this.hostname_ = hostname.replace(/\/+$/, '');
+
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.identity.authenticated.UploadOneTimeKeysRequest,
+ *   !proto.identity.client.Empty>}
+ */
+const methodDescriptor_IdentityClientService_UploadOneTimeKeys = new grpc.web.MethodDescriptor(
+  '/identity.authenticated.IdentityClientService/UploadOneTimeKeys',
+  grpc.web.MethodType.UNARY,
+  proto.identity.authenticated.UploadOneTimeKeysRequest,
+  identity_client_pb.Empty,
+  /**
+   * @param {!proto.identity.authenticated.UploadOneTimeKeysRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  identity_client_pb.Empty.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.identity.authenticated.UploadOneTimeKeysRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.RpcError, ?proto.identity.client.Empty)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.identity.client.Empty>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.identity.authenticated.IdentityClientServiceClient.prototype.uploadOneTimeKeys =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/identity.authenticated.IdentityClientService/UploadOneTimeKeys',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityClientService_UploadOneTimeKeys,
+      callback);
+};
+
+
+/**
+ * @param {!proto.identity.authenticated.UploadOneTimeKeysRequest} request The
+ *     request proto
+ * @param {?Object<string, string>=} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.identity.client.Empty>}
+ *     Promise that resolves to the response
+ */
+proto.identity.authenticated.IdentityClientServicePromiseClient.prototype.uploadOneTimeKeys =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/identity.authenticated.IdentityClientService/UploadOneTimeKeys',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityClientService_UploadOneTimeKeys);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.identity.authenticated.RefreshUserPreKeysRequest,
+ *   !proto.identity.client.Empty>}
+ */
+const methodDescriptor_IdentityClientService_RefreshUserPreKeys = new grpc.web.MethodDescriptor(
+  '/identity.authenticated.IdentityClientService/RefreshUserPreKeys',
+  grpc.web.MethodType.UNARY,
+  proto.identity.authenticated.RefreshUserPreKeysRequest,
+  identity_client_pb.Empty,
+  /**
+   * @param {!proto.identity.authenticated.RefreshUserPreKeysRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  identity_client_pb.Empty.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.identity.authenticated.RefreshUserPreKeysRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.RpcError, ?proto.identity.client.Empty)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.identity.client.Empty>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.identity.authenticated.IdentityClientServiceClient.prototype.refreshUserPreKeys =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/identity.authenticated.IdentityClientService/RefreshUserPreKeys',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityClientService_RefreshUserPreKeys,
+      callback);
+};
+
+
+/**
+ * @param {!proto.identity.authenticated.RefreshUserPreKeysRequest} request The
+ *     request proto
+ * @param {?Object<string, string>=} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.identity.client.Empty>}
+ *     Promise that resolves to the response
+ */
+proto.identity.authenticated.IdentityClientServicePromiseClient.prototype.refreshUserPreKeys =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/identity.authenticated.IdentityClientService/RefreshUserPreKeys',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityClientService_RefreshUserPreKeys);
+};
+
+
+/**
+ * @const
+ * @type {!grpc.web.MethodDescriptor<
+ *   !proto.identity.authenticated.OutboundKeysForUserRequest,
+ *   !proto.identity.authenticated.KeyserverKeysResponse>}
+ */
+const methodDescriptor_IdentityClientService_GetKeyserverKeys = new grpc.web.MethodDescriptor(
+  '/identity.authenticated.IdentityClientService/GetKeyserverKeys',
+  grpc.web.MethodType.UNARY,
+  proto.identity.authenticated.OutboundKeysForUserRequest,
+  proto.identity.authenticated.KeyserverKeysResponse,
+  /**
+   * @param {!proto.identity.authenticated.OutboundKeysForUserRequest} request
+   * @return {!Uint8Array}
+   */
+  function(request) {
+    return request.serializeBinary();
+  },
+  proto.identity.authenticated.KeyserverKeysResponse.deserializeBinary
+);
+
+
+/**
+ * @param {!proto.identity.authenticated.OutboundKeysForUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>} metadata User defined
+ *     call metadata
+ * @param {function(?grpc.web.RpcError, ?proto.identity.authenticated.KeyserverKeysResponse)}
+ *     callback The callback function(error, response)
+ * @return {!grpc.web.ClientReadableStream<!proto.identity.authenticated.KeyserverKeysResponse>|undefined}
+ *     The XHR Node Readable Stream
+ */
+proto.identity.authenticated.IdentityClientServiceClient.prototype.getKeyserverKeys =
+    function(request, metadata, callback) {
+  return this.client_.rpcCall(this.hostname_ +
+      '/identity.authenticated.IdentityClientService/GetKeyserverKeys',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityClientService_GetKeyserverKeys,
+      callback);
+};
+
+
+/**
+ * @param {!proto.identity.authenticated.OutboundKeysForUserRequest} request The
+ *     request proto
+ * @param {?Object<string, string>=} metadata User defined
+ *     call metadata
+ * @return {!Promise<!proto.identity.authenticated.KeyserverKeysResponse>}
+ *     Promise that resolves to the response
+ */
+proto.identity.authenticated.IdentityClientServicePromiseClient.prototype.getKeyserverKeys =
+    function(request, metadata) {
+  return this.client_.unaryCall(this.hostname_ +
+      '/identity.authenticated.IdentityClientService/GetKeyserverKeys',
+      request,
+      metadata || {},
+      methodDescriptor_IdentityClientService_GetKeyserverKeys);
+};
+
+
+module.exports = proto.identity.authenticated;
diff --git a/web/protobufs/identity-auth-client.cjs.flow b/web/protobufs/identity-auth-client.cjs.flow
new file mode 100644
--- /dev/null
+++ b/web/protobufs/identity-auth-client.cjs.flow
@@ -0,0 +1,57 @@
+// @flow
+
+import * as grpcWeb from 'grpc-web';
+
+import * as identityAuthStructs from './identity-auth-structs.cjs';
+import * as identityStructs from './identity-structs.cjs';
+
+
+declare export class IdentityClientServiceClient {
+  constructor (hostname: string,
+               credentials?: null | { +[index: string]: string; },
+               options?: null | { +[index: string]: any; }): void;
+
+  uploadOneTimeKeys(
+    request: identityAuthStructs.UploadOneTimeKeysRequest,
+    metadata: grpcWeb.Metadata | void,
+    callback: (err: grpcWeb.RpcError,
+               response: identityStructs.Empty) => void
+  ): grpcWeb.ClientReadableStream<identityStructs.Empty>;
+
+  refreshUserPreKeys(
+    request: identityAuthStructs.RefreshUserPreKeysRequest,
+    metadata: grpcWeb.Metadata | void,
+    callback: (err: grpcWeb.RpcError,
+               response: identityStructs.Empty) => void
+  ): grpcWeb.ClientReadableStream<identityStructs.Empty>;
+
+  getKeyserverKeys(
+    request: identityAuthStructs.OutboundKeysForUserRequest,
+    metadata: grpcWeb.Metadata | void,
+    callback: (err: grpcWeb.RpcError,
+               response: identityAuthStructs.KeyserverKeysResponse) => void
+  ): grpcWeb.ClientReadableStream<identityAuthStructs.KeyserverKeysResponse>;
+
+}
+
+declare export class IdentityClientServicePromiseClient {
+  constructor (hostname: string,
+               credentials?: null | { +[index: string]: string; },
+               options?: null | { +[index: string]: any; }): void;
+
+  uploadOneTimeKeys(
+    request: identityAuthStructs.UploadOneTimeKeysRequest,
+    metadata?: grpcWeb.Metadata
+  ): Promise<identityStructs.Empty>;
+
+  refreshUserPreKeys(
+    request: identityAuthStructs.RefreshUserPreKeysRequest,
+    metadata?: grpcWeb.Metadata
+  ): Promise<identityStructs.Empty>;
+
+  getKeyserverKeys(
+    request: identityAuthStructs.OutboundKeysForUserRequest,
+    metadata?: grpcWeb.Metadata
+  ): Promise<identityAuthStructs.KeyserverKeysResponse>;
+
+}
diff --git a/web/protobufs/identity-auth-structs.cjs b/web/protobufs/identity-auth-structs.cjs
new file mode 100644
--- /dev/null
+++ b/web/protobufs/identity-auth-structs.cjs
@@ -0,0 +1,1174 @@
+// source: identity_authenticated.proto
+/**
+ * @fileoverview
+ * @enhanceable
+ * @suppress {missingRequire} reports error on implicit type usages.
+ * @suppress {messageConventions} JS Compiler reports an error if a variable or
+ *     field starts with 'MSG_' and isn't a translatable message.
+ * @public
+ * @generated
+ */
+// GENERATED CODE -- DO NOT EDIT!
+/* eslint-disable */
+// @ts-nocheck
+
+var jspb = require('google-protobuf');
+var goog = jspb;
+var global =
+    (typeof globalThis !== 'undefined' && globalThis) ||
+    (typeof window !== 'undefined' && window) ||
+    (typeof global !== 'undefined' && global) ||
+    (typeof self !== 'undefined' && self) ||
+    (function () { return this; }).call(null) ||
+    Function('return this')();
+
+var identity_client_pb = require('./identity-structs.cjs');
+goog.object.extend(proto, identity_client_pb);
+goog.exportSymbol('proto.identity.authenticated.KeyserverKeysResponse', null, global);
+goog.exportSymbol('proto.identity.authenticated.OutboundKeyInfo', null, global);
+goog.exportSymbol('proto.identity.authenticated.OutboundKeysForUserRequest', null, global);
+goog.exportSymbol('proto.identity.authenticated.RefreshUserPreKeysRequest', null, global);
+goog.exportSymbol('proto.identity.authenticated.UploadOneTimeKeysRequest', null, global);
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, proto.identity.authenticated.UploadOneTimeKeysRequest.repeatedFields_, null);
+};
+goog.inherits(proto.identity.authenticated.UploadOneTimeKeysRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.identity.authenticated.UploadOneTimeKeysRequest.displayName = 'proto.identity.authenticated.UploadOneTimeKeysRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.identity.authenticated.RefreshUserPreKeysRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.identity.authenticated.RefreshUserPreKeysRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.identity.authenticated.RefreshUserPreKeysRequest.displayName = 'proto.identity.authenticated.RefreshUserPreKeysRequest';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.identity.authenticated.OutboundKeyInfo = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.identity.authenticated.OutboundKeyInfo, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.identity.authenticated.OutboundKeyInfo.displayName = 'proto.identity.authenticated.OutboundKeyInfo';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.identity.authenticated.KeyserverKeysResponse = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.identity.authenticated.KeyserverKeysResponse, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.identity.authenticated.KeyserverKeysResponse.displayName = 'proto.identity.authenticated.KeyserverKeysResponse';
+}
+/**
+ * Generated by JsPbCodeGenerator.
+ * @param {Array=} opt_data Optional initial data array, typically from a
+ * server response, or constructed directly in Javascript. The array is used
+ * in place and becomes part of the constructed object. It is not cloned.
+ * If no data is provided, the constructed object will be empty, but still
+ * valid.
+ * @extends {jspb.Message}
+ * @constructor
+ */
+proto.identity.authenticated.OutboundKeysForUserRequest = function(opt_data) {
+  jspb.Message.initialize(this, opt_data, 0, -1, null, null);
+};
+goog.inherits(proto.identity.authenticated.OutboundKeysForUserRequest, jspb.Message);
+if (goog.DEBUG && !COMPILED) {
+  /**
+   * @public
+   * @override
+   */
+  proto.identity.authenticated.OutboundKeysForUserRequest.displayName = 'proto.identity.authenticated.OutboundKeysForUserRequest';
+}
+
+/**
+ * List of repeated fields within this message type.
+ * @private {!Array<number>}
+ * @const
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest.repeatedFields_ = [1,2];
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.identity.authenticated.UploadOneTimeKeysRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.identity.authenticated.UploadOneTimeKeysRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    contentonetimeprekeysList: (f = jspb.Message.getRepeatedField(msg, 1)) == null ? undefined : f,
+    notifonetimeprekeysList: (f = jspb.Message.getRepeatedField(msg, 2)) == null ? undefined : f
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.identity.authenticated.UploadOneTimeKeysRequest}
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.identity.authenticated.UploadOneTimeKeysRequest;
+  return proto.identity.authenticated.UploadOneTimeKeysRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.identity.authenticated.UploadOneTimeKeysRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.identity.authenticated.UploadOneTimeKeysRequest}
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addContentonetimeprekeys(value);
+      break;
+    case 2:
+      var value = /** @type {string} */ (reader.readString());
+      msg.addNotifonetimeprekeys(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.identity.authenticated.UploadOneTimeKeysRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.identity.authenticated.UploadOneTimeKeysRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getContentonetimeprekeysList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      1,
+      f
+    );
+  }
+  f = message.getNotifonetimeprekeysList();
+  if (f.length > 0) {
+    writer.writeRepeatedString(
+      2,
+      f
+    );
+  }
+};
+
+
+/**
+ * repeated string contentOneTimePreKeys = 1;
+ * @return {!Array<string>}
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest.prototype.getContentonetimeprekeysList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 1));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.identity.authenticated.UploadOneTimeKeysRequest} returns this
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest.prototype.setContentonetimeprekeysList = function(value) {
+  return jspb.Message.setField(this, 1, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.identity.authenticated.UploadOneTimeKeysRequest} returns this
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest.prototype.addContentonetimeprekeys = 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.authenticated.UploadOneTimeKeysRequest} returns this
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest.prototype.clearContentonetimeprekeysList = function() {
+  return this.setContentonetimeprekeysList([]);
+};
+
+
+/**
+ * repeated string notifOneTimePreKeys = 2;
+ * @return {!Array<string>}
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest.prototype.getNotifonetimeprekeysList = function() {
+  return /** @type {!Array<string>} */ (jspb.Message.getRepeatedField(this, 2));
+};
+
+
+/**
+ * @param {!Array<string>} value
+ * @return {!proto.identity.authenticated.UploadOneTimeKeysRequest} returns this
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest.prototype.setNotifonetimeprekeysList = function(value) {
+  return jspb.Message.setField(this, 2, value || []);
+};
+
+
+/**
+ * @param {string} value
+ * @param {number=} opt_index
+ * @return {!proto.identity.authenticated.UploadOneTimeKeysRequest} returns this
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest.prototype.addNotifonetimeprekeys = function(value, opt_index) {
+  return jspb.Message.addToRepeatedField(this, 2, value, opt_index);
+};
+
+
+/**
+ * Clears the list making it empty but non-null.
+ * @return {!proto.identity.authenticated.UploadOneTimeKeysRequest} returns this
+ */
+proto.identity.authenticated.UploadOneTimeKeysRequest.prototype.clearNotifonetimeprekeysList = function() {
+  return this.setNotifonetimeprekeysList([]);
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.identity.authenticated.RefreshUserPreKeysRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.identity.authenticated.RefreshUserPreKeysRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.identity.authenticated.RefreshUserPreKeysRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.authenticated.RefreshUserPreKeysRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    newcontentprekeys: (f = msg.getNewcontentprekeys()) && identity_client_pb.PreKey.toObject(includeInstance, f),
+    newnotifprekeys: (f = msg.getNewnotifprekeys()) && identity_client_pb.PreKey.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.identity.authenticated.RefreshUserPreKeysRequest}
+ */
+proto.identity.authenticated.RefreshUserPreKeysRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.identity.authenticated.RefreshUserPreKeysRequest;
+  return proto.identity.authenticated.RefreshUserPreKeysRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.identity.authenticated.RefreshUserPreKeysRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.identity.authenticated.RefreshUserPreKeysRequest}
+ */
+proto.identity.authenticated.RefreshUserPreKeysRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new identity_client_pb.PreKey;
+      reader.readMessage(value,identity_client_pb.PreKey.deserializeBinaryFromReader);
+      msg.setNewcontentprekeys(value);
+      break;
+    case 2:
+      var value = new identity_client_pb.PreKey;
+      reader.readMessage(value,identity_client_pb.PreKey.deserializeBinaryFromReader);
+      msg.setNewnotifprekeys(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.identity.authenticated.RefreshUserPreKeysRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.identity.authenticated.RefreshUserPreKeysRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.identity.authenticated.RefreshUserPreKeysRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.authenticated.RefreshUserPreKeysRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getNewcontentprekeys();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      identity_client_pb.PreKey.serializeBinaryToWriter
+    );
+  }
+  f = message.getNewnotifprekeys();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      identity_client_pb.PreKey.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional identity.client.PreKey newContentPreKeys = 1;
+ * @return {?proto.identity.client.PreKey}
+ */
+proto.identity.authenticated.RefreshUserPreKeysRequest.prototype.getNewcontentprekeys = function() {
+  return /** @type{?proto.identity.client.PreKey} */ (
+    jspb.Message.getWrapperField(this, identity_client_pb.PreKey, 1));
+};
+
+
+/**
+ * @param {?proto.identity.client.PreKey|undefined} value
+ * @return {!proto.identity.authenticated.RefreshUserPreKeysRequest} returns this
+*/
+proto.identity.authenticated.RefreshUserPreKeysRequest.prototype.setNewcontentprekeys = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.identity.authenticated.RefreshUserPreKeysRequest} returns this
+ */
+proto.identity.authenticated.RefreshUserPreKeysRequest.prototype.clearNewcontentprekeys = function() {
+  return this.setNewcontentprekeys(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.identity.authenticated.RefreshUserPreKeysRequest.prototype.hasNewcontentprekeys = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional identity.client.PreKey newNotifPreKeys = 2;
+ * @return {?proto.identity.client.PreKey}
+ */
+proto.identity.authenticated.RefreshUserPreKeysRequest.prototype.getNewnotifprekeys = function() {
+  return /** @type{?proto.identity.client.PreKey} */ (
+    jspb.Message.getWrapperField(this, identity_client_pb.PreKey, 2));
+};
+
+
+/**
+ * @param {?proto.identity.client.PreKey|undefined} value
+ * @return {!proto.identity.authenticated.RefreshUserPreKeysRequest} returns this
+*/
+proto.identity.authenticated.RefreshUserPreKeysRequest.prototype.setNewnotifprekeys = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.identity.authenticated.RefreshUserPreKeysRequest} returns this
+ */
+proto.identity.authenticated.RefreshUserPreKeysRequest.prototype.clearNewnotifprekeys = function() {
+  return this.setNewnotifprekeys(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.identity.authenticated.RefreshUserPreKeysRequest.prototype.hasNewnotifprekeys = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.toObject = function(opt_includeInstance) {
+  return proto.identity.authenticated.OutboundKeyInfo.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.identity.authenticated.OutboundKeyInfo} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.authenticated.OutboundKeyInfo.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    identityinfo: (f = msg.getIdentityinfo()) && identity_client_pb.IdentityKeyInfo.toObject(includeInstance, f),
+    contentprekey: (f = msg.getContentprekey()) && identity_client_pb.PreKey.toObject(includeInstance, f),
+    notifprekey: (f = msg.getNotifprekey()) && identity_client_pb.PreKey.toObject(includeInstance, f),
+    onetimecontentprekey: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    onetimenotifprekey: jspb.Message.getFieldWithDefault(msg, 5, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.identity.authenticated.OutboundKeyInfo}
+ */
+proto.identity.authenticated.OutboundKeyInfo.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.identity.authenticated.OutboundKeyInfo;
+  return proto.identity.authenticated.OutboundKeyInfo.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.identity.authenticated.OutboundKeyInfo} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.identity.authenticated.OutboundKeyInfo}
+ */
+proto.identity.authenticated.OutboundKeyInfo.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new identity_client_pb.IdentityKeyInfo;
+      reader.readMessage(value,identity_client_pb.IdentityKeyInfo.deserializeBinaryFromReader);
+      msg.setIdentityinfo(value);
+      break;
+    case 2:
+      var value = new identity_client_pb.PreKey;
+      reader.readMessage(value,identity_client_pb.PreKey.deserializeBinaryFromReader);
+      msg.setContentprekey(value);
+      break;
+    case 3:
+      var value = new identity_client_pb.PreKey;
+      reader.readMessage(value,identity_client_pb.PreKey.deserializeBinaryFromReader);
+      msg.setNotifprekey(value);
+      break;
+    case 4:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setOnetimecontentprekey(value);
+      break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setOnetimenotifprekey(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.identity.authenticated.OutboundKeyInfo.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.identity.authenticated.OutboundKeyInfo} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.authenticated.OutboundKeyInfo.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getIdentityinfo();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      identity_client_pb.IdentityKeyInfo.serializeBinaryToWriter
+    );
+  }
+  f = message.getContentprekey();
+  if (f != null) {
+    writer.writeMessage(
+      2,
+      f,
+      identity_client_pb.PreKey.serializeBinaryToWriter
+    );
+  }
+  f = message.getNotifprekey();
+  if (f != null) {
+    writer.writeMessage(
+      3,
+      f,
+      identity_client_pb.PreKey.serializeBinaryToWriter
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 4));
+  if (f != null) {
+    writer.writeString(
+      4,
+      f
+    );
+  }
+  f = /** @type {string} */ (jspb.Message.getField(message, 5));
+  if (f != null) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional identity.client.IdentityKeyInfo identityInfo = 1;
+ * @return {?proto.identity.client.IdentityKeyInfo}
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.getIdentityinfo = function() {
+  return /** @type{?proto.identity.client.IdentityKeyInfo} */ (
+    jspb.Message.getWrapperField(this, identity_client_pb.IdentityKeyInfo, 1));
+};
+
+
+/**
+ * @param {?proto.identity.client.IdentityKeyInfo|undefined} value
+ * @return {!proto.identity.authenticated.OutboundKeyInfo} returns this
+*/
+proto.identity.authenticated.OutboundKeyInfo.prototype.setIdentityinfo = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.identity.authenticated.OutboundKeyInfo} returns this
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.clearIdentityinfo = function() {
+  return this.setIdentityinfo(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.hasIdentityinfo = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+/**
+ * optional identity.client.PreKey contentPrekey = 2;
+ * @return {?proto.identity.client.PreKey}
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.getContentprekey = function() {
+  return /** @type{?proto.identity.client.PreKey} */ (
+    jspb.Message.getWrapperField(this, identity_client_pb.PreKey, 2));
+};
+
+
+/**
+ * @param {?proto.identity.client.PreKey|undefined} value
+ * @return {!proto.identity.authenticated.OutboundKeyInfo} returns this
+*/
+proto.identity.authenticated.OutboundKeyInfo.prototype.setContentprekey = function(value) {
+  return jspb.Message.setWrapperField(this, 2, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.identity.authenticated.OutboundKeyInfo} returns this
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.clearContentprekey = function() {
+  return this.setContentprekey(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.hasContentprekey = function() {
+  return jspb.Message.getField(this, 2) != null;
+};
+
+
+/**
+ * optional identity.client.PreKey notifPrekey = 3;
+ * @return {?proto.identity.client.PreKey}
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.getNotifprekey = function() {
+  return /** @type{?proto.identity.client.PreKey} */ (
+    jspb.Message.getWrapperField(this, identity_client_pb.PreKey, 3));
+};
+
+
+/**
+ * @param {?proto.identity.client.PreKey|undefined} value
+ * @return {!proto.identity.authenticated.OutboundKeyInfo} returns this
+*/
+proto.identity.authenticated.OutboundKeyInfo.prototype.setNotifprekey = function(value) {
+  return jspb.Message.setWrapperField(this, 3, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.identity.authenticated.OutboundKeyInfo} returns this
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.clearNotifprekey = function() {
+  return this.setNotifprekey(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.hasNotifprekey = function() {
+  return jspb.Message.getField(this, 3) != null;
+};
+
+
+/**
+ * optional string oneTimeContentPrekey = 4;
+ * @return {string}
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.getOnetimecontentprekey = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 4, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.identity.authenticated.OutboundKeyInfo} returns this
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.setOnetimecontentprekey = function(value) {
+  return jspb.Message.setField(this, 4, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.identity.authenticated.OutboundKeyInfo} returns this
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.clearOnetimecontentprekey = function() {
+  return jspb.Message.setField(this, 4, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.hasOnetimecontentprekey = function() {
+  return jspb.Message.getField(this, 4) != null;
+};
+
+
+/**
+ * optional string oneTimeNotifPrekey = 5;
+ * @return {string}
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.getOnetimenotifprekey = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.identity.authenticated.OutboundKeyInfo} returns this
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.setOnetimenotifprekey = function(value) {
+  return jspb.Message.setField(this, 5, value);
+};
+
+
+/**
+ * Clears the field making it undefined.
+ * @return {!proto.identity.authenticated.OutboundKeyInfo} returns this
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.clearOnetimenotifprekey = function() {
+  return jspb.Message.setField(this, 5, undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.identity.authenticated.OutboundKeyInfo.prototype.hasOnetimenotifprekey = function() {
+  return jspb.Message.getField(this, 5) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.identity.authenticated.KeyserverKeysResponse.prototype.toObject = function(opt_includeInstance) {
+  return proto.identity.authenticated.KeyserverKeysResponse.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.identity.authenticated.KeyserverKeysResponse} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.authenticated.KeyserverKeysResponse.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    keyserverinfo: (f = msg.getKeyserverinfo()) && proto.identity.authenticated.OutboundKeyInfo.toObject(includeInstance, f)
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.identity.authenticated.KeyserverKeysResponse}
+ */
+proto.identity.authenticated.KeyserverKeysResponse.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.identity.authenticated.KeyserverKeysResponse;
+  return proto.identity.authenticated.KeyserverKeysResponse.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.identity.authenticated.KeyserverKeysResponse} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.identity.authenticated.KeyserverKeysResponse}
+ */
+proto.identity.authenticated.KeyserverKeysResponse.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = new proto.identity.authenticated.OutboundKeyInfo;
+      reader.readMessage(value,proto.identity.authenticated.OutboundKeyInfo.deserializeBinaryFromReader);
+      msg.setKeyserverinfo(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.identity.authenticated.KeyserverKeysResponse.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.identity.authenticated.KeyserverKeysResponse.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.identity.authenticated.KeyserverKeysResponse} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.authenticated.KeyserverKeysResponse.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getKeyserverinfo();
+  if (f != null) {
+    writer.writeMessage(
+      1,
+      f,
+      proto.identity.authenticated.OutboundKeyInfo.serializeBinaryToWriter
+    );
+  }
+};
+
+
+/**
+ * optional OutboundKeyInfo keyserverInfo = 1;
+ * @return {?proto.identity.authenticated.OutboundKeyInfo}
+ */
+proto.identity.authenticated.KeyserverKeysResponse.prototype.getKeyserverinfo = function() {
+  return /** @type{?proto.identity.authenticated.OutboundKeyInfo} */ (
+    jspb.Message.getWrapperField(this, proto.identity.authenticated.OutboundKeyInfo, 1));
+};
+
+
+/**
+ * @param {?proto.identity.authenticated.OutboundKeyInfo|undefined} value
+ * @return {!proto.identity.authenticated.KeyserverKeysResponse} returns this
+*/
+proto.identity.authenticated.KeyserverKeysResponse.prototype.setKeyserverinfo = function(value) {
+  return jspb.Message.setWrapperField(this, 1, value);
+};
+
+
+/**
+ * Clears the message field making it undefined.
+ * @return {!proto.identity.authenticated.KeyserverKeysResponse} returns this
+ */
+proto.identity.authenticated.KeyserverKeysResponse.prototype.clearKeyserverinfo = function() {
+  return this.setKeyserverinfo(undefined);
+};
+
+
+/**
+ * Returns whether this field is set.
+ * @return {boolean}
+ */
+proto.identity.authenticated.KeyserverKeysResponse.prototype.hasKeyserverinfo = function() {
+  return jspb.Message.getField(this, 1) != null;
+};
+
+
+
+
+
+if (jspb.Message.GENERATE_TO_OBJECT) {
+/**
+ * Creates an object representation of this proto.
+ * Field names that are reserved in JavaScript and will be renamed to pb_name.
+ * Optional fields that are not set will be set to undefined.
+ * To access a reserved field use, foo.pb_<name>, eg, foo.pb_default.
+ * For the list of reserved names please see:
+ *     net/proto2/compiler/js/internal/generator.cc#kKeyword.
+ * @param {boolean=} opt_includeInstance Deprecated. whether to include the
+ *     JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @return {!Object}
+ */
+proto.identity.authenticated.OutboundKeysForUserRequest.prototype.toObject = function(opt_includeInstance) {
+  return proto.identity.authenticated.OutboundKeysForUserRequest.toObject(opt_includeInstance, this);
+};
+
+
+/**
+ * Static version of the {@see toObject} method.
+ * @param {boolean|undefined} includeInstance Deprecated. Whether to include
+ *     the JSPB instance for transitional soy proto support:
+ *     http://goto/soy-param-migration
+ * @param {!proto.identity.authenticated.OutboundKeysForUserRequest} msg The msg instance to transform.
+ * @return {!Object}
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.authenticated.OutboundKeysForUserRequest.toObject = function(includeInstance, msg) {
+  var f, obj = {
+    userid: jspb.Message.getFieldWithDefault(msg, 1, "")
+  };
+
+  if (includeInstance) {
+    obj.$jspbMessageInstance = msg;
+  }
+  return obj;
+};
+}
+
+
+/**
+ * Deserializes binary data (in protobuf wire format).
+ * @param {jspb.ByteSource} bytes The bytes to deserialize.
+ * @return {!proto.identity.authenticated.OutboundKeysForUserRequest}
+ */
+proto.identity.authenticated.OutboundKeysForUserRequest.deserializeBinary = function(bytes) {
+  var reader = new jspb.BinaryReader(bytes);
+  var msg = new proto.identity.authenticated.OutboundKeysForUserRequest;
+  return proto.identity.authenticated.OutboundKeysForUserRequest.deserializeBinaryFromReader(msg, reader);
+};
+
+
+/**
+ * Deserializes binary data (in protobuf wire format) from the
+ * given reader into the given message object.
+ * @param {!proto.identity.authenticated.OutboundKeysForUserRequest} msg The message object to deserialize into.
+ * @param {!jspb.BinaryReader} reader The BinaryReader to use.
+ * @return {!proto.identity.authenticated.OutboundKeysForUserRequest}
+ */
+proto.identity.authenticated.OutboundKeysForUserRequest.deserializeBinaryFromReader = function(msg, reader) {
+  while (reader.nextField()) {
+    if (reader.isEndGroup()) {
+      break;
+    }
+    var field = reader.getFieldNumber();
+    switch (field) {
+    case 1:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setUserid(value);
+      break;
+    default:
+      reader.skipField();
+      break;
+    }
+  }
+  return msg;
+};
+
+
+/**
+ * Serializes the message to binary data (in protobuf wire format).
+ * @return {!Uint8Array}
+ */
+proto.identity.authenticated.OutboundKeysForUserRequest.prototype.serializeBinary = function() {
+  var writer = new jspb.BinaryWriter();
+  proto.identity.authenticated.OutboundKeysForUserRequest.serializeBinaryToWriter(this, writer);
+  return writer.getResultBuffer();
+};
+
+
+/**
+ * Serializes the given message to binary data (in protobuf wire
+ * format), writing to the given BinaryWriter.
+ * @param {!proto.identity.authenticated.OutboundKeysForUserRequest} message
+ * @param {!jspb.BinaryWriter} writer
+ * @suppress {unusedLocalVariables} f is only used for nested messages
+ */
+proto.identity.authenticated.OutboundKeysForUserRequest.serializeBinaryToWriter = function(message, writer) {
+  var f = undefined;
+  f = message.getUserid();
+  if (f.length > 0) {
+    writer.writeString(
+      1,
+      f
+    );
+  }
+};
+
+
+/**
+ * optional string userID = 1;
+ * @return {string}
+ */
+proto.identity.authenticated.OutboundKeysForUserRequest.prototype.getUserid = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 1, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.identity.authenticated.OutboundKeysForUserRequest} returns this
+ */
+proto.identity.authenticated.OutboundKeysForUserRequest.prototype.setUserid = function(value) {
+  return jspb.Message.setProto3StringField(this, 1, value);
+};
+
+
+goog.object.extend(exports, proto.identity.authenticated);
diff --git a/web/protobufs/identity-auth-structs.cjs.flow b/web/protobufs/identity-auth-structs.cjs.flow
new file mode 100644
--- /dev/null
+++ b/web/protobufs/identity-auth-structs.cjs.flow
@@ -0,0 +1,134 @@
+// @flow
+
+import {
+  Message,
+  BinaryWriter,
+  BinaryReader,
+  Map as ProtoMap,
+} from 'google-protobuf';
+
+import * as identityStructs from './identity-structs.cjs';
+
+declare export class UploadOneTimeKeysRequest extends Message {
+  getContentonetimeprekeysList(): Array<string>;
+  setContentonetimeprekeysList(value: Array<string>): UploadOneTimeKeysRequest;
+  clearContentonetimeprekeysList(): UploadOneTimeKeysRequest;
+  addContentonetimeprekeys(value: string, index?: number): UploadOneTimeKeysRequest;
+
+  getNotifonetimeprekeysList(): Array<string>;
+  setNotifonetimeprekeysList(value: Array<string>): UploadOneTimeKeysRequest;
+  clearNotifonetimeprekeysList(): UploadOneTimeKeysRequest;
+  addNotifonetimeprekeys(value: string, index?: number): UploadOneTimeKeysRequest;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): UploadOneTimeKeysRequestObject;
+  static toObject(includeInstance: boolean, msg: UploadOneTimeKeysRequest): UploadOneTimeKeysRequestObject;
+  static serializeBinaryToWriter(message: UploadOneTimeKeysRequest, writer: BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): UploadOneTimeKeysRequest;
+  static deserializeBinaryFromReader(message: UploadOneTimeKeysRequest, reader: BinaryReader): UploadOneTimeKeysRequest;
+}
+
+export type UploadOneTimeKeysRequestObject = {
+  contentonetimeprekeysList: Array<string>,
+  notifonetimeprekeysList: Array<string>,
+};
+
+declare export class RefreshUserPreKeysRequest extends Message {
+  getNewcontentprekeys(): identityStructs.PreKey | void;
+  setNewcontentprekeys(value?: identityStructs.PreKey): RefreshUserPreKeysRequest;
+  hasNewcontentprekeys(): boolean;
+  clearNewcontentprekeys(): RefreshUserPreKeysRequest;
+
+  getNewnotifprekeys(): identityStructs.PreKey | void;
+  setNewnotifprekeys(value?: identityStructs.PreKey): RefreshUserPreKeysRequest;
+  hasNewnotifprekeys(): boolean;
+  clearNewnotifprekeys(): RefreshUserPreKeysRequest;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): RefreshUserPreKeysRequestObject;
+  static toObject(includeInstance: boolean, msg: RefreshUserPreKeysRequest): RefreshUserPreKeysRequestObject;
+  static serializeBinaryToWriter(message: RefreshUserPreKeysRequest, writer: BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): RefreshUserPreKeysRequest;
+  static deserializeBinaryFromReader(message: RefreshUserPreKeysRequest, reader: BinaryReader): RefreshUserPreKeysRequest;
+}
+
+export type RefreshUserPreKeysRequestObject = {
+  newcontentprekeys?: identityStructs.PreKeyObject,
+  newnotifprekeys?: identityStructs.PreKeyObject,
+}
+
+declare export class OutboundKeyInfo extends Message {
+  getIdentityinfo(): identityStructs.IdentityKeyInfo | void;
+  setIdentityinfo(value?: identityStructs.IdentityKeyInfo): OutboundKeyInfo;
+  hasIdentityinfo(): boolean;
+  clearIdentityinfo(): OutboundKeyInfo;
+
+  getContentprekey(): identityStructs.PreKey | void;
+  setContentprekey(value?: identityStructs.PreKey): OutboundKeyInfo;
+  hasContentprekey(): boolean;
+  clearContentprekey(): OutboundKeyInfo;
+
+  getNotifprekey(): identityStructs.PreKey | void;
+  setNotifprekey(value?: identityStructs.PreKey): OutboundKeyInfo;
+  hasNotifprekey(): boolean;
+  clearNotifprekey(): OutboundKeyInfo;
+
+  getOnetimecontentprekey(): string;
+  setOnetimecontentprekey(value: string): OutboundKeyInfo;
+  hasOnetimecontentprekey(): boolean;
+  clearOnetimecontentprekey(): OutboundKeyInfo;
+
+  getOnetimenotifprekey(): string;
+  setOnetimenotifprekey(value: string): OutboundKeyInfo;
+  hasOnetimenotifprekey(): boolean;
+  clearOnetimenotifprekey(): OutboundKeyInfo;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): OutboundKeyInfoObject;
+  static toObject(includeInstance: boolean, msg: OutboundKeyInfo): OutboundKeyInfoObject;
+  static serializeBinaryToWriter(message: OutboundKeyInfo, writer: BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): OutboundKeyInfo;
+  static deserializeBinaryFromReader(message: OutboundKeyInfo, reader: BinaryReader): OutboundKeyInfo;
+}
+
+export type OutboundKeyInfoObject = {
+  identityinfo?: identityStructs.IdentityKeyInfoObject,
+  contentprekey?: identityStructs.PreKeyObject,
+  notifprekey?: identityStructs.PreKeyObject,
+  onetimecontentprekey?: string,
+  onetimenotifprekey?: string,
+};
+
+declare export class KeyserverKeysResponse extends Message {
+  getKeyserverinfo(): OutboundKeyInfo | void;
+  setKeyserverinfo(value?: OutboundKeyInfo): KeyserverKeysResponse;
+  hasKeyserverinfo(): boolean;
+  clearKeyserverinfo(): KeyserverKeysResponse;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): KeyserverKeysResponseObject;
+  static toObject(includeInstance: boolean, msg: KeyserverKeysResponse): KeyserverKeysResponseObject;
+  static serializeBinaryToWriter(message: KeyserverKeysResponse, writer: BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): KeyserverKeysResponse;
+  static deserializeBinaryFromReader(message: KeyserverKeysResponse, reader: BinaryReader): KeyserverKeysResponse;
+}
+
+export type KeyserverKeysResponseObject = {
+  keyserverinfo?: OutboundKeyInfoObject,
+};
+
+declare export class OutboundKeysForUserRequest extends Message {
+  getUserid(): string;
+  setUserid(value: string): OutboundKeysForUserRequest;
+
+  serializeBinary(): Uint8Array;
+  toObject(includeInstance?: boolean): OutboundKeysForUserRequestObject;
+  static toObject(includeInstance: boolean, msg: OutboundKeysForUserRequest): OutboundKeysForUserRequestObject;
+  static serializeBinaryToWriter(message: OutboundKeysForUserRequest, writer: BinaryWriter): void;
+  static deserializeBinary(bytes: Uint8Array): OutboundKeysForUserRequest;
+  static deserializeBinaryFromReader(message: OutboundKeysForUserRequest, reader: BinaryReader): OutboundKeysForUserRequest;
+}
+
+export type OutboundKeysForUserRequestObject = {
+  userid: string,
+};