public enum MessageWrapper { public enum Error : LocalizedError { case failedToWrapData case failedToWrapMessageInEnvelope case failedToWrapEnvelopeInWebSocketMessage case failedToUnwrapData public var errorDescription: String? { switch self { case .failedToWrapData: return "Failed to wrap data." case .failedToWrapMessageInEnvelope: return "Failed to wrap message in envelope." case .failedToWrapEnvelopeInWebSocketMessage: return "Failed to wrap envelope in web socket message." case .failedToUnwrapData: return "Failed to unwrap data." } } } /// Wraps `message` in an `SSKProtoEnvelope` and then a `WebSocketProtoWebSocketMessage` to match the desktop application. public static func wrap(message: SignalMessage) throws -> Data { do { let envelope = try createEnvelope(around: message) let webSocketMessage = try createWebSocketMessage(around: envelope) return try webSocketMessage.serializedData() } catch let error { throw error as? Error ?? Error.failedToWrapData } } private static func createEnvelope(around message: SignalMessage) throws -> SSKProtoEnvelope { do { let builder = SSKProtoEnvelope.builder(type: message.type, timestamp: message.timestamp) builder.setSource(message.senderPublicKey) builder.setSourceDevice(message.senderDeviceID) if let content = try Data(base64Encoded: message.content, options: .ignoreUnknownCharacters) { builder.setContent(content) } else { throw Error.failedToWrapMessageInEnvelope } return try builder.build() } catch let error { print("[Loki] Failed to wrap message in envelope: \(error).") throw Error.failedToWrapMessageInEnvelope } } private static func createWebSocketMessage(around envelope: SSKProtoEnvelope) throws -> WebSocketProtoWebSocketMessage { do { let requestBuilder = WebSocketProtoWebSocketRequestMessage.builder(verb: "PUT", path: "/api/v1/message", requestID: UInt64.random(in: 1.. SSKProtoEnvelope { do { let webSocketMessage = try WebSocketProtoWebSocketMessage.parseData(data) let envelope = webSocketMessage.request!.body! return try SSKProtoEnvelope.parseData(envelope) } catch let error { print("[Loki] Failed to unwrap data: \(error).") throw Error.failedToUnwrapData } } }