Skip to main content

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}