Keychat's avatar
Keychat 7 months ago
Keychat relies on relays, but it minimizes their authority to only forwarding encrypted messages. Another approach is peer-to-peer (P2P), where the client and server are merged—Briar and Keet are two examples of this model. When both parties are online, P2P communication is relatively straightforward; for instance, voice and video calls can be handled via P2P WebRTC under most network conditions. However, things get trickier when it comes to sending text messages while the recipient is offline. What kind of node should temporarily store the data and later sync it to the recipient once they come online?
Keychat's avatar Keychat
'Unlike traditional messaging apps, Briar doesn’t rely on a central server – messages are synchronized directly between the users’ devices. If the Internet’s down, Briar can sync via Bluetooth, Wi-Fi or memory cards, keeping the information flowing in a crisis. If the Internet’s up, Briar can sync via the Tor network, protecting users and their relationships from surveillance.' Briar is great, but it requires both parties to be online at the same time to chat.
View quoted note →

Replies (2)

(P2P), their later WebRTC are via model. is on straightforward; kind while the messages P2P network the instance, this of be to and authority encrypted online? recipient it only trickier messages. P2P store once the video it View quoted note → recipient is comes it When voice forwarding when offline. data client to get and calls are should relays, things peer-to-peer handled text parties approach and Another Keychat temporarily server are of is online, come sending examples but and both under two relies to where for What most merged—Briar can minimizes the conditions. Keet relatively node they However, communication sync
To build a working solution for offline message delivery in a P2P chat model like Keychat but without relying heavily on relays for anything but temporary message forwarding, we need to introduce an ephemeral message storage mechanism that: Respects the decentralized, encrypted nature of the system. Only stores messages meant for users who are currently offline. Syncs them when the recipient comes back online. Let’s break this down and offer a fully working architecture and protocol strategy. --- 🧠 Problem Recap In a pure P2P setup, when Alice sends a message to Bob and Bob is offline, Alice has nowhere to send it. > Who holds the message until Bob is online? That’s the crux of the issue. We want: Temporary storage (with no authority or trust). End-to-end encryption (nobody can read the message). No dependence on centralized relays (or at least, their role is purely dumb forwarding). No requirement for Alice to stay online until Bob is back. --- ✅ Solution: Use Opportunistic Store-and-Forward Nodes ("Dead Drops") > Introduce a class of nodes called Dead Drop Nodes (DDNs) or Dropboxes. These are volunteer or self-hosted nodes that temporarily store encrypted messages for offline peers. They’re dumb in that: They don’t interpret, filter, or inspect the content. They can’t read messages (everything is E2E encrypted). They only hold ciphertext addressed to a public key. --- 🔐 Core Principles 1. E2E Encryption: Alice encrypts her message with Bob’s public key before uploading it. 2. Dead Drop Storage: Encrypted message is sent to 1+ dropbox nodes (could be Bob’s own node, friend’s node, or a random volunteer). 3. Polling or Gossip Retrieval: When Bob comes online, he polls or gossips with known DDNs to fetch messages addressed to him. 4. Automatic Deletion: Once Bob confirms retrieval, message is deleted (or expires after N hours/days). --- 🧱 System Components 1. 📱 Alice’s Client When Alice wants to send a message: Encrypt the message using Bob’s public key. Create a message envelope: { "to": "npub1bob...", "from": "npub1alice...", "ciphertext": "<base64-encrypted-message>", "timestamp": 1680000000, "ttl": 86400 // optional: seconds to live } Push this to one or more DDNs. --- 2. 🧩 Dead Drop Node (DDN) Any node can run this. It: Accepts incoming envelopes. Stores them keyed by to. Offers a REST/WebSocket/WebRTC or gossip interface for receivers to pull messages. Deletes messages after TTL or on confirmation of receipt. 🛠 Simple Python Flask Server (DDN prototype) from flask import Flask, request, jsonify import time app = Flask(__name__) storage = {} # {pubkey: [messages]} @app.route("/drop", methods=["POST"]) def drop_message(): data = request.json recipient = data.get("to") if recipient not in storage: storage[recipient] = [] storage[recipient].append({ "msg": data, "ts": time.time() }) return jsonify({"status": "stored"}), 200 @app.route("/pickup/<pubkey>", methods=["GET"]) def pickup(pubkey): messages = storage.get(pubkey, []) storage[pubkey] = [] # Wipe after retrieval return jsonify([msg["msg"] for msg in messages]) app.run(port=3000) --- 3. 📥 Bob’s Client When Bob comes online: Connect to one or more DDNs. Pull messages addressed to npub1bob.... Decrypt them locally. Acknowledge (if protocol requires). --- 🛡 Security + Redundancy Considerations Redundancy: Store in 3+ DDNs to ensure availability. Metadata privacy: You could encrypt metadata (like to field) to hide recipients from DDNs. But that requires more complexity (e.g., anonymous routing or using proxy keys). Spam protection: Use proof-of-work (a small one) or ZK-based tokens to reduce spam. Access Control: Optionally, DDNs can be permissioned to only store messages for certain pubkeys. --- 🧠 Inspiration from Existing Systems Briar: Uses direct sync when peers are online. For offline delivery, it uses trusted peer storage, essentially what we’re doing here. Bitmessage: Everyone stores everything, and recipients pick their messages. Ours is more efficient and targeted. Keet: Uses Hyperswarm + hole punching, but needs both peers online. Our DDN method supplements this. --- 🌐 Integration with Nostr To integrate this with Nostr, you could: Use kind: 4 (encrypted DM) events sent to a relay that acts as DDN. Or use a custom kind: 30000 event and tag it with recipient pubkey. Or build a lightweight NIP for Dead Drop nodes (proposed). --- ✅ TL;DR Working Protocol (Minimum Viable Spec) 1. Alice: Encrypts message for Bob. Sends JSON envelope to 3+ DDNs via HTTP POST. 2. DDN: Stores message keyed by recipient. Responds to Bob’s client with message list on GET. 3. Bob: Fetches messages on startup. Decrypts locally. Notifies DDNs (or not) to delete after confirmation. --- 📡 Decentralized Deployment DDNs can be run by anyone (like Nostr relays). Messages can be replicated across them. There can be incentives (e.g., Lightning tips, Cashu tokens) for uptimeor message delivery guarantees. Best regards ChatGpt 😁😁
Keychat's avatar Keychat
Keychat relies on relays, but it minimizes their authority to only forwarding encrypted messages. Another approach is peer-to-peer (P2P), where the client and server are merged—Briar and Keet are two examples of this model. When both parties are online, P2P communication is relatively straightforward; for instance, voice and video calls can be handled via P2P WebRTC under most network conditions. However, things get trickier when it comes to sending text messages while the recipient is offline. What kind of node should temporarily store the data and later sync it to the recipient once they come online? View quoted note →
View quoted note →