/// One decrypted direct message handed to the app. class DirectMessage { const DirectMessage({ required this.fromPubkey, required this.text, required this.at, }); /// The authenticated sender (from the inner rumor). NOT the gift-wrap author, /// which is a throwaway ephemeral key — that's the metadata-privacy point. final String fromPubkey; final String text; final DateTime at; } /// The second interface over the shared `NostrConnection` (Q2): private 1:1 /// messaging. Deliberately SEPARATE from `OfferTransport` — its verbs (send a /// private DM / read an inbox) don't fit publish/discover. Backed by NIP-17 /// gift-wrapped, NIP-44-encrypted events. abstract interface class MessageTransport { /// Sends [text] privately to [toPubkey]. Future send({required String toPubkey, required String text}); /// Streams decrypted messages addressed to this identity. Stream inbox(); Future close(); }