river_core/chat_delegate.rs
1use serde::{Deserialize, Serialize};
2
3/// Room key identifier (owner's verifying key bytes)
4pub type RoomKey = [u8; 32];
5
6/// Unique identifier for a signing request (for request/response correlation)
7pub type RequestId = u64;
8
9/// Messages sent from the App to the Chat Delegate
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub enum ChatDelegateRequestMsg {
12 // Key-value storage operations
13 StoreRequest {
14 key: ChatDelegateKey,
15 value: Vec<u8>,
16 },
17 GetRequest {
18 key: ChatDelegateKey,
19 },
20 DeleteRequest {
21 key: ChatDelegateKey,
22 },
23 ListRequest,
24
25 // Signing key management
26 /// Store a signing key for a room (room_key = owner's verifying key bytes)
27 StoreSigningKey {
28 room_key: RoomKey,
29 signing_key_bytes: [u8; 32],
30 },
31 /// Get the public key for a stored signing key
32 GetPublicKey {
33 room_key: RoomKey,
34 },
35
36 // Signing operations - pass serialized data, get signature back
37 // All signing ops include request_id for response correlation
38 /// Sign a message (MessageV1 serialized)
39 SignMessage {
40 room_key: RoomKey,
41 request_id: RequestId,
42 message_bytes: Vec<u8>,
43 },
44 /// Sign a member invitation (Member serialized)
45 SignMember {
46 room_key: RoomKey,
47 request_id: RequestId,
48 member_bytes: Vec<u8>,
49 },
50 /// Sign a ban (BanV1 serialized)
51 SignBan {
52 room_key: RoomKey,
53 request_id: RequestId,
54 ban_bytes: Vec<u8>,
55 },
56 /// Sign a room configuration (Configuration serialized)
57 SignConfig {
58 room_key: RoomKey,
59 request_id: RequestId,
60 config_bytes: Vec<u8>,
61 },
62 /// Sign member info (MemberInfo serialized)
63 SignMemberInfo {
64 room_key: RoomKey,
65 request_id: RequestId,
66 member_info_bytes: Vec<u8>,
67 },
68 /// Sign a secret version record (SecretVersionRecordV1 serialized)
69 SignSecretVersion {
70 room_key: RoomKey,
71 request_id: RequestId,
72 record_bytes: Vec<u8>,
73 },
74 /// Sign an encrypted secret for member (EncryptedSecretForMemberV1 serialized)
75 SignEncryptedSecret {
76 room_key: RoomKey,
77 request_id: RequestId,
78 secret_bytes: Vec<u8>,
79 },
80 /// Sign a room upgrade (RoomUpgrade serialized)
81 SignUpgrade {
82 room_key: RoomKey,
83 request_id: RequestId,
84 upgrade_bytes: Vec<u8>,
85 },
86
87 /// Ask the delegate to subscribe to a room contract so the delegate can
88 /// drive secret rotation when the membership set changes.
89 ///
90 /// `contract_id` is the 32-byte ContractInstanceId for the room contract,
91 /// computed by the UI as `BLAKE3(room_contract_wasm_hash || params)` where
92 /// `params` is the cbor-serialised `ChatRoomParametersV1 { owner: room_owner_vk }`.
93 /// We pass it explicitly rather than recomputing it inside the delegate so
94 /// that the delegate WASM doesn't need to bundle the room-contract WASM.
95 EnsureRoomSubscription {
96 room_owner_vk: RoomKey,
97 contract_id: [u8; 32],
98 },
99}
100
101#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
102pub struct ChatDelegateKey(pub Vec<u8>);
103
104impl ChatDelegateKey {
105 pub fn new(key: Vec<u8>) -> Self {
106 Self(key)
107 }
108
109 pub fn as_bytes(&self) -> &[u8] {
110 &self.0
111 }
112}
113
114/// Responses sent from the Chat Delegate to the App
115#[derive(Debug, Clone, Serialize, Deserialize)]
116pub enum ChatDelegateResponseMsg {
117 // Key-value storage responses
118 GetResponse {
119 key: ChatDelegateKey,
120 value: Option<Vec<u8>>,
121 },
122 ListResponse {
123 keys: Vec<ChatDelegateKey>,
124 },
125 StoreResponse {
126 key: ChatDelegateKey,
127 value_size: usize,
128 result: Result<(), String>,
129 },
130 DeleteResponse {
131 key: ChatDelegateKey,
132 result: Result<(), String>,
133 },
134
135 // Signing key management responses
136 /// Response to StoreSigningKey
137 StoreSigningKeyResponse {
138 room_key: RoomKey,
139 result: Result<(), String>,
140 },
141 /// Response to GetPublicKey
142 GetPublicKeyResponse {
143 room_key: RoomKey,
144 /// The public key bytes if the signing key exists
145 public_key: Option<[u8; 32]>,
146 },
147
148 // Signing response (used for all signing operations)
149 /// Response to any signing operation
150 SignResponse {
151 room_key: RoomKey,
152 /// The request ID for correlation
153 request_id: RequestId,
154 /// The signature bytes (64 bytes for Ed25519, as Vec for serde compatibility)
155 signature: Result<Vec<u8>, String>,
156 },
157
158 /// Response to [`ChatDelegateRequestMsg::EnsureRoomSubscription`].
159 ///
160 /// `Ok(())` means the delegate emitted a `SubscribeContractRequest` to the
161 /// runtime; the actual subscription confirmation flows back to the
162 /// delegate as `InboundDelegateMsg::SubscribeContractResponse` and is not
163 /// surfaced to the UI.
164 EnsureRoomSubscriptionResponse {
165 room_owner_vk: RoomKey,
166 result: Result<(), String>,
167 },
168}