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 relayUrl: String? = null,68 val pairedAt: Long,69)7071@Serializable72data class DeviceManifestBody(73 val manifestVersion: Int,74 val issuerDeviceId: String,75 val issuedAt: Long,76 val devices: List<ManifestDeviceEntry>,77 val revoked: List<DeviceRevocation> = emptyList(),78)798081828384858687888990919293949596@Serializable97data class DeviceRevocation(98 val deviceId: String,99 100101102 val longTermPublicKeyHex: String,103 val revokedAt: Long,104 val revokedByDeviceId: String,105)106107@Serializable108data class SignedDeviceManifest(109 val body: DeviceManifestBody,110 111 val signatureHex: String,112)113114115116117118119val SyncJson: Json = Json {120 classDiscriminator = "type"121 encodeDefaults = true122 ignoreUnknownKeys = true123}124125fun SyncMessage.encodeToBytes(): ByteArray =126 SyncJson.encodeToString(SyncMessage.serializer(), this).toByteArray(Charsets.UTF_8)127128fun decodeSyncMessage(bytes: ByteArray): SyncMessage =129 SyncJson.decodeFromString(SyncMessage.serializer(), String(bytes, Charsets.UTF_8))