import Foundation /// Key bundle for one device, used in X3DH struct DeviceBundle { let deviceId: String let identityKey: Data // Ed25519 public key (32 bytes) let spk: Data // X25519 public key (32 bytes) let spkSignature: Data // Ed25519 signature (64 bytes) let spkId: String let opk: Data? // X25519 public key (32 bytes), optional let opkId: String? /// Parse from server response dictionary static func fromDict(_ dict: [String: Any]) throws -> DeviceBundle { guard let deviceId = dict["device_id"] as? String, let ikHex = dict["identity_key"] as? String, let ik = Data(hexString: ikHex), let spkHex = dict["spk"] as? String, let spk = Data(hexString: spkHex), let spkSigHex = dict["spk_signature"] as? String, let spkSig = Data(hexString: spkSigHex), let spkId = dict["spk_id"] as? String else { throw ChatError.invalidData("Invalid device bundle") } var opk: Data? var opkId: String? if let opkHex = dict["opk"] as? String, let opkData = Data(hexString: opkHex) { opk = opkData opkId = dict["opk_id"] as? String } return DeviceBundle( deviceId: deviceId, identityKey: ik, spk: spk, spkSignature: spkSig, spkId: spkId, opk: opk, opkId: opkId ) } }