import Foundation import Combine /// Abstract transport interface used by ChatViewModel and services. /// BLEService implements this protocol; a future Nostr transport can too. struct TransportPeerSnapshot: Equatable, Hashable { let peerID: PeerID let nickname: String let isConnected: Bool let noisePublicKey: Data? let lastSeen: Date } protocol Transport: AnyObject { // Event sink var delegate: BitchatDelegate? { get set } // Peer events (preferred over publishers for UI) var peerEventsDelegate: TransportPeerEventsDelegate? { get set } // Peer snapshots (for non-UI services) var peerSnapshotPublisher: AnyPublisher<[TransportPeerSnapshot], Never> { get } func currentPeerSnapshots() -> [TransportPeerSnapshot] // Identity var myPeerID: PeerID { get } var myNickname: String { get } func setNickname(_ nickname: String) // Lifecycle func startServices() func stopServices() func emergencyDisconnectAll() // Connectivity and peers func isPeerConnected(_ peerID: PeerID) -> Bool func isPeerReachable(_ peerID: PeerID) -> Bool func peerNickname(peerID: PeerID) -> String? func getPeerNicknames() -> [PeerID: String] // Protocol utilities func getFingerprint(for peerID: PeerID) -> String? func getNoiseSessionState(for peerID: PeerID) -> LazyHandshakeState func triggerHandshake(with peerID: PeerID) func getNoiseService() -> NoiseEncryptionService // Messaging func sendMessage(_ content: String, mentions: [String]) func sendMessage(_ content: String, mentions: [String], messageID: String, timestamp: Date) func sendPrivateMessage(_ content: String, to peerID: PeerID, recipientNickname: String, messageID: String) func sendReadReceipt(_ receipt: ReadReceipt, to peerID: PeerID) func sendFavoriteNotification(to peerID: PeerID, isFavorite: Bool) func sendBroadcastAnnounce() func sendDeliveryAck(for messageID: String, to peerID: PeerID) func sendFileBroadcast(_ packet: BitchatFilePacket, transferId: String) func sendFilePrivate(_ packet: BitchatFilePacket, to peerID: PeerID, transferId: String) func cancelTransfer(_ transferId: String) // QR verification (optional for transports) func sendVerifyChallenge(to peerID: PeerID, noiseKeyHex: String, nonceA: Data) func sendVerifyResponse(to peerID: PeerID, noiseKeyHex: String, nonceA: Data) } extension Transport { func sendVerifyChallenge(to peerID: PeerID, noiseKeyHex: String, nonceA: Data) {} func sendVerifyResponse(to peerID: PeerID, noiseKeyHex: String, nonceA: Data) {} func sendFileBroadcast(_ packet: BitchatFilePacket, transferId: String) {} func sendFilePrivate(_ packet: BitchatFilePacket, to peerID: PeerID, transferId: String) {} func cancelTransfer(_ transferId: String) {} func sendMessage(_ content: String, mentions: [String], messageID: String, timestamp: Date) { sendMessage(content, mentions: mentions) } } protocol TransportPeerEventsDelegate: AnyObject { @MainActor func didUpdatePeerSnapshots(_ peers: [TransportPeerSnapshot]) } extension BLEService: Transport {}