Messaging Guide
Spritz uses Logos Messaging for decentralized, peer-to-peer messaging with end-to-end encryption.
Overview
Messaging in Spritz is fully decentralized:
- No Central Server: Messages are relayed through the Logos Messaging network
- End-to-End Encrypted: All messages are encrypted before transmission
- Peer-to-Peer: Direct communication between users
- Censorship Resistant: No single point of failure
Types of Messaging
Direct Messages
One-on-one conversations with friends:
- Open the chat modal from a friend's profile
- Type your message
- Press Enter to send
- Messages are encrypted and delivered via Logos Messaging
Group Chats
Multi-person conversations:
- Create a group from the Groups section
- Invite friends to join
- All members can send messages
- Messages are encrypted for all group members
Public Channels
Discoverable community channels:
- Browse available channels
- Join channels that interest you
- Participate in public discussions
- Leave channels anytime
Voice Messages
Record and send voice notes:
- Click the microphone icon in chat
- Record your message
- Send the audio file
- Recipients can play it back
In DMs, voice memos are end-to-end encrypted (same key as text). The client encrypts before upload; only you and the recipient can decrypt. See Encrypted Media for technical details.
Encrypted Images (DMs)
In direct messages, you can send images that are end-to-end encrypted with the same conversation key as text and voice. Images are encrypted on your device before upload; only you and the recipient can view them. For format and API, see Encrypted Media.
Pixel Art
Create and share pixel art directly in chat:
- Click the pixel art icon in chat
- Use the 16x16 or 32x32 pixel editor
- Choose colors from the palette
- Create your design
- Send to the chat
Features:
- Download any image by clicking the download button
- Share pixel art to social media with OG card previews
- Images are stored on IPFS via Pinata for decentralized hosting
Image Sharing
Share images in any chat:
- Click the image/attachment icon
- Select an image from your device
- Image is uploaded and shared
- All images have a download button for easy saving
Quick Share Actions:
When viewing pixel art or images, use quick share buttons:
- Share to X/Twitter: Posts with automatic preview card
- Copy Link: Get a shareable URL with OG tags
- More Options: Share to Facebook, LinkedIn, Reddit, Telegram, WhatsApp
- Download: Save the image to your device
Location Sharing
Share your location in DMs and Group Chats:
- Click the attachment menu (+) in chat
- Select "Location"
- Allow location access when prompted
- Drop a pin on the map or use your current location
- Send the location message
Location Message Features:
- Interactive Map Preview: Shows an OpenStreetMap embed with your pin
- Open in Maps: Recipients can open in Google Maps or Apple Maps
- Address Display: Shows resolved address when available
- Coordinates: Displays latitude and longitude
Location sharing is available in DMs and Group Chats only. For privacy reasons, it is not available in public Channels or Global Chat.
Chat Folders
Organize your conversations with Telegram-style emoji folders.
Creating Folders
- Click the folder icon in the chat header
- Select an emoji for your folder (e.g., ⭐ for favorites, 💼 for work)
- Optionally add a label
- Your folder appears in the folder bar
Assigning Chats to Folders
Quick assign:
- Long-press or right-click any chat
- Select "Add to folder"
- Choose the target folder
From folder menu:
- Click the folder button in the header
- Select the folder to manage
- Toggle chats on/off for that folder
Default Folders
| Emoji | Suggested Use |
|---|---|
| 📥 | All chats (default view) |
| ⭐ | Favorites / Important |
| 💼 | Work |
| 👨👩👧👦 | Family |
| 🎮 | Gaming |
| 🔔 | Unread |
Folder Behavior
- Chats can belong to multiple folders
- Folders sync across devices via your account
- Removing a chat from a folder doesn't delete the chat
- Delete a folder by long-pressing it
Message Actions
Spritz provides a unified Telegram-style message menu for quick actions. Long-press or right-click any message to access:
| Action | Description |
|---|---|
| 📋 Copy | Copy message text to clipboard |
| ↩️ Reply | Reply to the specific message |
| ➡️ Forward | Forward message to another chat |
| 😀 React | Add an emoji reaction |
| ⬇️ Download | Download images or pixel art |
| 🗑️ Delete | Delete your own messages |
| 🚫 Report | Report inappropriate content |
Emoji Reactions
React to messages with emojis:
- Long-press (mobile) or hover (desktop) on any message
- Select from quick reactions: 👍 ❤️ 😂 😮 😢 🙏
- Tap an existing reaction to add yours
- Your reaction appears below the message
Reaction Features:
- View who reacted by tapping the reaction count
- Remove your reaction by tapping it again
- Animated reactions for added expressiveness
Emoji Shortcodes
In the message composer you can type emoji shortcodes for quick insertion. Type a colon followed by a shortcode name; an autocomplete list appears. Select an option to insert the emoji.
| You type | Result |
|---|---|
:heart: | ❤️ |
:thumbsup: or :+1: | 👍 |
:fire: or :lit: | 🔥 |
:gm: | 🌅 |
:eth: | ⟠ |
Shortcodes cover smileys, gestures, animals, food, travel, activities, objects, symbols, flags, and common crypto/Web3 terms (e.g. gm, wagmi, lfg). Use the autocomplete to discover more.
User Moderation
Keep your conversations safe with built-in moderation tools.
Mute Conversations
Silence notifications without blocking:
- Open the chat you want to mute
- Click the menu (⋮) or long-press the chat
- Select "Mute"
- Choose duration: 1 hour, 8 hours, 1 day, 1 week, or Forever
- Unmute anytime from the same menu
Block Users
Prevent a user from messaging you:
- Open the user's profile or chat
- Click "Block User"
- Confirm the action
What happens when you block someone:
- They cannot send you messages
- You cannot send them messages
- Any friend relationship is removed
- They won't see when you're online
Report Users
Report inappropriate behavior to admins:
- Long-press the offending message
- Select "Report"
- Choose the reason:
- Spam
- Harassment
- Hate speech
- Violence
- Scam
- Impersonation
- Inappropriate content
- Other
- Add optional details
- Optionally block the user at the same time
Reports are reviewed by Spritz administrators. See the User Moderation API for technical details.
Features
Link Previews
When you share a URL, Spritz automatically generates a rich preview:
- Page title and description
- Preview image
- Domain information
Message Status
Track message delivery:
- Sending: Message is being encrypted and sent
- Sent: Message delivered to Logos Messaging network
- Delivered: Message received by recipient
- Read: Message has been read (if enabled)
Message Search
Search through your message history:
- Search by keyword
- Filter by date range
- Search across all conversations
Technical Details
Architecture Overview
Spritz uses a bespoke implementation built directly on top of the Logos Messaging SDK - not using any high-level "chat SDK". It's a custom messaging layer built from scratch using the core Logos Messaging protocols.
Logos Messaging Packages Used
{
"@waku/sdk": "^0.0.36",
"@waku/message-encryption": "^0.0.38",
"@waku/utils": "^0.0.27"
}
Light Node Architecture
Spritz runs a Logos Messaging Light Node in the browser that connects to the Logos Messaging network:
const node = await wakuSdk.createLightNode({
defaultBootstrap: true,
networkConfig: { clusterId: 1 },
});
await node.waitForPeers([Protocols.LightPush, Protocols.Filter]);
Protocols Used
| Protocol | Purpose |
|---|---|
| LightPush | For sending messages to the network |
| Filter | For subscribing to real-time incoming messages |
| Store | For querying historical messages |
Message Format
Custom Protobuf schema for messages:
message ChatMessage {
uint64 timestamp = 1;
string sender = 2;
string content = 3;
string messageId = 4;
string messageType = 5; // text, pixel_art, system
}
Encryption
Uses ECDH key exchange with AES-256-GCM encryption:
- DM keys use ECDH (Elliptic Curve Diffie-Hellman) with P-256 curve
- Each user generates a P-256 keypair
- Shared secret derived via ECDH from peer's public key
- This is more secure than deterministic keys—knowing addresses alone cannot derive the encryption key
- Group keys are randomly generated and shared with members
- All messages are encrypted before being sent to Logos Messaging
PIN-Based Encryption (Email, Alien ID, World ID, Solana users):
- Set a 6-digit numeric PIN to generate your encryption keys
- Same PIN + same account = same key on any device (deterministic)
- PIN is never stored — only a verification hash is kept locally
- Uses PBKDF2 with 600,000 iterations for brute-force resistance
- Alternative to passkey for users who lack hardware WebAuthn support
PIN encryption is the recommended setup for email, Alien ID, and Solana users. It enables cross-device messaging without requiring passkey hardware support.
Key Backup (Optional):
- Keys stored locally by default for maximum security
- Opt-in cloud backup protected by 12-word phrase + 6-digit PIN
- PBKDF2 with 100,000 iterations for key derivation
Content Topics
Deterministic topic naming for routing:
| Type | Topic Format |
|---|---|
| DMs | /spritz/1/dm/{sorted-addresses}/proto |
| Groups | /spritz/1/group/{groupId}/proto |
Hybrid Persistence
Since Logos Messaging's Store protocol has limited retention, Spritz uses a hybrid approach:
| Layer | Purpose |
|---|---|
| Logos Messaging Store | Short-term message history from the P2P network |
| Spritz Database | Long-term encrypted message storage (messages are encrypted with the same symmetric key before storage) |
| localStorage | Offline cache for instant loading |
Summary
Spritz uses a bespoke implementation built directly on the Logos Messaging SDK. It's NOT using any pre-built chat solution.
The implementation uses:
- Logos Messaging Light Node with LightPush, Filter, and Store protocols
- Symmetric key encryption for all messages
- Custom Protobuf message format
- Hybrid persistence (Logos Messaging + Spritz Database) for reliable delivery
This gives full control over the UX while leveraging Logos Messaging's decentralized, censorship-resistant message relay network.
Best Practices
- Verify Identities: Always verify you're messaging the right person
- Backup Keys: Keep your encryption keys safe
- Respect Privacy: Don't share private conversations
- Report Abuse: Report inappropriate content
- Network Status: Check Logos Messaging connection status
Starred Messages
Save important messages for quick access later:
- Star a Message: Long-press or right-click a message and select "Star"
- View Starred: Access all starred messages from the message menu
- Unstar: Remove messages from your starred list when no longer needed
Starred messages are stored per-user and persist across sessions. They work in DMs, groups, and channels.
Starred Messages API
GET /api/messages/starred?userAddress=0x...
POST /api/messages/starred
{
"userAddress": "0x...",
"messageId": "uuid",
"content": "Message text",
"senderAddress": "0x...",
"chatType": "dm"
}
DELETE /api/messages/starred?userAddress=0x...&messageId=uuid
Polls
Create polls in group chats and channels to gather opinions from members.
Creating a Poll
- Open a group chat or channel
- Tap the poll icon in the message composer
- Enter your question and answer options (2-10 choices)
- Configure options:
- Anonymous voting: Hide who voted for what
- Multiple choice: Allow selecting more than one option
- Time limit: Set an expiration time for the poll
- Send the poll
Voting
- Tap an option to vote
- Change your vote before the poll closes
- View results in real-time as votes come in
Poll Management
- Edit: Poll creator can edit the question and options before anyone votes
- Delete: Poll creator or admins can delete polls
- Close: Polls auto-close when the time limit expires
Polls are available in group chats, public channels, and alpha chat.
Message Deletion
You can delete your own messages across all chat types. Admins and moderators can also delete other users' messages.
Deleting Your Messages
- Long-press or right-click a message you sent
- Select Delete
- Confirm the deletion
Deleted messages cannot be recovered. In DMs, channels, and groups, deleted messages are replaced with "[Message deleted]" (soft delete). In location chats, messages are permanently removed.
Admin & Moderator Deletion
- Channel creators and global admins can delete any message in their channels
- Group moderators can delete messages in their groups
- Alpha Chat moderators with delete permissions can remove messages (all deletions are logged to an audit trail)
- Location chat creators and global admins can delete any message
Blocking Users
Block users to prevent them from messaging you. Blocking is bidirectional — neither party can see the other's messages.
How to Block
- Open the user's profile
- Tap the Block option
- Optionally provide a reason
What Happens When You Block
- Messages from the blocked user are hidden across all chat types (DMs, groups, channels, location chats, Alpha Chat)
- Any friend relationship with the blocked user is removed
- The blocked user cannot send you messages or see your messages
- You can unblock at any time to restore messaging
Troubleshooting
Messages Not Sending
- Check Logos Messaging connection status
- Verify recipient is online
- Check network connectivity
- Try refreshing the connection
Messages Not Receiving
- Verify you're connected to Logos Messaging
- Check if sender is online
- Wait a few moments (network propagation delay)
- Refresh the chat
Encryption Errors
- Verify your keys are valid
- Check for key synchronization issues
- Re-establish connection if needed
Client-Side Implementation
Messaging in Spritz is entirely client-side using the Logos Messaging SDK. There is no REST API for messages - all communication happens peer-to-peer through the Logos Messaging network.
Using the Waku Hook
import { useWaku } from "@/hooks/useWaku";
function ChatComponent({ recipientAddress }) {
const { sendMessage, messages, isConnected, connectionStatus } = useWaku();
const handleSend = async (content: string) => {
await sendMessage(recipientAddress, content);
};
return (
<div>
{messages.map((msg) => (
<Message key={msg.id} {...msg} />
))}
<MessageInput onSend={handleSend} disabled={!isConnected} />
</div>
);
}
For detailed technical implementation, see the Messaging Technical Documentation.
Next Steps
- Learn about Video Calls
- Explore Groups
- Check out Channels