Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "vendor/waku"]
path = vendor/waku
url = git@github.com:waku-org/nwaku.git
url = https://jazzz@github.com/jazzz/nwaku
80 changes: 70 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,79 @@
# Waku Vibe Template
# Nim Chat POC

This is a project template for vibe coding with Waku in nim.
This is a technical proof of consuming the [chat_proto](https://github.com/waku-org/chat_proto/tree/base_types?tab=readme-ov-file) in nim.

The project imports Waku, builds dependencies and links the needed libraries, so you can get to hacking.

## Getting Started
This POC introduces the following Conversation Types:
- Inbox : Asymmetric channel for receiving invites
- PrivateV1: 1:1 private messaing with Forward Secrecy and Post compromise security

After cloning the repo, initialize the Waku side of the project and run the example code.
Messages are delivered over Waku

`nimble initialize` - Sets up the Waku dependencies
`nimble run` - Runs and example of using Waku Filter.
See [nim_chat_poc](./src/nim_chat_poc.nim) for a client side usage example.

## Troubleshooting

If it doesn't work and your error is not listed below, please open an issue or PR.
## Quick Start

//[Placeholder]
```
# Build Dependencies and link libraries
nimble initialize

# Run the default binary
nimble run
```

## Details

### Message Flow

To establish a secure conversation, Saro and Raya need to:
1. Exchange key material
2. Agree on a secret key, and location to communicate

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.

Key derivation and message framing is defined by Inbox spec


```mermaid
sequenceDiagram
actor S as Saro
participant SI as Saro Inbox
participant C as Convo
participant RI as Raya Inbox
actor R as Raya


Note over SI,RI: All clients subscribe to their default Inbox

SI ->> S: Subscribe
RI ->> R: Subscribe

Note over R: Key Information is exchanged OOB

Note over S: Conversation is created
C ->> S : Subscribe
S ->> RI : Send Invite `I1`
S ->> C : Send Message `M1`

RI --) R : Recv `I1`
Note over R: Conversation is joined
C ->> R : Subscribe
C --) R: Recv `M1`

R ->> C: Send M2
C -->> S: Recv M2
```




## Limitations

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. Currently messages are not sent over the wire. They are simulated using a `TransportMessage`.


## License

[MIT](https://choosealicense.com/licenses/mit/)
3 changes: 3 additions & 0 deletions nim.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@
--experimental

--passL: "./vendor/waku/librln_v0.7.0.a"

--define: chronicles_runtime_filtering

14 changes: 7 additions & 7 deletions nim_chat_poc.nimble
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ task initialize, "Initialize the project after cloning":

requires "nim >= 2.2.4"

requires "protobuf_serialization >= 0.1.0"
requires "secp256k1 >= 0.6.0.3.2"
requires "protobuf_serialization"
requires "secp256k1"
requires "blake2"
requires "chronicles"
requires "libp2p >= 1.11.0"
requires "libp2p"
requires "nimchacha20poly1305" # TODO: remove
requires "confutils >= 0.1.0"
requires "eth >= 0.8.0"
requires "regex >= 0.26.3"
requires "web3 >= 0.7.0"
requires "confutils"
requires "eth"
requires "regex"
requires "web3"
9 changes: 9 additions & 0 deletions protos/common_frames.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
syntax = "proto3";

package wap.common_frames;

message ContentFrame {
uint32 domain = 1;
uint32 tag = 2;
bytes bytes = 3;
}
28 changes: 28 additions & 0 deletions protos/conversations/group_v1.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
syntax = "proto3";

package wap.convos.group_v1;

import "base.proto";
import "common_frames.proto";



message ConversationInvite_GroupV1 {
repeated string participants = 1;
}



message GroupV1Frame {
// SDS like information: Message ID and channel_id extracted for utility
string message_id = 2;
string channel_id = 3; // Channel_id is associated with a set of participants
// This conflicts with conversation based encryption,
// need to ensure the derived sender is a valid participant
base.ReliabilityInfo reliability_info = 10;

oneof frame_type {
common_frames.ContentFrame content = 100;
// ...
}
}
24 changes: 24 additions & 0 deletions protos/encryption.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
syntax = "proto3";

package wap.encryption;


// TODO: This also encompasses plaintexts, is there a better name?
// Alternatives: ???
message EncryptedPayload {

oneof encryption {
encryption.Plaintext plaintext = 1;
encryption.Ecies ecies = 2;
}
}

message Plaintext {
bytes payload=1;
}

message Ecies {
bytes encrypted_bytes=1;
bytes ephemeral_pubkey = 2;
bytes tag = 3;
}
16 changes: 16 additions & 0 deletions protos/envelope.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
syntax = "proto3";

package wap.envelope;


///////////////////////////////////////////////////////////////////////////////
// Payload Framing Messages
///////////////////////////////////////////////////////////////////////////////

message WapEnvelopeV1 {

string conversation_hint = 1;
uint64 salt = 2;

bytes payload = 5;
}
17 changes: 17 additions & 0 deletions protos/inbox.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
syntax = "proto3";

package wap.inbox;

import "invite.proto";

message Note{
string text = 1;
}

message InboxV1Frame {
string recipient = 1;
oneof frame_type {
invite.InvitePrivateV1 invite_private_v1 = 10;
Note note = 11;
}
}
11 changes: 11 additions & 0 deletions protos/invite.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
syntax = "proto3";

package wap.invite;

message InvitePrivateV1 {
bytes initiator = 1;
bytes initiator_ephemeral = 2;
bytes participant = 3;
int32 participant_ephemeral_id= 4;
string discriminator = 5;
}
23 changes: 23 additions & 0 deletions protos/private_v1.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
syntax = "proto3";

package wap.convos.private_v1;

import "common_frames.proto";




message Placeholder {
uint32 counter = 1;
}

message PrivateV1Frame {
string conversation_id = 1;
bytes sender = 2;

oneof frame_type {
common_frames.ContentFrame content = 10;
Placeholder placeholder = 11;
// ....
}
}
23 changes: 23 additions & 0 deletions protos/reliability.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
syntax = "proto3";

package wap.reliability;

///////////////////////////////////////////////////////////////////////////////
// SDS Payloads
///////////////////////////////////////////////////////////////////////////////

message HistoryEntry {
string message_id = 1; // Unique identifier of the SDS message, as defined in `Message`
bytes retrieval_hint = 2; // Optional information to help remote parties retrieve this SDS
// message; For example, A Waku deterministic message hash or routing payload hash
}

message ReliablePayload {
string message_id = 2;
string channel_id = 3;
int32 lamport_timestamp = 10;
repeated HistoryEntry causal_history = 11;
bytes bloom_filter = 12;
// Optional field causes errors in nim protobuf generation. Removing for now as optional is implied anways.
bytes content = 20;
}
Loading