Decentralized MLS proof-of-concept that coordinates secure group membership through
off-chain consensus and a Waku relay.
This repository now ships a native desktop client built with Dioxus that drives the MLS core directly.
- de-mls – core library that manages MLS groups, consensus, and Waku integration
- crates/de_mls_gateway – bridges UI commands (
AppCmd) to the core runtime and streamsAppEvents back - crates/ui_bridge – bootstrap glue that hosts the async command loop for desktop clients
- apps/de_mls_desktop_ui – Dioxus desktop UI with login, chat, stewardship, and voting flows
- tests/ – integration tests that exercise the MLS state machine and consensus paths
Run a lightweight nwaku node that your local clients can connect to:
docker run \
-p 8645:8645 \
-p 60000:60000 \
wakuorg/nwaku:v0.33.1 \
--cluster-id=15 \
--rest \
--relay \
--rln-relay=false \
--pubsub-topic=/waku/2/rs/15/1Take note of the node multiaddr printed in the logs (looks like /ip4/127.0.0.1/tcp/60000/p2p/<peer-id>).
The desktop app reads the same environment variables the MLS core uses:
export NODE_PORT=60001 # UDP/TCP port the embedded Waku client will bind to
export PEER_ADDRESSES=/ip4/127.0.0.1/tcp/60000/p2p/<peer-id>
export RUST_LOG=info,de_mls_gateway=info # optional; controls UI + gateway loggingUse a unique NODE_PORT per local client so the embedded Waku nodes do not collide.
PEER_ADDRESSES accepts a comma-separated list if you want to bootstrap from multiple relays.
cargo run -p de_mls_desktop_uiThe first run creates apps/de_mls_desktop_ui/logs/de_mls_ui.log and starts the event bridge
and embedded Waku client.
Repeat steps 2–3 in another terminal with a different NODE_PORT to simulate multiple users.
-
Login screen – paste an Ethereum-compatible secp256k1 private key (hex, with or without
0x) and clickEnter.
On success the app derives your wallet address, stores it in session state, and navigates to the home layout. -
Header bar – shows the derived address and allows runtime log-level changes (
error→trace).
Log files rotate daily underapps/de_mls_desktop_ui/logs/. -
Groups panel – lists every MLS group returned by the gateway.
UseCreateorJointo open a modal, enter the group name, and the UI automatically refreshes the list and opens the group. -
Chat panel – displays live conversation messages for the active group.
Compose text messages at the bottom; the UI also offers:Leave groupto request a self-ban (the backend fills in your address)Request banto request ban for another user Member lists are fetched automatically when a group is opened so you can pick existing members from the ban modal.
-
Consensus panel – keeps stewards and members aligned:
- Shows whether you are a steward for the active group
- Lists pending steward requests collected during the current epoch
- Surfaces the proposal currently open for voting with
YES/NObuttons - Stores the latest proposal decisions with timestamps for quick auditing
- Working – normal mode; all MLS messages are allowed
- Waiting – a steward epoch is active; only the steward may push
BATCH_PROPOSALS_MESSAGE - Voting – the consensus phase; everyone may submit
VOTE/USER_VOTE, the steward can still publish proposal metadata
Transitions:
Working --start_steward_epoch()--> Waiting (if proposals exist)
Working --start_steward_epoch()--> Working (if no proposals)
Waiting --start_voting()---------> Voting
Waiting --no_proposals_found()---> Working
Voting --complete_voting(YES)----> Waiting --apply_proposals()--> Working
Voting --complete_voting(NO)-----> Working
Stewards always return to Working after an epoch finishes;
edge cases such as missing proposals are handled defensively with detailed tracing.
cargo test– runs the Rust unit + integration test suitecargo fmt --all check/cargo clippy– keep formatting and linting consistent with the codebaseRUST_BACKTRACE=full– helpful when debugging state-machine transitions during development
Logs for the desktop UI live in apps/de_mls_desktop_ui/logs/; core logs are emitted to stdout as well.
Issues and pull requests are welcome. Please include reproduction steps, relevant logs, and test coverage where possible.