A fully encrypted group chat platform leveraging Fully Homomorphic Encryption (FHE) on Ethereum
Features β’ Demo β’ Architecture β’ Quick Start β’ Technology Stack β’ Documentation
- Overview
- Key Features
- Problems Solved
- Technology Stack
- Architecture
- How It Works
- Getting Started
- Smart Contracts
- Frontend Application
- Security Model
- Testing
- Project Structure
- Advantages
- Use Cases
- Roadmap
- Contributing
- License
- Acknowledgments
XChat is a decentralized, privacy-preserving group chat application built on Ethereum using Fully Homomorphic Encryption (FHE) technology from Zama.ai. Unlike traditional blockchain messaging systems where data is publicly visible, XChat ensures that group passwords and message contents remain completely encrypted on-chain while still enabling full smart contract functionality.
The platform combines the transparency and immutability of blockchain technology with military-grade encryption, creating a truly private and censorship-resistant communication protocol.
- On-Chain Encryption: Group passwords stored as encrypted addresses using FHE
- Zero-Knowledge Communication: Messages encrypted with AES-256 using FHE-derived keys
- Fully Decentralized: No central servers, all data lives on Ethereum
- WhatsApp-Style UX: Familiar, intuitive interface for mainstream adoption
- Confidential Tokens: Built-in encrypted token (XCoin) for in-app donations
- Permissionless: Anyone can create groups and join without gatekeepers
-
FHE-Encrypted Group Passwords
- Each group has a unique password stored as an encrypted Ethereum address
- Passwords are never exposed in plaintext on-chain
- Only group members can decrypt the password using Zama's FHE protocol
- Automatic ACL (Access Control List) management for key distribution
-
End-to-End Encrypted Messages
- Messages are AES-256-GCM encrypted client-side before being sent to the blockchain
- Encryption keys are derived from FHE-decrypted group passwords
- Even the smart contract cannot read message contents
-
Confidential Token Support
- ConfidentialXCoin: A fully encrypted ERC-20 token using Zama's FHE
- Enables private donations to group creators
- Balances and transfers are fully confidential
- Group Creation: Create unlimited groups with custom names and auto-generated encrypted passwords
- Open Join Model: Anyone can join any group (customizable for private groups)
- Real-Time Updates: WebSocket-based event listening for instant message delivery
- Message History: All messages stored on-chain for permanent accessibility
- Member Management: Track group membership and member counts
- Pagination Support: Efficient loading of large message histories
- WhatsApp-Inspired Design: Clean, modern UI with familiar chat patterns
- Responsive Layout: Works seamlessly on desktop and mobile devices
- Wallet Integration: RainbowKit integration for easy wallet connection
- Toast Notifications: Non-intrusive status updates
- Color-Coded Avatars: Unique colors generated from wallet addresses
- Message Bubbles: Distinct styling for sent vs. received messages
- XCoin Faucet: Get test tokens for donations
- Confidential Transfers: Donate encrypted tokens to group creators
- Balance Privacy: Token balances hidden from public view
Problem: Traditional blockchain applications expose all data publicly, making them unsuitable for private communication.
Solution: XChat uses FHE to encrypt sensitive data (passwords, balances) at the smart contract level, and AES encryption for message content. This ensures that even though data is on-chain, it remains private.
Problem: Platforms like WhatsApp, Telegram, and Discord are centralized, vulnerable to censorship, data breaches, and single points of failure.
Solution: XChat is fully decentralized. Messages are stored on Ethereum, eliminating central servers and making the platform censorship-resistant and immune to platform shutdowns.
Problem: Secure key distribution is one of the hardest problems in cryptography. How do you share encryption keys with group members without exposing them?
Solution: XChat uses FHE to store encrypted group passwords on-chain. When users join a group, they're automatically granted decryption rights through the FHE ACL system, solving the key distribution problem elegantly.
Problem: Users must trust messaging platforms not to read their messages, even in "end-to-end encrypted" systems.
Solution: XChat's encryption happens entirely client-side, and the smart contract code is open-source and immutable. No trust requiredβusers can verify the code themselves.
Problem: Centralized platforms can delete messages, ban users, or shut down entirely, causing data loss.
Solution: All messages are permanently stored on Ethereum. Users truly own their data, and it cannot be deleted or modified by any third party.
Problem: Token transfers on public blockchains reveal sender, recipient, and amount, compromising financial privacy.
Solution: XCoin uses Zama's confidential token standard, keeping all transaction details private while maintaining blockchain auditability for the owner.
| Technology | Version | Purpose |
|---|---|---|
| Solidity | 0.8.24 / 0.8.27 | Smart contract programming language |
| Hardhat | ^2.26.0 | Ethereum development environment |
| @fhevm/solidity | ^0.8.0 | Zama's FHE library for Solidity |
| @zama-fhe/oracle-solidity | ^0.1.0 | FHE oracle integration |
| new-confidential-contracts | ^0.1.1 | Confidential token standards |
| TypeChain | ^8.3.2 | TypeScript bindings for contracts |
| Hardhat Deploy | ^0.11.45 | Deployment management |
| Technology | Version | Purpose |
|---|---|---|
| React | ^19.1.1 | UI framework |
| TypeScript | ~5.8.3 | Type-safe JavaScript |
| Vite | ^7.1.6 | Build tool and dev server |
| ethers.js | ^6.15.0 | Ethereum interaction library |
| wagmi | ^2.17.0 | React hooks for Ethereum |
| viem | ^2.37.6 | TypeScript Ethereum library |
| RainbowKit | ^2.2.8 | Wallet connection UI |
| @tanstack/react-query | ^5.89.0 | Async state management |
| @zama-fhe/relayer-sdk | ^0.2.0 | FHE relayer integration |
| Technology | Purpose |
|---|---|
| Zama FHEVM | Fully Homomorphic Encryption on Ethereum |
| AES-256-GCM | Client-side message encryption |
| Web Crypto API | Browser-native cryptographic operations |
| EIP-712 | Typed data signing for FHE key pairs |
| Technology | Purpose |
|---|---|
| Ethereum Sepolia Testnet | Deployment target |
| IPFS (future) | Decentralized file storage |
| The Graph (future) | Blockchain data indexing |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β User Browser β
β ββββββββββββββββ ββββββββββββββββ ββββββββββββββββββββ β
β β React UI β β Web Crypto β β Wallet (MetaMask)β β
β β (WhatsApp β β (AES-256) β β β β
β β Style) β β β β β β
β ββββββββ¬ββββββββ ββββββββ¬ββββββββ ββββββββββ¬ββββββββββ β
β β β β β
βββββββββββΌββββββββββββββββββΌβββββββββββββββββββββΌββββββββββββββ
β β β
β β β
βΌ βΌ βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Ethereum Layer β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β XChat Smart Contract β β
β β β’ FHE-encrypted group passwords (eaddress) β β
β β β’ AES-encrypted messages (string) β β
β β β’ Group metadata (name, owner, members) β β
β β β’ ACL management (FHE.allow) β β
β ββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ β
β β β
β ββββββββββββββββββββ΄ββββββββββββββββββββββββββββββββββββ β
β β ConfidentialXCoin (ERC-20 with FHE) β β
β β β’ Encrypted balances (euint64) β β
β β β’ Confidential transfers β β
β β β’ Faucet for testing β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Zama FHE Coprocessor β
β β’ ACL Contract (0x6878...9b6c) β
β β’ Coprocessor (0x848B...8595) β
β β’ Decryption Oracle (0xa02C...8812) β
β β’ KMS Verifier (0x1364...acAC) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
1. User inputs group name
2. Generate random Ethereum address as password
3. Encrypt password with FHE (eaddress)
4. Submit to XChat.createGroup(name, encryptedPassword, proof)
5. Contract stores encrypted password and grants ACL to creator
6. Emit GroupCreated event
1. User clicks "Join" on a group
2. Call XChat.joinGroup(groupId)
3. Contract sets isMember[groupId][user] = true
4. Contract grants FHE decryption rights: FHE.allow(encPassword, user)
5. Emit GroupJoined event
1. User clicks "Load Key" button
2. Client requests encrypted password handle from contract
3. Client generates FHE keypair and signs EIP-712 message
4. Client calls Zama relayer to decrypt password β cleartext address
5. Derive AES-256 key from address using PBKDF2
6. Store key locally (state)
7. User types message
8. Encrypt message with AES-256-GCM (produces {iv, data})
9. Send JSON.stringify({iv, data}) to XChat.sendMessage()
10. Contract stores encrypted string on-chain
11. Emit MessageSent event
1. Client subscribes to MessageSent events for groupId
2. For each message, fetch ciphertext from contract
3. Parse JSON to get {iv, data}
4. Decrypt with stored AES key β plaintext message
5. Render in UI
- Node.js: >= 20.0.0
- npm: >= 7.0.0
- Git
- MetaMask or another Web3 wallet
- Sepolia ETH: For deploying and testing (get from faucet)
# Clone the repository
git clone https://github.com/yourusername/xchat.git
cd xchat
# Install dependencies
npm install
# Install UI dependencies
cd ui
npm install
cd ..- Set up environment variables
Create a .env file in the root directory:
# Wallet Configuration
PRIVATE_KEY=your_private_key_here
MNEMONIC=your twelve word mnemonic phrase here
# Network Configuration
SEPOLIA_RPC_URL=https://eth-sepolia.public.blastapi.io
INFURA_API_KEY=your_infura_api_key
# Optional: Etherscan API for contract verification
ETHERSCAN_API_KEY=your_etherscan_api_key- Configure Hardhat variables (alternative to .env)
npx hardhat vars setupFollow the prompts to set:
MNEMONICETHERSCAN_API_KEY
npm run compileThis compiles contracts and generates TypeChain types.
# Run all tests
npm test
# Run with coverage
npm run coverage
# Run on Sepolia testnet
npm run test:sepolia# Start local blockchain (in one terminal)
npx hardhat node
# Deploy contracts locally (in another terminal)
npx hardhat deploy --network localhost
# Start frontend dev server
cd ui
npm run devOpen http://localhost:5173 in your browser.
# Deploy XChat contract
npm run deploy:sepolia
# Deploy with automatic config update (recommended)
npm run deploy:sepolia:fullThis will:
- Deploy XChat.sol
- Deploy ConfidentialXCoin.sol
- Update frontend config with contract addresses
- Output deployment addresses
After deployment, update ui/src/config/contracts.ts with your contract addresses:
export const XCHAT_ADDRESS = '0xYourXChatAddress';
export const XCOIN_ADDRESS = '0xYourXCoinAddress';cd ui
npm run build
# Deploy dist/ folder to your hosting service
# (Netlify, Vercel, IPFS, etc.)Main contract for group chat functionality.
// Create a new group with encrypted password
function createGroup(
string calldata name,
externalEaddress passwordInput,
bytes calldata inputProof
) external returns (uint256 groupId)
// Join an existing group
function joinGroup(uint256 groupId) external
// Get group information
function getGroup(uint256 groupId)
external view
returns (string memory name, address owner, uint256 createdAt, uint256 memberCount)
// Get encrypted group password handle
function getGroupPassword(uint256 groupId)
external view
returns (eaddress)
// Send an encrypted message
function sendMessage(uint256 groupId, string calldata ciphertext)
external
// Get message history
function getMessages(uint256 groupId, uint256 offset, uint256 limit)
external view
returns (address[] memory senders, string[] memory ciphertexts, uint256[] memory timestamps)event GroupCreated(uint256 indexed groupId, string name, address indexed owner);
event GroupJoined(uint256 indexed groupId, address indexed member);
event MessageSent(uint256 indexed groupId, address indexed sender, string ciphertext, uint256 timestamp);Confidential ERC-20 token for in-app donations.
// Mint tokens to yourself (testnet only)
function faucet() external
// Confidential transfer
function confidentialTransfer(
address to,
bytes32 encryptedAmount,
bytes calldata inputProof
) externalui/
βββ src/
β βββ components/
β β βββ XChatApp.tsx # Main chat list component
β β βββ Toast.tsx # Toast notification system
β β βββ WalletFloat.tsx # Floating wallet display
β βββ pages/
β β βββ GroupPage.tsx # Individual group chat page
β βββ hooks/
β β βββ useEthersSigner.ts # Convert wagmi client to ethers signer
β β βββ useZamaInstance.ts # Initialize Zama FHE SDK
β β βββ crypto.ts # AES encryption/decryption utilities
β βββ config/
β β βββ contracts.ts # Contract addresses and ABIs
β β βββ wagmi.ts # Wagmi/RainbowKit configuration
β βββ styles/
β β βββ whatsapp.css # WhatsApp-inspired styles
β βββ App.tsx # Root component with routing
β βββ main.tsx # Application entry point
β βββ index.css # Global styles
βββ public/ # Static assets
βββ package.json
βββ vite.config.ts
Displays the list of all available groups with:
- Real-time group count updates
- Membership status indicators
- Group creation modal
- WhatsApp-style list UI
Individual group chat interface with:
- Message history loading from contract storage
- Real-time message listening via WebSocket events
- FHE key decryption flow
- AES message encryption/decryption
- Donation modal for sending XCoin to group creators
- Message bubbles with sender identification
// Derive AES key from FHE-decrypted address
async function deriveAesKeyFromAddress(address: string): Promise<CryptoKey>
// Encrypt message with AES-256-GCM
async function encryptMessage(key: CryptoKey, plaintext: string): Promise<{iv: string, data: string}>
// Decrypt message
async function decryptMessage(key: CryptoKey, encrypted: {iv: string, data: string}): Promise<string>XChat is designed to protect against:
- Passive Observers: Anyone reading the blockchain cannot see group passwords or message contents
- Malicious Nodes: Ethereum validators cannot decrypt sensitive data
- Contract Exploits: FHE ensures even contract vulnerabilities don't expose plaintext data
- Man-in-the-Middle: All encryption happens client-side with user-controlled keys
β Group Password Confidentiality: Stored as FHE-encrypted addresses, only decryptable by group members
β Message Confidentiality: AES-256-GCM encryption with keys derived from FHE passwords
β Forward Secrecy: Each group has a unique password; compromise of one doesn't affect others
β Access Control: FHE ACL system ensures only authorized users can decrypt passwords
β Immutability: All data stored on Ethereum cannot be altered or deleted
β Censorship Resistance: No central authority can block users or delete groups
test/
βββ XChat.test.ts # XChat contract unit tests
βββ ConfidentialXCoin.test.ts # XCoin contract unit tests
# Run all tests
npm test
# Run specific test file
npx hardhat test test/XChat.test.ts
# Run with gas reporting
REPORT_GAS=true npm test
# Run with coverage
npm run coverageThe test suite covers:
- Group creation with FHE encryption
- Membership management
- ACL permission grants
- Message sending and retrieval
- Pagination of message history
- XCoin faucet and transfers
- Edge cases and error conditions
XChat/
βββ contracts/ # Solidity smart contracts
β βββ XChat.sol # Main chat contract
β βββ ConfidentialXCoin.sol # Confidential token
βββ deploy/ # Hardhat deployment scripts
β βββ 01_deploy_xchat.ts
β βββ 02_deploy_xcoin.ts
βββ test/ # Contract tests
β βββ XChat.test.ts
β βββ ConfidentialXCoin.test.ts
βββ tasks/ # Hardhat tasks
β βββ accounts.ts
β βββ FHECounter.ts
β βββ XChat.ts
βββ ui/ # React frontend
β βββ src/
β βββ public/
β βββ package.json
βββ types/ # TypeChain generated types
βββ artifacts/ # Compiled contracts
βββ cache/ # Hardhat cache
βββ docs/ # Documentation
β βββ zama_doc_relayer.md
β βββ zama_llm.md
βββ .env # Environment variables (gitignored)
βββ hardhat.config.ts # Hardhat configuration
βββ package.json
βββ tsconfig.json
βββ README.md
| Feature | XChat | Traditional Apps |
|---|---|---|
| Censorship Resistance | β Fully decentralized | β Can ban users/groups |
| Data Ownership | β User owns all data | β Platform owns data |
| Server Shutdowns | β Immune (on blockchain) | β Can go offline permanently |
| Privacy from Platform | β Platform can't read messages | |
| Permanent Records | β Immutable on-chain | β Can be deleted |
| Open Source | β Fully auditable |
| Feature | XChat | Others |
|---|---|---|
| On-Chain Encryption | β FHE at contract level | |
| No IPFS Dependency | β Fully on Ethereum | |
| Automatic Key Distribution | β FHE ACL system | β Manual key sharing |
| Encrypted Tokens | β Built-in FHE tokens | β Standard tokens |
| Group Password Security | β FHE-encrypted addresses |
- True Privacy: FHE ensures computational privacyβeven the blockchain cannot see sensitive data
- No Servers: Eliminates hosting costs, maintenance, and single points of failure
- Composability: Smart contract primitives can be integrated into other dApps
- Auditability: All code is open-source and on-chain
- Micro-Donations: Built-in confidential token enables creator support
- Progressive Decentralization: Can start with simple features and add DAO governance later
Scenario: Activist groups, journalists, whistleblowers need censorship-resistant, private communication.
How XChat Helps: Messages cannot be intercepted, traced, or censored by governments or corporations.
Scenario: Decentralized organizations need on-chain communication channels tied to governance.
How XChat Helps: Chat groups can be programmatically tied to token holdings or governance participation.
Scenario: NFT projects want token-gated chats for holders.
How XChat Helps: Add token-gating logic to joinGroup() function (requires holding specific NFT).
Scenario: Web3 projects need to provide private support channels.
How XChat Helps: Create support groups with encrypted conversation history.
Scenario: Companies need blockchain-based communication with guaranteed privacy.
How XChat Helps: FHE ensures competitors or chain analysts cannot read business discussions.
Scenario: Community leaders want to monetize groups without subscriptions.
How XChat Helps: Built-in XCoin donations allow supporters to tip creators privately.
- XChat smart contract with FHE encryption
- ConfidentialXCoin token
- React frontend with WhatsApp-style UI
- RainbowKit wallet integration
- AES message encryption
- Real-time event listening
- Sepolia testnet deployment
- Private Groups: Add invite-only group functionality
- Admin Controls: Group owner can remove members
- File Sharing: Upload encrypted files to IPFS, share links in chat
- Emoji Reactions: React to messages with emojis
- Read Receipts: Track which members have seen messages
- User Profiles: ENS name integration, custom avatars
- Group Icons: Upload custom group images
- Rotating Keys: Implement periodic key rotation for forward secrecy
- Multi-Sig Groups: Require multiple admins to approve changes
- Message Expiry: Self-destructing messages after time period
- Backup & Recovery: Encrypted key backup to IPFS with recovery phrase
- Cross-Chain Support: Deploy to Polygon, Arbitrum, Optimism
- Threads: Reply to specific messages
- Mentions: @user notifications
- Link Previews: Display metadata for shared URLs
- GIF Support: Integrate Giphy or similar
- Voice Messages: Upload encrypted audio to IPFS
- Video Calls: Integrate WebRTC for P2P encrypted calls
- Premium Features: Paid tiers with more storage, groups, etc.
- Token-Gated Groups: Require NFT or token holdings to join
- Ads (Optional): Encrypted, user-controlled ad system
- DAO Governance: Community votes on features and treasury
- Layer 2 Migration: Move to zkSync or StarkNet for lower fees
- Mobile Apps: React Native iOS/Android apps
- XChat SDK: JavaScript library for integrating XChat into other dApps
- Bots & Integrations: Allow bots to post notifications
- Bridges: Cross-chain messaging between L1s and L2s
- Decentralized Relayer Network: Remove dependency on Zama's centralized relayer
- Formal Security Audit: Third-party audit of contracts
- Bug Bounty Program: Incentivize security researchers
We welcome contributions from the community! Here's how you can help:
If you find a bug, please open an issue with:
- Detailed description of the bug
- Steps to reproduce
- Expected vs. actual behavior
- Screenshots if applicable
- Your browser/wallet/environment details
Have an idea? Open a feature request issue with:
- Clear description of the feature
- Use case and benefits
- Proposed implementation (if you have ideas)
- Fork the repository
- Create a feature branch:
git checkout -b feature/your-feature-name - Make your changes
- Write/update tests as needed
- Run linters:
npm run lint - Run tests:
npm test - Commit with clear messages:
git commit -m "Add feature: your feature" - Push to your fork:
git push origin feature/your-feature-name - Open a Pull Request with:
- Description of changes
- Related issue numbers
- Testing done
- Follow existing code style (Prettier/ESLint configs provided)
- Write meaningful commit messages
- Add tests for new features
- Update documentation as needed
- Keep PRs focused and atomic
Be respectful, inclusive, and constructive. We're building together.
This project is licensed under the BSD-3-Clause-Clear License.
See LICENSE file for full details.
- β Commercial use allowed
- β Modification allowed
- β Distribution allowed
- β Private use allowed
- β No patent rights granted
β οΈ Must include copyright noticeβ οΈ Must include license text
- Zama.ai: For pioneering FHEVM technology and making on-chain encryption possible
- Ethereum Foundation: For creating the decentralized platform we build on
- Hardhat: For the excellent developer tooling
- RainbowKit: For beautiful wallet connection UX
- WhatsApp: UI/UX inspiration for mainstream appeal
- Signal: Privacy-first messaging philosophy
- Status: Web3 messaging pioneering work
- XMTP: Decentralized messaging research
Thank you to all contributors, testers, and users who make XChat possible. Special thanks to:
- Early testers who provided invaluable feedback
- The Zama developer community for FHE guidance
- The Ethereum developer community for endless resources
- Website: [Coming Soon]
- Documentation: docs.xchat.app
- Twitter: @XChatProtocol
- Discord: Join Community
- Email: support@xchat.app
- Check the Documentation
- Search Issues
- Ask in Discord
- Review FAQ
Built with β€οΈ by the XChat Team