src/chat/delivery/waku_client.nim: - After the gifter-client returns its optimistic leaf_index, spawn a background watcher that polls the gifter's new membership-status RPC (short-lived libp2p streams on /logos/rln/membership/status/ 1.0.0) until the on-chain membership PDA materialises for our id. If the authoritative leaf differs from the optimistic snapshot, the watcher rewrites lezGm.membershipIndex. The OnchainLEZGroupManager's poll loop picks up the corrected proof on its next iteration; spam_protection's self-verify rejects bad proofs until then. vendor/nwaku bump pulls in: - New /logos/rln/membership/status/1.0.0 codec + handlers on the gifter server. - MembershipStatusRequest/Response RPC messages. - WakuRlnGifterClient.queryMembershipStatus. - Mix-node gifter-client watcher with the same pattern.
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.