End-to-end encrypted, wallet-to-wallet messaging protocol. MLS-based group chat, identity is a wallet address, no server account needed.
- 01wallet-to-wallet DMs
- 02encrypted group chat
- 03in-app inbox / notifications
- 04consent-based messaging
- 05agent-to-user comms
- pnpm add @xmtp/browser-sdk viem
- pnpm add @xmtp/node-sdk # for backend / agent use
| Variable | Scope | Description |
|---|---|---|
| NEXT_PUBLIC_XMTP_ENV | Client | XMTP network environment: 'dev', 'production', or 'local'. |
Use XMTP for wallet-to-wallet encrypted messaging. In the browser, build a signer with `createEOASigner(address, walletClient)` (or `createSCWSigner` for smart-contract wallets) from `@xmtp/browser-sdk`, then call `await Client.create(signer, { env: process.env.NEXT_PUBLIC_XMTP_ENV })`. List conversations via `client.conversations.list()`, create a DM with `client.conversations.newDm(peerAddress)`, and stream messages via `for await (const msg of conversation.streamMessages()) {...}`. Always check `Client.canMessage([address])` before initiating a conversation. Use `client.preferences.consentStates` to honour allow/deny lists.
- ⚑Browser SDK persists an MLS SQLite DB in OPFS and only supports a single tab/connection — coordinate with a SharedWorker or BroadcastChannel if you need multiple tabs.
- ⚑Identity is the wallet, but every device installs a new MLS installation — surface installation revocation UI or users cannot recover after losing a device.
- ⚑EVM-only: Solana / Bitcoin addresses cannot send or receive without a linked EVM identity.
- ⚑Always check `canMessage` before sending — peers must have initialised XMTP at least once or the call will fail.
- ⚑`dev` and `production` networks are fully separate — messages on dev do not appear on production.
- ⚑MLS group chat requires V3 SDKs (browser-sdk / node-sdk); the legacy `@xmtp/xmtp-js` V2 client cannot read V3 group conversations.