diff --git a/README.md b/README.md index 0129dc9..cb54b42 100644 --- a/README.md +++ b/README.md @@ -1,145 +1,130 @@ # Logos Chat -This is the technical proof of a modular e2ee chat protocol using Waku. You can find discussion and details [here](https://github.com/waku-org/specs/pull/73) +[![Tests](https://github.com/logos-messaging/logos-chat/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/logos-messaging/logos-chat/actions/workflows/ci.yml) +![ProjectStatus]( https://img.shields.io/badge/Project_Status-Preview-orange) + +A privacy focused decentralized messaging SDK, built on the Logos Stack. Logos Chat provides permission-less, censorship-resistant communication for humans and clankers. -See [EchoBot](./examples/bot_echo.nim) for a minimal client side usage example. -See [Client](./src/chat/client.nim) for the main entry point to the SDK ## Quick Start -``` -# Build Dependencies and link libraries +### Prerequisites + +- [Nim](https://nim-lang.org/) >= 2.2.4 +- [Rust](https://www.rust-lang.org/tools/install) (for libchat cryptographic backend) +- Make + +### Build + +```bash +# Initialize submodules and dependencies make update -# Build executables +# Build all targets (examples + shared library) make all # Run tests make tests - -# Run an example of two clients communicating -./build/pingpong ``` -## API - -### Client - -#### `new_client(WakuClient, Identity) -> Client` -Constructs a new Client instance - -#### `create_intro_bundle(Client) -> IntroBundle` -Creates a package of keys required by initiators to initialize a conversation. - -#### `new_private_conversation(Client, IntroBundle, Seq)` -Used by a client to initialize a conversation. Requires the `IntroBundle` of the other participant, as well as an initial message. - -#### `list_conversations(Client) -> Seq` -Returns a list of conversations known to this client. - -#### `get_conversation(Client, String) -> Conversation` -Returns a conversation given the conversation ID. - -#### `on_new_message (Client, Callback(Conversation, ReceivedMessage)) -> Void`
`on_new_conversation(Client, Callback(Conversation)) -> Void`
`on_new_delivery_ack(Client, Callback(Conversation, String)) -> Void` -Registers callback to receive updates for events. - -#### `start(Client) -> Void`
`stop(Client) -> Void` -Start MUST be called in order to receive messages. Stop should be called to finalize remaining tasks. - -### Conversation - -#### `id(Conversation) -> String` -Returns the Conversation Identifier (ConvoId). - -#### `send_message(Conversation, Seq) -> String` -Sends content bytes to the conversation and returns a message_id. -### WakuClient +### Quick Tasks -#### `default_config() -> DefaultConfig` -Creates a safe waku configuration to initialize a WakuClient. - -#### `init_waku_client(WakuConfig) -> WakuClient` -Create a wakuClient from a configuration. - -### Identity - -#### `create_identity*(name: string)-> Identity` -Creates a new random identity +Here are common tasks to get up and running. See [`examples/`](examples/) for full examples, including [`pingpong.nim`](examples/pingpong.nim) which demonstrates a full two-client conversation. -## Details +**Initialize Client** +```nim +let waku = initWakuClient(DefaultConfig()) +var client = newClient(waku).get() +... +... +client.start() +``` -### Features +**Create Introduction Bundle** -Current state of the [ChatSDK FURPS](https://github.com/waku-org/pm/blob/master/FURPS/application/chat_sdk.md) +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. -| ID | Feature | Status | Notes | -|-----|----------------------------|--------|---------------------------------------------------------| -| F1 | Permissionless Accounts | ✅ | | -| F2 | 1:1 Messaging | ✅ | | -| F3 | FS + PCS | 🟡 | PCS in place — needs noise implementation | -| F4 | Delivery Receipts | ✅ | | -| F5 | Basic Content Types | ✅ | Types need formal definition; plugin system prototyped | -| F6 | Default Message Store | 🚫 | Wont do - api changed, apps handle message storage | -| F7 | Default Secrets Store | ➡️ | Deferred - Not required for dev api preview | -| U1 | Non-interactive Initiation | ✅ | | -| U2 | Invite Links | ✅ | | -| U3 | 25 Lines of Code | ✅ | | -| R1 | Dropped Message Detection | 🚫 | Wont do - uses reliable channels | -| P1 | 10K Active Clients | ⚪ | | -| S1 | RLN Compatible | 🟡 | RLN supported, but not implemented yet | -| S2 | Future Proof | 🟡 | | -| S3 | Go Bindings | 🚫 | Wont do - Refocus on Logos-core | -| S4 | Rust Bindings | 🚫 | Wont do - Refocus on Logos-core | -| +1 | Sender Privacy | ✅ | Needs verification | -| +2 | Membership Privacy | 🟡 | Needs verification | -| +3 | User Activity Privacy | 🟡 | Needs verification | -| +4 | Nimble Compatible | ⛔ | Blocked — upstream dependency conflicts +```nim +... +# 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. +```nim +... +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. +```nim +... +client.onNewMessage(proc( convo: Conversation, msg: ReceivedMessage ) {.async.} = + echo convo.id(), msg.content -### Message Flow +) +... +``` -To establish a secure conversation, Saro and Raya need to: -1. Find each others identityKeys -2. Agree on a secret key, and location to communicate +**Send Message** -For this technical proof, recipient identity keys are exchanged out of bound via an invite link. More complex identity systems will be explored in the future. .. +```nim +... +let content = @[1,2,3] +let convo = client.getConversation( convo_id ) +await client.sendMessage( content ) +... +``` +## Message Flow - ```mermaid +```mermaid sequenceDiagram participant S as Saro participant R as Raya Note over R,S: Discovery - R -->> S: Send Invite Link via established channel + R -->> S: Send intro bundle via established channel Note over R,S: Initialization - S ->> R: PrivateV1 Invite + S ->> R: PrivateV1 Invite + initial message Note over R,S: Operation - loop + loop Encrypted messaging par - R->> S: Send Message + R ->> S: Send Message and - S->> R: Send Message + S ->> R: Send Message end end - ``` +``` +### C Bindings -## Limitations +A shared library with C bindings is available: -1. `.proto` files are included in this repo due to complications in importing nested packages using `?subdir=`. Once resolved there will be a single definition of protocol types. -1. Messages are sent using waku, however wakunode discovery has not been implemented. As a stopgap a manual discovery process based on staticpeers is used. +```bash +make liblogoschat +``` + +This produces `build/liblogoschat.{dylib,so,dll}`. See [`library/liblogoschat.h`](library/liblogoschat.h) and [`examples/cbindings/`](examples/cbindings/) for usage. ## License -[MIT](https://choosealicense.com/licenses/mit/) \ No newline at end of file +Dual-licensed under [MIT](LICENSE-MIT) and [Apache 2.0](LICENSE-APACHE). diff --git a/examples/cbindings/README.md b/examples/cbindings/README.md index b6df51b..e36f54f 100644 --- a/examples/cbindings/README.md +++ b/examples/cbindings/README.md @@ -51,9 +51,3 @@ make run_bob --help Show help ``` -## Waku Configuration - -- **Cluster ID**: 42 -- **Shard ID**: 2 -- **PubSub Topic**: `/waku/2/rs/42/2` -- **Port**: Random between 50000-50200 (or specify with --port)