diff --git a/keyserver/addons/rust-node-addon/src/identity_client/register_user.rs b/keyserver/addons/rust-node-addon/src/identity_client/register_user.rs
--- a/keyserver/addons/rust-node-addon/src/identity_client/register_user.rs
+++ b/keyserver/addons/rust-node-addon/src/identity_client/register_user.rs
@@ -47,6 +47,7 @@
     username,
     device_key_upload: Some(device_key_upload),
     farcaster_id: None,
+    initial_device_list: "".to_string(),
   };
 
   // Finish OPAQUE registration and send final registration request
diff --git a/native/native_rust_library/src/identity/login.rs b/native/native_rust_library/src/identity/login.rs
--- a/native/native_rust_library/src/identity/login.rs
+++ b/native/native_rust_library/src/identity/login.rs
@@ -228,6 +228,7 @@
       device_type: DEVICE_TYPE.into(),
     }),
     farcaster_id: None,
+    initial_device_list: "".to_string(),
   };
 
   let mut identity_client = get_unauthenticated_client(
diff --git a/native/native_rust_library/src/identity/registration.rs b/native/native_rust_library/src/identity/registration.rs
--- a/native/native_rust_library/src/identity/registration.rs
+++ b/native/native_rust_library/src/identity/registration.rs
@@ -117,6 +117,7 @@
       device_type: DEVICE_TYPE.into(),
     }),
     farcaster_id: password_user_info.farcaster_id,
+    initial_device_list: "".to_string(),
   };
 
   let mut identity_client = get_unauthenticated_client(
@@ -176,6 +177,7 @@
       device_type: DEVICE_TYPE.into(),
     }),
     farcaster_id: wallet_user_info.farcaster_id,
+    initial_device_list: "".to_string(),
   };
 
   let mut identity_client = get_unauthenticated_client(
diff --git a/services/commtest/src/identity/device.rs b/services/commtest/src/identity/device.rs
--- a/services/commtest/src/identity/device.rs
+++ b/services/commtest/src/identity/device.rs
@@ -82,6 +82,7 @@
       device_type: device_type.into(),
     }),
     farcaster_id: None,
+    initial_device_list: "".to_string(),
   };
 
   let mut identity_client = get_unauthenticated_client(
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
@@ -121,6 +121,16 @@
   // Information needed to open a new channel to current user's device
   DeviceKeyUpload device_key_upload = 3;
   optional string farcaster_id = 4;
+  // A stringified JSON object of the following format:
+  // {
+  //   "rawDeviceList": JSON.stringify({
+  //     "devices": [<primary_device_id: string>]
+  //     "timestamp": <UTC timestamp in milliseconds: int>,
+  //   }),
+  //   "curPrimarySignature": "base64-encoded primary device signature"
+  // }
+  // It's an empty string for older clients which don't sign device lists yet.
+  string initial_device_list = 5;
 }
 
 message ReservedRegistrationStartRequest {
@@ -134,6 +144,16 @@
   string keyserver_message = 4;
   // Above message signed with authoritative keyserver's signing ed25519 key
   string keyserver_signature = 5;
+  // A stringified JSON object of the following format:
+  // {
+  //   "rawDeviceList": JSON.stringify({
+  //     "devices": [<primary_device_id: string>]
+  //     "timestamp": <UTC timestamp in milliseconds: int>,
+  //   }),
+  //   "curPrimarySignature": "base64-encoded primary device signature"
+  // }
+  // It's an empty string for older clients which don't sign device lists yet.
+  string initial_device_list = 6;
 }
 
 // Messages sent from a client to Identity Service
@@ -196,6 +216,17 @@
   // communication with this user
   DeviceKeyUpload device_key_upload = 3;
   optional string farcaster_id = 4;
+  // A stringified JSON object of the following format:
+  // {
+  //   "rawDeviceList": JSON.stringify({
+  //     "devices": [<primary_device_id: string>]
+  //     "timestamp": <UTC timestamp in milliseconds: int>,
+  //   }),
+  //   "curPrimarySignature": "base64-encoded primary device signature"
+  // }
+  // It's an empty string when used outside `RegisterWalletUser` RPC
+  // and for older clients which don't sign device lists yet.
+  string initial_device_list = 5;
 }
 
 message ReservedWalletRegistrationRequest {
@@ -209,6 +240,17 @@
   string keyserver_message = 4;
   // Above message signed with authoritative keyserver's signing ed25519 key
   string keyserver_signature = 5;
+  // A stringified JSON object of the following format:
+  // {
+  //   "rawDeviceList": JSON.stringify({
+  //     "devices": [<primary_device_id: string>]
+  //     "timestamp": <UTC timestamp in milliseconds: int>,
+  //   }),
+  //   "curPrimarySignature": "base64-encoded primary device signature"
+  // }
+  // It's an empty string when used for older clients 
+  // which don't sign device lists yet.
+  string initial_device_list = 6;
 }
 
 // UploadKeysForRegisteredDeviceAndLogIn
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
@@ -1440,7 +1440,8 @@
     opaqueRegistrationRequest: msg.getOpaqueRegistrationRequest_asB64(),
     username: jspb.Message.getFieldWithDefault(msg, 2, ""),
     deviceKeyUpload: (f = msg.getDeviceKeyUpload()) && proto.identity.unauth.DeviceKeyUpload.toObject(includeInstance, f),
-    farcasterId: jspb.Message.getFieldWithDefault(msg, 4, "")
+    farcasterId: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    initialDeviceList: jspb.Message.getFieldWithDefault(msg, 5, "")
   };
 
   if (includeInstance) {
@@ -1494,6 +1495,10 @@
       var value = /** @type {string} */ (reader.readString());
       msg.setFarcasterId(value);
       break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setInitialDeviceList(value);
+      break;
     default:
       reader.skipField();
       break;
@@ -1552,6 +1557,13 @@
       f
     );
   }
+  f = message.getInitialDeviceList();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
 };
 
 
@@ -1688,6 +1700,24 @@
 };
 
 
+/**
+ * optional string initial_device_list = 5;
+ * @return {string}
+ */
+proto.identity.unauth.RegistrationStartRequest.prototype.getInitialDeviceList = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.identity.unauth.RegistrationStartRequest} returns this
+ */
+proto.identity.unauth.RegistrationStartRequest.prototype.setInitialDeviceList = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
 
 
 
@@ -1724,7 +1754,8 @@
     username: jspb.Message.getFieldWithDefault(msg, 2, ""),
     deviceKeyUpload: (f = msg.getDeviceKeyUpload()) && proto.identity.unauth.DeviceKeyUpload.toObject(includeInstance, f),
     keyserverMessage: jspb.Message.getFieldWithDefault(msg, 4, ""),
-    keyserverSignature: jspb.Message.getFieldWithDefault(msg, 5, "")
+    keyserverSignature: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    initialDeviceList: jspb.Message.getFieldWithDefault(msg, 6, "")
   };
 
   if (includeInstance) {
@@ -1782,6 +1813,10 @@
       var value = /** @type {string} */ (reader.readString());
       msg.setKeyserverSignature(value);
       break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setInitialDeviceList(value);
+      break;
     default:
       reader.skipField();
       break;
@@ -1847,6 +1882,13 @@
       f
     );
   }
+  f = message.getInitialDeviceList();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
 };
 
 
@@ -1983,6 +2025,24 @@
 };
 
 
+/**
+ * optional string initial_device_list = 6;
+ * @return {string}
+ */
+proto.identity.unauth.ReservedRegistrationStartRequest.prototype.getInitialDeviceList = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.identity.unauth.ReservedRegistrationStartRequest} returns this
+ */
+proto.identity.unauth.ReservedRegistrationStartRequest.prototype.setInitialDeviceList = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, value);
+};
+
+
 
 
 
@@ -3197,7 +3257,8 @@
     siweMessage: jspb.Message.getFieldWithDefault(msg, 1, ""),
     siweSignature: jspb.Message.getFieldWithDefault(msg, 2, ""),
     deviceKeyUpload: (f = msg.getDeviceKeyUpload()) && proto.identity.unauth.DeviceKeyUpload.toObject(includeInstance, f),
-    farcasterId: jspb.Message.getFieldWithDefault(msg, 4, "")
+    farcasterId: jspb.Message.getFieldWithDefault(msg, 4, ""),
+    initialDeviceList: jspb.Message.getFieldWithDefault(msg, 5, "")
   };
 
   if (includeInstance) {
@@ -3251,6 +3312,10 @@
       var value = /** @type {string} */ (reader.readString());
       msg.setFarcasterId(value);
       break;
+    case 5:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setInitialDeviceList(value);
+      break;
     default:
       reader.skipField();
       break;
@@ -3309,6 +3374,13 @@
       f
     );
   }
+  f = message.getInitialDeviceList();
+  if (f.length > 0) {
+    writer.writeString(
+      5,
+      f
+    );
+  }
 };
 
 
@@ -3421,6 +3493,24 @@
 };
 
 
+/**
+ * optional string initial_device_list = 5;
+ * @return {string}
+ */
+proto.identity.unauth.WalletAuthRequest.prototype.getInitialDeviceList = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 5, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.identity.unauth.WalletAuthRequest} returns this
+ */
+proto.identity.unauth.WalletAuthRequest.prototype.setInitialDeviceList = function(value) {
+  return jspb.Message.setProto3StringField(this, 5, value);
+};
+
+
 
 
 
@@ -3457,7 +3547,8 @@
     siweSignature: jspb.Message.getFieldWithDefault(msg, 2, ""),
     deviceKeyUpload: (f = msg.getDeviceKeyUpload()) && proto.identity.unauth.DeviceKeyUpload.toObject(includeInstance, f),
     keyserverMessage: jspb.Message.getFieldWithDefault(msg, 4, ""),
-    keyserverSignature: jspb.Message.getFieldWithDefault(msg, 5, "")
+    keyserverSignature: jspb.Message.getFieldWithDefault(msg, 5, ""),
+    initialDeviceList: jspb.Message.getFieldWithDefault(msg, 6, "")
   };
 
   if (includeInstance) {
@@ -3515,6 +3606,10 @@
       var value = /** @type {string} */ (reader.readString());
       msg.setKeyserverSignature(value);
       break;
+    case 6:
+      var value = /** @type {string} */ (reader.readString());
+      msg.setInitialDeviceList(value);
+      break;
     default:
       reader.skipField();
       break;
@@ -3580,6 +3675,13 @@
       f
     );
   }
+  f = message.getInitialDeviceList();
+  if (f.length > 0) {
+    writer.writeString(
+      6,
+      f
+    );
+  }
 };
 
 
@@ -3692,6 +3794,24 @@
 };
 
 
+/**
+ * optional string initial_device_list = 6;
+ * @return {string}
+ */
+proto.identity.unauth.ReservedWalletRegistrationRequest.prototype.getInitialDeviceList = function() {
+  return /** @type {string} */ (jspb.Message.getFieldWithDefault(this, 6, ""));
+};
+
+
+/**
+ * @param {string} value
+ * @return {!proto.identity.unauth.ReservedWalletRegistrationRequest} returns this
+ */
+proto.identity.unauth.ReservedWalletRegistrationRequest.prototype.setInitialDeviceList = function(value) {
+  return jspb.Message.setProto3StringField(this, 6, 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
@@ -121,6 +121,9 @@
   hasFarcasterId(): boolean;
   clearFarcasterId(): RegistrationStartRequest;
 
+  getInitialDeviceList(): string;
+  setInitialDeviceList(value: string): RegistrationStartRequest;
+
   serializeBinary(): Uint8Array;
   toObject(includeInstance?: boolean): RegistrationStartRequestObject;
   static toObject(includeInstance: boolean, msg: RegistrationStartRequest): RegistrationStartRequestObject;
@@ -134,6 +137,7 @@
   username: string,
   deviceKeyUpload?: DeviceKeyUploadObject,
   farcasterId?: string,
+  initialDeviceList: string,
 };
 
 declare export class ReservedRegistrationStartRequest extends Message {
@@ -156,6 +160,9 @@
   getKeyserverSignature(): string;
   setKeyserverSignature(value: string): ReservedRegistrationStartRequest;
 
+  getInitialDeviceList(): string;
+  setInitialDeviceList(value: string): ReservedRegistrationStartRequest;
+
   serializeBinary(): Uint8Array;
   toObject(includeInstance?: boolean): ReservedRegistrationStartRequestObject;
   static toObject(includeInstance: boolean, msg: ReservedRegistrationStartRequest): ReservedRegistrationStartRequestObject;
@@ -170,6 +177,7 @@
   deviceKeyUpload?: DeviceKeyUploadObject,
   keyserverMessage: string,
   keyserverSignature: string,
+  initialDeviceList: string,
 };
 
 declare export class RegistrationFinishRequest extends Message {
@@ -331,6 +339,9 @@
   hasFarcasterId(): boolean;
   clearFarcasterId(): WalletAuthRequest;
 
+  getInitialDeviceList(): string;
+  setInitialDeviceList(value: string): WalletAuthRequest;
+
   serializeBinary(): Uint8Array;
   toObject(includeInstance?: boolean): WalletAuthRequestObject;
   static toObject(includeInstance: boolean, msg: WalletAuthRequest): WalletAuthRequestObject;
@@ -344,6 +355,7 @@
   siweSignature: string,
   deviceKeyUpload?: DeviceKeyUploadObject,
   farcasterId?: string,
+  initialDeviceList: string,
 };
 
 declare export class ReservedWalletRegistrationRequest extends Message {
@@ -364,6 +376,9 @@
   getKeyserverSignature(): string;
   setKeyserverSignature(value: string): ReservedWalletRegistrationRequest;
 
+  getInitialDeviceList(): string;
+  setInitialDeviceList(value: string): ReservedWalletRegistrationRequest;
+
   serializeBinary(): Uint8Array;
   toObject(includeInstance?: boolean): ReservedWalletRegistrationRequestObject;
   static toObject(includeInstance: boolean, msg: ReservedWalletRegistrationRequest): ReservedWalletRegistrationRequestObject;
@@ -378,6 +393,7 @@
   deviceKeyUpload?: DeviceKeyUploadObject,
   keyserverMessage: string,
   keyserverSignature: string,
+  initialDeviceList: string,
 };
 
 declare export class SecondaryDeviceKeysUploadRequest extends Message {