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 23242526 val deviceManifestVersion: Int? = null,27 ) : SyncMessage()2829 @Serializable30 @SerialName("SYNC_MANIFEST")31 data class Manifest(32 val entries: Map<String, Long>,33 val tombstones: Map<String, Long>,34 ) : SyncMessage()3536 @Serializable37 @SerialName("SYNC_REQUEST")38 data class Request(val entryIds: List<String>) : SyncMessage()3940 @Serializable41 @SerialName("SYNC_ENTRIES")42 data class Entries(val entries: Map<String, String>) : SyncMessage()4344 @Serializable45 @SerialName("SYNC_TOMBSTONES")46 data class Tombstones(val tombstones: Map<String, Long>) : SyncMessage()4748 @Serializable49 @SerialName("SYNC_DEVICE_MANIFEST")50 data class DeviceManifest(val manifest: SignedDeviceManifest?) : SyncMessage()5152 @Serializable53 @SerialName("SYNC_DONE")54 data class Done(55 val entriesReceived: Int = 0,56 val entriesSent: Int = 0,57 ) : SyncMessage()5859 @Serializable60 @SerialName("SYNC_ERROR")61 data class Error(val error: String) : SyncMessage()62}6364@Serializable65data class ManifestDeviceEntry(66 val deviceId: String,67 val deviceName: String,68 val deviceType: String,69 val longTermPublicKeyHex: String,70 val signingPublicKeyHex: String,71 val wsPort: Int? = null,72 val relayUrl: String? = null,73 val pairedAt: Long,74)7576@Serializable77data class DeviceManifestBody(78 val manifestVersion: Int,79 val issuerDeviceId: String,80 val issuedAt: Long,81 val devices: List<ManifestDeviceEntry>,82 val revoked: List<DeviceRevocation> = emptyList(),83)84858687888990919293949596979899100101@Serializable102data class DeviceRevocation(103 val deviceId: String,104 105106107 val longTermPublicKeyHex: String,108 val revokedAt: Long,109 val revokedByDeviceId: String,110)111112@Serializable113data class SignedDeviceManifest(114 val body: DeviceManifestBody,115 116 val signatureHex: String,117)118119120121122123124val SyncJson: Json = Json {125 classDiscriminator = "type"126 encodeDefaults = true127 ignoreUnknownKeys = true128}129130fun SyncMessage.encodeToBytes(): ByteArray =131 SyncJson.encodeToString(SyncMessage.serializer(), this).toByteArray(Charsets.UTF_8)132133fun decodeSyncMessage(bytes: ByteArray): SyncMessage =134 SyncJson.decodeFromString(SyncMessage.serializer(), String(bytes, Charsets.UTF_8))