mirror of
https://github.com/logos-messaging/chat_proto.git
synced 2026-01-03 05:23:08 +00:00
Merge b8d83fc5f015476f90ff73a7178cd73b4dfd1ccd into c883557b8be84ec03b71c6cd85e25710ca899b8a
This commit is contained in:
commit
b3a78526ad
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/rust/target
|
||||
24
README.md
24
README.md
@ -1 +1,23 @@
|
||||
# chat_proto
|
||||
# chat_proto
|
||||

|
||||
|
||||
|
||||
This repository contains the core implementation of the $CHAT_PROTO types.
|
||||
|
||||
To make them easy to use, implementations in Rust and Nim are provided developers can focus on building.
|
||||
|
||||
|
||||
## Structure
|
||||
|
||||
- **proto:** Protobuf definitions for Core and Conversation types
|
||||
- **nim:** nimble package for generated types in nim
|
||||
- **rust:** cargo crate for generated types in rust
|
||||
- **specs:** current home of the specifications - these will likely be moved out of the repo. They are currently in lockstep with the type definitions which minimizes desync.
|
||||
|
||||
## Related Repositories
|
||||
|
||||
- [Nim POC](https://github.com/waku-org/nim-chat-poc/tree/jazzz/inbox) - This is a demo of the types being consumed in`nim`
|
||||
- Importing packages from a monorepo appears to be broken in `nimble`, as a short term work around. The `.proto` files have been embedded in the POC, and will be removed once resolved
|
||||
|
||||
- [Rust POC](https://github.com/jazzz/umbra) - This is demo of the types being consumed in `rust`
|
||||
|
||||
|
||||
14
nim/.devcontainer/devcontainer.json
Normal file
14
nim/.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "WapTypes",
|
||||
"image": "nimlang/nim",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"NimLang.nimlang", //Nim lang extension
|
||||
"vadimcn.vscode-lldb", //for Nim debug
|
||||
"streetsidesoftware.code-spell-checker" //spell checker
|
||||
]
|
||||
}
|
||||
},
|
||||
"postCreateCommand": "./.devcontainer/post_create.sh"
|
||||
}
|
||||
1
nim/.devcontainer/post_create.sh
Executable file
1
nim/.devcontainer/post_create.sh
Executable file
@ -0,0 +1 @@
|
||||
nimble install nimlangserver
|
||||
2
nim/.gitignore
vendored
Normal file
2
nim/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
nimble.develop
|
||||
nimble.paths
|
||||
19
nim/chat_proto.nim
Normal file
19
nim/chat_proto.nim
Normal file
@ -0,0 +1,19 @@
|
||||
import protobuf_serialization
|
||||
import protobuf_serialization/proto_parser
|
||||
|
||||
import_proto3 "../proto/umbra/encryption.proto"
|
||||
import_proto3 "../proto/umbra/envelope.proto"
|
||||
import_proto3 "../proto/umbra/inbox.proto"
|
||||
import_proto3 "../proto/umbra/reliability.proto"
|
||||
|
||||
export protobuf_serialization
|
||||
|
||||
# TODO: Do the Objects have to be listed manually?
|
||||
export EncryptedPayload
|
||||
export HistoryEntry
|
||||
export InboxV1Frame
|
||||
export ReliablePayload
|
||||
export UmbraEnvelopeV1
|
||||
|
||||
|
||||
|
||||
14
nim/chat_proto.nimble
Normal file
14
nim/chat_proto.nimble
Normal file
@ -0,0 +1,14 @@
|
||||
# Package
|
||||
packageName = "chat_proto"
|
||||
version = "0.1.0"
|
||||
author = "jazzz"
|
||||
description = "Type definitions for the chat protocol"
|
||||
license = "MIT"
|
||||
# bin = @["chat_proto"]
|
||||
# installDirs = @["../proto"]
|
||||
|
||||
|
||||
# Dependencies
|
||||
requires "nim >= 2.0.14"
|
||||
requires "chronicles"
|
||||
requires "protobuf_serialization"
|
||||
4
nim/config.nims
Normal file
4
nim/config.nims
Normal file
@ -0,0 +1,4 @@
|
||||
# begin Nimble config (version 2)
|
||||
when withDir(thisDir(), system.fileExists("nimble.paths")):
|
||||
include "nimble.paths"
|
||||
# end Nimble config
|
||||
1
nim/tests/config.nims
Normal file
1
nim/tests/config.nims
Normal file
@ -0,0 +1 @@
|
||||
switch("path", "$projectDir/../src")
|
||||
13
nim/tests/test_encoding.nim
Normal file
13
nim/tests/test_encoding.nim
Normal file
@ -0,0 +1,13 @@
|
||||
import unittest
|
||||
|
||||
import chat_proto
|
||||
|
||||
suite "Type Encoding Tests":
|
||||
test "HistoryEntry roundtrip":
|
||||
let x = chat_proto.HistoryEntry(message_id: "12345", retrieval_hint: @[1'u8, 2, 3, 255])
|
||||
let encoded = Protobuf.encode(x)
|
||||
let decoded = Protobuf.decode(encoded, HistoryEntry)
|
||||
|
||||
check x.message_id == decoded.message_id
|
||||
check x.retrieval_hint == decoded.retrieval_hint
|
||||
check x == decoded
|
||||
9
proto/wap/common_frames.proto
Normal file
9
proto/wap/common_frames.proto
Normal file
@ -0,0 +1,9 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package wap.common_frames;
|
||||
|
||||
message ContentFrame {
|
||||
uint32 domain = 1;
|
||||
uint32 tag = 2;
|
||||
bytes bytes = 3;
|
||||
}
|
||||
22
proto/wap/conversations/private_v1.proto
Normal file
22
proto/wap/conversations/private_v1.proto
Normal file
@ -0,0 +1,22 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package wap.convos.private_v1;
|
||||
|
||||
import "common_frames.proto";
|
||||
|
||||
|
||||
|
||||
|
||||
message Placeholder {
|
||||
uint32 counter = 1;
|
||||
}
|
||||
|
||||
message PrivateV1Frame {
|
||||
string conversation_id = 1;
|
||||
|
||||
oneof frame_type {
|
||||
common_frames.ContentFrame content = 10;
|
||||
Placeholder placeholder = 11;
|
||||
// ....
|
||||
}
|
||||
}
|
||||
15
proto/wap/encryption.proto
Normal file
15
proto/wap/encryption.proto
Normal file
@ -0,0 +1,15 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package wap.encryption;
|
||||
|
||||
|
||||
message EncryptedPayload {
|
||||
oneof encryption {
|
||||
NoiseKN noise_KN = 3;
|
||||
}
|
||||
}
|
||||
|
||||
message NoiseKN {
|
||||
bytes encrypted_bytes = 1;
|
||||
bytes ephemeral_pubkey = 2;
|
||||
}
|
||||
16
proto/wap/envelope.proto
Normal file
16
proto/wap/envelope.proto
Normal file
@ -0,0 +1,16 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package wap.envelope;
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Payload Framing Messages
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
message WapEnvelopeV1 {
|
||||
|
||||
string conversation_hint = 1;
|
||||
uint64 salt = 2;
|
||||
|
||||
bytes payload = 5;
|
||||
}
|
||||
12
proto/wap/inbox.proto
Normal file
12
proto/wap/inbox.proto
Normal file
@ -0,0 +1,12 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package wap.inbox;
|
||||
|
||||
import "invite.proto";
|
||||
|
||||
message InboxV1Frame {
|
||||
string recipient = 1;
|
||||
oneof frame_type {
|
||||
invite.InvitePrivateV1 invite_private_v1 = 10;
|
||||
}
|
||||
}
|
||||
7
proto/wap/invite.proto
Normal file
7
proto/wap/invite.proto
Normal file
@ -0,0 +1,7 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package wap.invite;
|
||||
|
||||
message InvitePrivateV1 {
|
||||
repeated string participants = 1;
|
||||
}
|
||||
23
proto/wap/reliability.proto
Normal file
23
proto/wap/reliability.proto
Normal file
@ -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;
|
||||
}
|
||||
12
rust/.devcontainer/devcontainer.json
Normal file
12
rust/.devcontainer/devcontainer.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "Rust-WapTypes",
|
||||
"image": "mcr.microsoft.com/devcontainers/rust:latest",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"pbkit.vscode-pbkit"
|
||||
]
|
||||
}
|
||||
},
|
||||
"postCreateCommand": "bash -i .devcontainer/postcreate.sh"
|
||||
}
|
||||
2
rust/.devcontainer/postcreate.sh
Executable file
2
rust/.devcontainer/postcreate.sh
Executable file
@ -0,0 +1,2 @@
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y protobuf-compiler
|
||||
5
rust/.vscode/settings.json
vendored
Normal file
5
rust/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"[rust]": {
|
||||
"editor.formatOnSave": true
|
||||
}
|
||||
}
|
||||
593
rust/Cargo.lock
generated
Normal file
593
rust/Cargo.lock
generated
Normal file
@ -0,0 +1,593 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.98"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"iovec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"r-efi",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iovec"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.174"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
||||
|
||||
[[package]]
|
||||
name = "multimap"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084"
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3672b37090dbd86368a4145bc067582552b29c27377cad4e0a306c97f9bd7772"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.13.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5"
|
||||
dependencies = [
|
||||
"bytes 1.10.1",
|
||||
"prost-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-build"
|
||||
version = "0.13.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"itertools",
|
||||
"log",
|
||||
"multimap",
|
||||
"once_cell",
|
||||
"petgraph",
|
||||
"prettyplease",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"regex",
|
||||
"syn",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.13.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.13.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16"
|
||||
dependencies = [
|
||||
"prost",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protobuf"
|
||||
version = "2.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94"
|
||||
|
||||
[[package]]
|
||||
name = "protobuf-codegen"
|
||||
version = "2.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "033460afb75cf755fcfc16dfaed20b86468082a2ea24e05ac35ab4a099a017d6"
|
||||
dependencies = [
|
||||
"protobuf",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protoc"
|
||||
version = "2.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0218039c514f9e14a5060742ecd50427f8ac4f85a6dc58f2ddb806e318c55ee"
|
||||
dependencies = [
|
||||
"log",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "protoc-rust"
|
||||
version = "2.28.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22f8a182bb17c485f20bdc4274a8c39000a61024cfe461c799b50fec77267838"
|
||||
dependencies = [
|
||||
"protobuf",
|
||||
"protobuf-codegen",
|
||||
"protoc",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "r-efi"
|
||||
version = "5.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.4.15",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.9.4",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.104"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"rustix 1.0.7",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "wap-types"
|
||||
version = "0.0.2-dev"
|
||||
dependencies = [
|
||||
"bytes 0.4.12",
|
||||
"prost",
|
||||
"prost-build",
|
||||
"protoc-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.14.2+wasi-0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
|
||||
dependencies = [
|
||||
"wit-bindgen-rt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
|
||||
dependencies = [
|
||||
"either",
|
||||
"home",
|
||||
"once_cell",
|
||||
"rustix 0.38.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
|
||||
dependencies = [
|
||||
"windows-targets 0.53.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm 0.52.6",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c66f69fcc9ce11da9966ddb31a40968cad001c5bedeb5c2b82ede4253ab48aef"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.53.0",
|
||||
"windows_aarch64_msvc 0.53.0",
|
||||
"windows_i686_gnu 0.53.0",
|
||||
"windows_i686_gnullvm 0.53.0",
|
||||
"windows_i686_msvc 0.53.0",
|
||||
"windows_x86_64_gnu 0.53.0",
|
||||
"windows_x86_64_gnullvm 0.53.0",
|
||||
"windows_x86_64_msvc 0.53.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.39.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
18
rust/cargo.toml
Normal file
18
rust/cargo.toml
Normal file
@ -0,0 +1,18 @@
|
||||
[workspace]
|
||||
|
||||
members = [
|
||||
"wap-types"
|
||||
]
|
||||
|
||||
default-members = [
|
||||
"wap-types"
|
||||
]
|
||||
|
||||
resolver = "3"
|
||||
|
||||
[workspace.package]
|
||||
version = "0.0.1-dev"
|
||||
|
||||
[workspace.dependencies]
|
||||
|
||||
|
||||
12
rust/wap-types/Cargo.toml
Normal file
12
rust/wap-types/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "wap-types"
|
||||
edition = "2024"
|
||||
version = "0.0.2-dev"
|
||||
|
||||
[dependencies]
|
||||
prost = "0.13.5"
|
||||
bytes = "0.4"
|
||||
|
||||
[build-dependencies]
|
||||
prost-build = "0.13.5"
|
||||
protoc-rust = "2"
|
||||
43
rust/wap-types/build.rs
Normal file
43
rust/wap-types/build.rs
Normal file
@ -0,0 +1,43 @@
|
||||
extern crate protoc_rust;
|
||||
|
||||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
fn get_proto_dir() -> PathBuf {
|
||||
println!(
|
||||
"Manifest dir: {:?}",
|
||||
env::var("CARGO_MANIFEST_DIR").unwrap()
|
||||
);
|
||||
// protos are stored in ../../proto/
|
||||
let mut proto_root_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
||||
proto_root_dir.pop();
|
||||
proto_root_dir.pop();
|
||||
proto_root_dir.push("proto");
|
||||
proto_root_dir.push("wap");
|
||||
|
||||
println!("proto_dir: {:?}", proto_root_dir);
|
||||
proto_root_dir
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut config = prost_build::Config::new();
|
||||
|
||||
// Create mod file to maintain import hierarchy
|
||||
config.include_file("mod.rs");
|
||||
|
||||
config
|
||||
.compile_protos(
|
||||
&[
|
||||
"envelope.proto",
|
||||
"common_frames.proto",
|
||||
"conversations/private_v1.proto",
|
||||
"encryption.proto",
|
||||
"inbox.proto",
|
||||
"invite.proto",
|
||||
"reliability.proto"
|
||||
],
|
||||
// set proto_path
|
||||
&[get_proto_dir().to_str().unwrap()],
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
24
rust/wap-types/src/lib.rs
Normal file
24
rust/wap-types/src/lib.rs
Normal file
@ -0,0 +1,24 @@
|
||||
pub mod payload;
|
||||
|
||||
pub use payload::types::wap::*;
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
mod tests {
|
||||
use super::*;
|
||||
use prost::Message;
|
||||
|
||||
#[test]
|
||||
fn test_private_v1_roundtrip() {
|
||||
convos::private_v1::PrivateV1Frame {
|
||||
conversation_id: "conversationId".to_string(),
|
||||
frame_type: Some(convos::private_v1::private_v1_frame::FrameType::Content(
|
||||
common_frames::ContentFrame {
|
||||
domain: 0,
|
||||
tag: 0,
|
||||
bytes: "Hello, World!".to_string().encode_to_vec(),
|
||||
},
|
||||
)),
|
||||
};
|
||||
}
|
||||
}
|
||||
94
rust/wap-types/src/payload.rs
Normal file
94
rust/wap-types/src/payload.rs
Normal file
@ -0,0 +1,94 @@
|
||||
pub mod types {
|
||||
include!(concat!(env!("OUT_DIR"), "/mod.rs"));
|
||||
}
|
||||
|
||||
use prost::Message;
|
||||
pub use types::wap::*;
|
||||
|
||||
use crate::{
|
||||
convos::private_v1::{PrivateV1Frame, private_v1_frame},
|
||||
encryption::EncryptedPayload,
|
||||
envelope::WapEnvelopeV1,
|
||||
inbox::{InboxV1Frame, inbox_v1_frame},
|
||||
};
|
||||
|
||||
impl PrivateV1Frame {
|
||||
pub fn new(conversation_id: String, frame: private_v1_frame::FrameType) -> Self {
|
||||
PrivateV1Frame {
|
||||
conversation_id,
|
||||
frame_type: Some(frame),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InboxV1Frame {
|
||||
pub fn new(recipient: String, frame: inbox_v1_frame::FrameType) -> Self {
|
||||
InboxV1Frame {
|
||||
recipient: recipient,
|
||||
// conversation_id,
|
||||
frame_type: Some(frame),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ToEnvelope {
|
||||
fn to_envelope(self, conversation_id: String, salt: u64) -> WapEnvelopeV1;
|
||||
}
|
||||
|
||||
impl ToEnvelope for EncryptedPayload {
|
||||
fn to_envelope(self, conversation_id: String, salt: u64) -> WapEnvelopeV1 {
|
||||
WapEnvelopeV1 {
|
||||
conversation_hint: conversation_id, // TODO
|
||||
salt,
|
||||
payload: self.encode_to_vec(), // Avoid allocation here?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use prost::Message;
|
||||
|
||||
use crate::reliability::ReliablePayload;
|
||||
use crate::common_frames::ContentFrame;
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_private_v1_roundtrip() {
|
||||
let text = "Hello, World!".to_string();
|
||||
|
||||
let msg = PrivateV1Frame {
|
||||
conversation_id: "conversationId".to_string(),
|
||||
frame_type: Some(private_v1_frame::FrameType::Content(
|
||||
ContentFrame {
|
||||
domain: 0,
|
||||
tag: 0,
|
||||
bytes: text.encode_to_vec(),
|
||||
},
|
||||
)),
|
||||
};
|
||||
|
||||
let reliable = ReliablePayload {
|
||||
message_id: "msg_id".into(),
|
||||
channel_id: msg.conversation_id.clone(),
|
||||
lamport_timestamp: 0,
|
||||
causal_history: vec![],
|
||||
bloom_filter: vec![1, 2, 3, 4],
|
||||
content: msg.encode_to_vec(),
|
||||
};
|
||||
|
||||
let buf = reliable.encode_to_vec();
|
||||
|
||||
let reliable_msg = ReliablePayload::decode(&*buf).unwrap();
|
||||
|
||||
let msg_from_bytes =
|
||||
PrivateV1Frame::decode(&*reliable_msg.content)
|
||||
.expect("Failed to decode message");
|
||||
|
||||
assert_eq!(
|
||||
msg, msg_from_bytes,
|
||||
"Encoded and decoded messages should match"
|
||||
);
|
||||
}
|
||||
}
|
||||
122
specs/<PROTO>.md
Normal file
122
specs/<PROTO>.md
Normal file
@ -0,0 +1,122 @@
|
||||
---
|
||||
title: Waku Application Protocol
|
||||
name: A private decentralized messaging protocol for multiple usecases.
|
||||
category: Standards Track
|
||||
status: raw
|
||||
tags: chat
|
||||
editor: Jazz Alyxzander<jazz@status.im>
|
||||
contributors:
|
||||
---
|
||||
# Abstract
|
||||
|
||||
This specification defines a modular communication protocol designed to provide a privacy focused approach to common messaging patterns. The protocol employs a lean root layer that defers to independent sub-protocols for defining communication behavior, with versioning as a first-class concept for handling protocol evolution.
|
||||
|
||||
# Background / Rationale / Motivation
|
||||
|
||||
Traditionally communication protocols face several critical challenges as they grow.
|
||||
|
||||
Different communication scenarios have vastly different requirements. A protocol optimized for high-volume public broadcasts performs poorly for intimate encrypted conversations, and vice versa. Monolithic protocols cannot optimize for these diverse use cases simultaneously.
|
||||
|
||||
Once widely deployed, communication protocols become difficult to modify. Even minor changes can break compatibility across clients. As a result versioning becomes a complex negotiation problem, which makes deploying protocol updates difficult. At each stage protocols become increasingly difficult to modify, which slows down forward progress and eventually leads to ossification.
|
||||
|
||||
A preferred approach would be to practice resiliency at the protocol level by focusing on versioning from the beginning.
|
||||
|
||||
# Theory / Semantics
|
||||
|
||||
This protocol is a lean coordination layer which provides the backbone for smaller independent "Conversation" sub-protocols. Conversation protocols completely define a pathway for communication. This root protocol provides common functionality to support a wide array of communication use cases, and the remaining functionality is deferred to Conversation protocols to define.
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
P(%PROTO) --> C1(Conversation)
|
||||
P --> C2(Conversation)
|
||||
P --> C3(....)
|
||||
style C3 fill:#FFFFFF,stroke:#,stroke-width:1px,stroke-dasharray: 5 1
|
||||
```
|
||||
|
||||
## Conversations
|
||||
ConversationTypes are standalone methods to send and receive messages. While a full service "chat" protocol needs to provide additional features such as identity management, message history, backups and versioning, conversations are more narrowly scoped.
|
||||
|
||||
They can be created permissionlessly within the %PROTO, as there is no required registration. Developers are free to use any given conversation type as long as all intended participants support it.
|
||||
|
||||
ConversationTypes MUST adhere to the [Conversations](./conversations.md) specification in order to maintain compatibility, however network adoption is not a requirement.
|
||||
|
||||
|
||||
|
||||
## Versioning
|
||||
|
||||
Incompatible versions of a conversation protocol result in distinct conversationTypes (E.g. PrivateV1 vs PrivateV3). The opinionated strategy is to allow multiplexing at the conversation level, rather than requiring the entire network of clients to run the same version.
|
||||
|
||||
Individual conversationTypes can implement functionality to migrate participants to a conversation, but that is deferred to contributors. By making this a conversationType issue, different use cases can choose a system that works for them.
|
||||
|
||||
Developers wishing to interop with other projects will need to ensure they have overlapping support of ConversationTypes.
|
||||
|
||||
|
||||
## Default Inbox
|
||||
There exists a circular dependency in initializing a Conversation. Conversations require an established conversation to send an invitation, yet at the beginning no channel exists between contacts.
|
||||
|
||||
To resolve this all clients MUST implement a default [Inbox](./inbox.md) to receive initial messages. The default inbox allows clients to discover new conversations asynchronously without prior coordination. By listening in a static location.
|
||||
|
||||
The default inbox MUST be configured with the parameters:
|
||||
- **inbox_addr:** `client_address`
|
||||
- **discriminator:** "default"
|
||||
|
||||
As the clients address is directly linked to the content_topic there is some metadata leakage, and this pathway SHOULD only be used as a last resort.
|
||||
|
||||
## Envelopes
|
||||
As clients can support multiple sub-protocols simultaneously, a mechanism is required to determine how decode messages.
|
||||
|
||||
All payloads sent MUST be deterministically decodable. Deterministic decoding means that clients can always classify a envelope as 1 of 3 states: Readable, BadlyFormed, Addressed to someone else. To support this %PROTO uses an Envelope to link encrypted payloads with the information required to process them. As this payload is sent in the clear the payloads cannot contain any identifiable information.
|
||||
|
||||
|
||||
|
||||
### Conversation Hinting
|
||||
Conversation_ids are sufficient to allow clients to lookup the required encryption parameters and decrypt a message. However this would leak Conversation metadata. Instead a hint is used which allows clients to check if this message is of interest.
|
||||
|
||||
Messages with an unknown hint can be safely disregarded.
|
||||
|
||||
ConversationHints are computed by using a salted hash of the `conversationId`. specifically defined as `lowercase_hex(blake2s(salt || conversation_id))`
|
||||
[TODO: Should conversations define their own hinting?]
|
||||
|
||||
|
||||
|
||||
## Wire Format Specification / Syntax
|
||||
|
||||
The wire format is specified using protocol buffers v3.
|
||||
|
||||
```protobuf
|
||||
|
||||
message WapEnvelopeV1 {
|
||||
|
||||
string conversation_hint = 1;
|
||||
uint32 salt = 2;
|
||||
|
||||
EncryptedBytes encrypted_bytes = 3;
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
## Implementation Suggestions (optional)
|
||||
|
||||
### User level Conversations
|
||||
|
||||
Application developers should maintain standalone identifiers for user-level conversations that are separate from the protocol-level conversation_id. A single logical conversation from the user's perspective may utilize multiple ConversationTypes over time. As versions are considered different types, the underlying relationship is many to one. By maintaining application-level conversation identifiers, developers can provide users with consistent conversation continuity while the underlying protocol mechanisms handle version transitions and security upgrades transparently.
|
||||
|
||||
|
||||
## (Further Optional Sections)
|
||||
|
||||
|
||||
## Security/Privacy Considerations
|
||||
|
||||
Messages inherit the privacy and security properties of the ConversationType used to send them. Please refer to the corresponding specifications when analyzing properties.
|
||||
|
||||
### Default Inbox Privacy
|
||||
Messages sent to the default inbox are linkable to an client (as it is derived from the clients address). This means that if a target client address is known to an observer, they can determine if any messages were sent to the target using the default inbox. In this case the Envelopes contain no sender information, so this does not leak social graph information.
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
||||
|
||||
## References
|
||||
|
||||
A list of references.
|
||||
89
specs/conversations.md
Normal file
89
specs/conversations.md
Normal file
@ -0,0 +1,89 @@
|
||||
---
|
||||
title: CONVERSATIONS
|
||||
name: Conversation based communications
|
||||
category: Standards Track
|
||||
status: raw
|
||||
tags: chat
|
||||
editor: Jazz Alyxzander<jazz@status.im>
|
||||
contributors:
|
||||
---
|
||||
# Abstract
|
||||
|
||||
This specification outlines the requirements for defining a ConversationType
|
||||
|
||||
# Background / Rationale / Motivation
|
||||
|
||||
Modern communication systems require a reliable and flexible way to establish and manage conversations between participants.
|
||||
While simple message-passing protocols exist, they lack the ability to manage state across a stream of messages.
|
||||
|
||||
The Conversations Protocol addresses this gap by defining a mechanism to establish long term communication sessions in decentralized environments.
|
||||
|
||||
|
||||
# Theory / Semantics
|
||||
|
||||
A ConversationType is a specification which defines a method for clients to communicate.
|
||||
Each ConversationType defines its own encryption, encoding, and message types which are necessary for operation.
|
||||
|
||||
A Conversation is an instance of a particular ConversationType which contains the associated state such as membership, encryption parameters, names etc.
|
||||
|
||||
## Requirements
|
||||
To be considered valid, every ConversationType specification is required to define the operation completely.
|
||||
|
||||
A ConversationType MUST define which encryption scheme is used
|
||||
A ConversationType MUST define which Frames are used.
|
||||
A ConversationType MUST define which encoding is used.
|
||||
A ConversationType MUST define which content topics are valid places to receive messages.
|
||||
A ConversationType MUST define how to generate conversation_ids
|
||||
|
||||
A ConversationType SHOULD define membership requirements and limitations.
|
||||
A ConversationType SHOULD define privacy and security guarantees.
|
||||
A ConversationType SHOULD maintain a deterministic decoding tree.
|
||||
|
||||
## ConversationType Identifiers
|
||||
ConversationTypes are identified by the title of the specification. This allows developers to lookup the associated specification.
|
||||
|
||||
[TODO: This doesn't make any sense, as its been mentioned that new versions of a conversationType are distinct types. Which is it? ]
|
||||
|
||||
E.g. inbox.md -> InboxV1
|
||||
|
||||
## Conversation Identifiers
|
||||
|
||||
conversation_ids allow for the efficient lookup of encryption state.
|
||||
|
||||
Care should be taken to ensure that conversation_ids do not conflict.
|
||||
[TODO: Should more guidance be added later? e,g mandating a format to ensure uniqueness between conversationTypes -- /<convo_name>/<version>/<ident>]
|
||||
|
||||
[TODO: touch on the nuance of generating conversation_ids from participant lists?]
|
||||
|
||||
|
||||
## Framing
|
||||
To disambiguate between different logical layers, payload types sent by a Conversation are referred to as `Frames`.
|
||||
Conversations are free to determine which frames are needed for their specific use cases.
|
||||
|
||||
|
||||
|
||||
|
||||
## Encryption
|
||||
Conversation types are free to choose which ever encryption mechanism works best for their application.
|
||||
[TODO: Expand on recomendations]
|
||||
|
||||
|
||||
## Content Topics
|
||||
Content topics are how ConversationTypes define where an how messages are discovered by participants.
|
||||
|
||||
When developing new ConversationTypes contributors should consider:
|
||||
- Privacy impacts of the chosen topic policy.
|
||||
- Channel binding and the impacts on message security.
|
||||
|
||||
|
||||
## Security/Privacy Considerations
|
||||
|
||||
This approach puts heavy requirements on ConversationTypes to build their own cryptography without providing much guidance. Finding mechanisms that provide safety while maintaining the flexibility should be prioritized in follow up work.
|
||||
|
||||
## Copyright
|
||||
|
||||
Copyright and related rights waived via [CC0](https://creativecommons.org/publicdomain/zero/1.0/).
|
||||
|
||||
## References
|
||||
|
||||
A list of references.
|
||||
1
specs/inbox.md
Normal file
1
specs/inbox.md
Normal file
@ -0,0 +1 @@
|
||||
Moved to WakuSpecs - https://github.com/waku-org/specs/pull/72
|
||||
Loading…
x
Reference in New Issue
Block a user