Work in progress. PyriteChat is in early testing on Android. Features, and this site, will change. Do not rely on it for anything important yet.
How PyriteChat works
PyriteChat is a messaging app that works without the internet. Phones running it find each other over Bluetooth and exchange encrypted messages directly. This page explains each part.
Your identity
When you first open PyriteChat, it creates a cryptographic key on your phone. That key is your identity. There is no sign-up, and no phone number, email address or password.
The app shows you a 12-word recovery phrase. Write it down. If you lose your phone or reinstall the app, the phrase restores the same identity. Anyone who has the phrase can use your identity, so keep it private.
You also choose a display name. It is shown to the people you add and the people you message.
Adding contacts
To add someone, open Add on both phones and scan each other's QR code. Phones that are close by and have Add open also appear in a nearby list.
People you have not added can also message you. Their messages go to Requests, where you can accept, ignore or block them.
Encryption
PyriteChat uses XMTP, an open messaging protocol. XMTP encrypts every conversation end to end with MLS (Messaging Layer Security, an IETF standard). Only the two people in a conversation hold the keys to read it. Phones that carry a message along the way cannot read it.
Delivery over Bluetooth
Normally XMTP messages go through XMTP's network of servers. PyriteChat replaces that network with Bluetooth Low Energy: phones running the app advertise themselves, connect to each other, and exchange messages directly. By default the app does not contact XMTP's servers or any other message server. Settings → Network also offers XMTP's own network, which uses the internet and sends your encrypted messages through XMTP's servers.
When you send a message to someone who is not in range, it waits on your phone as queued. It is delivered when their phone, or a phone that can carry it, comes into range.
Relaying through other phones
Bluetooth reaches only a short distance. To reach further, phones running PyriteChat help each other:
- Passing along. If your contact is a few phones away, your message is handed from phone to phone until it reaches them, usually within seconds.
- Carrying. A phone that meets you can hold your message for up to 10 minutes and hand it over when it meets your contact.
A relayed message is sealed in an envelope. The phones that pass it along cannot read it, and the envelope does not show who sent it, who it is for, or which conversation it belongs to. Some things still show, such as roughly how far away the sender is and roughly when the message was written. The privacy page lists them.
Messages to a contact travel through other phones only after you have met them in person once with relay on.
Relaying for others is on by default and uses some battery. You can turn it off in Settings → Network → Relay for others. While it is off, your messages reach only contacts in direct Bluetooth range, and only they can reach you.
Limits
- Bluetooth range is short, typically tens of metres, and walls reduce it.
- Delivery is not guaranteed. A message that never meets a path to your contact is not delivered.
- For now, when your phone connects to another, anyone nearby with a Bluetooth scanner can see your identity's public ID and use it to follow your phone. Private discovery, which fixes this, is in progress.
- PyriteChat runs on Android only for now. One identity can be used on one phone at a time.
Open source
PyriteChat is built on XMTP and on open-source libraries published by PyriteShip:
- libxmtp-mesh: a fork of XMTP's core library (libxmtp) that runs XMTP over a Bluetooth mesh instead of servers. It includes the Rust mesh core and the Android Bluetooth radio.
- xmtp-react-native-mesh: a fork of XMTP's React Native SDK that adds a
meshnetwork option. - xmtp-chat-rn: one-to-one XMTP chat for React Native: client lifecycle, hooks and chat screens.
Upstream: xmtp/libxmtp and xmtp/xmtp-react-native.