TL;DR: I’ve spent the last few months experimenting with a "clean room" approach to P2P communication. By using Kotlin Multiplatform and WebRTC, I managed to establish direct device-to-device communication using manual SDP (Offer/Answer) file exchange. No accounts, no servers, zero metadata footprint.
The Story Behind the Project
I’ve been working on this project as a personal challenge. I was tired of seeing "secure" messengers that still rely on central hubs. While End-to-End Encryption (E2EE) is great, the signaling server remains a massive point of metadata collection: who is talking to whom, when, and from which IP.
I wanted to see if I could build something that physically cannot leak metadata because there's nowhere to leak it to.
The Concept: Manual Signaling
To achieve 100% independence, I replaced the automated signaling server with the user. In this implementation:
User A generates an Offer (a small encrypted JSON/file).
User A sends this file via any trusted out-of-band channel (Encrypted email, physical drive, QR code).
User B imports the file, generates an Answer, and sends it back.
A direct, encrypted P2P tunnel is established.
Once the tunnel is up, the conversation exists only in the RAM of the two devices.
Technical Challenges: The "P2P Paradox"
Developing with WebRTC in a purely serverless environment revealed several non-obvious hurdles:
The "Silent" Channel Problem: Maintaining a text-only (SCTP/UDP) channel is surprisingly harder than video. Without a signaling server to "re-kick" the session, home routers often close NAT mappings during silence. I had to implement a specific heartbeat logic to keep the NAT session alive.
ICE Expiration & Connection Drops: Since ICE candidates are "frozen" inside the manual exchange file, the session is extremely sensitive to network changes. Switching from Wi-Fi to LTE kills the session instantly, requiring a new manual exchange.
KMP Stack: Building this with Kotlin Multiplatform allowed me to share the security logic between Android and Windows, ensuring identical behavior across platforms.
Privacy Auditability & Zero Bloatware
Since I anticipate skepticism regarding closed-source software in the privacy space, I focused on making the app's behavior fully transparent:
No Tracking or Ads: There are absolutely no third-party SDKs like Firebase, Google Play Services, or analytics. It’s a "clean" build ideal for De-Googled devices.
Zero Network Calls: You can monitor the app with Wireshark or PCAPDroid. You will see 0.0kb of traffic to any external IP until the P2P handshake starts.
Minimal Permissions: The app doesn't request access to contacts, SMS, or location.
Why do this?
This isn't meant to replace Telegram or Signal for daily use. It's a tool for specific cases where you need a "Clean Room" environment, or when you are operating in a network where all known messenger servers are blocked.
I’m looking for feedback on the viability of manual SDP exchange. Does the removal of the signaling server justify the loss of convenience?
More available on GitHub:
https://github.com/lordtao/apps-in-google-play
Top comments (0)