From 39474393c0584980031ce04e4be65bdf731fdcf8 Mon Sep 17 00:00:00 2001 From: kaichaosun Date: Tue, 6 Jan 2026 15:30:37 +0800 Subject: [PATCH] feat: buf generate with prost --- README.md | 60 +++++++++++- buf.gen.yaml | 6 ++ buf.yaml | 10 ++ gen/rust/.gitignore | 1 + gen/rust/Cargo.lock | 95 +++++++++++++++++++ gen/rust/Cargo.toml | 7 ++ gen/rust/src/lib.rs | 30 ++++++ .../private_v1/wap.convos.private_v1.rs | 31 ++++++ gen/rust/src/wap/encryption/wap.encryption.rs | 39 ++++++++ gen/rust/src/wap/envelope/wap.envelope.rs | 16 ++++ gen/rust/src/wap/inbox/wap.inbox.rs | 25 +++++ gen/rust/src/wap/invite/wap.invite.rs | 18 ++++ .../src/wap/reliability/wap.reliability.rs | 32 +++++++ protos/conversations/group_v1.proto | 28 ------ 14 files changed, 369 insertions(+), 29 deletions(-) create mode 100644 buf.gen.yaml create mode 100644 buf.yaml create mode 100644 gen/rust/.gitignore create mode 100644 gen/rust/Cargo.lock create mode 100644 gen/rust/Cargo.toml create mode 100644 gen/rust/src/lib.rs create mode 100644 gen/rust/src/wap/convos/private_v1/wap.convos.private_v1.rs create mode 100644 gen/rust/src/wap/encryption/wap.encryption.rs create mode 100644 gen/rust/src/wap/envelope/wap.envelope.rs create mode 100644 gen/rust/src/wap/inbox/wap.inbox.rs create mode 100644 gen/rust/src/wap/invite/wap.invite.rs create mode 100644 gen/rust/src/wap/reliability/wap.reliability.rs delete mode 100644 protos/conversations/group_v1.proto diff --git a/README.md b/README.md index 2f12ed0..ccba49f 100644 --- a/README.md +++ b/README.md @@ -1 +1,59 @@ -# chat_proto \ No newline at end of file +# Chat Protobuf Definitionss + +This repository contains the canonical **protobuf definitions** for the WAP (Waku Application Protocol) used by LibChat and related components. + +It is **schema-only**: +- No application logic +- Stable, versioned wire formats +- Intended to be consumed by multiple languages + +Generated bindings (e.g. Rust) are produced from these schemas. + +--- + +## Prerequisites + +This project uses [Buf](https://buf.build) for protobuf linting and code generation. + +### Install Buf + +On macOS and Linux: +```sh +brew install bufbuild/buf/buf +``` + +For other platforms, See https://buf.build/docs/cli/installation/. + +## Repository Structure + +``` +protos/ # Protobuf source files +buf.yaml # Buf module configuration +buf.gen.yaml # Code generation configuration +gen/ + └── rust/ # Generated Rust bindings (prost) +``` + +## Generate Rust bindings + +``` +buf generate +``` + +This will generate Rust code under: `gen/rust/`, The generated crate can be used directly as a dependency in Rust projects. + +## Usage (Rust) + +Add in Cargo.toml: +``` +chat-proto = { git = "https://github.com/logos-messaging/chat_proto" } +``` + +Example import: +``` +use chat_proto::wap::{ + inbox::InboxV1Frame, + invite::InvitePrivateV1, + encryption::EncryptedPayload, +}; +``` diff --git a/buf.gen.yaml b/buf.gen.yaml new file mode 100644 index 0000000..1473f61 --- /dev/null +++ b/buf.gen.yaml @@ -0,0 +1,6 @@ +version: v2 +plugins: + - remote: buf.build/community/neoeinstein-prost:v0.5.0 + out: gen/rust/src + opt: + - bytes=. diff --git a/buf.yaml b/buf.yaml new file mode 100644 index 0000000..3e61dfc --- /dev/null +++ b/buf.yaml @@ -0,0 +1,10 @@ +version: v2 + +modules: + - path: protos +lint: + use: + - DEFAULT +breaking: + use: + - FILE diff --git a/gen/rust/.gitignore b/gen/rust/.gitignore new file mode 100644 index 0000000..2f7896d --- /dev/null +++ b/gen/rust/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/gen/rust/Cargo.lock b/gen/rust/Cargo.lock new file mode 100644 index 0000000..6f9eaaa --- /dev/null +++ b/gen/rust/Cargo.lock @@ -0,0 +1,95 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + +[[package]] +name = "bytes" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" + +[[package]] +name = "chat-proto" +version = "0.1.0" +dependencies = [ + "prost", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "proc-macro2" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7231bd9b3d3d33c86b58adbac74b5ec0ad9f496b19d22801d773636feaa95f3d" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9120690fafc389a67ba3803df527d0ec9cbbc9cc45e4cc20b332996dfb672425" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "quote" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "syn" +version = "2.0.113" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678faa00651c9eb72dd2020cbdf275d92eccb2400d568e419efdd64838145cb4" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" diff --git a/gen/rust/Cargo.toml b/gen/rust/Cargo.toml new file mode 100644 index 0000000..96d14d7 --- /dev/null +++ b/gen/rust/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "chat-proto" +version = "0.1.0" +edition = "2021" + +[dependencies] +prost = "0.14" diff --git a/gen/rust/src/lib.rs b/gen/rust/src/lib.rs new file mode 100644 index 0000000..d41c597 --- /dev/null +++ b/gen/rust/src/lib.rs @@ -0,0 +1,30 @@ +// #![allow(clippy::all)] +// #![allow(warnings)] + +pub mod wap { + pub mod convos { + pub mod private_v1 { + include!("wap/convos/private_v1/wap.convos.private_v1.rs"); + } + } + + pub mod encryption { + include!("wap/encryption/wap.encryption.rs"); + } + + pub mod envelope { + include!("wap/envelope/wap.envelope.rs"); + } + + pub mod inbox { + include!("wap/inbox/wap.inbox.rs"); + } + + pub mod invite { + include!("wap/invite/wap.invite.rs"); + } + + pub mod reliability { + include!("wap/reliability/wap.reliability.rs"); + } +} diff --git a/gen/rust/src/wap/convos/private_v1/wap.convos.private_v1.rs b/gen/rust/src/wap/convos/private_v1/wap.convos.private_v1.rs new file mode 100644 index 0000000..b658325 --- /dev/null +++ b/gen/rust/src/wap/convos/private_v1/wap.convos.private_v1.rs @@ -0,0 +1,31 @@ +// @generated +// This file is @generated by prost-build. +#[derive(Clone, Copy, PartialEq, Eq, Hash, ::prost::Message)] +pub struct Placeholder { + #[prost(uint32, tag="1")] + pub counter: u32, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct PrivateV1Frame { + #[prost(string, tag="1")] + pub conversation_id: ::prost::alloc::string::String, + #[prost(bytes="bytes", tag="2")] + pub sender: ::prost::bytes::Bytes, + /// Sender reported timestamp + #[prost(int64, tag="3")] + pub timestamp: i64, + #[prost(oneof="private_v1_frame::FrameType", tags="10, 11")] + pub frame_type: ::core::option::Option, +} +/// Nested message and enum types in `PrivateV1Frame`. +pub mod private_v1_frame { + #[derive(Clone, PartialEq, Eq, Hash, ::prost::Oneof)] + pub enum FrameType { + #[prost(bytes, tag="10")] + Content(::prost::bytes::Bytes), + /// .... + #[prost(message, tag="11")] + Placeholder(super::Placeholder), + } +} +// @@protoc_insertion_point(module) diff --git a/gen/rust/src/wap/encryption/wap.encryption.rs b/gen/rust/src/wap/encryption/wap.encryption.rs new file mode 100644 index 0000000..1495f03 --- /dev/null +++ b/gen/rust/src/wap/encryption/wap.encryption.rs @@ -0,0 +1,39 @@ +// @generated +// This file is @generated by prost-build. +/// TODO: This also encompasses plaintexts, is there a better name? +/// Alternatives: ??? +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct EncryptedPayload { + #[prost(oneof="encrypted_payload::Encryption", tags="1, 2")] + pub encryption: ::core::option::Option, +} +/// Nested message and enum types in `EncryptedPayload`. +pub mod encrypted_payload { + #[derive(Clone, PartialEq, Eq, Hash, ::prost::Oneof)] + pub enum Encryption { + #[prost(message, tag="1")] + Plaintext(super::Plaintext), + #[prost(message, tag="2")] + Doubleratchet(super::Doubleratchet), + } +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct Plaintext { + #[prost(bytes="bytes", tag="1")] + pub payload: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct Doubleratchet { + /// 32 byte array + #[prost(bytes="bytes", tag="1")] + pub dh: ::prost::bytes::Bytes, + #[prost(uint32, tag="2")] + pub msg_num: u32, + #[prost(uint32, tag="3")] + pub prev_chain_len: u32, + #[prost(bytes="bytes", tag="4")] + pub ciphertext: ::prost::bytes::Bytes, + #[prost(string, tag="5")] + pub aux: ::prost::alloc::string::String, +} +// @@protoc_insertion_point(module) diff --git a/gen/rust/src/wap/envelope/wap.envelope.rs b/gen/rust/src/wap/envelope/wap.envelope.rs new file mode 100644 index 0000000..c6b26c4 --- /dev/null +++ b/gen/rust/src/wap/envelope/wap.envelope.rs @@ -0,0 +1,16 @@ +// @generated +// This file is @generated by prost-build. +// ///////////////////////////////////////////////////////////////////////////// +// Payload Framing Messages +// ///////////////////////////////////////////////////////////////////////////// + +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct WapEnvelopeV1 { + #[prost(string, tag="1")] + pub conversation_hint: ::prost::alloc::string::String, + #[prost(uint64, tag="2")] + pub salt: u64, + #[prost(bytes="bytes", tag="5")] + pub payload: ::prost::bytes::Bytes, +} +// @@protoc_insertion_point(module) diff --git a/gen/rust/src/wap/inbox/wap.inbox.rs b/gen/rust/src/wap/inbox/wap.inbox.rs new file mode 100644 index 0000000..a08b290 --- /dev/null +++ b/gen/rust/src/wap/inbox/wap.inbox.rs @@ -0,0 +1,25 @@ +// @generated +// This file is @generated by prost-build. +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct Note { + #[prost(string, tag="1")] + pub text: ::prost::alloc::string::String, +} +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct InboxV1Frame { + #[prost(string, tag="1")] + pub recipient: ::prost::alloc::string::String, + #[prost(oneof="inbox_v1_frame::FrameType", tags="10, 11")] + pub frame_type: ::core::option::Option, +} +/// Nested message and enum types in `InboxV1Frame`. +pub mod inbox_v1_frame { + #[derive(Clone, PartialEq, Eq, Hash, ::prost::Oneof)] + pub enum FrameType { + #[prost(message, tag="10")] + InvitePrivateV1(super::super::invite::InvitePrivateV1), + #[prost(message, tag="11")] + Note(super::Note), + } +} +// @@protoc_insertion_point(module) diff --git a/gen/rust/src/wap/invite/wap.invite.rs b/gen/rust/src/wap/invite/wap.invite.rs new file mode 100644 index 0000000..013e528 --- /dev/null +++ b/gen/rust/src/wap/invite/wap.invite.rs @@ -0,0 +1,18 @@ +// @generated +// This file is @generated by prost-build. +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct InvitePrivateV1 { + #[prost(bytes="bytes", tag="1")] + pub initiator: ::prost::bytes::Bytes, + #[prost(bytes="bytes", tag="2")] + pub initiator_ephemeral: ::prost::bytes::Bytes, + #[prost(bytes="bytes", tag="3")] + pub participant: ::prost::bytes::Bytes, + #[prost(int32, tag="4")] + pub participant_ephemeral_id: i32, + #[prost(string, tag="5")] + pub discriminator: ::prost::alloc::string::String, + #[prost(message, optional, tag="6")] + pub initial_message: ::core::option::Option, +} +// @@protoc_insertion_point(module) diff --git a/gen/rust/src/wap/reliability/wap.reliability.rs b/gen/rust/src/wap/reliability/wap.reliability.rs new file mode 100644 index 0000000..36f2e46 --- /dev/null +++ b/gen/rust/src/wap/reliability/wap.reliability.rs @@ -0,0 +1,32 @@ +// @generated +// This file is @generated by prost-build. +// ///////////////////////////////////////////////////////////////////////////// +// SDS Payloads +// ///////////////////////////////////////////////////////////////////////////// + +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct HistoryEntry { + /// Unique identifier of the SDS message, as defined in `Message` + #[prost(string, tag="1")] + pub message_id: ::prost::alloc::string::String, + /// Optional information to help remote parties retrieve this SDS + #[prost(bytes="bytes", tag="2")] + pub retrieval_hint: ::prost::bytes::Bytes, +} +#[derive(Clone, PartialEq, ::prost::Message)] +pub struct ReliablePayload { + #[prost(string, tag="2")] + pub message_id: ::prost::alloc::string::String, + #[prost(string, tag="3")] + pub channel_id: ::prost::alloc::string::String, + #[prost(int32, tag="10")] + pub lamport_timestamp: i32, + #[prost(message, repeated, tag="11")] + pub causal_history: ::prost::alloc::vec::Vec, + #[prost(bytes="bytes", tag="12")] + pub bloom_filter: ::prost::bytes::Bytes, + /// Optional field causes errors in nim protobuf generation. Removing for now as optional is implied anways. + #[prost(bytes="bytes", tag="20")] + pub content: ::prost::bytes::Bytes, +} +// @@protoc_insertion_point(module) diff --git a/protos/conversations/group_v1.proto b/protos/conversations/group_v1.proto deleted file mode 100644 index fde7013..0000000 --- a/protos/conversations/group_v1.proto +++ /dev/null @@ -1,28 +0,0 @@ -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; - // ... - } -}