mirror of
https://github.com/logos-messaging/libchat.git
synced 2026-08-12 01:53:18 +00:00
A standalone room-chat TUI on the reliable channels API, with no MLS or libchat stack in the way — the channels API on its own. One process per participant (--nick/--room), --peer to wire two local instances directly or logos.dev discovery otherwise. The author's nick travels inside the payload because a received event's sender_id reports the receiving channel's own participant id, not the originator's. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ai43sF2rymPFMG9iki9fwL
channel-chat
A room chat built directly on logos-delivery's reliable channels API, via
waku-bindings. It is deliberately
small: no MLS, no libchat stack, no encryption of the chat itself — just the
channels API, so the API is the only thing on screen.
For the full encrypted client see bin/chat-cli, which uses
these same channels underneath as its transport.
Running
One process per participant, each with its own nick:
cargo run -p channel-chat -- --nick Alice --room lobby # terminal 1
cargo run -p channel-chat -- --nick Bob --room lobby # terminal 2
Type and press Enter to send; Esc quits. The node takes a few seconds to start
and find peers on logos.dev, so the first message may need a retry. Each
instance prints its own multiaddr at startup; to wire two local instances
together without waiting on discovery, pass one to the other:
cargo run -p channel-chat -- --nick Bob --room lobby --peer /ip4/127.0.0.1/tcp/60001/p2p/16Uiu2...
| Flag | Default | Meaning |
|---|---|---|
--nick |
(required) | Display name, and the channel's SDS participant id |
--room |
lobby |
Room to join — everyone in a room shares one channel |
--port |
0 (OS picks) |
TCP port for the node |
--peer |
(none) | Multiaddr to dial directly, instead of waiting on discovery |
What it does
- Starts a node on the
logos.devpreset. The preset is what supplies the entry nodes and autosharding — a channel's shard is derived from its content topic, so a node without autosharding cannot carry one. - Registers the three channel listeners —
received,sent,error— before starting the node. - Opens channel
{room}on content topic/logos-chat-example/1/{room}/proto. - Subscribes to that content topic. Creating a channel does not subscribe; ingress arrives through the messaging layer, so without this nothing lands.
- Sends with
channel_send, and closes the channel on quit.
Notes
- Run each participant under a different
--nick. The nick is both the participant id and (via./data-channel-chat-{nick}) the storage root. The persistency layer is a process-wide singleton keyed on that root, and SDS rows are keyed by channel id, so two participants sharing a root would each load the other's causal history and silently drop the other's messages as replays. This is also why participants are separate processes rather than tasks. - Sends are acknowledged asynchronously, so the outcome shows up in the status
bar (
sent/SEND FAILED) rather than at the call site. That reliability — acks, retransmission, causal ordering — is what channels add over a raw relay publish. - A node does not receive its own channel messages, so your own lines are echoed locally.
- The author's nick travels inside the payload, not in
sender_id. A received event'ssender_idis filled in from the receiving channel's own participant id (reliable_channel.nim'sreportReceivedemitsself.senderId), so reading the author off it would attribute every incoming message to whoever is reading it. Worth knowing before reaching for that field.