Global, restart-based Required/None anonymity mode: route chat messages through the
libp2p mixnet for sender anonymity, on the logos-delivery (efafdfdc2) nwaku stack.
Static RLN spam protection; no on-chain LEZ gifter / dynamic membership.
Delivery (src/chat/delivery/waku_client.nim):
- WakuConfig.mixEnabled/mixNodes/minMixPoolSize; parseMixNodes, waitForMixPool,
getMixPoolSize, mixReady.
- Required mode: sendBytes -> lightpushPublish(mixify=true) over the mix pool,
fail-fast below minMixPoolSize (no relay fallback). None mode: relay publish.
Errors propagate up to chat_send_message.
- Receive via WakuFilter (subscribe to static peers; no relay mounted), refreshed
by a 60s keep-alive.
- Static RLN: pre-populated rln_tree.db + per-peer keystore; nodekey config to adopt
a provisioned identity. No per-send root-convergence wait (static membership).
API / build:
- chat_get_mix_status FFI -> {mixEnabled,mixReady,mixPoolSize,minPoolSize}.
- Reproducible nix build: librln consumed as a cdylib (avoids the two-Rust-staticlib
symbol collision); -d:libp2p_mix_experimental_exit_is_dest.
- vendor/nwaku -> efafdfdc2; vendor/nim-protobuf-serialization -> 38d24eb (0.4.0).
Logos Chat
A privacy focused decentralized messaging SDK, built on the Logos Stack. Logos Chat provides permission-less, censorship-resistant communication for humans and clankers.
Quick Start
Prerequisites
Build
# Initialize submodules and dependencies
make update
# Build all targets (examples + shared library)
make all
# Run tests
make tests
Quick Tasks
Here are common tasks to get up and running. See examples/ for full examples, including pingpong.nim which demonstrates a full two-client conversation.
Initialize Client
let waku = initWakuClient(DefaultConfig())
var client = newClient(waku).get()
...
...
client.start()
Create Introduction Bundle
Introductions are single use key-bundles required by Senders to initiate a conversation. Recipients must generate them before anyone can contact them. IntroBundles contain no secrets and can be published, or transmitted over over other channels.
...
# IntroBundles are sent to other clients Out-of-Band to establish a conversation.
let intro_bundle = client.createIntroBundle()
...
Create 1:1 Chat
Once a Sender has retrieved a bundle then they can create a conversation. All conversations must have an initial message.
...
let initial_content = @[1,2,3]
# This intro_bundle must come from another client
let convo_id = await client.newPrivateConversation( intro_bundle, initial_content )
...
Receive Message
Receiving a message is accomplished by registering a callback.
...
client.onNewMessage(proc( convo: Conversation, msg: ReceivedMessage ) {.async.} =
echo convo.id(), msg.content
)
...
Send Message
...
let content = @[1,2,3]
let convo = client.getConversation( convo_id )
await client.sendMessage( content )
...
Message Flow
sequenceDiagram
participant S as Saro
participant R as Raya
Note over R,S: Discovery
R -->> S: Send intro bundle via established channel
Note over R,S: Initialization
S ->> R: PrivateV1 Invite + initial message
Note over R,S: Operation
loop Encrypted messaging
par
R ->> S: Send Message
and
S ->> R: Send Message
end
end
C Bindings
A shared library with C bindings is available:
make liblogoschat
This produces build/liblogoschat.{dylib,so,dll}. See library/liblogoschat.h and examples/cbindings/ for usage.
License
Dual-licensed under MIT and Apache 2.0.