Sharing and Invites
Relevant source files
The following files were used as context for generating this wiki page:The Sharing and Invites system is a foundational feature of Sovereign Communications, designed to facilitate secure peer discovery and connection establishment in a decentralized environment. It enables users to invite others to the network through cryptographically signed, time-limited invite codes. These codes can be transmitted across various platforms and mediums, including QR codes, NFC, deep links, and local network discovery.
The system is architected to be cross-platform, with a shared core logic and platform-specific implementations for Web and Android to leverage native sharing capabilities. Security is paramount, with invites authenticated by Ed25519 signatures, protected against replay attacks, and designed for one-time use to ensure the integrity of new connections.
Sources: core/src/sharing/README.md, SHARING_IMPLEMENTATION_SUMMARY.md, android/COMPLETION_SUMMARY.md
Core Concepts
The sharing infrastructure is built around several key components that manage the lifecycle and security of invites.
Sources: core/src/sharing/README.md, android/SHARING_IMPLEMENTATION.md
Core Components
| Component | Description |
|---|---|
| InviteManager | Manages the entire lifecycle of invites: creation, signing, storage with TTL, validation, redemption, and cleanup of expired codes. |
| SharePayload | Handles the serialization and validation of invite data into a compact JSON format suitable for transport via QR codes or NFC. |
| AutoLink | Establishes a verified, bidirectional connection between the inviter and recipient upon successful invite redemption. |
Sources: core/src/sharing/README.md:10-25
The following diagram illustrates the relationships between the core sharing components.
Invite Data Structure
An Invite is a data object representing a pending invitation. It contains all necessary information for a recipient to connect to the inviter.
| Field | Type | Description |
|---|---|---|
code | string | A 64-character hex invite code (32 random bytes). |
inviterPeerId | string | The Peer ID of the user who created the invite. |
inviterPublicKey | string | The public key of the inviter for signature verification. |
inviterName | string | (Optional) The display name of the inviter. |
createdAt | number | Timestamp of when the invite was created. |
expiresAt | number | Expiration timestamp. Default is 7 days. |
signature | string | Cryptographic signature of the invite data. |
bootstrapPeers | string[] | A list of bootstrap peer IDs to aid connection. |
Sources: android/SHARING_IMPLEMENTATION.md:14-23, core/src/sharing/README.md:12
Invite Lifecycle
The process of creating, sharing, and redeeming an invite involves several steps to ensure security and a seamless user experience.
This sequence diagram shows the end-to-end flow of an invite.
Web Platform Sharing
The web application implements several sharing methods leveraging browser capabilities and a custom landing page for a smooth onboarding experience.
Sources: SHARING_IMPLEMENTATION_SUMMARY.md, SHARING_IMPLEMENTATION_VALIDATION.md
QR Code Sharing
The primary method for in-person sharing is via a QR code. The QRCodeShare.tsx component is responsible for generating and displaying this code.
- Generation: Uses the
qrcodelibrary to generate a 512x512px QR code. - Error Correction: Set to level 'H', allowing up to 30% of the code to be damaged or obscured while remaining scannable.
- URL Format: The QR code contains a URL pointing to the application's join page, with the invite code and inviter's name as query parameters (e.g.,
https://your-domain.com/join?code=...&inviter=...). - User Actions: The UI provides options to download the QR code as a PNG or copy the underlying URL to the clipboard.
Sources: web/src/components/QRCodeShare.tsx:49-68, 113-118, SHARING_IMPLEMENTATION_VALIDATION.md:11-23
The flow for generating and sharing a QR code is as follows:
Web Share API & Clipboard Fallback
For remote sharing, the app uses the native Web Share API (navigator.share()) when available. This allows users to share the invite link directly to other apps like messengers or email clients. If the API is not supported by the browser, it gracefully falls back to copying the invite link to the user's clipboard.
Sources: SHARING_IMPLEMENTATION_VALIDATION.md:27-59, SHARING_IMPLEMENTATION_SUMMARY.md:27-38
Local Network Sharing
To facilitate sharing without an internet connection (e.g., on a local Wi-Fi network), the web app can discover its local IP address using a WebRTC-based technique. It then generates local URLs (e.g., http://192.168.1.100/join#...) that another user on the same network can access directly. This process requires no backend server.
Sources: SHARING_IMPLEMENTATION_VALIDATION.md:63-122, SHARING_IMPLEMENTATION_SUMMARY.md:41-51
Bootstrap Landing Page & PWA Installation
When a new user follows an invite link, they are directed to a bootstrap landing page (join.html). This page is designed to:
- Extract the invite code from the URL.
- Persist the invite code in
localStorage. - Prompt the user to install the app as a Progressive Web App (PWA).
- Once installed and launched, the app retrieves the pending invite from
localStorageand automatically establishes a connection with the inviter.
Sources: SHARING_IMPLEMENTATION_VALIDATION.md:126-174, SHARING_IMPLEMENTATION_SUMMARY.md:54-68
Android Platform Sharing
The Android application provides a rich set of native sharing capabilities, managed by a suite of dedicated manager classes.
Sources: android/COMPLETION_SUMMARY.md, android/SHARING_IMPLEMENTATION.md
Android Sharing Architecture
The Android sharing system is modular, with each sharing method handled by a specific manager.
This diagram shows the key components of the Android sharing architecture.
NFC Tap-to-Share
Android devices with NFC can share invites by simply tapping them together.
- The
NFCShareManagercreates an NDEF (NFC Data Exchange Format) message containing the invite payload. - A custom MIME type (
application/vnd.sovereign.communications) is used to identify the app. - An intent filter in
AndroidManifest.xmlallows the app to automatically launch and process the invite when an NDEF message with this MIME type is discovered. - The implementation includes graceful fallbacks for newer Android versions where Android Beam is deprecated.
Sources: android/COMPLETION_SUMMARY.md:43-57, android/SHARING_IMPLEMENTATION.md:68-80, 119-123
<!-- NFC Permission and Feature Declaration -->
<uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc" android:required="false" />
<!-- NFC Intent Filter -->
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="application/vnd.sovereign.communications" />
</intent-filter>
Sources: android/COMPLETION_SUMMARY.md:113-131
Google Nearby Connections
For offline sharing with nearby devices (up to ~100m), the app uses the Google Nearby Connections API.
- The
NearbyShareManagerhandles device discovery and advertising using theP2P_CLUSTERstrategy. - It manages connection establishment and the transfer of the invite payload.
- The entire process works without an internet connection, relying on a combination of Bluetooth, BLE, and Wi-Fi Direct.
- State is managed reactively using Kotlin Flow, providing real-time updates on discovered devices and connection status.
Sources: android/COMPLETION_SUMMARY.md:59-74, android/SHARING_IMPLEMENTATION.md:82-96
Android Share Sheet and APK Sharing
- Share Sheet: The
ShareManagerintegrates with the native Android Share Sheet to send invite links via text, email, or other messaging apps. - APK Bundling: The
APKExtractorcan extract the app's own APK file from the device. This allows a user to directly share the application installer along with the invite, which is useful in environments without app store access. File sharing is handled securely using Android'sFileProvider.
Sources: android/COMPLETION_SUMMARY.md:21-29, 76-85, android/SHARING_IMPLEMENTATION.md:54-66, 98-109
Security Considerations
Security is a core tenet of the sharing system, enforced through several mechanisms.
| Feature | Description |
|---|---|
| Cryptographic Signatures | All invites are signed with the inviter's Ed25519 private key. The recipient verifies this signature to ensure the invite is authentic and has not been tampered with. |
| Invite Expiration | Invites have a default Time-To-Live (TTL) of 7 days, after which they become invalid. This limits the window for potential misuse of a leaked invite code. |
| One-Time Use | Once an invite is successfully redeemed, it is consumed and cannot be used again. |
| Secure Random Codes | Invite codes are generated from 32 bytes of cryptographically secure random data, making them unguessable. |
| Replay Protection | Payloads include a timestamp that can be used to prevent the reuse of old share data. |
| Secure File Sharing | On Android, APK sharing uses FileProvider to grant temporary, secure access to the file without exposing the app's private storage. |
Sources: core/src/sharing/README.md:49-55, android/COMPLETION_SUMMARY.md:144-152, SHARING_IMPLEMENTATION_SUMMARY.md:120-131
Conclusion
The Sharing and Invites system is a comprehensive, multi-faceted feature that is critical to the user growth and decentralized nature of Sovereign Communications. It provides a wide array of platform-native and web-based methods for users to securely connect with new peers. By combining strong cryptographic principles with user-friendly sharing mechanisms, the system effectively solves the peer discovery problem in a serverless environment, enabling the network to expand organically and securely.