feat: buf generate with prost

This commit is contained in:
kaichaosun 2026-01-06 15:30:37 +08:00
parent 4d1c32a5e2
commit 39474393c0
No known key found for this signature in database
GPG Key ID: 223E0F992F4F03BF
14 changed files with 369 additions and 29 deletions

View File

@ -1 +1,59 @@
# chat_proto
# 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,
};
```

6
buf.gen.yaml Normal file
View File

@ -0,0 +1,6 @@
version: v2
plugins:
- remote: buf.build/community/neoeinstein-prost:v0.5.0
out: gen/rust/src
opt:
- bytes=.

10
buf.yaml Normal file
View File

@ -0,0 +1,10 @@
version: v2
modules:
- path: protos
lint:
use:
- DEFAULT
breaking:
use:
- FILE

1
gen/rust/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
target/

95
gen/rust/Cargo.lock generated Normal file
View File

@ -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"

7
gen/rust/Cargo.toml Normal file
View File

@ -0,0 +1,7 @@
[package]
name = "chat-proto"
version = "0.1.0"
edition = "2021"
[dependencies]
prost = "0.14"

30
gen/rust/src/lib.rs Normal file
View File

@ -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");
}
}

View File

@ -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<private_v1_frame::FrameType>,
}
/// 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)

View File

@ -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<encrypted_payload::Encryption>,
}
/// 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)

View File

@ -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)

View File

@ -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<inbox_v1_frame::FrameType>,
}
/// 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)

View File

@ -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<super::encryption::EncryptedPayload>,
}
// @@protoc_insertion_point(module)

View File

@ -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<HistoryEntry>,
#[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)

View File

@ -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;
// ...
}
}