1package com.peachpasswords.sync23import kotlinx.serialization.SerialName4import kotlinx.serialization.Serializable5import kotlinx.serialization.json.Json678910111213@Serializable14sealed class SyncMessage {15 @Serializable16 @SerialName("SYNC_HELLO")17 data class Hello(18 val vaultId: String,19 val deviceId: String,20 val version: Long,21 val deviceTime: Long,22 ) : SyncMessage()2324 @Serializable25 @SerialName("SYNC_MANIFEST")26 data class Manifest(27 val entries: Map<String, Long>,28 val tombstones: Map<String, Long>,29 ) : SyncMessage()3031 @Serializable32 @SerialName("SYNC_REQUEST")33 data class Request(val entryIds: List<String>) : SyncMessage()3435 @Serializable36 @SerialName("SYNC_ENTRIES")37 data class Entries(val entries: Map<String, String>) : SyncMessage()3839 @Serializable40 @SerialName("SYNC_TOMBSTONES")41 data class Tombstones(val tombstones: Map<String, Long>) : SyncMessage()4243 @Serializable44 @SerialName("SYNC_DEVICE_MANIFEST")45 data class DeviceManifest(val manifest: SignedDeviceManifest?) : SyncMessage()4647 @Serializable48 @SerialName("SYNC_DONE")49 data class Done(50 val entriesReceived: Int = 0,51 val entriesSent: Int = 0,52 ) : SyncMessage()5354 @Serializable55 @SerialName("SYNC_ERROR")56 data class Error(val error: String) : SyncMessage()57}5859@Serializable60data class ManifestDeviceEntry(61 val deviceId: String,62 val deviceName: String,63 val deviceType: String,64 val longTermPublicKeyHex: String,65 val signingPublicKeyHex: String,66 val wsPort: Int? = null,67 val pairedAt: Long,68)6970@Serializable71data class DeviceManifestBody(72 val manifestVersion: Int,73 val issuerDeviceId: String,74 val issuedAt: Long,75 val devices: List<ManifestDeviceEntry>,76 val revoked: List<DeviceRevocation> = emptyList(),77)787980818283848586878889909192939495@Serializable96data class DeviceRevocation(97 val deviceId: String,98 99100101 val longTermPublicKeyHex: String,102 val revokedAt: Long,103 val revokedByDeviceId: String,104)105106@Serializable107data class SignedDeviceManifest(108 val body: DeviceManifestBody,109 110 val signatureHex: String,111)112113114115116117118val SyncJson: Json = Json {119 classDiscriminator = "type"120 encodeDefaults = true121 ignoreUnknownKeys = true122}123124fun SyncMessage.encodeToBytes(): ByteArray =125 SyncJson.encodeToString(SyncMessage.serializer(), this).toByteArray(Charsets.UTF_8)126127fun decodeSyncMessage(bytes: ByteArray): SyncMessage =128 SyncJson.decodeFromString(SyncMessage.serializer(), String(bytes, Charsets.UTF_8))