osmaczko dfedfb10a4
feat: statically link libchat and rln via rust-bundle
Add rust-bundle, a single staticlib crate that depends on both libchat
and rln as rlibs. This ensures rustc links Rust std exactly once,
eliminating duplicate symbol errors on all platforms. Nim targets link
against liblogos_chat_bundle.a; Nix uses a bundleDrv instead of
separate libchat and rln derivations.

Reference: https://doc.rust-lang.org/reference/linkage.html#mixed-rust-and-foreign-codebases
2026-02-28 13:08:25 +01:00
2026-02-27 18:30:34 +00:00
2026-02-22 17:51:59 -08:00
2026-02-27 18:30:34 +00:00
2026-02-22 17:51:59 -08:00
2025-07-24 17:00:30 -07:00
2026-02-18 22:20:14 +01:00
2026-02-18 22:20:16 +01:00
2026-02-23 15:58:29 +01:00
2025-09-26 11:22:45 -07:00
2026-02-23 07:56:21 -08:00

Logos Chat

Tests ProjectStatus

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

  • Nim >= 2.2.4
  • Rust (for libchat cryptographic backend)
  • Make

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.

Description
LogosChat client SDK for decentralized messaging
https://logos.co/tech-stack
Readme
Languages
Nim 68.8%
Nix 13.2%
Makefile 8.3%
C 8%
Shell 1.7%