Matrix protocol in OCaml, Eio specialised

Add accessors, pp functions, and missing .mli files to ocaml-matrix

matrix_proto changes:
- Add pp functions to all matrix_id modules (User_id, Room_id, etc.)
- Add make constructors and accessor functions to event content types
- Add pp functions to Msgtype, Event_type, and message content types
- Add doc comments with @see links to Matrix spec

matrix_client changes:
- Create 13 missing .mli files: backup, calls, matrix_client, olm,
push, room_preview, send_queue, sliding_sync, spaces, store,
timeline, uiaa, verification
- Fix type annotation in verification.ml

All tests pass and dune build @doc-full produces no warnings.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

+4191 -153
+243
lib/matrix_client/backup.mli
···
··· 1 + (** Server-side key backup and recovery. 2 + 3 + This module implements Matrix server-side backup of room keys using the 4 + m.megolm_backup.v1.curve25519-aes-sha2 backup algorithm. 5 + 6 + Key backup allows clients to store encrypted room keys on the server so 7 + they can be recovered on new devices or after data loss. 8 + 9 + Note: Due to various known flaws in this algorithm, it is provided mainly 10 + for backwards compatibility with existing backups. 11 + 12 + @see <https://spec.matrix.org/v1.11/client-server-api/#server-side-key-backups> Key Backups *) 13 + 14 + (** {1 Signature Verification} *) 15 + 16 + (** Signature verification state. *) 17 + type signature_state = 18 + | Missing 19 + | Invalid 20 + | Valid_but_not_trusted 21 + | Valid_and_trusted 22 + 23 + val signature_state_trusted : signature_state -> bool 24 + (** Check if a signature state indicates trust. *) 25 + 26 + (** Signature verification result. *) 27 + type signature_verification = { 28 + device_signature : signature_state; 29 + user_identity_signature : signature_state; 30 + other_signatures : (string * signature_state) list; 31 + } 32 + 33 + val signature_verification_trusted : signature_verification -> bool 34 + (** Check if any signature is trusted. *) 35 + 36 + val empty_signature_verification : signature_verification 37 + (** Empty signature verification with all signatures missing. *) 38 + 39 + (** {1 Auth Data Types} *) 40 + 41 + (** Auth data for m.megolm_backup.v1.curve25519-aes-sha2. *) 42 + type megolm_v1_auth_data = { 43 + public_key : string; 44 + signatures : (string * (string * string) list) list; 45 + } 46 + 47 + val signatures_to_json : (string * (string * string) list) list -> string 48 + (** Convert signatures to JSON string. *) 49 + 50 + val megolm_v1_auth_data_to_json : megolm_v1_auth_data -> string 51 + (** Encode auth data to JSON string. *) 52 + 53 + (** {1 Backup Info} *) 54 + 55 + (** Room key backup info - describes the backup algorithm and parameters. *) 56 + type backup_info = 57 + | Megolm_v1_curve25519_aes_sha2 of megolm_v1_auth_data 58 + | Other of { algorithm : string; auth_data : Jsont.json } 59 + 60 + (** Backup version info from server. *) 61 + type backup_version_info = { 62 + version : string; 63 + algorithm : string; 64 + auth_data : Jsont.json; 65 + count : int; 66 + etag : string; 67 + } 68 + 69 + (** {1 Backup Keys} *) 70 + 71 + (** Private key for decrypting backed up room keys. *) 72 + type backup_decryption_key = { 73 + private_key : string; 74 + public_key : string; 75 + } 76 + 77 + (** Public key for encrypting room keys for backup. *) 78 + type backup_encryption_key = { 79 + public_key : string; 80 + mutable backup_version : string option; 81 + mutable signatures : (string * (string * string) list) list; 82 + } 83 + 84 + val generate_backup_key : unit -> backup_decryption_key 85 + (** Generate a new backup key pair. *) 86 + 87 + val encryption_key_of_decryption_key : backup_decryption_key -> backup_encryption_key 88 + (** Create encryption key from decryption key. *) 89 + 90 + val encryption_key_of_base64 : string -> (backup_encryption_key, string) result 91 + (** Create encryption key from base64 public key. *) 92 + 93 + val backup_algorithm : string 94 + (** The backup algorithm name. *) 95 + 96 + (** {1 Encrypted Session Data} *) 97 + 98 + (** Encrypted session data (matches Matrix spec). *) 99 + type encrypted_session_data = { 100 + ephemeral : string; 101 + ciphertext : string; 102 + mac : string; 103 + } 104 + 105 + (** Key backup data for a single session. *) 106 + type key_backup_data = { 107 + first_message_index : int; 108 + forwarded_count : int; 109 + is_verified : bool; 110 + session_data : encrypted_session_data; 111 + } 112 + 113 + (** Room key backup request (for upload). *) 114 + type keys_backup_request = { 115 + rooms : (string * (string * key_backup_data) list) list; 116 + } 117 + 118 + (** {1 Encryption/Decryption} *) 119 + 120 + val encrypt_room_key : 121 + backup_encryption_key -> 122 + session_key:string -> 123 + session_id:string -> 124 + room_id:string -> 125 + sender_key:string -> 126 + (encrypted_session_data, string) result 127 + (** Encrypt a room key for backup using X25519/AES-256/HMAC-SHA256. *) 128 + 129 + val decrypt_room_key : 130 + backup_decryption_key -> 131 + encrypted_session_data -> 132 + (string, string) result 133 + (** Decrypt a room key from backup. *) 134 + 135 + (** {1 Backup Machine} *) 136 + 137 + (** State of the backup machine. *) 138 + type backup_state = 139 + | Disabled 140 + | Creating 141 + | Enabling 142 + | Resuming 143 + | Enabled 144 + | Downloading 145 + | Disabling 146 + 147 + (** Backup machine for managing room key backups. *) 148 + type t = { 149 + user_id : Matrix_proto.Id.User_id.t; 150 + device_id : Matrix_proto.Id.Device_id.t; 151 + mutable state : backup_state; 152 + mutable encryption_key : backup_encryption_key option; 153 + mutable decryption_key : backup_decryption_key option; 154 + mutable backup_version : string option; 155 + mutable pending_sessions : (string * string * string) list; 156 + mutable backed_up_sessions : (string * string) list; 157 + } 158 + 159 + val create : 160 + user_id:Matrix_proto.Id.User_id.t -> 161 + device_id:Matrix_proto.Id.Device_id.t -> 162 + t 163 + (** Create a new backup machine. *) 164 + 165 + val is_enabled : t -> bool 166 + (** Check if backup is enabled. *) 167 + 168 + val backup_version : t -> string option 169 + (** Get the current backup version. *) 170 + 171 + (** {1 Backup Setup} *) 172 + 173 + val enable_with_new_key : t -> backup_decryption_key 174 + (** Enable backup with a new key. *) 175 + 176 + val enable_with_key : t -> backup_decryption_key -> unit 177 + (** Enable backup with an existing decryption key. *) 178 + 179 + val enable_upload_only : t -> backup_encryption_key -> string -> unit 180 + (** Enable backup with only an encryption key (upload-only mode). *) 181 + 182 + val set_backup_version : t -> string -> unit 183 + (** Set the backup version after creating. *) 184 + 185 + val disable : t -> unit 186 + (** Disable backup. *) 187 + 188 + (** {1 Session Management} *) 189 + 190 + val mark_session_for_backup : 191 + t -> 192 + room_id:string -> 193 + session_id:string -> 194 + sender_key:string -> 195 + unit 196 + (** Mark a session as needing backup. *) 197 + 198 + val pending_count : t -> int 199 + (** Get number of pending sessions. *) 200 + 201 + val is_session_backed_up : t -> room_id:string -> session_id:string -> bool 202 + (** Check if a session has been backed up. *) 203 + 204 + val mark_session_backed_up : t -> room_id:string -> session_id:string -> unit 205 + (** Mark a session as backed up. *) 206 + 207 + (** {1 Room Key Recovery} *) 208 + 209 + (** Recovered room key data. *) 210 + type recovered_room_key = { 211 + room_id : string; 212 + session_id : string; 213 + session_key : string; 214 + sender_key : string; 215 + algorithm : string; 216 + forwarded : bool; 217 + } 218 + 219 + val parse_recovered_key : string -> recovered_room_key option 220 + (** Parse a recovered room key from decrypted JSON. *) 221 + 222 + (** Result of importing keys from backup. *) 223 + type import_result = { 224 + imported_count : int; 225 + total_count : int; 226 + keys : recovered_room_key list; 227 + } 228 + 229 + (** {1 Backup API Helpers} *) 230 + 231 + val build_auth_data : backup_encryption_key -> megolm_v1_auth_data 232 + (** Build auth data for a new backup. *) 233 + 234 + val create_version_request_body : t -> (string, string) result 235 + (** Create backup version request body. *) 236 + 237 + (** {1 Recovery Key Format} *) 238 + 239 + val encode_recovery_key : backup_decryption_key -> (string, string) result 240 + (** Encode a backup decryption key as a recovery key (human-readable). *) 241 + 242 + val decode_recovery_key : string -> (backup_decryption_key, string) result 243 + (** Decode a recovery key to a backup decryption key. *)
+119
lib/matrix_client/calls.mli
···
··· 1 + (** VoIP call signaling operations. 2 + 3 + @see <https://spec.matrix.org/v1.11/client-server-api/#voice-over-ip> VoIP *) 4 + 5 + (** {1 Call State} *) 6 + 7 + (** Call state. *) 8 + type call_state = 9 + | Ringing 10 + | Connected 11 + | Ended 12 + 13 + (** {1 Call ID Generation} *) 14 + 15 + val generate_call_id : unit -> string 16 + (** Generate a new call ID. *) 17 + 18 + val generate_party_id : unit -> string 19 + (** Generate a new party ID for multi-party calls. *) 20 + 21 + (** {1 Call Signaling} *) 22 + 23 + val send_invite : 24 + Client.t -> 25 + room_id:Matrix_proto.Id.Room_id.t -> 26 + call_id:string -> 27 + offer:Matrix_proto.Event.Call_invite_content.sdp_content -> 28 + lifetime:int -> 29 + ?version:int -> 30 + ?party_id:string -> 31 + ?invitee:string -> 32 + unit -> 33 + (Matrix_proto.Id.Event_id.t, Error.t) result 34 + (** Send a call invite. 35 + 36 + @param room_id The room to send the invite in 37 + @param call_id The call ID 38 + @param offer The SDP offer 39 + @param lifetime How long the invite is valid in milliseconds 40 + @param version Call version (0 or 1) 41 + @param party_id Party ID for version 1 calls 42 + @param invitee Optional user to invite (for version 1 calls) *) 43 + 44 + val send_candidates : 45 + Client.t -> 46 + room_id:Matrix_proto.Id.Room_id.t -> 47 + call_id:string -> 48 + candidates:Matrix_proto.Event.Call_candidates_content.candidate list -> 49 + ?version:int -> 50 + ?party_id:string -> 51 + unit -> 52 + (Matrix_proto.Id.Event_id.t, Error.t) result 53 + (** Send call candidates (ICE candidates). 54 + 55 + @param room_id The room 56 + @param call_id The call ID 57 + @param candidates List of ICE candidates 58 + @param version Call version 59 + @param party_id Party ID for version 1 calls *) 60 + 61 + val send_answer : 62 + Client.t -> 63 + room_id:Matrix_proto.Id.Room_id.t -> 64 + call_id:string -> 65 + answer:Matrix_proto.Event.Call_answer_content.sdp_content -> 66 + ?version:int -> 67 + ?party_id:string -> 68 + unit -> 69 + (Matrix_proto.Id.Event_id.t, Error.t) result 70 + (** Send a call answer. 71 + 72 + @param room_id The room 73 + @param call_id The call ID 74 + @param answer The SDP answer 75 + @param version Call version 76 + @param party_id Party ID for version 1 calls *) 77 + 78 + val send_hangup : 79 + Client.t -> 80 + room_id:Matrix_proto.Id.Room_id.t -> 81 + call_id:string -> 82 + ?reason:Matrix_proto.Event.Call_hangup_content.reason -> 83 + ?version:int -> 84 + ?party_id:string -> 85 + unit -> 86 + (Matrix_proto.Id.Event_id.t, Error.t) result 87 + (** Hang up a call. 88 + 89 + @param room_id The room 90 + @param call_id The call ID 91 + @param reason Optional hangup reason 92 + @param version Call version 93 + @param party_id Party ID for version 1 calls *) 94 + 95 + val reject_call : 96 + Client.t -> 97 + room_id:Matrix_proto.Id.Room_id.t -> 98 + call_id:string -> 99 + ?version:int -> 100 + ?party_id:string -> 101 + unit -> 102 + (Matrix_proto.Id.Event_id.t, Error.t) result 103 + (** Reject an incoming call (same as hangup but with different semantics). *) 104 + 105 + (** {1 TURN Server} *) 106 + 107 + (** TURN server credentials. *) 108 + type turn_server = { 109 + username : string; 110 + password : string; 111 + uris : string list; 112 + ttl : int; 113 + } 114 + 115 + val turn_server_jsont : turn_server Jsont.t 116 + (** JSON codec for TURN server. *) 117 + 118 + val get_turn_server : Client.t -> (turn_server, Error.t) result 119 + (** Get TURN server credentials from the homeserver. *)
+113
lib/matrix_client/matrix_client.mli
···
··· 1 + (** Matrix Client SDK for OCaml. 2 + 3 + This library provides a full Matrix client implementation using 4 + the requests library for HTTP and jsont for JSON encoding/decoding. 5 + 6 + {2 Core Modules} 7 + 8 + - {!module:Client} - HTTP client and session management 9 + - {!module:Auth} - Authentication (login, logout, registration) 10 + - {!module:Sync} - Traditional /sync endpoint 11 + 12 + {2 Room Operations} 13 + 14 + - {!module:Rooms} - Room creation, joining, leaving 15 + - {!module:Messages} - Sending and receiving messages 16 + - {!module:State} - Room state management 17 + - {!module:Relations} - Reactions, edits, threads, replies 18 + 19 + {2 User Features} 20 + 21 + - {!module:Profile} - User profile management 22 + - {!module:Presence} - Online/offline status 23 + - {!module:Typing} - Typing indicators 24 + - {!module:Receipts} - Read receipts 25 + - {!module:Account} - Account settings 26 + 27 + {2 Media & Devices} 28 + 29 + - {!module:Media} - Upload/download media 30 + - {!module:Devices} - Device management 31 + 32 + {2 Discovery} 33 + 34 + - {!module:Directory} - Room directory 35 + - {!module:Room_preview} - Room preview and public rooms 36 + 37 + {2 End-to-End Encryption} 38 + 39 + - {!module:Keys} - Key management for E2EE 40 + 41 + {2 Advanced Features} 42 + 43 + - {!module:Spaces} - Matrix spaces (MSC1772) 44 + - {!module:Sliding_sync} - Sliding sync protocol (MSC3575) 45 + - {!module:Push} - Push notifications and rules 46 + - {!module:Calls} - VoIP signaling *) 47 + 48 + (** {1 Core} *) 49 + 50 + module Error = Error 51 + module Client = Client 52 + module Auth = Auth 53 + module Sync = Sync 54 + 55 + (** {1 Rooms} *) 56 + 57 + module Rooms = Rooms 58 + module Messages = Messages 59 + module State = State 60 + module Relations = Relations 61 + 62 + (** {1 User Features} *) 63 + 64 + module Profile = Profile 65 + module Typing = Typing 66 + module Receipts = Receipts 67 + module Account = Account 68 + module Presence = Presence 69 + 70 + (** {1 Media & Devices} *) 71 + 72 + module Media = Media 73 + module Devices = Devices 74 + 75 + (** {1 Discovery} *) 76 + 77 + module Directory = Directory 78 + module Room_preview = Room_preview 79 + 80 + (** {1 End-to-End Encryption} *) 81 + 82 + module Keys = Keys 83 + module Olm = Olm 84 + module Verification = Verification 85 + module Backup = Backup 86 + 87 + (** {1 Storage & Caching} *) 88 + 89 + module Store = Store 90 + module Timeline = Timeline 91 + 92 + (** {1 User-Interactive Auth} *) 93 + 94 + module Uiaa = Uiaa 95 + 96 + (** {1 Offline Support} *) 97 + 98 + module Send_queue = Send_queue 99 + 100 + (** {1 Advanced Features} *) 101 + 102 + module Spaces = Spaces 103 + module Sliding_sync = Sliding_sync 104 + module Push = Push 105 + module Calls = Calls 106 + 107 + (** {1 Session Persistence} *) 108 + 109 + module Session = Session 110 + 111 + (** {1 CLI Support} *) 112 + 113 + module Cmd = Cmd
+327
lib/matrix_client/olm.mli
···
··· 1 + (** Olm/Megolm cryptographic session management. 2 + 3 + This module implements the Olm double-ratchet algorithm for encrypted 4 + to-device messages, and Megolm for encrypted room messages. 5 + 6 + @see <https://spec.matrix.org/v1.11/client-server-api/#end-to-end-encryption> E2EE *) 7 + 8 + (** {1 Olm Account} *) 9 + 10 + (** Olm account - manages identity keys and one-time keys. 11 + 12 + An Olm account contains: 13 + - Ed25519 identity key (for signing) 14 + - Curve25519 identity key (for key exchange) 15 + - One-time keys (for session establishment) *) 16 + module Account : sig 17 + (** Account type. *) 18 + type t = { 19 + ed25519_priv : Mirage_crypto_ec.Ed25519.priv; 20 + ed25519_pub : Mirage_crypto_ec.Ed25519.pub; 21 + curve25519_secret : Mirage_crypto_ec.X25519.secret; 22 + curve25519_public : string; 23 + mutable one_time_keys : (string * (Mirage_crypto_ec.X25519.secret * string)) list; 24 + mutable fallback_key : (string * (Mirage_crypto_ec.X25519.secret * string)) option; 25 + mutable next_key_id : int; 26 + max_one_time_keys : int; 27 + } 28 + 29 + val create : unit -> t 30 + (** Generate a new Olm account with fresh identity keys. *) 31 + 32 + val ed25519_key : t -> string 33 + (** Get the Ed25519 identity key as base64. *) 34 + 35 + val curve25519_key : t -> string 36 + (** Get the Curve25519 identity key as base64. *) 37 + 38 + val identity_keys : t -> string * string 39 + (** Get the identity keys as a pair (ed25519, curve25519). *) 40 + 41 + val sign : t -> string -> string 42 + (** Sign a message with the account's Ed25519 key. *) 43 + 44 + val generate_one_time_keys : t -> int -> unit 45 + (** Generate new one-time keys. *) 46 + 47 + val one_time_keys : t -> (string * string) list 48 + (** Get one-time keys for upload (key_id -> public_key). *) 49 + 50 + val signed_one_time_keys : t -> (string * string * string) list 51 + (** Get signed one-time keys for upload. Returns [(key_id, public_key, signature)]. *) 52 + 53 + val mark_keys_as_published : t -> unit 54 + (** Mark one-time keys as published. *) 55 + 56 + val generate_fallback_key : t -> unit 57 + (** Generate a fallback key. *) 58 + 59 + val fallback_key : t -> (string * string) option 60 + (** Get the fallback key if one exists. *) 61 + 62 + val remove_one_time_key : t -> string -> unit 63 + (** Remove a one-time key by ID (after session creation). *) 64 + 65 + val one_time_keys_count : t -> int 66 + (** Number of unpublished one-time keys. *) 67 + 68 + val max_one_time_keys : t -> int 69 + (** Maximum number of one-time keys this account can hold. *) 70 + end 71 + 72 + (** {1 Olm Session} *) 73 + 74 + (** Olm session state for the double ratchet algorithm. *) 75 + module Session : sig 76 + type chain_key = { key : string; index : int } 77 + type root_key = string 78 + type message_key = string 79 + 80 + (** Session type. *) 81 + type t = { 82 + session_id : string; 83 + their_identity_key : string; 84 + mutable their_ratchet_key : string option; 85 + mutable our_ratchet_secret : Mirage_crypto_ec.X25519.secret; 86 + mutable our_ratchet_public : string; 87 + mutable root_key : root_key; 88 + mutable sending_chain : chain_key option; 89 + mutable receiving_chains : (string * chain_key) list; 90 + mutable skipped_keys : ((string * int) * message_key) list; 91 + creation_time : Ptime.t; 92 + } 93 + 94 + val create_outbound : 95 + Account.t -> 96 + their_identity_key:string -> 97 + their_one_time_key:string -> 98 + t 99 + (** Create a new outbound session (when sending first message). *) 100 + 101 + val create_inbound : 102 + Account.t -> 103 + their_identity_key:string -> 104 + their_ephemeral_key:string -> 105 + one_time_key_id:string -> 106 + t 107 + (** Create a new inbound session (when receiving first message). *) 108 + 109 + val session_id : t -> string 110 + (** Get session ID. *) 111 + 112 + val their_identity_key : t -> string 113 + (** Get their identity key. *) 114 + 115 + val encrypt : t -> string -> int * string 116 + (** Encrypt a plaintext message. Returns (message_type, ciphertext). *) 117 + 118 + val decrypt : t -> message_type:int -> ciphertext:string -> (string, string) result 119 + (** Decrypt a message. *) 120 + 121 + val is_pre_key_message : int -> bool 122 + (** Check if this is a pre-key message (first message in session). *) 123 + end 124 + 125 + (** {1 Megolm Sessions} *) 126 + 127 + (** Megolm session for room message encryption. 128 + 129 + Megolm uses a ratchet that only moves forward, making it efficient 130 + for encrypting many messages to many recipients. *) 131 + module Megolm : sig 132 + 133 + (** Inbound session for decrypting received room messages. *) 134 + module Inbound : sig 135 + (** Inbound session type. *) 136 + type t = { 137 + session_id : string; 138 + sender_key : string; 139 + room_id : string; 140 + mutable ratchet : string array; 141 + mutable message_index : int; 142 + mutable received_indices : int list; 143 + signing_key : string; 144 + creation_time : Ptime.t; 145 + } 146 + 147 + val of_export : 148 + session_id:string -> 149 + sender_key:string -> 150 + room_id:string -> 151 + ratchet:string array -> 152 + message_index:int -> 153 + signing_key:string -> 154 + t 155 + (** Create from exported session data. *) 156 + 157 + val from_room_key : 158 + sender_key:string -> 159 + room_id:string -> 160 + session_id:string -> 161 + session_key:string -> 162 + signing_key:string -> 163 + t 164 + (** Create from room key event (m.room_key). *) 165 + 166 + val session_id : t -> string 167 + (** Get session ID. *) 168 + 169 + val sender_key : t -> string 170 + (** Get sender key. *) 171 + 172 + val room_id : t -> string 173 + (** Get room ID. *) 174 + 175 + val first_known_index : t -> int 176 + (** Get first known message index. *) 177 + 178 + val decrypt : t -> ciphertext:string -> message_index:int -> (string, string) result 179 + (** Decrypt a message. *) 180 + end 181 + 182 + (** Outbound session for encrypting messages to send to a room. *) 183 + module Outbound : sig 184 + (** Outbound session type. *) 185 + type t = { 186 + session_id : string; 187 + room_id : string; 188 + mutable ratchet : string array; 189 + mutable message_index : int; 190 + signing_priv : Mirage_crypto_ec.Ed25519.priv; 191 + signing_pub : Mirage_crypto_ec.Ed25519.pub; 192 + creation_time : Ptime.t; 193 + mutable message_count : int; 194 + max_messages : int; 195 + max_age : Ptime.Span.t; 196 + mutable shared_with : (string * string) list; 197 + } 198 + 199 + val create : room_id:string -> t 200 + (** Create a new outbound session for a room. *) 201 + 202 + val session_id : t -> string 203 + (** Get session ID. *) 204 + 205 + val room_id : t -> string 206 + (** Get room ID. *) 207 + 208 + val message_index : t -> int 209 + (** Get current message index. *) 210 + 211 + val needs_rotation : t -> bool 212 + (** Check if session should be rotated. *) 213 + 214 + val export_session_key : t -> string 215 + (** Export the session key for sharing via m.room_key. *) 216 + 217 + val signing_key : t -> string 218 + (** Get the signing key. *) 219 + 220 + val encrypt : t -> string -> int * string 221 + (** Encrypt a message. Returns (message_index, ciphertext). *) 222 + 223 + val mark_shared_with : t -> user_id:string -> device_id:string -> unit 224 + (** Mark session as shared with a user/device. *) 225 + 226 + val is_shared_with : t -> user_id:string -> device_id:string -> bool 227 + (** Check if already shared with a user/device. *) 228 + 229 + val shared_with : t -> (string * string) list 230 + (** Get list of users this session is shared with. *) 231 + end 232 + end 233 + 234 + (** {1 Olm Machine} *) 235 + 236 + (** Olm Machine - high-level state machine for E2EE operations. *) 237 + module Machine : sig 238 + type t 239 + (** Machine type. *) 240 + 241 + val create : user_id:string -> device_id:string -> t 242 + (** Create a new OlmMachine. *) 243 + 244 + val identity_keys : t -> string * string 245 + (** Get identity keys. *) 246 + 247 + val device_keys_for_upload : t -> string * string * string list * (string * string) list 248 + (** Get device keys for upload. Returns (user_id, device_id, algorithms, keys). *) 249 + 250 + val generate_one_time_keys : t -> int -> unit 251 + (** Generate one-time keys if needed. *) 252 + 253 + val one_time_keys_for_upload : t -> (string * string * string) list 254 + (** Get one-time keys for upload. *) 255 + 256 + val mark_keys_as_published : t -> unit 257 + (** Mark keys as uploaded. *) 258 + 259 + val receive_device_keys : t -> user_id:string -> devices:(string * Keys.queried_device_keys) list -> unit 260 + (** Store device keys from key query response. *) 261 + 262 + val get_outbound_group_session : t -> room_id:string -> Megolm.Outbound.t 263 + (** Get or create outbound Megolm session for a room. *) 264 + 265 + val receive_room_key : 266 + t -> 267 + sender_key:string -> 268 + room_id:string -> 269 + session_id:string -> 270 + session_key:string -> 271 + signing_key:string -> 272 + unit 273 + (** Store inbound Megolm session from room key event. *) 274 + 275 + val encrypt_room_message : t -> room_id:string -> content:string -> string 276 + (** Encrypt a room message using Megolm. *) 277 + 278 + val decrypt_room_message : 279 + t -> 280 + room_id:string -> 281 + sender_key:string -> 282 + session_id:string -> 283 + ciphertext:string -> 284 + message_index:int -> 285 + (string, string) result 286 + (** Decrypt a room message. *) 287 + 288 + val get_olm_session : t -> their_identity_key:string -> Session.t option 289 + (** Get or create Olm session for a device. *) 290 + 291 + val create_olm_session : 292 + t -> 293 + their_identity_key:string -> 294 + their_one_time_key:string -> 295 + Session.t 296 + (** Create outbound Olm session. *) 297 + 298 + val create_inbound_session : 299 + t -> 300 + their_identity_key:string -> 301 + their_ephemeral_key:string -> 302 + one_time_key_id:string -> 303 + Session.t 304 + (** Process inbound Olm message to create session. *) 305 + 306 + val encrypt_to_device : 307 + t -> 308 + their_identity_key:string -> 309 + their_one_time_key:string -> 310 + plaintext:string -> 311 + int * string 312 + (** Encrypt a to-device message. *) 313 + 314 + val decrypt_to_device : 315 + t -> 316 + their_identity_key:string -> 317 + message_type:int -> 318 + ciphertext:string -> 319 + (string, string) result 320 + (** Decrypt a to-device message. *) 321 + 322 + val one_time_keys_count : t -> int 323 + (** Number of one-time keys remaining. *) 324 + 325 + val should_upload_keys : t -> bool 326 + (** Should upload more one-time keys? *) 327 + end
+204
lib/matrix_client/push.mli
···
··· 1 + (** Push notification operations. 2 + 3 + @see <https://spec.matrix.org/v1.11/client-server-api/#push-notifications> Push Notifications *) 4 + 5 + (** {1 Push Rule Types} *) 6 + 7 + (** Push rule kinds. *) 8 + type rule_kind = 9 + | Override 10 + | Underride 11 + | Sender 12 + | Room 13 + | Content 14 + 15 + val rule_kind_to_string : rule_kind -> string 16 + (** Convert rule kind to string. *) 17 + 18 + val rule_kind_of_string : string -> (rule_kind, string) result 19 + (** Parse rule kind from string. *) 20 + 21 + val rule_kind_jsont : rule_kind Jsont.t 22 + (** JSON codec for rule kind. *) 23 + 24 + (** {1 Push Rule Actions} *) 25 + 26 + (** Push rule action. *) 27 + type action = 28 + | Notify 29 + | Dont_notify 30 + | Coalesce 31 + | Set_tweak of string * Jsont.json 32 + 33 + val action_jsont : action Jsont.t 34 + (** JSON codec for action. *) 35 + 36 + (** {1 Push Rule Conditions} *) 37 + 38 + (** Push rule condition. *) 39 + type condition = { 40 + kind : string; 41 + key : string option; 42 + pattern : string option; 43 + is_ : string option; 44 + } 45 + 46 + val condition_jsont : condition Jsont.t 47 + (** JSON codec for condition. *) 48 + 49 + (** {1 Push Rules} *) 50 + 51 + (** Push rule. *) 52 + type rule = { 53 + rule_id : string; 54 + default : bool; 55 + enabled : bool; 56 + actions : action list; 57 + conditions : condition list option; 58 + pattern : string option; 59 + } 60 + 61 + val rule_jsont : rule Jsont.t 62 + (** JSON codec for rule. *) 63 + 64 + (** {1 Push Ruleset} *) 65 + 66 + (** Push ruleset. *) 67 + type ruleset = { 68 + override : rule list; 69 + underride : rule list; 70 + sender : rule list; 71 + room : rule list; 72 + content : rule list; 73 + } 74 + 75 + val ruleset_jsont : ruleset Jsont.t 76 + (** JSON codec for ruleset. *) 77 + 78 + (** Push rules response. *) 79 + type push_rules_response = { 80 + global : ruleset; 81 + } 82 + 83 + val push_rules_response_jsont : push_rules_response Jsont.t 84 + (** JSON codec for push rules response. *) 85 + 86 + (** {1 Push Rule Operations} *) 87 + 88 + val get_push_rules : Client.t -> (push_rules_response, Error.t) result 89 + (** Get all push rules. *) 90 + 91 + val get_push_rule : 92 + Client.t -> 93 + scope:string -> 94 + kind:rule_kind -> 95 + rule_id:string -> 96 + (rule, Error.t) result 97 + (** Get a specific push rule. *) 98 + 99 + val delete_push_rule : 100 + Client.t -> 101 + scope:string -> 102 + kind:rule_kind -> 103 + rule_id:string -> 104 + (unit, Error.t) result 105 + (** Delete a push rule. *) 106 + 107 + val set_push_rule : 108 + Client.t -> 109 + scope:string -> 110 + kind:rule_kind -> 111 + rule_id:string -> 112 + actions:action list -> 113 + ?conditions:condition list -> 114 + ?pattern:string -> 115 + ?before:string -> 116 + ?after:string -> 117 + unit -> 118 + (unit, Error.t) result 119 + (** Add or update a push rule. *) 120 + 121 + val set_push_rule_enabled : 122 + Client.t -> 123 + scope:string -> 124 + kind:rule_kind -> 125 + rule_id:string -> 126 + enabled:bool -> 127 + (unit, Error.t) result 128 + (** Enable or disable a push rule. *) 129 + 130 + val set_push_rule_actions : 131 + Client.t -> 132 + scope:string -> 133 + kind:rule_kind -> 134 + rule_id:string -> 135 + actions:action list -> 136 + (unit, Error.t) result 137 + (** Set the actions for a push rule. *) 138 + 139 + (** {1 Pusher Types} *) 140 + 141 + (** Pusher kinds. *) 142 + type pusher_kind = 143 + | Http 144 + | Email 145 + 146 + val pusher_kind_to_string : pusher_kind -> string 147 + (** Convert pusher kind to string. *) 148 + 149 + val pusher_kind_of_string : string -> (pusher_kind, string) result 150 + (** Parse pusher kind from string. *) 151 + 152 + val pusher_kind_jsont : pusher_kind Jsont.t 153 + (** JSON codec for pusher kind. *) 154 + 155 + (** Pusher data. *) 156 + type pusher_data = { 157 + url : string option; 158 + format : string option; 159 + } 160 + 161 + val pusher_data_jsont : pusher_data Jsont.t 162 + (** JSON codec for pusher data. *) 163 + 164 + (** Pusher. *) 165 + type pusher = { 166 + pushkey : string; 167 + kind : pusher_kind; 168 + app_id : string; 169 + app_display_name : string; 170 + device_display_name : string; 171 + profile_tag : string option; 172 + lang : string; 173 + data : pusher_data; 174 + } 175 + 176 + val pusher_jsont : pusher Jsont.t 177 + (** JSON codec for pusher. *) 178 + 179 + (** {1 Pusher Operations} *) 180 + 181 + val get_pushers : Client.t -> (pusher list, Error.t) result 182 + (** Get all pushers for the current user. *) 183 + 184 + val set_pusher : 185 + Client.t -> 186 + pushkey:string -> 187 + kind:pusher_kind -> 188 + app_id:string -> 189 + app_display_name:string -> 190 + device_display_name:string -> 191 + ?profile_tag:string -> 192 + lang:string -> 193 + data:pusher_data -> 194 + ?append:bool -> 195 + unit -> 196 + (unit, Error.t) result 197 + (** Set a pusher. *) 198 + 199 + val delete_pusher : 200 + Client.t -> 201 + pushkey:string -> 202 + app_id:string -> 203 + (unit, Error.t) result 204 + (** Delete a pusher by setting kind to null. *)
+151
lib/matrix_client/room_preview.mli
···
··· 1 + (** Room preview operations. 2 + 3 + Get information about a room before joining it. 4 + 5 + @see <https://spec.matrix.org/v1.11/client-server-api/#listing-rooms> Room Directory *) 6 + 7 + (** {1 Room Preview} *) 8 + 9 + (** Room preview information. *) 10 + type room_preview = { 11 + room_id : Matrix_proto.Id.Room_id.t; 12 + name : string option; 13 + topic : string option; 14 + avatar_url : string option; 15 + canonical_alias : Matrix_proto.Id.Room_alias.t option; 16 + join_rule : Matrix_proto.Event.Join_rule.t option; 17 + num_joined_members : int; 18 + room_type : string option; 19 + world_readable : bool; 20 + guest_can_join : bool; 21 + membership : Matrix_proto.Event.Membership.t option; 22 + } 23 + 24 + (** {1 Room Summary (MSC3266)} *) 25 + 26 + (** Summary returned by room summary endpoint. *) 27 + type room_summary = { 28 + room_id : string; 29 + membership : Matrix_proto.Event.Membership.t option; 30 + is_encrypted : bool option; 31 + room_name : string option; 32 + topic : string option; 33 + avatar_url : string option; 34 + canonical_alias : string option; 35 + joined_members_count : int option; 36 + invited_members_count : int option; 37 + room_version : string option; 38 + room_type : string option; 39 + join_rule : Matrix_proto.Event.Join_rule.t option; 40 + guest_can_join : bool option; 41 + world_readable : bool option; 42 + } 43 + 44 + val room_summary_jsont : room_summary Jsont.t 45 + (** JSON codec for room summary. *) 46 + 47 + val get_summary : 48 + Client.t -> 49 + room_id_or_alias:[< `Room_id of Matrix_proto.Id.Room_id.t | `Room_alias of Matrix_proto.Id.Room_alias.t ] -> 50 + ?via:string list -> 51 + unit -> 52 + (room_summary, Error.t) result 53 + (** Get room summary (MSC3266). 54 + 55 + This is the preferred way to get room information before joining. *) 56 + 57 + (** {1 Public Rooms} *) 58 + 59 + (** Public room from directory listing. *) 60 + type public_room = { 61 + room_id : Matrix_proto.Id.Room_id.t; 62 + name : string option; 63 + topic : string option; 64 + avatar_url : string option; 65 + canonical_alias : Matrix_proto.Id.Room_alias.t option; 66 + num_joined_members : int; 67 + world_readable : bool; 68 + guest_can_join : bool; 69 + join_rule : Matrix_proto.Event.Join_rule.t option; 70 + room_type : string option; 71 + } 72 + 73 + val public_room_jsont : public_room Jsont.t 74 + (** JSON codec for public room. *) 75 + 76 + (** Public rooms response. *) 77 + type public_rooms_response = { 78 + chunk : public_room list; 79 + next_batch : string option; 80 + prev_batch : string option; 81 + total_room_count_estimate : int option; 82 + } 83 + 84 + val public_rooms_response_jsont : public_rooms_response Jsont.t 85 + (** JSON codec for public rooms response. *) 86 + 87 + val get_public_rooms : 88 + Client.t -> 89 + ?limit:int -> 90 + ?since:string -> 91 + ?server:string -> 92 + unit -> 93 + (public_rooms_response, Error.t) result 94 + (** Get list of public rooms. 95 + 96 + @param limit Maximum number of rooms to return 97 + @param since Pagination token 98 + @param server Server to query for rooms *) 99 + 100 + (** {1 Public Rooms Search} *) 101 + 102 + (** Search filter for public rooms. *) 103 + type public_rooms_filter = { 104 + generic_search_term : string option; 105 + room_types : string list option; 106 + } 107 + 108 + val public_rooms_filter_jsont : public_rooms_filter Jsont.t 109 + (** JSON codec for public rooms filter. *) 110 + 111 + val search_public_rooms : 112 + Client.t -> 113 + ?search_term:string -> 114 + ?limit:int -> 115 + ?since:string -> 116 + ?room_types:string list -> 117 + ?server:string -> 118 + unit -> 119 + (public_rooms_response, Error.t) result 120 + (** Search public rooms with filters. 121 + 122 + @param search_term Text to search for 123 + @param limit Maximum number of rooms 124 + @param since Pagination token 125 + @param room_types Filter by room type 126 + @param server Server to query *) 127 + 128 + (** {1 Room Alias Resolution} *) 129 + 130 + val resolve_alias : 131 + Client.t -> 132 + room_alias:Matrix_proto.Id.Room_alias.t -> 133 + (Matrix_proto.Id.Room_id.t * string list, Error.t) result 134 + (** Resolve a room alias to a room ID and servers. *) 135 + 136 + (** {1 Knocking (MSC2403)} *) 137 + 138 + val knock : 139 + Client.t -> 140 + room_id_or_alias:[< `Room_id of Matrix_proto.Id.Room_id.t | `Room_alias of Matrix_proto.Id.Room_alias.t ] -> 141 + ?reason:string -> 142 + ?via:string list -> 143 + unit -> 144 + (Matrix_proto.Id.Room_id.t, Error.t) result 145 + (** Knock on a room (MSC2403). 146 + 147 + Request to join a room that has knock join rules. 148 + 149 + @param room_id_or_alias The room to knock on 150 + @param reason Optional reason for the knock request 151 + @param via Servers to try *)
+287
lib/matrix_client/send_queue.mli
···
··· 1 + (** Send queue for serialized message sending and offline support. 2 + 3 + This module provides: 4 + - Offline message queueing 5 + - Automatic retry with backoff 6 + - Transaction ID tracking for deduplication 7 + - Local echo support 8 + - Media upload coordination 9 + 10 + Each room has its own queue to serialize sends, preventing race conditions 11 + and ensuring messages are sent in order. *) 12 + 13 + (** {1 Queue Request Types} *) 14 + 15 + (** Type of queued request. *) 16 + type request_kind = 17 + | Event of { 18 + event_type : string; 19 + content : Jsont.json; 20 + txn_id : string; 21 + } 22 + | MediaUpload of { 23 + content_type : string; 24 + data_size : int; 25 + local_path : string option; 26 + txn_id : string; 27 + } 28 + | Reaction of { 29 + relates_to : Matrix_proto.Id.Event_id.t; 30 + key : string; 31 + txn_id : string; 32 + } 33 + | Redaction of { 34 + event_id : Matrix_proto.Id.Event_id.t; 35 + reason : string option; 36 + txn_id : string; 37 + } 38 + 39 + (** Request state. *) 40 + type request_state = 41 + | Pending 42 + | Sending 43 + | Sent 44 + | Failed of string 45 + | Cancelled 46 + 47 + (** Queued request with metadata. *) 48 + type queued_request = { 49 + id : int; 50 + room_id : Matrix_proto.Id.Room_id.t; 51 + kind : request_kind; 52 + mutable state : request_state; 53 + created_at : int64; 54 + mutable retry_count : int; 55 + mutable last_error : string option; 56 + mutable depends_on : int option; 57 + mutable dependents : int list; 58 + } 59 + 60 + (** Result of sending a request. *) 61 + type send_result = 62 + | Sent_ok of { event_id : Matrix_proto.Id.Event_id.t option } 63 + | Send_failed of { error : string; retryable : bool } 64 + | Send_cancelled 65 + 66 + (** {1 Room Send Queue} *) 67 + 68 + (** Room-specific send queue. *) 69 + type room_send_queue = { 70 + room_id : Matrix_proto.Id.Room_id.t; 71 + mutable requests : queued_request list; 72 + mutable next_id : int; 73 + mutable enabled : bool; 74 + mutable is_processing : bool; 75 + max_retries : int; 76 + retry_delay_ms : int; 77 + mutable on_state_change : (queued_request -> unit) option; 78 + } 79 + 80 + (** {1 Send Handle} *) 81 + 82 + (** Handle for a queued request, allowing cancellation and status checks. *) 83 + type send_handle = { 84 + request_id : int; 85 + txn_id : string; 86 + room_id : Matrix_proto.Id.Room_id.t; 87 + queue : room_send_queue; 88 + } 89 + 90 + (** {1 Global Send Queue} *) 91 + 92 + (** Global send queue manager. *) 93 + type t = { 94 + user_id : Matrix_proto.Id.User_id.t; 95 + mutable room_queues : (string * room_send_queue) list; 96 + mutable globally_enabled : bool; 97 + mutable on_error : (queued_request -> string -> unit) option; 98 + } 99 + 100 + (** {1 Queue Creation} *) 101 + 102 + val create_room_queue : 103 + room_id:Matrix_proto.Id.Room_id.t -> 104 + ?max_retries:int -> 105 + ?retry_delay_ms:int -> 106 + unit -> 107 + room_send_queue 108 + (** Create a new room send queue. *) 109 + 110 + val create : user_id:Matrix_proto.Id.User_id.t -> t 111 + (** Create a new global send queue manager. *) 112 + 113 + val get_room_queue : t -> Matrix_proto.Id.Room_id.t -> room_send_queue 114 + (** Get or create a room queue. *) 115 + 116 + (** {1 Enqueueing Requests} *) 117 + 118 + val generate_txn_id : unit -> string 119 + (** Generate a new transaction ID. *) 120 + 121 + val enqueue : room_send_queue -> request_kind -> send_handle 122 + (** Enqueue a request. *) 123 + 124 + val send_message : 125 + t -> 126 + room_id:Matrix_proto.Id.Room_id.t -> 127 + event_type:string -> 128 + content:Jsont.json -> 129 + send_handle 130 + (** Enqueue a message event. *) 131 + 132 + val send_text : t -> room_id:Matrix_proto.Id.Room_id.t -> body:string -> send_handle 133 + (** Enqueue a text message. *) 134 + 135 + val send_reaction : 136 + t -> 137 + room_id:Matrix_proto.Id.Room_id.t -> 138 + relates_to:Matrix_proto.Id.Event_id.t -> 139 + key:string -> 140 + send_handle 141 + (** Enqueue a reaction. *) 142 + 143 + val send_redaction : 144 + t -> 145 + room_id:Matrix_proto.Id.Room_id.t -> 146 + event_id:Matrix_proto.Id.Event_id.t -> 147 + ?reason:string -> 148 + unit -> 149 + send_handle 150 + (** Enqueue a redaction. *) 151 + 152 + (** {1 Dependencies} *) 153 + 154 + val add_dependency : parent:send_handle -> child:send_handle -> unit 155 + (** Add a dependency between requests. *) 156 + 157 + (** {1 Request State Management} *) 158 + 159 + val cancel : send_handle -> bool 160 + (** Cancel a queued request. Returns true if cancelled. *) 161 + 162 + val abort : send_handle -> bool 163 + (** Abort a request (cancel and remove). *) 164 + 165 + val get_request : send_handle -> queued_request option 166 + (** Get request by handle. *) 167 + 168 + val is_pending : send_handle -> bool 169 + (** Check if request is still pending. *) 170 + 171 + val is_sent : send_handle -> bool 172 + (** Check if request was sent. *) 173 + 174 + (** {1 Queue Processing} *) 175 + 176 + val next_sendable : room_send_queue -> queued_request option 177 + (** Get next sendable request from queue. *) 178 + 179 + val mark_sending : room_send_queue -> queued_request -> unit 180 + (** Mark request as being sent. *) 181 + 182 + val mark_sent : room_send_queue -> queued_request -> unit 183 + (** Mark request as successfully sent. *) 184 + 185 + val mark_failed : room_send_queue -> queued_request -> string -> retryable:bool -> unit 186 + (** Mark request as failed with optional retry. *) 187 + 188 + val cleanup_queue : room_send_queue -> unit 189 + (** Remove completed/cancelled/failed requests. *) 190 + 191 + (** {1 Queue Statistics} *) 192 + 193 + val pending_count : room_send_queue -> int 194 + (** Count of pending requests in a room queue. *) 195 + 196 + val total_pending : t -> int 197 + (** Count of all pending requests across all rooms. *) 198 + 199 + val pending_requests : room_send_queue -> queued_request list 200 + (** Get all pending requests for a room. *) 201 + 202 + val failed_requests : room_send_queue -> queued_request list 203 + (** Get all failed requests for a room. *) 204 + 205 + (** {1 Queue Control} *) 206 + 207 + val set_room_enabled : room_send_queue -> bool -> unit 208 + (** Enable/disable a room queue. *) 209 + 210 + val set_enabled : t -> bool -> unit 211 + (** Enable/disable all queues globally. *) 212 + 213 + val is_enabled : t -> bool 214 + (** Check if globally enabled. *) 215 + 216 + val is_room_enabled : room_send_queue -> bool 217 + (** Check if a room queue is enabled. *) 218 + 219 + (** {1 Event Callbacks} *) 220 + 221 + val on_state_change : room_send_queue -> (queued_request -> unit) -> unit 222 + (** Set callback for state changes. *) 223 + 224 + val on_error : t -> (queued_request -> string -> unit) -> unit 225 + (** Set global error callback. *) 226 + 227 + (** {1 Persistence} *) 228 + 229 + (** Serializable queue state. *) 230 + type persisted_request = { 231 + p_room_id : string; 232 + p_kind : request_kind; 233 + p_created_at : int64; 234 + p_retry_count : int; 235 + p_depends_on : int option; 236 + } 237 + 238 + val request_to_persisted : queued_request -> persisted_request 239 + (** Convert request to persistable form. *) 240 + 241 + val requests_to_persist : t -> persisted_request list 242 + (** Get all pending requests for persistence. *) 243 + 244 + val restore_requests : t -> persisted_request list -> unit 245 + (** Restore requests from persistence. *) 246 + 247 + (** {1 Local Echo} *) 248 + 249 + val local_echo_event : queued_request -> (string * Jsont.json * string) option 250 + (** Create a local echo event from a queued request. 251 + Returns [(event_type, content, txn_id)] or [None]. *) 252 + 253 + val matches_txn_id : queued_request -> event_id:Matrix_proto.Id.Event_id.t -> bool 254 + (** Check if an event_id matches a transaction ID (for local echo replacement). *) 255 + 256 + (** {1 Retry Logic} *) 257 + 258 + val retry_delay : room_send_queue -> queued_request -> int 259 + (** Calculate delay for next retry (exponential backoff). *) 260 + 261 + val should_retry : room_send_queue -> queued_request -> bool 262 + (** Check if a request should be retried. *) 263 + 264 + (** {1 Media Upload Support} *) 265 + 266 + val send_media : 267 + t -> 268 + room_id:Matrix_proto.Id.Room_id.t -> 269 + content_type:string -> 270 + data_size:int -> 271 + ?local_path:string -> 272 + event_content:Jsont.json -> 273 + unit -> 274 + send_handle * send_handle 275 + (** Create a media upload request with dependent event send. 276 + Returns [(upload_handle, event_handle)]. *) 277 + 278 + (** {1 Internal} *) 279 + 280 + val txn_id_of_kind : request_kind -> string 281 + (** Get transaction ID from request kind. *) 282 + 283 + val dependencies_satisfied : room_send_queue -> queued_request -> bool 284 + (** Check if a request's dependencies are satisfied. *) 285 + 286 + val update_state : room_send_queue -> queued_request -> request_state -> unit 287 + (** Update request state. *)
+281
lib/matrix_client/sliding_sync.mli
···
··· 1 + (** Sliding Sync (MSC3575) - Efficient sync protocol. 2 + 3 + Sliding sync is a more efficient alternative to the traditional /sync 4 + endpoint, designed for clients with many rooms. 5 + 6 + @see <https://spec.matrix.org/unstable/client-server-api/#sliding-sync> Sliding Sync *) 7 + 8 + (** {1 Room Subscription} *) 9 + 10 + (** Room subscription mode. *) 11 + type room_subscription = { 12 + required_state : (string * string) list; 13 + timeline_limit : int option; 14 + include_old_rooms : bool option; 15 + } 16 + 17 + val room_subscription_jsont : room_subscription Jsont.t 18 + (** JSON codec for room subscription. *) 19 + 20 + (** {1 List Operations} *) 21 + 22 + (** List operation for sliding window. *) 23 + type list_op = 24 + | Sync of int * int 25 + | Insert of int * string 26 + | Delete of int 27 + | Invalidate of int * int 28 + 29 + (** {1 List Configuration} *) 30 + 31 + (** List filters. *) 32 + type list_filters = { 33 + is_dm : bool option; 34 + spaces : string list option; 35 + is_encrypted : bool option; 36 + is_invite : bool option; 37 + room_types : string list option; 38 + not_room_types : string list option; 39 + room_name_like : string option; 40 + tags : string list option; 41 + not_tags : string list option; 42 + } 43 + 44 + val list_filters_jsont : list_filters Jsont.t 45 + (** JSON codec for list filters. *) 46 + 47 + (** Sliding sync list configuration. *) 48 + type list_config = { 49 + ranges : (int * int) list; 50 + sort : string list option; 51 + required_state : (string * string) list; 52 + timeline_limit : int option; 53 + filters : list_filters option; 54 + bump_event_types : string list option; 55 + } 56 + 57 + val list_config_jsont : list_config Jsont.t 58 + (** JSON codec for list config. *) 59 + 60 + (** {1 Extensions} *) 61 + 62 + (** To-device extension. *) 63 + type to_device_ext = { 64 + enabled : bool; 65 + since : string option; 66 + limit : int option; 67 + } 68 + 69 + val to_device_ext_jsont : to_device_ext Jsont.t 70 + (** JSON codec for to_device extension. *) 71 + 72 + (** E2EE extension. *) 73 + type e2ee_ext = { 74 + enabled : bool; 75 + } 76 + 77 + val e2ee_ext_jsont : e2ee_ext Jsont.t 78 + (** JSON codec for E2EE extension. *) 79 + 80 + (** Account data extension. *) 81 + type account_data_ext = { 82 + enabled : bool; 83 + lists : string list option; 84 + rooms : string list option; 85 + } 86 + 87 + val account_data_ext_jsont : account_data_ext Jsont.t 88 + (** JSON codec for account data extension. *) 89 + 90 + (** Typing extension. *) 91 + type typing_ext = { 92 + enabled : bool; 93 + lists : string list option; 94 + rooms : string list option; 95 + } 96 + 97 + val typing_ext_jsont : typing_ext Jsont.t 98 + (** JSON codec for typing extension. *) 99 + 100 + (** Receipts extension. *) 101 + type receipts_ext = { 102 + enabled : bool; 103 + lists : string list option; 104 + rooms : string list option; 105 + } 106 + 107 + val receipts_ext_jsont : receipts_ext Jsont.t 108 + (** JSON codec for receipts extension. *) 109 + 110 + (** Extensions configuration. *) 111 + type extensions = { 112 + to_device : to_device_ext option; 113 + e2ee : e2ee_ext option; 114 + account_data : account_data_ext option; 115 + typing : typing_ext option; 116 + receipts : receipts_ext option; 117 + } 118 + 119 + val extensions_jsont : extensions Jsont.t 120 + (** JSON codec for extensions. *) 121 + 122 + (** {1 Request} *) 123 + 124 + (** Sliding sync request. *) 125 + type request = { 126 + lists : (string * list_config) list; 127 + room_subscriptions : (string * room_subscription) list; 128 + unsubscribe_rooms : string list; 129 + extensions : extensions option; 130 + pos : string option; 131 + timeout : int option; 132 + } 133 + 134 + val request_jsont : request Jsont.t 135 + (** JSON codec for request. *) 136 + 137 + (** {1 Response Types} *) 138 + 139 + (** Hero information. *) 140 + type hero = { 141 + user_id : string; 142 + name : string option; 143 + avatar : string option; 144 + } 145 + 146 + val hero_jsont : hero Jsont.t 147 + (** JSON codec for hero. *) 148 + 149 + (** Room response data. *) 150 + type room_response = { 151 + name : string option; 152 + avatar : string option; 153 + heroes : hero list option; 154 + is_dm : bool option; 155 + initial : bool option; 156 + required_state : Jsont.json list; 157 + timeline : Jsont.json list; 158 + prev_batch : string option; 159 + limited : bool option; 160 + joined_count : int option; 161 + invited_count : int option; 162 + notification_count : int option; 163 + highlight_count : int option; 164 + num_live : int option; 165 + timestamp : int64 option; 166 + } 167 + 168 + val room_response_jsont : room_response Jsont.t 169 + (** JSON codec for room response. *) 170 + 171 + (** List operation response. *) 172 + type list_op_response = { 173 + op : string; 174 + range : (int * int) option; 175 + index : int option; 176 + room_ids : string list option; 177 + room_id : string option; 178 + } 179 + 180 + val list_op_response_jsont : list_op_response Jsont.t 181 + (** JSON codec for list operation response. *) 182 + 183 + (** List response. *) 184 + type list_response = { 185 + count : int; 186 + ops : list_op_response list; 187 + } 188 + 189 + val list_response_jsont : list_response Jsont.t 190 + (** JSON codec for list response. *) 191 + 192 + (** {1 Extensions Response} *) 193 + 194 + (** To-device response. *) 195 + type to_device_response = { 196 + next_batch : string; 197 + events : Jsont.json list; 198 + } 199 + 200 + val to_device_response_jsont : to_device_response Jsont.t 201 + (** JSON codec for to_device response. *) 202 + 203 + (** Device lists. *) 204 + type device_lists = { 205 + changed : string list; 206 + left : string list; 207 + } 208 + 209 + val device_lists_jsont : device_lists Jsont.t 210 + (** JSON codec for device lists. *) 211 + 212 + (** E2EE response. *) 213 + type e2ee_response = { 214 + device_lists : device_lists option; 215 + device_one_time_keys_count : (string * int) list; 216 + device_unused_fallback_key_types : string list; 217 + } 218 + 219 + val e2ee_response_jsont : e2ee_response Jsont.t 220 + (** JSON codec for E2EE response. *) 221 + 222 + (** Account data response. *) 223 + type account_data_response = { 224 + global : Jsont.json list; 225 + rooms : (string * Jsont.json list) list; 226 + } 227 + 228 + val account_data_response_jsont : account_data_response Jsont.t 229 + (** JSON codec for account data response. *) 230 + 231 + (** Typing response. *) 232 + type typing_response = { 233 + rooms : (string * string list) list; 234 + } 235 + 236 + val typing_response_jsont : typing_response Jsont.t 237 + (** JSON codec for typing response. *) 238 + 239 + (** Receipts response. *) 240 + type receipts_response = { 241 + rooms : (string * Jsont.json) list; 242 + } 243 + 244 + val receipts_response_jsont : receipts_response Jsont.t 245 + (** JSON codec for receipts response. *) 246 + 247 + (** Extensions response. *) 248 + type extensions_response = { 249 + to_device : to_device_response option; 250 + e2ee : e2ee_response option; 251 + account_data : account_data_response option; 252 + typing : typing_response option; 253 + receipts : receipts_response option; 254 + } 255 + 256 + val extensions_response_jsont : extensions_response Jsont.t 257 + (** JSON codec for extensions response. *) 258 + 259 + (** {1 Full Response} *) 260 + 261 + (** Full sliding sync response. *) 262 + type response = { 263 + pos : string; 264 + lists : (string * list_response) list; 265 + rooms : (string * room_response) list; 266 + extensions : extensions_response option; 267 + } 268 + 269 + val response_jsont : response Jsont.t 270 + (** JSON codec for response. *) 271 + 272 + (** {1 Sync Operations} *) 273 + 274 + val sync : Client.t -> request:request -> unit -> (response, Error.t) result 275 + (** Perform a sliding sync request. 276 + 277 + This is the main entry point for sliding sync. The client should maintain 278 + the position token and include it in subsequent requests. *) 279 + 280 + val initial_request : ?timeline_limit:int -> ?room_limit:int -> unit -> request 281 + (** Create a default request for initial sync. *)
+124
lib/matrix_client/spaces.mli
···
··· 1 + (** Space operations for Matrix spaces. 2 + 3 + Spaces are special rooms with type ["m.space"] that contain child rooms 4 + via [m.space.child] state events. 5 + 6 + @see <https://spec.matrix.org/v1.11/client-server-api/#spaces> Spaces *) 7 + 8 + (** {1 Types} *) 9 + 10 + (** Space hierarchy information. *) 11 + type space_room = { 12 + room_id : Matrix_proto.Id.Room_id.t; 13 + name : string option; 14 + topic : string option; 15 + canonical_alias : Matrix_proto.Id.Room_alias.t option; 16 + avatar_url : string option; 17 + num_joined_members : int; 18 + room_type : string option; 19 + join_rule : Matrix_proto.Event.Join_rule.t option; 20 + children_state : child_state list; 21 + world_readable : bool; 22 + guest_can_join : bool; 23 + } 24 + 25 + (** Child room state information. *) 26 + and child_state = { 27 + state_key : string; 28 + via : string list; 29 + order : string option; 30 + suggested : bool; 31 + } 32 + 33 + (** Response from space hierarchy request. *) 34 + type hierarchy_response = { 35 + rooms : space_room list; 36 + next_batch : string option; 37 + } 38 + 39 + (** {1 Hierarchy Operations} *) 40 + 41 + val get_hierarchy : 42 + Client.t -> 43 + room_id:Matrix_proto.Id.Room_id.t -> 44 + ?suggested_only:bool -> 45 + ?limit:int -> 46 + ?max_depth:int -> 47 + ?from:string -> 48 + unit -> 49 + (hierarchy_response, Error.t) result 50 + (** Get the hierarchy of a space. 51 + 52 + @param room_id The space room ID 53 + @param suggested_only If true, only return suggested rooms 54 + @param limit Maximum number of rooms to return per request 55 + @param max_depth Maximum depth to recurse into the hierarchy 56 + @param from Pagination token *) 57 + 58 + (** {1 Space Management} *) 59 + 60 + val add_child : 61 + Client.t -> 62 + space_id:Matrix_proto.Id.Room_id.t -> 63 + child_id:Matrix_proto.Id.Room_id.t -> 64 + ?via:string list -> 65 + ?order:string -> 66 + ?suggested:bool -> 67 + unit -> 68 + (Matrix_proto.Id.Event_id.t, Error.t) result 69 + (** Add a child room to a space. 70 + 71 + @param space_id The parent space room ID 72 + @param child_id The child room ID 73 + @param via Server names to route through 74 + @param order Optional ordering string 75 + @param suggested Whether the room is suggested *) 76 + 77 + val remove_child : 78 + Client.t -> 79 + space_id:Matrix_proto.Id.Room_id.t -> 80 + child_id:Matrix_proto.Id.Room_id.t -> 81 + (unit, Error.t) result 82 + (** Remove a child room from a space. *) 83 + 84 + val set_parent : 85 + Client.t -> 86 + room_id:Matrix_proto.Id.Room_id.t -> 87 + parent_id:Matrix_proto.Id.Room_id.t -> 88 + ?via:string list -> 89 + ?canonical:bool -> 90 + unit -> 91 + (Matrix_proto.Id.Event_id.t, Error.t) result 92 + (** Set the parent space for a room. 93 + 94 + @param room_id The child room ID 95 + @param parent_id The parent space ID 96 + @param via Server names to route through 97 + @param canonical Whether this is the canonical parent *) 98 + 99 + val remove_parent : 100 + Client.t -> 101 + room_id:Matrix_proto.Id.Room_id.t -> 102 + parent_id:Matrix_proto.Id.Room_id.t -> 103 + (unit, Error.t) result 104 + (** Remove a parent space from a room. *) 105 + 106 + (** {1 Space Creation} *) 107 + 108 + val is_space : string option -> bool 109 + (** Check if a room type indicates a space. *) 110 + 111 + val create_space : 112 + Client.t -> 113 + name:string -> 114 + ?topic:string -> 115 + ?visibility:[ `Public | `Private ] -> 116 + ?invite:Matrix_proto.Id.User_id.t list -> 117 + unit -> 118 + (Matrix_proto.Id.Room_id.t, Error.t) result 119 + (** Create a new space. 120 + 121 + @param name The space name 122 + @param topic Optional topic 123 + @param visibility Room visibility (public or private) 124 + @param invite List of users to invite *)
+474
lib/matrix_client/store.mli
···
··· 1 + (** Persistent storage layer for Matrix SDK state. 2 + 3 + This module provides pluggable storage interfaces matching the Rust SDK's 4 + storage architecture. Implementations can be provided for: 5 + - In-memory (default, non-persistent) 6 + - SQLite (persistent file-based) 7 + - Custom backends 8 + 9 + Storage is split into separate stores: 10 + - {!module-type:STATE_STORE}: Room state, user profiles, sync tokens 11 + - {!module-type:CRYPTO_STORE}: E2EE keys, sessions, device info 12 + - {!module-type:EVENT_CACHE_STORE}: Event history and pagination *) 13 + 14 + (** {1 Key-Value Data Types} *) 15 + 16 + (** Types of data that can be stored in the state store's KV section. *) 17 + type kv_data = 18 + | Sync_token of string 19 + | Filter of { filter_id : string; filter : Jsont.json } 20 + | User_avatar_url of { user_id : Matrix_proto.Id.User_id.t; url : string option } 21 + | Recently_visited_rooms of Matrix_proto.Id.Room_id.t list 22 + | Composer_draft of { 23 + room_id : Matrix_proto.Id.Room_id.t; 24 + plain_text : string; 25 + html_text : string option; 26 + draft_type : [ `New | `Edit of Matrix_proto.Id.Event_id.t | `Reply of Matrix_proto.Id.Event_id.t ]; 27 + } 28 + 29 + (** {1 State Changes Aggregate} *) 30 + 31 + (** User profile information in a room. *) 32 + type member_profile = { 33 + display_name : string option; 34 + avatar_url : string option; 35 + } 36 + 37 + (** Room metadata and summary. *) 38 + type room_info = { 39 + room_id : Matrix_proto.Id.Room_id.t; 40 + room_type : string option; 41 + name : string option; 42 + topic : string option; 43 + avatar_url : string option; 44 + canonical_alias : Matrix_proto.Id.Room_alias.t option; 45 + joined_member_count : int; 46 + invited_member_count : int; 47 + is_encrypted : bool; 48 + is_direct : bool; 49 + prev_batch : string option; 50 + notification_count : int; 51 + highlight_count : int; 52 + } 53 + 54 + (** Aggregated state changes from a sync response. *) 55 + type state_changes = { 56 + sync_token : string option; 57 + account_data : (string * Jsont.json) list; 58 + presence : (string * Jsont.json) list; 59 + room_infos : (string * room_info) list; 60 + room_state : (string * (string * (string * Jsont.json) list) list) list; 61 + room_account_data : (string * (string * Jsont.json) list) list; 62 + stripped_state : (string * (string * (string * Jsont.json) list) list) list; 63 + receipts : (string * Jsont.json) list; 64 + profiles : (string * (string * member_profile) list) list; 65 + } 66 + 67 + (** Empty state changes record. *) 68 + val empty_state_changes : state_changes 69 + 70 + (** {1 STATE_STORE Module Type} *) 71 + 72 + (** Module type for room state storage. *) 73 + module type STATE_STORE = sig 74 + type t 75 + (** The store instance type. *) 76 + 77 + type error 78 + (** The error type for storage operations. *) 79 + 80 + val create : unit -> t 81 + (** Create a new store. *) 82 + 83 + (** {2 State Changes} *) 84 + 85 + val save_changes : t -> state_changes -> (unit, error) result 86 + (** Save aggregated state changes from sync. *) 87 + 88 + (** {2 Sync Token} *) 89 + 90 + val get_sync_token : t -> string option 91 + (** Get the current sync token. *) 92 + 93 + val set_sync_token : t -> string -> unit 94 + (** Set the sync token. *) 95 + 96 + (** {2 Room State} *) 97 + 98 + val get_state_event : 99 + t -> 100 + room_id:Matrix_proto.Id.Room_id.t -> 101 + event_type:string -> 102 + state_key:string -> 103 + Jsont.json option 104 + (** Get a specific state event. *) 105 + 106 + val get_state_events : 107 + t -> 108 + room_id:Matrix_proto.Id.Room_id.t -> 109 + event_type:string -> 110 + (string * Jsont.json) list 111 + (** Get all state events of a type for a room. Returns state_key -> event pairs. *) 112 + 113 + val get_room_info : t -> Matrix_proto.Id.Room_id.t -> room_info option 114 + (** Get room info. *) 115 + 116 + val get_room_ids : t -> Matrix_proto.Id.Room_id.t list 117 + (** Get all room IDs. *) 118 + 119 + (** {2 User Profiles} *) 120 + 121 + val get_profile : 122 + t -> 123 + room_id:Matrix_proto.Id.Room_id.t -> 124 + user_id:Matrix_proto.Id.User_id.t -> 125 + member_profile option 126 + (** Get user profile in a room. *) 127 + 128 + (** {2 Account Data} *) 129 + 130 + val get_account_data : t -> event_type:string -> Jsont.json option 131 + (** Get global account data. *) 132 + 133 + val get_room_account_data : 134 + t -> room_id:Matrix_proto.Id.Room_id.t -> event_type:string -> Jsont.json option 135 + (** Get room-specific account data. *) 136 + 137 + (** {2 Receipts} *) 138 + 139 + val get_receipts : t -> room_id:Matrix_proto.Id.Room_id.t -> Jsont.json option 140 + (** Get receipt data for a room. *) 141 + 142 + (** {2 Presence} *) 143 + 144 + val get_presence : t -> user_id:Matrix_proto.Id.User_id.t -> Jsont.json option 145 + (** Get presence for a user. *) 146 + 147 + (** {2 Key-Value Store} *) 148 + 149 + val get_kv : t -> string -> kv_data option 150 + (** Get a key-value entry. *) 151 + 152 + val set_kv : t -> string -> kv_data -> unit 153 + (** Set a key-value entry. *) 154 + 155 + val remove_kv : t -> string -> unit 156 + (** Remove a key-value entry. *) 157 + 158 + (** {2 Cleanup} *) 159 + 160 + val clear : t -> unit 161 + (** Clear all data from the store. *) 162 + end 163 + 164 + (** {1 Crypto Types} *) 165 + 166 + (** Device key information for E2EE. *) 167 + type device_keys = { 168 + user_id : Matrix_proto.Id.User_id.t; 169 + device_id : Matrix_proto.Id.Device_id.t; 170 + algorithms : string list; 171 + keys : (string * string) list; 172 + signatures : (string * (string * string) list) list; 173 + unsigned : Jsont.json option; 174 + } 175 + 176 + (** Cross-signing identity keys. *) 177 + type cross_signing_keys = { 178 + master_key : (string * string) list option; 179 + self_signing_key : (string * string) list option; 180 + user_signing_key : (string * string) list option; 181 + } 182 + 183 + (** Olm session data. *) 184 + type olm_session = { 185 + session_id : string; 186 + sender_key : string; 187 + pickle : string; 188 + created_at : int64; 189 + last_used_at : int64; 190 + } 191 + 192 + (** Megolm inbound group session. *) 193 + type inbound_group_session = { 194 + session_id : string; 195 + room_id : Matrix_proto.Id.Room_id.t; 196 + sender_key : string; 197 + signing_key : string option; 198 + pickle : string; 199 + imported : bool; 200 + backed_up : bool; 201 + history_visibility : string option; 202 + algorithm : string; 203 + } 204 + 205 + (** Megolm outbound group session. *) 206 + type outbound_group_session = { 207 + session_id : string; 208 + room_id : Matrix_proto.Id.Room_id.t; 209 + pickle : string; 210 + creation_time : int64; 211 + message_count : int; 212 + shared_with : (string * (string * int) list) list; 213 + } 214 + 215 + (** Tracked user for key updates. *) 216 + type tracked_user = { 217 + user_id : Matrix_proto.Id.User_id.t; 218 + dirty : bool; 219 + } 220 + 221 + (** Aggregated crypto changes. *) 222 + type crypto_changes = { 223 + account_pickle : string option; 224 + private_identity : cross_signing_keys option; 225 + olm_sessions : olm_session list; 226 + inbound_group_sessions : inbound_group_session list; 227 + outbound_group_sessions : outbound_group_session list; 228 + devices_new : device_keys list; 229 + devices_changed : device_keys list; 230 + devices_deleted : (Matrix_proto.Id.User_id.t * Matrix_proto.Id.Device_id.t) list; 231 + tracked_users : tracked_user list; 232 + message_hashes : (string * string) list; 233 + backup_decryption_key : string option; 234 + } 235 + 236 + (** Empty crypto changes record. *) 237 + val empty_crypto_changes : crypto_changes 238 + 239 + (** {1 CRYPTO_STORE Module Type} *) 240 + 241 + (** Module type for E2EE key storage. *) 242 + module type CRYPTO_STORE = sig 243 + type t 244 + (** The store instance type. *) 245 + 246 + type error 247 + (** The error type for storage operations. *) 248 + 249 + val create : unit -> t 250 + (** Create a new store. *) 251 + 252 + (** {2 Account} *) 253 + 254 + val load_account : t -> string option 255 + (** Load the pickled Olm account. *) 256 + 257 + val save_account : t -> string -> unit 258 + (** Save the pickled Olm account. *) 259 + 260 + (** {2 Batch Changes} *) 261 + 262 + val save_changes : t -> crypto_changes -> (unit, error) result 263 + (** Save multiple crypto changes atomically. *) 264 + 265 + (** {2 Olm Sessions} *) 266 + 267 + val get_sessions : t -> sender_key:string -> olm_session list 268 + (** Get Olm sessions for a sender key. *) 269 + 270 + val get_session : t -> session_id:string -> olm_session option 271 + (** Get a specific Olm session. *) 272 + 273 + (** {2 Megolm Sessions} *) 274 + 275 + val get_inbound_group_session : 276 + t -> 277 + room_id:Matrix_proto.Id.Room_id.t -> 278 + session_id:string -> 279 + inbound_group_session option 280 + (** Get an inbound group session. *) 281 + 282 + val get_inbound_group_sessions_for_room : 283 + t -> room_id:Matrix_proto.Id.Room_id.t -> inbound_group_session list 284 + (** Get all inbound group sessions for a room. *) 285 + 286 + val get_sessions_for_backup : t -> limit:int -> inbound_group_session list 287 + (** Get sessions needing backup. *) 288 + 289 + val mark_sessions_backed_up : t -> session_ids:string list -> unit 290 + (** Mark sessions as backed up. *) 291 + 292 + val get_outbound_group_session : 293 + t -> room_id:Matrix_proto.Id.Room_id.t -> outbound_group_session option 294 + (** Get outbound group session for a room. *) 295 + 296 + (** {2 Device Keys} *) 297 + 298 + val get_device : 299 + t -> 300 + user_id:Matrix_proto.Id.User_id.t -> 301 + device_id:Matrix_proto.Id.Device_id.t -> 302 + device_keys option 303 + (** Get a specific device's keys. *) 304 + 305 + val get_user_devices : t -> user_id:Matrix_proto.Id.User_id.t -> device_keys list 306 + (** Get all devices for a user. *) 307 + 308 + (** {2 Cross-Signing} *) 309 + 310 + val get_user_identity : 311 + t -> user_id:Matrix_proto.Id.User_id.t -> cross_signing_keys option 312 + (** Get user's cross-signing keys. *) 313 + 314 + val get_private_identity : t -> cross_signing_keys option 315 + (** Get own cross-signing identity (private keys). *) 316 + 317 + (** {2 User Tracking} *) 318 + 319 + val get_tracked_users : t -> tracked_user list 320 + (** Get all tracked users. *) 321 + 322 + val mark_user_dirty : t -> user_id:Matrix_proto.Id.User_id.t -> unit 323 + (** Mark a user as needing key update. *) 324 + 325 + (** {2 Replay Protection} *) 326 + 327 + val is_message_known : t -> hash:string -> bool 328 + (** Check if a message hash is known (replay protection). *) 329 + 330 + (** {2 Backup} *) 331 + 332 + val get_backup_key : t -> string option 333 + (** Get the backup decryption key. *) 334 + 335 + val set_backup_key : t -> string -> unit 336 + (** Set the backup decryption key. *) 337 + 338 + (** {2 Custom Storage} *) 339 + 340 + val get_custom_value : t -> string -> string option 341 + (** Get a custom stored value. *) 342 + 343 + val set_custom_value : t -> string -> string -> unit 344 + (** Set a custom value. *) 345 + 346 + val remove_custom_value : t -> string -> unit 347 + (** Remove a custom value. *) 348 + 349 + (** {2 Cleanup} *) 350 + 351 + val clear : t -> unit 352 + (** Clear all data from the store. *) 353 + end 354 + 355 + (** {1 Event Cache Types} *) 356 + 357 + (** Cached event entry. *) 358 + type cached_event = { 359 + event_id : Matrix_proto.Id.Event_id.t; 360 + room_id : Matrix_proto.Id.Room_id.t; 361 + sender : Matrix_proto.Id.User_id.t; 362 + origin_server_ts : int64; 363 + event_type : string; 364 + content : Jsont.json; 365 + unsigned : Jsont.json option; 366 + } 367 + 368 + (** Gap in event history (for pagination). *) 369 + type event_gap = { 370 + prev_token : string; 371 + } 372 + 373 + (** Chunk of events in linked list. *) 374 + type event_chunk = { 375 + chunk_id : int; 376 + events : cached_event list; 377 + gap : event_gap option; 378 + prev_chunk_id : int option; 379 + next_chunk_id : int option; 380 + } 381 + 382 + (** {1 EVENT_CACHE_STORE Module Type} *) 383 + 384 + (** Module type for event history storage. *) 385 + module type EVENT_CACHE_STORE = sig 386 + type t 387 + (** The store instance type. *) 388 + 389 + type error 390 + (** The error type for storage operations. *) 391 + 392 + val create : unit -> t 393 + (** Create a new store. *) 394 + 395 + (** {2 Event Storage} *) 396 + 397 + val save_event : t -> cached_event -> unit 398 + (** Save an event to cache. *) 399 + 400 + val get_event : 401 + t -> room_id:Matrix_proto.Id.Room_id.t -> event_id:Matrix_proto.Id.Event_id.t -> 402 + cached_event option 403 + (** Get an event by ID. *) 404 + 405 + val get_room_events : 406 + t -> 407 + room_id:Matrix_proto.Id.Room_id.t -> 408 + ?limit:int -> 409 + ?event_type:string -> 410 + unit -> 411 + cached_event list 412 + (** Get events for a room. *) 413 + 414 + (** {2 Linked Chunk Management} *) 415 + 416 + val get_last_chunk : t -> room_id:Matrix_proto.Id.Room_id.t -> event_chunk option 417 + (** Get the most recent chunk for a room. *) 418 + 419 + val get_chunk : t -> room_id:Matrix_proto.Id.Room_id.t -> chunk_id:int -> event_chunk option 420 + (** Load a specific chunk. *) 421 + 422 + val save_chunk : t -> room_id:Matrix_proto.Id.Room_id.t -> event_chunk -> unit 423 + (** Save a chunk. *) 424 + 425 + (** {2 Deduplication} *) 426 + 427 + val filter_duplicates : 428 + t -> 429 + room_id:Matrix_proto.Id.Room_id.t -> 430 + event_ids:Matrix_proto.Id.Event_id.t list -> 431 + Matrix_proto.Id.Event_id.t list 432 + (** Filter out events that are already cached. *) 433 + 434 + (** {2 Relations} *) 435 + 436 + val find_event_relations : 437 + t -> 438 + room_id:Matrix_proto.Id.Room_id.t -> 439 + event_id:Matrix_proto.Id.Event_id.t -> 440 + ?rel_type:string -> 441 + unit -> 442 + cached_event list 443 + (** Find events related to a given event (replies, edits, reactions). *) 444 + 445 + (** {2 Cleanup} *) 446 + 447 + val remove_room : t -> room_id:Matrix_proto.Id.Room_id.t -> unit 448 + (** Remove all events for a room. *) 449 + 450 + val clear : t -> unit 451 + (** Clear all cached events. *) 452 + end 453 + 454 + (** {1 In-Memory Implementations} *) 455 + 456 + (** In-memory state store implementation. *) 457 + module Memory_state_store : STATE_STORE 458 + 459 + (** In-memory crypto store implementation. *) 460 + module Memory_crypto_store : CRYPTO_STORE 461 + 462 + (** In-memory event cache store implementation. *) 463 + module Memory_event_cache_store : EVENT_CACHE_STORE 464 + 465 + (** {1 Store Creation Helpers} *) 466 + 467 + val create_memory_state_store : unit -> Memory_state_store.t 468 + (** Create an in-memory state store. *) 469 + 470 + val create_memory_crypto_store : unit -> Memory_crypto_store.t 471 + (** Create an in-memory crypto store. *) 472 + 473 + val create_memory_event_cache_store : unit -> Memory_event_cache_store.t 474 + (** Create an in-memory event cache store. *)
+233
lib/matrix_client/timeline.mli
···
··· 1 + (** Room timeline management and event caching. 2 + 3 + This module provides: 4 + - Event storage and retrieval 5 + - Timeline pagination (forward and backward) 6 + - Room state tracking 7 + - Event deduplication *) 8 + 9 + (** {1 Linked Chunk Data Structure} *) 10 + 11 + (** A linked chunk data structure for efficient timeline operations. 12 + Based on the matrix-rust-sdk LinkedChunk pattern. *) 13 + module LinkedChunk : sig 14 + (** A chunk of items in the linked list. *) 15 + type 'a chunk = { 16 + mutable items : 'a list; 17 + mutable prev : 'a chunk option; 18 + mutable next : 'a chunk option; 19 + id : int; 20 + max_size : int; 21 + } 22 + 23 + (** The linked chunk container. *) 24 + type 'a t = { 25 + mutable head : 'a chunk option; 26 + mutable tail : 'a chunk option; 27 + mutable next_id : int; 28 + max_chunk_size : int; 29 + } 30 + 31 + val create : ?max_chunk_size:int -> unit -> 'a t 32 + (** Create a new empty linked chunk. Default chunk size is 50. *) 33 + 34 + val push_back : 'a t -> 'a -> unit 35 + (** Push an item to the back (newest end) of the timeline. *) 36 + 37 + val push_front : 'a t -> 'a -> unit 38 + (** Push an item to the front (oldest end) of the timeline. *) 39 + 40 + val push_front_items : 'a t -> 'a list -> unit 41 + (** Push multiple items to the front (for back-pagination). *) 42 + 43 + val iter : ('a -> unit) -> 'a t -> unit 44 + (** Iterate over all items from oldest to newest. *) 45 + 46 + val iter_rev : ('a -> unit) -> 'a t -> unit 47 + (** Iterate over all items from newest to oldest. *) 48 + 49 + val last_n : 'a t -> int -> 'a list 50 + (** Get the last N items (most recent). *) 51 + 52 + val length : 'a t -> int 53 + (** Total number of items. *) 54 + 55 + val find_opt : ('a -> bool) -> 'a t -> 'a option 56 + (** Find an item by predicate. *) 57 + 58 + val clear : 'a t -> unit 59 + (** Clear all items. *) 60 + end 61 + 62 + (** {1 Event Types} *) 63 + 64 + (** Timeline event wrapper with metadata. *) 65 + type event_item = { 66 + event : Jsont.json; 67 + event_id : Matrix_proto.Id.Event_id.t; 68 + sender : Matrix_proto.Id.User_id.t; 69 + origin_server_ts : int64; 70 + event_type : string; 71 + local_echo : bool; 72 + decrypted : bool; 73 + } 74 + 75 + (** Room state entry. *) 76 + type state_entry = { 77 + event_type : string; 78 + state_key : string; 79 + content : Jsont.json; 80 + sender : Matrix_proto.Id.User_id.t; 81 + event_id : Matrix_proto.Id.Event_id.t option; 82 + } 83 + 84 + (** {1 Timeline Type} *) 85 + 86 + (** Room timeline with state tracking. *) 87 + type t = { 88 + room_id : Matrix_proto.Id.Room_id.t; 89 + events : event_item LinkedChunk.t; 90 + mutable state : ((string * string) * state_entry) list; 91 + mutable prev_batch : string option; 92 + mutable next_batch : string option; 93 + mutable event_ids : string list; 94 + max_events : int; 95 + mutable name : string option; 96 + mutable topic : string option; 97 + mutable avatar_url : string option; 98 + mutable canonical_alias : Matrix_proto.Id.Room_alias.t option; 99 + mutable joined_member_count : int; 100 + mutable invited_member_count : int; 101 + mutable is_encrypted : bool; 102 + mutable is_direct : bool; 103 + mutable notification_count : int; 104 + mutable highlight_count : int; 105 + } 106 + 107 + (** {1 Creation} *) 108 + 109 + val create : room_id:Matrix_proto.Id.Room_id.t -> ?max_events:int -> unit -> t 110 + (** Create a new timeline for a room. *) 111 + 112 + (** {1 Event Operations} *) 113 + 114 + val has_event : t -> Matrix_proto.Id.Event_id.t -> bool 115 + (** Check if an event is already in the timeline. *) 116 + 117 + val add_event : 118 + t -> 119 + event:Jsont.json -> 120 + event_id:Matrix_proto.Id.Event_id.t -> 121 + sender:Matrix_proto.Id.User_id.t -> 122 + origin_server_ts:int64 -> 123 + event_type:string -> 124 + ?local_echo:bool -> 125 + ?decrypted:bool -> 126 + unit -> 127 + unit 128 + (** Add an event to the timeline. *) 129 + 130 + val add_events_back : 131 + t -> 132 + (Jsont.json * Matrix_proto.Id.Event_id.t * Matrix_proto.Id.User_id.t * int64 * string * bool) list -> 133 + unit 134 + (** Add events from back-pagination (older events). *) 135 + 136 + val find_event : t -> Matrix_proto.Id.Event_id.t -> event_item option 137 + (** Find an event by ID. *) 138 + 139 + val get_last_events : t -> int -> event_item list 140 + (** Get the last N events. *) 141 + 142 + val get_all_events : t -> event_item list 143 + (** Get all events. *) 144 + 145 + (** {1 State Operations} *) 146 + 147 + val update_state : 148 + t -> 149 + event_type:string -> 150 + state_key:string -> 151 + content:Jsont.json -> 152 + sender:Matrix_proto.Id.User_id.t -> 153 + ?event_id:Matrix_proto.Id.Event_id.t -> 154 + unit -> 155 + unit 156 + (** Update room state from a state event. *) 157 + 158 + val get_state : t -> event_type:string -> state_key:string -> state_entry option 159 + (** Get state for a specific event type and state key. *) 160 + 161 + val get_state_by_type : t -> event_type:string -> state_entry list 162 + (** Get all state for an event type. *) 163 + 164 + val get_members : t -> state_entry list 165 + (** Get room members from state. *) 166 + 167 + (** {1 Room Info} *) 168 + 169 + val display_name : t -> string option 170 + (** Get room display name (computed from state). *) 171 + 172 + (** {1 Pagination} *) 173 + 174 + val set_prev_batch : t -> string -> unit 175 + (** Set pagination token for back-pagination. *) 176 + 177 + val set_next_batch : t -> string -> unit 178 + (** Set pagination token for forward sync. *) 179 + 180 + (** {1 Sync Updates} *) 181 + 182 + val update_from_sync : 183 + t -> 184 + joined_count:int -> 185 + invited_count:int -> 186 + notification_count:int -> 187 + highlight_count:int -> 188 + unit 189 + (** Update from sync response. *) 190 + 191 + (** {1 Timeline Management} *) 192 + 193 + val clear_timeline : t -> unit 194 + (** Clear timeline (but keep state). *) 195 + 196 + val confirm_local_echo : 197 + t -> 198 + local_event_id:Matrix_proto.Id.Event_id.t -> 199 + confirmed_event_id:Matrix_proto.Id.Event_id.t -> 200 + unit 201 + (** Replace local echo with confirmed event. *) 202 + 203 + (** {1 Timeline Cache} *) 204 + 205 + (** Room timeline cache - manages timelines for multiple rooms. *) 206 + module Cache : sig 207 + type cache 208 + (** The cache type. *) 209 + 210 + val create : ?max_rooms:int -> unit -> cache 211 + (** Create a new timeline cache. *) 212 + 213 + val get_or_create : cache -> Matrix_proto.Id.Room_id.t -> t 214 + (** Get or create a timeline for a room. *) 215 + 216 + val get : cache -> Matrix_proto.Id.Room_id.t -> t option 217 + (** Get a timeline if it exists. *) 218 + 219 + val remove : cache -> Matrix_proto.Id.Room_id.t -> unit 220 + (** Remove a timeline from the cache. *) 221 + 222 + val all_room_ids : cache -> Matrix_proto.Id.Room_id.t list 223 + (** Get all room IDs in the cache. *) 224 + end 225 + 226 + (** {1 Back-Pagination} *) 227 + 228 + val paginate_back : 229 + Client.t -> 230 + t -> 231 + limit:int -> 232 + ((Jsont.json * Matrix_proto.Id.Event_id.t * Matrix_proto.Id.User_id.t * int64 * string * bool) list, Error.t) result 233 + (** Fetch older messages via back-pagination. *)
+236
lib/matrix_client/uiaa.mli
···
··· 1 + (** User-Interactive Authentication API (UIAA). 2 + 3 + UIAA is Matrix's mechanism for protecting sensitive operations that require 4 + additional verification beyond just an access token. Operations like: 5 + - Deleting devices 6 + - Changing passwords 7 + - Adding 3PIDs 8 + - Deactivating accounts 9 + 10 + When these operations return a 401 with UIAA challenge, clients must 11 + complete authentication stages before the operation can proceed. 12 + 13 + @see <https://spec.matrix.org/v1.11/client-server-api/#user-interactive-authentication-api> UIAA *) 14 + 15 + (** {1 Authentication Types} *) 16 + 17 + (** Authentication stage types. *) 18 + type auth_type = 19 + | Password 20 + | Recaptcha 21 + | OAuth2 22 + | Email_identity 23 + | Msisdn 24 + | Dummy 25 + | Registration_token 26 + | Terms 27 + | Sso 28 + | Sso_fallback 29 + | Custom of string 30 + 31 + val auth_type_of_string : string -> auth_type 32 + (** Parse auth type from string. *) 33 + 34 + val auth_type_to_string : auth_type -> string 35 + (** Convert auth type to string. *) 36 + 37 + (** {1 Authentication Flow} *) 38 + 39 + (** Authentication flow - a sequence of stages that must be completed. *) 40 + type auth_flow = { 41 + stages : auth_type list; 42 + } 43 + 44 + val auth_flow_jsont : auth_flow Jsont.t 45 + (** JSON codec for auth flow. *) 46 + 47 + (** {1 UIAA Response} *) 48 + 49 + (** UIAA response from server when authentication is required. *) 50 + type uiaa_response = { 51 + session : string option; 52 + flows : auth_flow list; 53 + completed : auth_type list; 54 + params : Jsont.json option; 55 + error : string option; 56 + errcode : string option; 57 + } 58 + 59 + val uiaa_response_jsont : uiaa_response Jsont.t 60 + (** JSON codec for UIAA response. *) 61 + 62 + (** {1 User Identifiers} *) 63 + 64 + (** User identifier for authentication. *) 65 + type user_identifier = 66 + | User of string 67 + | ThirdParty of { medium : string; address : string } 68 + | Phone of { country : string; phone : string } 69 + 70 + (** Third-party identity credentials. *) 71 + type threepid_creds = { 72 + sid : string; 73 + client_secret : string; 74 + id_server : string option; 75 + id_access_token : string option; 76 + } 77 + 78 + (** {1 Authentication Data} *) 79 + 80 + (** Authentication data to send in response to UIAA challenge. *) 81 + type auth_data = 82 + | Password_auth of { 83 + identifier : user_identifier; 84 + password : string; 85 + session : string option; 86 + } 87 + | Recaptcha_auth of { 88 + response : string; 89 + session : string option; 90 + } 91 + | Email_identity_auth of { 92 + threepid_creds : threepid_creds; 93 + session : string option; 94 + } 95 + | Msisdn_auth of { 96 + threepid_creds : threepid_creds; 97 + session : string option; 98 + } 99 + | Dummy_auth of { 100 + session : string option; 101 + } 102 + | Token_auth of { 103 + token : string; 104 + session : string option; 105 + } 106 + | Terms_auth of { 107 + session : string option; 108 + } 109 + 110 + val user_identifier_to_json : user_identifier -> string 111 + (** Encode user identifier to JSON string. *) 112 + 113 + val auth_data_to_json : auth_data -> string 114 + (** Encode auth data to JSON string. *) 115 + 116 + (** {1 UIAA Result} *) 117 + 118 + (** Result of a UIAA operation. *) 119 + type 'a uiaa_result = 120 + | Uiaa_success of 'a 121 + | Uiaa_auth_required of uiaa_response 122 + | Uiaa_error of Error.t 123 + 124 + (** {1 Response Parsing} *) 125 + 126 + val is_uiaa_response : int -> string -> bool 127 + (** Check if a response is a UIAA challenge (401 with flows). *) 128 + 129 + val parse_uiaa_response : string -> uiaa_response option 130 + (** Parse a UIAA response from error body. *) 131 + 132 + (** {1 Auth Data Constructors} *) 133 + 134 + val password_auth : 135 + user_id:string -> 136 + password:string -> 137 + ?session:string -> 138 + unit -> 139 + auth_data 140 + (** Create password authentication data. *) 141 + 142 + val dummy_auth : ?session:string -> unit -> auth_data 143 + (** Create dummy authentication (for flows that allow it). *) 144 + 145 + val recaptcha_auth : response:string -> ?session:string -> unit -> auth_data 146 + (** Create recaptcha authentication. *) 147 + 148 + val email_identity_auth : 149 + sid:string -> 150 + client_secret:string -> 151 + ?id_server:string -> 152 + ?id_access_token:string -> 153 + ?session:string -> 154 + unit -> 155 + auth_data 156 + (** Create email identity authentication. *) 157 + 158 + val token_auth : token:string -> ?session:string -> unit -> auth_data 159 + (** Create registration token authentication. *) 160 + 161 + val terms_auth : ?session:string -> unit -> auth_data 162 + (** Create terms acceptance authentication. *) 163 + 164 + (** {1 Flow Analysis} *) 165 + 166 + val find_simplest_flow : uiaa_response -> auth_flow option 167 + (** Find the simplest flow to complete (fewest stages). *) 168 + 169 + val flow_contains_only : auth_flow -> auth_type list -> bool 170 + (** Check if a flow contains only the given auth types. *) 171 + 172 + val has_password_only_flow : uiaa_response -> bool 173 + (** Check if password-only auth is available. *) 174 + 175 + val has_dummy_flow : uiaa_response -> bool 176 + (** Check if dummy auth is available. *) 177 + 178 + val remaining_stages : uiaa_response -> auth_flow -> auth_type list 179 + (** Get the remaining stages to complete. *) 180 + 181 + (** {1 UIAA Wrapper} *) 182 + 183 + val with_uiaa : 184 + make_request:(string option -> ('a, Error.t) result) -> 185 + auth_callback:(uiaa_response -> auth_data option) -> 186 + 'a uiaa_result 187 + (** UIAA-protected request wrapper. 188 + 189 + Handles the UIAA flow automatically: 190 + 1. Makes the initial request 191 + 2. If 401 with UIAA, calls the auth_callback to get auth data 192 + 3. Retries the request with auth data 193 + 4. Repeats until success or failure *) 194 + 195 + val add_auth_to_body : string -> string -> string 196 + (** Helper to add auth field to a request body. *) 197 + 198 + (** {1 Token Request} *) 199 + 200 + (** Response from token request. *) 201 + type request_token_response = { 202 + sid : string; 203 + submit_url : string option; 204 + } 205 + 206 + val request_token_response_jsont : request_token_response Jsont.t 207 + (** JSON codec for token response. *) 208 + 209 + val request_email_token : 210 + Client.t -> 211 + email:string -> 212 + client_secret:string -> 213 + send_attempt:int -> 214 + ?next_link:string -> 215 + unit -> 216 + (request_token_response, Error.t) result 217 + (** Request a token for email validation. *) 218 + 219 + val request_msisdn_token : 220 + Client.t -> 221 + country:string -> 222 + phone_number:string -> 223 + client_secret:string -> 224 + send_attempt:int -> 225 + ?next_link:string -> 226 + unit -> 227 + (request_token_response, Error.t) result 228 + (** Request a token for phone number validation. *) 229 + 230 + val validate_email_token : 231 + Client.t -> 232 + sid:string -> 233 + client_secret:string -> 234 + token:string -> 235 + (unit, Error.t) result 236 + (** Validate a token. *)
+1 -1
lib/matrix_client/verification.ml
··· 218 device.local_trust <- trust 219 220 (** Check if device is signed by a self-signing key *) 221 - let verify_device_with_self_signing ~self_signing_key ~device = 222 match get_ed25519_key self_signing_key.key with 223 | None -> false 224 | Some (_key_id, _pub_key) ->
··· 218 device.local_trust <- trust 219 220 (** Check if device is signed by a self-signing key *) 221 + let verify_device_with_self_signing ~(self_signing_key:self_signing_pubkey) ~device = 222 match get_ed25519_key self_signing_key.key with 223 | None -> false 224 | Some (_key_id, _pub_key) ->
+354
lib/matrix_client/verification.mli
···
··· 1 + (** Cross-signing and device verification. 2 + 3 + This module implements Matrix cross-signing for identity verification: 4 + - Cross-signing key management (master, self-signing, user-signing keys) 5 + - Device verification (local trust, cross-signing trust) 6 + - User identity verification 7 + - SAS (Short Authentication String) verification protocol 8 + 9 + @see <https://spec.matrix.org/v1.11/client-server-api/#cross-signing> Cross-Signing *) 10 + 11 + (** {1 Trust States} *) 12 + 13 + (** Local trust state for a device. *) 14 + type local_trust = 15 + | Verified 16 + | BlackListed 17 + | Ignored 18 + | Unset 19 + 20 + val local_trust_to_int : local_trust -> int 21 + (** Convert local trust to int for storage. *) 22 + 23 + val local_trust_of_int : int -> local_trust 24 + (** Parse local trust from int. *) 25 + 26 + (** Own user identity verification state. *) 27 + type own_identity_state = 28 + | Never_verified 29 + | Verification_violation 30 + | Identity_verified 31 + 32 + (** {1 Cross-Signing Key Types} *) 33 + 34 + (** Cross-signing key usage. *) 35 + type key_usage = 36 + | Master 37 + | Self_signing 38 + | User_signing 39 + 40 + val key_usage_to_string : key_usage -> string 41 + (** Convert key usage to string. *) 42 + 43 + val key_usage_of_string : string -> key_usage option 44 + (** Parse key usage from string. *) 45 + 46 + (** Public cross-signing key. *) 47 + type cross_signing_pubkey = { 48 + user_id : Matrix_proto.Id.User_id.t; 49 + usage : key_usage list; 50 + keys : (string * string) list; 51 + signatures : (string * (string * string) list) list; 52 + } 53 + 54 + val get_ed25519_key : cross_signing_pubkey -> (string * string) option 55 + (** Extract the first Ed25519 key from a cross-signing key. *) 56 + 57 + (** {1 Private Cross-Signing Keys} *) 58 + 59 + (** Private key for signing operations. *) 60 + type private_key = { 61 + public_key : string; 62 + secret_key : string; 63 + } 64 + 65 + (** Private cross-signing identity (holds the private keys). *) 66 + type private_cross_signing_identity = { 67 + user_id : Matrix_proto.Id.User_id.t; 68 + mutable master_key : private_key option; 69 + mutable self_signing_key : private_key option; 70 + mutable user_signing_key : private_key option; 71 + mutable shared : bool; 72 + } 73 + 74 + val create_private_identity : user_id:Matrix_proto.Id.User_id.t -> private_cross_signing_identity 75 + (** Create a new private cross-signing identity. *) 76 + 77 + val generate_ed25519_key : unit -> private_key 78 + (** Generate a new Ed25519 key pair. *) 79 + 80 + val generate_cross_signing_keys : private_cross_signing_identity -> unit 81 + (** Generate all cross-signing keys for a user. *) 82 + 83 + val sign_with_key : private_key -> string -> (string, string) result 84 + (** Sign data with a private key. *) 85 + 86 + (** {1 Cross-Signing Public Keys} *) 87 + 88 + (** Master public key. *) 89 + type master_pubkey = { 90 + key : cross_signing_pubkey; 91 + } 92 + 93 + (** Self-signing public key. *) 94 + type self_signing_pubkey = { 95 + key : cross_signing_pubkey; 96 + } 97 + 98 + (** User-signing public key. *) 99 + type user_signing_pubkey = { 100 + key : cross_signing_pubkey; 101 + } 102 + 103 + val pubkey_from_private : 104 + user_id:Matrix_proto.Id.User_id.t -> 105 + usage:key_usage -> 106 + private_key -> 107 + cross_signing_pubkey 108 + (** Create a public cross-signing key from private key. *) 109 + 110 + (** {1 Signature Verification} *) 111 + 112 + val verify_signature : 113 + public_key_b64:string -> 114 + signature_b64:string -> 115 + data:string -> 116 + bool 117 + (** Verify an Ed25519 signature. *) 118 + 119 + val canonicalize_json : Jsont.json -> string 120 + (** Canonicalize JSON for signing. *) 121 + 122 + val verify_cross_signing_signature : 123 + signer_key:cross_signing_pubkey -> 124 + signed_key:cross_signing_pubkey -> 125 + bool 126 + (** Verify that a cross-signing key is signed by another key. *) 127 + 128 + (** {1 Device Verification} *) 129 + 130 + (** Device with verification state. *) 131 + type verified_device = { 132 + user_id : Matrix_proto.Id.User_id.t; 133 + device_id : Matrix_proto.Id.Device_id.t; 134 + keys : (string * string) list; 135 + algorithms : string list; 136 + display_name : string option; 137 + mutable local_trust : local_trust; 138 + mutable cross_signing_trusted : bool; 139 + } 140 + 141 + val create_verified_device : 142 + user_id:Matrix_proto.Id.User_id.t -> 143 + device_id:Matrix_proto.Id.Device_id.t -> 144 + keys:(string * string) list -> 145 + algorithms:string list -> 146 + ?display_name:string -> 147 + unit -> 148 + verified_device 149 + (** Create a verified device from device keys. *) 150 + 151 + val is_device_verified : verified_device -> bool 152 + (** Check if a device is verified (locally or via cross-signing). *) 153 + 154 + val set_device_local_trust : verified_device -> local_trust -> unit 155 + (** Set local trust state for a device. *) 156 + 157 + val verify_device_with_self_signing : 158 + self_signing_key:self_signing_pubkey -> 159 + device:verified_device -> 160 + bool 161 + (** Check if device is signed by a self-signing key. *) 162 + 163 + (** {1 User Identity} *) 164 + 165 + (** Own user identity. *) 166 + type own_user_identity = { 167 + user_id : Matrix_proto.Id.User_id.t; 168 + master_key : master_pubkey; 169 + self_signing_key : self_signing_pubkey; 170 + user_signing_key : user_signing_pubkey; 171 + mutable state : own_identity_state; 172 + } 173 + 174 + (** Other user identity. *) 175 + type other_user_identity = { 176 + user_id : Matrix_proto.Id.User_id.t; 177 + master_key : master_pubkey; 178 + self_signing_key : self_signing_pubkey; 179 + mutable pinned_master_key : master_pubkey option; 180 + mutable was_previously_verified : bool; 181 + } 182 + 183 + (** User identity (own or other). *) 184 + type user_identity = 185 + | Own of own_user_identity 186 + | Other of other_user_identity 187 + 188 + val identity_user_id : user_identity -> Matrix_proto.Id.User_id.t 189 + (** Get user ID from identity. *) 190 + 191 + val is_own_identity_verified : own_user_identity -> bool 192 + (** Check if own identity is verified. *) 193 + 194 + val is_other_identity_verified : 195 + our_user_signing_key:user_signing_pubkey -> 196 + other_user_identity -> 197 + bool 198 + (** Check if other user identity is verified by us. *) 199 + 200 + val has_identity_changed : other_user_identity -> bool 201 + (** Check if a user's identity has changed since we pinned it. *) 202 + 203 + val pin_master_key : other_user_identity -> unit 204 + (** Pin the current master key for future change detection. *) 205 + 206 + (** {1 SAS Verification Protocol} *) 207 + 208 + (** SAS verification state. *) 209 + type sas_state = 210 + | Sas_created 211 + | Sas_started 212 + | Sas_accepted 213 + | Sas_keys_exchanged 214 + | Sas_confirmed 215 + | Sas_mac_received 216 + | Sas_done 217 + | Sas_cancelled of string 218 + 219 + (** Short authentication string output. *) 220 + type sas_output = 221 + | Decimal of int * int * int 222 + | Emoji of (int * string) list 223 + 224 + (** SAS verification methods. *) 225 + type sas_method = 226 + | Decimal_method 227 + | Emoji_method 228 + 229 + (** SAS verification session. *) 230 + type sas_session = { 231 + flow_id : string; 232 + mutable state : sas_state; 233 + our_user_id : Matrix_proto.Id.User_id.t; 234 + our_device_id : Matrix_proto.Id.Device_id.t; 235 + their_user_id : Matrix_proto.Id.User_id.t; 236 + their_device_id : Matrix_proto.Id.Device_id.t; 237 + mutable their_public_key : string option; 238 + mutable our_public_key : string option; 239 + mutable sas_bytes : string option; 240 + mutable methods : sas_method list; 241 + } 242 + 243 + val generate_flow_id : unit -> string 244 + (** Generate a random flow ID. *) 245 + 246 + val create_sas_session : 247 + our_user_id:Matrix_proto.Id.User_id.t -> 248 + our_device_id:Matrix_proto.Id.Device_id.t -> 249 + their_user_id:Matrix_proto.Id.User_id.t -> 250 + their_device_id:Matrix_proto.Id.Device_id.t -> 251 + sas_session 252 + (** Create a new SAS verification session. *) 253 + 254 + val sas_emoji_table : (int * string) array 255 + (** Standard SAS emoji table. *) 256 + 257 + val derive_sas_output : method_type:sas_method -> sas_bytes:string -> sas_output 258 + (** Derive SAS output from shared bytes. *) 259 + 260 + val get_sas_output : sas_session -> sas_method -> sas_output option 261 + (** Get SAS output for display. *) 262 + 263 + val confirm_sas : sas_session -> unit 264 + (** Confirm SAS match. *) 265 + 266 + val cancel_sas : sas_session -> string -> unit 267 + (** Cancel SAS verification. *) 268 + 269 + val is_sas_done : sas_session -> bool 270 + (** Check if SAS is complete. *) 271 + 272 + (** {1 QR Code Verification} *) 273 + 274 + (** QR verification mode. *) 275 + type qr_mode = 276 + | Self_verifying_master_key_trusts_device 277 + | Self_verifying_device_trusts_master_key 278 + | Verifying_another_user 279 + 280 + (** QR verification state. *) 281 + type qr_state = 282 + | Qr_started 283 + | Qr_scanned 284 + | Qr_confirmed 285 + | Qr_reciprocated 286 + | Qr_done 287 + | Qr_cancelled of string 288 + 289 + (** QR verification data. *) 290 + type qr_verification = { 291 + flow_id : string; 292 + mutable state : qr_state; 293 + mode : qr_mode; 294 + our_user_id : Matrix_proto.Id.User_id.t; 295 + their_user_id : Matrix_proto.Id.User_id.t; 296 + our_master_key : string; 297 + their_master_key : string option; 298 + mutable secret : string option; 299 + } 300 + 301 + val create_self_qr_verification : 302 + our_user_id:Matrix_proto.Id.User_id.t -> 303 + our_master_key:string -> 304 + mode:qr_mode -> 305 + qr_verification 306 + (** Create QR verification for self-verification. *) 307 + 308 + val create_user_qr_verification : 309 + our_user_id:Matrix_proto.Id.User_id.t -> 310 + their_user_id:Matrix_proto.Id.User_id.t -> 311 + our_master_key:string -> 312 + their_master_key:string -> 313 + qr_verification 314 + (** Create QR verification for verifying another user. *) 315 + 316 + (** {1 Verification Request} *) 317 + 318 + (** Verification request. *) 319 + type verification_request = { 320 + flow_id : string; 321 + from_user_id : Matrix_proto.Id.User_id.t; 322 + to_user_id : Matrix_proto.Id.User_id.t; 323 + from_device_id : Matrix_proto.Id.Device_id.t option; 324 + methods : string list; 325 + timestamp : int64; 326 + mutable accepted : bool; 327 + mutable cancelled : bool; 328 + } 329 + 330 + val create_verification_request : 331 + from_user_id:Matrix_proto.Id.User_id.t -> 332 + to_user_id:Matrix_proto.Id.User_id.t -> 333 + ?from_device_id:Matrix_proto.Id.Device_id.t -> 334 + unit -> 335 + verification_request 336 + (** Create a verification request. *) 337 + 338 + val accept_verification_request : verification_request -> unit 339 + (** Accept a verification request. *) 340 + 341 + val cancel_verification_request : verification_request -> unit 342 + (** Cancel a verification request. *) 343 + 344 + (** {1 Cross-Signing Upload} *) 345 + 346 + (** Data needed to upload cross-signing keys. *) 347 + type cross_signing_upload = { 348 + master_key : cross_signing_pubkey; 349 + self_signing_key : cross_signing_pubkey; 350 + user_signing_key : cross_signing_pubkey; 351 + } 352 + 353 + val build_cross_signing_upload : private_cross_signing_identity -> cross_signing_upload option 354 + (** Build upload data from private identity. *)
+587 -73
lib/matrix_proto/matrix_event.ml
··· 34 timestamp when the event was received by the originating server. *) 35 type t = int64 36 37 let of_ptime pt = 38 let span = Ptime.to_span pt in 39 let d, ps = Ptime.Span.to_d_ps span in ··· 47 let ps = Int64.mul rem_ms 1_000_000_000L in 48 Ptime.Span.of_d_ps (days, ps) |> Option.map Ptime.of_span |> Option.join 49 50 let jsont = Jsont.int64 51 end 52 53 (** {1 Unsigned Event Data} *) 54 55 module Unsigned = struct 56 - (** Unsigned data added by the homeserver. *) 57 58 type t = { 59 age : int64 option; ··· 63 transaction_id : Transaction_id.t option; 64 } 65 66 - let empty = { 67 - age = None; 68 - prev_content = None; 69 - prev_sender = None; 70 - redacted_because = None; 71 - transaction_id = None; 72 - } 73 74 let jsont = 75 Jsont.Object.( ··· 86 (** {1 Room Membership} *) 87 88 module Membership = struct 89 type t = 90 | Join 91 | Invite ··· 108 | "knock" -> Ok Knock 109 | s -> Error (`Unknown_membership s) 110 111 let jsont = 112 Jsont.enum [ 113 ("join", Join); ··· 121 (** {1 Join Rules} *) 122 123 module Join_rule = struct 124 type t = 125 | Public 126 | Invite ··· 129 | Knock_restricted 130 | Private 131 132 let jsont = 133 Jsont.enum [ 134 ("public", Public); ··· 143 (** {1 History Visibility} *) 144 145 module History_visibility = struct 146 type t = 147 | Invited 148 | Joined 149 | Shared 150 | World_readable 151 152 let jsont = 153 Jsont.enum [ 154 ("invited", Invited); ··· 161 (** {1 Room State Event Contents} *) 162 163 module Room_create_content = struct 164 type t = { 165 - creator : User_id.t option; (* Deprecated in v11, optional *) 166 room_version : string option; 167 - predecessor : predecessor option; 168 - type_ : string option; (* m.space for spaces *) 169 - } 170 - and predecessor = { 171 - room_id : Room_id.t; 172 - event_id : Event_id.t; 173 } 174 175 - let predecessor_jsont = 176 - Jsont.Object.( 177 - map (fun room_id event_id -> { room_id; event_id }) 178 - |> mem "room_id" Room_id.jsont ~enc:(fun p -> p.room_id) 179 - |> mem "event_id" Event_id.jsont ~enc:(fun p -> p.event_id) 180 - |> finish) 181 182 let jsont = 183 Jsont.Object.( ··· 185 { creator; room_version; predecessor; type_ }) 186 |> opt_mem "creator" User_id.jsont ~enc:(fun t -> t.creator) 187 |> opt_mem "room_version" Jsont.string ~enc:(fun t -> t.room_version) 188 - |> opt_mem "predecessor" predecessor_jsont ~enc:(fun t -> t.predecessor) 189 |> opt_mem "type" Jsont.string ~enc:(fun t -> t.type_) 190 |> finish) 191 end 192 193 module Room_name_content = struct 194 type t = { name : string } 195 196 let jsont = 197 Jsont.Object.( 198 map (fun name -> { name }) ··· 201 end 202 203 module Room_topic_content = struct 204 type t = { topic : string } 205 206 let jsont = 207 Jsont.Object.( 208 map (fun topic -> { topic }) ··· 211 end 212 213 module Room_avatar_content = struct 214 type t = { 215 url : string option; 216 - info : image_info option; 217 } 218 - and image_info = { 219 - h : int option; 220 - w : int option; 221 - mimetype : string option; 222 - size : int option; 223 - } 224 225 - let image_info_jsont = 226 - Jsont.Object.( 227 - map (fun h w mimetype size -> { h; w; mimetype; size }) 228 - |> opt_mem "h" Jsont.int ~enc:(fun t -> t.h) 229 - |> opt_mem "w" Jsont.int ~enc:(fun t -> t.w) 230 - |> opt_mem "mimetype" Jsont.string ~enc:(fun t -> t.mimetype) 231 - |> opt_mem "size" Jsont.int ~enc:(fun t -> t.size) 232 - |> finish) 233 234 let jsont = 235 Jsont.Object.( 236 map (fun url info -> { url; info }) 237 |> opt_mem "url" Jsont.string ~enc:(fun t -> t.url) 238 - |> opt_mem "info" image_info_jsont ~enc:(fun t -> t.info) 239 |> finish) 240 end 241 242 module Room_member_content = struct 243 type t = { 244 membership : Membership.t; 245 displayname : string option; ··· 248 reason : string option; 249 } 250 251 let jsont = 252 Jsont.Object.( 253 map (fun membership displayname avatar_url is_direct reason -> ··· 261 end 262 263 module Room_join_rules_content = struct 264 type t = { 265 join_rule : Join_rule.t; 266 - allow : allow_condition list option; 267 } 268 - and allow_condition = { 269 - type_ : string; 270 - room_id : Room_id.t option; 271 - } 272 273 - let allow_condition_jsont = 274 - Jsont.Object.( 275 - map (fun type_ room_id -> { type_; room_id }) 276 - |> mem "type" Jsont.string ~enc:(fun c -> c.type_) 277 - |> opt_mem "room_id" Room_id.jsont ~enc:(fun c -> c.room_id) 278 - |> finish) 279 280 let jsont = 281 Jsont.Object.( 282 map (fun join_rule allow -> { join_rule; allow }) 283 |> mem "join_rule" Join_rule.jsont ~enc:(fun t -> t.join_rule) 284 - |> opt_mem "allow" (Jsont.list allow_condition_jsont) ~enc:(fun t -> t.allow) 285 |> finish) 286 end 287 288 module Room_history_visibility_content = struct 289 type t = { history_visibility : History_visibility.t } 290 291 let jsont = 292 Jsont.Object.( 293 map (fun history_visibility -> { history_visibility }) ··· 297 end 298 299 module Room_canonical_alias_content = struct 300 type t = { 301 alias : Room_alias.t option; 302 alt_aliases : Room_alias.t list option; 303 } 304 305 let jsont = 306 Jsont.Object.( 307 map (fun alias alt_aliases -> { alias; alt_aliases }) ··· 311 end 312 313 module Room_power_levels_content = struct 314 type t = { 315 ban : int option; 316 events : (string * int) list option; ··· 323 users_default : int option; 324 } 325 326 - (* Helper for string -> int maps encoded as objects *) 327 module StringMap = Map.Make(String) 328 329 let int_map_jsont = ··· 351 end 352 353 module Room_encryption_content = struct 354 type t = { 355 algorithm : string; 356 rotation_period_ms : int64 option; 357 rotation_period_msgs : int option; 358 } 359 360 let jsont = 361 Jsont.Object.( 362 map (fun algorithm rotation_period_ms rotation_period_msgs -> ··· 368 end 369 370 module Room_pinned_events_content = struct 371 - type t = { 372 - pinned : string list; 373 - } 374 375 let jsont = 376 Jsont.Object.( ··· 380 end 381 382 module Room_server_acl_content = struct 383 type t = { 384 allow : string list; 385 allow_ip_literals : bool; 386 deny : string list; 387 } 388 389 let jsont = 390 Jsont.Object.( 391 map (fun allow allow_ip_literals deny -> ··· 397 end 398 399 module Room_tombstone_content = struct 400 type t = { 401 body : string; 402 replacement_room : Room_id.t; 403 } 404 405 let jsont = 406 Jsont.Object.( 407 map (fun body replacement_room -> { body; replacement_room }) ··· 411 end 412 413 module Room_guest_access_content = struct 414 type access = 415 | Can_join 416 | Forbidden 417 418 let access_jsont = 419 Jsont.enum [ 420 ("can_join", Can_join); 421 ("forbidden", Forbidden); 422 ] 423 424 - type t = { 425 - guest_access : access; 426 - } 427 428 let jsont = 429 Jsont.Object.( ··· 435 (** {1 Space Event Contents} *) 436 437 module Space_child_content = struct 438 type t = { 439 via : string list option; 440 order : string option; 441 suggested : bool option; 442 } 443 444 let jsont = 445 Jsont.Object.( 446 map (fun via order suggested -> { via; order; suggested }) ··· 451 end 452 453 module Space_parent_content = struct 454 type t = { 455 via : string list option; 456 canonical : bool option; 457 } 458 459 let jsont = 460 Jsont.Object.( 461 map (fun via canonical -> { via; canonical }) ··· 464 |> finish) 465 end 466 467 - (** {1 Call Event Contents} *) 468 469 module Call_invite_content = struct 470 type t = { 471 call_id : string; 472 party_id : string option; ··· 475 offer : sdp_content; 476 invitee : string option; 477 } 478 - and sdp_content = { 479 - type_ : string; 480 - sdp : string; 481 - } 482 483 let sdp_content_jsont = 484 Jsont.Object.( ··· 501 end 502 503 module Call_answer_content = struct 504 type sdp_content = { 505 type_ : string; 506 sdp : string; ··· 513 answer : sdp_content; 514 } 515 516 let sdp_content_jsont = 517 Jsont.Object.( 518 map (fun type_ sdp -> { type_; sdp }) ··· 532 end 533 534 module Call_hangup_content = struct 535 type reason = 536 | Ice_failed 537 | Invite_timeout ··· 540 | User_busy 541 | Unknown_error 542 543 let reason_jsont = 544 Jsont.enum [ 545 ("ice_failed", Ice_failed); ··· 557 reason : reason option; 558 } 559 560 let jsont = 561 Jsont.Object.( 562 map (fun call_id party_id version reason -> ··· 569 end 570 571 module Call_candidates_content = struct 572 type candidate = { 573 candidate : string; 574 sdp_mid : string; 575 sdp_m_line_index : int; 576 } 577 578 let candidate_jsont = 579 Jsont.Object.( 580 map (fun candidate sdp_mid sdp_m_line_index -> ··· 590 version : int; 591 candidates : candidate list; 592 } 593 594 let jsont = 595 Jsont.Object.( ··· 606 (** {1 Call Member Content (m.call.member)} *) 607 608 module Call_member_content = struct 609 - (** Focus type for MatrixRTC *) 610 type focus = { 611 type_ : string; 612 livekit_service_url : string option; 613 livekit_alias : string option; 614 } 615 616 let focus_jsont = 617 Jsont.Object.( ··· 632 membership_id : string option; 633 } 634 635 let membership_jsont = 636 Jsont.Object.( 637 map (fun call_id scope application device_id expires foci_active membership_id -> ··· 645 |> opt_mem "membership_id" Jsont.string ~enc:(fun t -> t.membership_id) 646 |> finish) 647 648 - type t = { 649 - memberships : membership list; 650 - } 651 652 let jsont = 653 Jsont.Object.( ··· 1124 (** {1 Message Event Contents} *) 1125 1126 module Msgtype = struct 1127 type t = 1128 | Text 1129 | Emote ··· 1157 | "m.location" -> Location 1158 | s -> Custom s 1159 1160 let jsont = 1161 Jsont.of_of_string ~kind:"msgtype" 1162 ~enc:to_string ··· 1164 end 1165 1166 module Text_message_content = struct 1167 type t = { 1168 body : string; 1169 msgtype : Msgtype.t; ··· 1171 formatted_body : string option; 1172 } 1173 1174 let jsont = 1175 Jsont.Object.( 1176 map (fun body msgtype format formatted_body -> ··· 1180 |> opt_mem "format" Jsont.string ~enc:(fun t -> t.format) 1181 |> opt_mem "formatted_body" Jsont.string ~enc:(fun t -> t.formatted_body) 1182 |> finish) 1183 - 1184 - let make ?(format = "org.matrix.custom.html") ?formatted_body body = 1185 - let msgtype = Msgtype.Text in 1186 - match formatted_body with 1187 - | None -> { body; msgtype; format = None; formatted_body = None } 1188 - | Some fb -> { body; msgtype; format = Some format; formatted_body = Some fb } 1189 end 1190 1191 module Media_info = struct ··· 1325 |> finish) 1326 end 1327 1328 - (** {1 Event Types} *) 1329 1330 module Event_type = struct 1331 type t = 1332 (* Room state events *) 1333 | Room_create ··· 1528 | "m.poll.response" -> Poll_response 1529 | "m.poll.end" -> Poll_end 1530 | s -> Custom s 1531 1532 let jsont = 1533 Jsont.of_of_string ~kind:"event_type"
··· 34 timestamp when the event was received by the originating server. *) 35 type t = int64 36 37 + let of_int64 t = t 38 + let to_int64 t = t 39 + 40 let of_ptime pt = 41 let span = Ptime.to_span pt in 42 let d, ps = Ptime.Span.to_d_ps span in ··· 50 let ps = Int64.mul rem_ms 1_000_000_000L in 51 Ptime.Span.of_d_ps (days, ps) |> Option.map Ptime.of_span |> Option.join 52 53 + let pp ppf t = Format.fprintf ppf "%Ld" t 54 + 55 let jsont = Jsont.int64 56 end 57 58 (** {1 Unsigned Event Data} *) 59 60 module Unsigned = struct 61 + (** Unsigned data added by the homeserver. 62 + 63 + This data is added by the homeserver and not part of the signed 64 + event content. It includes metadata like event age and previous 65 + content for state events. *) 66 67 type t = { 68 age : int64 option; ··· 72 transaction_id : Transaction_id.t option; 73 } 74 75 + let make ?age ?prev_content ?prev_sender ?redacted_because ?transaction_id () = 76 + { age; prev_content; prev_sender; redacted_because; transaction_id } 77 + 78 + let empty = make () 79 + 80 + let age t = t.age 81 + let prev_content t = t.prev_content 82 + let prev_sender t = t.prev_sender 83 + let redacted_because t = t.redacted_because 84 + let transaction_id t = t.transaction_id 85 + 86 + let pp ppf t = 87 + Format.fprintf ppf "@[<v>"; 88 + (match t.age with 89 + | Some a -> Format.fprintf ppf "age: %Ld@," a 90 + | None -> ()); 91 + (match t.transaction_id with 92 + | Some tid -> Format.fprintf ppf "transaction_id: %s@," (Transaction_id.to_string tid) 93 + | None -> ()); 94 + Format.fprintf ppf "@]" 95 96 let jsont = 97 Jsont.Object.( ··· 108 (** {1 Room Membership} *) 109 110 module Membership = struct 111 + (** Room membership states. 112 + 113 + @see <https://spec.matrix.org/v1.11/client-server-api/#room-membership> Room Membership *) 114 + 115 type t = 116 | Join 117 | Invite ··· 134 | "knock" -> Ok Knock 135 | s -> Error (`Unknown_membership s) 136 137 + let pp ppf t = Format.pp_print_string ppf (to_string t) 138 + 139 let jsont = 140 Jsont.enum [ 141 ("join", Join); ··· 149 (** {1 Join Rules} *) 150 151 module Join_rule = struct 152 + (** Room join rules. 153 + 154 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomjoin_rules> m.room.join_rules *) 155 + 156 type t = 157 | Public 158 | Invite ··· 161 | Knock_restricted 162 | Private 163 164 + let to_string = function 165 + | Public -> "public" 166 + | Invite -> "invite" 167 + | Knock -> "knock" 168 + | Restricted -> "restricted" 169 + | Knock_restricted -> "knock_restricted" 170 + | Private -> "private" 171 + 172 + let pp ppf t = Format.pp_print_string ppf (to_string t) 173 + 174 let jsont = 175 Jsont.enum [ 176 ("public", Public); ··· 185 (** {1 History Visibility} *) 186 187 module History_visibility = struct 188 + (** Room history visibility settings. 189 + 190 + @see <https://spec.matrix.org/v1.11/client-server-api/#room-history-visibility> Room History Visibility *) 191 + 192 type t = 193 | Invited 194 | Joined 195 | Shared 196 | World_readable 197 198 + let to_string = function 199 + | Invited -> "invited" 200 + | Joined -> "joined" 201 + | Shared -> "shared" 202 + | World_readable -> "world_readable" 203 + 204 + let pp ppf t = Format.pp_print_string ppf (to_string t) 205 + 206 let jsont = 207 Jsont.enum [ 208 ("invited", Invited); ··· 215 (** {1 Room State Event Contents} *) 216 217 module Room_create_content = struct 218 + (** Room creation state event content. 219 + 220 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomcreate> m.room.create *) 221 + 222 + module Predecessor = struct 223 + (** Information about a room's predecessor. *) 224 + 225 + type t = { 226 + room_id : Room_id.t; 227 + event_id : Event_id.t; 228 + } 229 + 230 + let make ~room_id ~event_id = { room_id; event_id } 231 + let room_id t = t.room_id 232 + let event_id t = t.event_id 233 + 234 + let pp ppf t = 235 + Format.fprintf ppf "@[<hov 2>predecessor:@ room_id=%a@ event_id=%a@]" 236 + Room_id.pp t.room_id Event_id.pp t.event_id 237 + 238 + let jsont = 239 + Jsont.Object.( 240 + map (fun room_id event_id -> { room_id; event_id }) 241 + |> mem "room_id" Room_id.jsont ~enc:(fun p -> p.room_id) 242 + |> mem "event_id" Event_id.jsont ~enc:(fun p -> p.event_id) 243 + |> finish) 244 + end 245 + 246 + type predecessor = Predecessor.t 247 + 248 type t = { 249 + creator : User_id.t option; 250 room_version : string option; 251 + predecessor : Predecessor.t option; 252 + type_ : string option; 253 } 254 255 + let make ?creator ?room_version ?predecessor ?type_ () = 256 + { creator; room_version; predecessor; type_ } 257 + 258 + let creator t = t.creator 259 + let room_version t = t.room_version 260 + let predecessor t = t.predecessor 261 + let room_type t = t.type_ 262 + 263 + let pp ppf t = 264 + Format.fprintf ppf "@[<v>"; 265 + (match t.creator with 266 + | Some u -> Format.fprintf ppf "creator: %a@," User_id.pp u 267 + | None -> ()); 268 + (match t.room_version with 269 + | Some v -> Format.fprintf ppf "room_version: %s@," v 270 + | None -> ()); 271 + (match t.predecessor with 272 + | Some p -> Format.fprintf ppf "%a@," Predecessor.pp p 273 + | None -> ()); 274 + (match t.type_ with 275 + | Some ty -> Format.fprintf ppf "type: %s@," ty 276 + | None -> ()); 277 + Format.fprintf ppf "@]" 278 279 let jsont = 280 Jsont.Object.( ··· 282 { creator; room_version; predecessor; type_ }) 283 |> opt_mem "creator" User_id.jsont ~enc:(fun t -> t.creator) 284 |> opt_mem "room_version" Jsont.string ~enc:(fun t -> t.room_version) 285 + |> opt_mem "predecessor" Predecessor.jsont ~enc:(fun t -> t.predecessor) 286 |> opt_mem "type" Jsont.string ~enc:(fun t -> t.type_) 287 |> finish) 288 end 289 290 module Room_name_content = struct 291 + (** Room name state event content. 292 + 293 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomname> m.room.name *) 294 + 295 type t = { name : string } 296 297 + let make ~name = { name } 298 + let name t = t.name 299 + 300 + let pp ppf t = Format.fprintf ppf "name: %s" t.name 301 + 302 let jsont = 303 Jsont.Object.( 304 map (fun name -> { name }) ··· 307 end 308 309 module Room_topic_content = struct 310 + (** Room topic state event content. 311 + 312 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomtopic> m.room.topic *) 313 + 314 type t = { topic : string } 315 316 + let make ~topic = { topic } 317 + let topic t = t.topic 318 + 319 + let pp ppf t = Format.fprintf ppf "topic: %s" t.topic 320 + 321 let jsont = 322 Jsont.Object.( 323 map (fun topic -> { topic }) ··· 326 end 327 328 module Room_avatar_content = struct 329 + (** Room avatar state event content. 330 + 331 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomavatar> m.room.avatar *) 332 + 333 + module Image_info = struct 334 + (** Image metadata. *) 335 + 336 + type t = { 337 + h : int option; 338 + w : int option; 339 + mimetype : string option; 340 + size : int option; 341 + } 342 + 343 + let make ?h ?w ?mimetype ?size () = { h; w; mimetype; size } 344 + let height t = t.h 345 + let width t = t.w 346 + let mimetype t = t.mimetype 347 + let size t = t.size 348 + 349 + let pp ppf t = 350 + Format.fprintf ppf "@[<hov 2>image_info:"; 351 + (match t.w, t.h with 352 + | Some w, Some h -> Format.fprintf ppf "@ %dx%d" w h 353 + | _ -> ()); 354 + (match t.mimetype with 355 + | Some m -> Format.fprintf ppf "@ %s" m 356 + | None -> ()); 357 + (match t.size with 358 + | Some s -> Format.fprintf ppf "@ %d bytes" s 359 + | None -> ()); 360 + Format.fprintf ppf "@]" 361 + 362 + let jsont = 363 + Jsont.Object.( 364 + map (fun h w mimetype size -> { h; w; mimetype; size }) 365 + |> opt_mem "h" Jsont.int ~enc:(fun t -> t.h) 366 + |> opt_mem "w" Jsont.int ~enc:(fun t -> t.w) 367 + |> opt_mem "mimetype" Jsont.string ~enc:(fun t -> t.mimetype) 368 + |> opt_mem "size" Jsont.int ~enc:(fun t -> t.size) 369 + |> finish) 370 + end 371 + 372 + type image_info = Image_info.t 373 + 374 type t = { 375 url : string option; 376 + info : Image_info.t option; 377 } 378 + 379 + let make ?url ?info () = { url; info } 380 + let url t = t.url 381 + let info t = t.info 382 383 + let pp ppf t = 384 + Format.fprintf ppf "@[<v>"; 385 + (match t.url with 386 + | Some u -> Format.fprintf ppf "url: %s@," u 387 + | None -> ()); 388 + (match t.info with 389 + | Some i -> Format.fprintf ppf "%a@," Image_info.pp i 390 + | None -> ()); 391 + Format.fprintf ppf "@]" 392 393 let jsont = 394 Jsont.Object.( 395 map (fun url info -> { url; info }) 396 |> opt_mem "url" Jsont.string ~enc:(fun t -> t.url) 397 + |> opt_mem "info" Image_info.jsont ~enc:(fun t -> t.info) 398 |> finish) 399 end 400 401 module Room_member_content = struct 402 + (** Room member state event content. 403 + 404 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroommember> m.room.member *) 405 + 406 type t = { 407 membership : Membership.t; 408 displayname : string option; ··· 411 reason : string option; 412 } 413 414 + let make ~membership ?displayname ?avatar_url ?is_direct ?reason () = 415 + { membership; displayname; avatar_url; is_direct; reason } 416 + 417 + let membership t = t.membership 418 + let displayname t = t.displayname 419 + let avatar_url t = t.avatar_url 420 + let is_direct t = t.is_direct 421 + let reason t = t.reason 422 + 423 + let pp ppf t = 424 + Format.fprintf ppf "@[<v>membership: %a" Membership.pp t.membership; 425 + (match t.displayname with 426 + | Some n -> Format.fprintf ppf "@,displayname: %s" n 427 + | None -> ()); 428 + (match t.avatar_url with 429 + | Some u -> Format.fprintf ppf "@,avatar_url: %s" u 430 + | None -> ()); 431 + (match t.is_direct with 432 + | Some d -> Format.fprintf ppf "@,is_direct: %b" d 433 + | None -> ()); 434 + (match t.reason with 435 + | Some r -> Format.fprintf ppf "@,reason: %s" r 436 + | None -> ()); 437 + Format.fprintf ppf "@]" 438 + 439 let jsont = 440 Jsont.Object.( 441 map (fun membership displayname avatar_url is_direct reason -> ··· 449 end 450 451 module Room_join_rules_content = struct 452 + (** Room join rules state event content. 453 + 454 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomjoin_rules> m.room.join_rules *) 455 + 456 + module Allow_condition = struct 457 + (** A condition for restricted room joins. *) 458 + 459 + type t = { 460 + type_ : string; 461 + room_id : Room_id.t option; 462 + } 463 + 464 + let make ~type_ ?room_id () = { type_; room_id } 465 + let condition_type t = t.type_ 466 + let room_id t = t.room_id 467 + 468 + let pp ppf t = 469 + Format.fprintf ppf "@[<hov 2>allow:@ type=%s" t.type_; 470 + (match t.room_id with 471 + | Some r -> Format.fprintf ppf "@ room_id=%a" Room_id.pp r 472 + | None -> ()); 473 + Format.fprintf ppf "@]" 474 + 475 + let jsont = 476 + Jsont.Object.( 477 + map (fun type_ room_id -> { type_; room_id }) 478 + |> mem "type" Jsont.string ~enc:(fun c -> c.type_) 479 + |> opt_mem "room_id" Room_id.jsont ~enc:(fun c -> c.room_id) 480 + |> finish) 481 + end 482 + 483 + type allow_condition = Allow_condition.t 484 + 485 type t = { 486 join_rule : Join_rule.t; 487 + allow : Allow_condition.t list option; 488 } 489 + 490 + let make ~join_rule ?allow () = { join_rule; allow } 491 + let join_rule t = t.join_rule 492 + let allow t = t.allow 493 494 + let pp ppf t = 495 + Format.fprintf ppf "@[<v>join_rule: %a" Join_rule.pp t.join_rule; 496 + (match t.allow with 497 + | Some conditions -> 498 + Format.fprintf ppf "@,allow: ["; 499 + List.iter (fun c -> Format.fprintf ppf "@,%a" Allow_condition.pp c) conditions; 500 + Format.fprintf ppf "]" 501 + | None -> ()); 502 + Format.fprintf ppf "@]" 503 504 let jsont = 505 Jsont.Object.( 506 map (fun join_rule allow -> { join_rule; allow }) 507 |> mem "join_rule" Join_rule.jsont ~enc:(fun t -> t.join_rule) 508 + |> opt_mem "allow" (Jsont.list Allow_condition.jsont) ~enc:(fun t -> t.allow) 509 |> finish) 510 end 511 512 module Room_history_visibility_content = struct 513 + (** Room history visibility state event content. 514 + 515 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomhistory_visibility> m.room.history_visibility *) 516 + 517 type t = { history_visibility : History_visibility.t } 518 519 + let make ~history_visibility = { history_visibility } 520 + let history_visibility t = t.history_visibility 521 + 522 + let pp ppf t = 523 + Format.fprintf ppf "history_visibility: %a" History_visibility.pp t.history_visibility 524 + 525 let jsont = 526 Jsont.Object.( 527 map (fun history_visibility -> { history_visibility }) ··· 531 end 532 533 module Room_canonical_alias_content = struct 534 + (** Room canonical alias state event content. 535 + 536 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomcanonical_alias> m.room.canonical_alias *) 537 + 538 type t = { 539 alias : Room_alias.t option; 540 alt_aliases : Room_alias.t list option; 541 } 542 543 + let make ?alias ?alt_aliases () = { alias; alt_aliases } 544 + let alias t = t.alias 545 + let alt_aliases t = t.alt_aliases 546 + 547 + let pp ppf t = 548 + Format.fprintf ppf "@[<v>"; 549 + (match t.alias with 550 + | Some a -> Format.fprintf ppf "alias: %a@," Room_alias.pp a 551 + | None -> ()); 552 + (match t.alt_aliases with 553 + | Some alts when alts <> [] -> 554 + Format.fprintf ppf "alt_aliases: [%a]" 555 + (Format.pp_print_list ~pp_sep:(fun ppf () -> Format.fprintf ppf ", ") 556 + Room_alias.pp) alts 557 + | _ -> ()); 558 + Format.fprintf ppf "@]" 559 + 560 let jsont = 561 Jsont.Object.( 562 map (fun alias alt_aliases -> { alias; alt_aliases }) ··· 566 end 567 568 module Room_power_levels_content = struct 569 + (** Room power levels state event content. 570 + 571 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroompower_levels> m.room.power_levels *) 572 + 573 type t = { 574 ban : int option; 575 events : (string * int) list option; ··· 582 users_default : int option; 583 } 584 585 + let make ?ban ?events ?events_default ?invite ?kick ?redact 586 + ?state_default ?users ?users_default () = 587 + { ban; events; events_default; invite; kick; redact; 588 + state_default; users; users_default } 589 + 590 + let ban t = t.ban 591 + let events t = t.events 592 + let events_default t = t.events_default 593 + let invite t = t.invite 594 + let kick t = t.kick 595 + let redact t = t.redact 596 + let state_default t = t.state_default 597 + let users t = t.users 598 + let users_default t = t.users_default 599 + 600 + let pp ppf t = 601 + Format.fprintf ppf "@[<v>"; 602 + (match t.ban with Some v -> Format.fprintf ppf "ban: %d@," v | None -> ()); 603 + (match t.kick with Some v -> Format.fprintf ppf "kick: %d@," v | None -> ()); 604 + (match t.invite with Some v -> Format.fprintf ppf "invite: %d@," v | None -> ()); 605 + (match t.redact with Some v -> Format.fprintf ppf "redact: %d@," v | None -> ()); 606 + (match t.events_default with Some v -> Format.fprintf ppf "events_default: %d@," v | None -> ()); 607 + (match t.state_default with Some v -> Format.fprintf ppf "state_default: %d@," v | None -> ()); 608 + (match t.users_default with Some v -> Format.fprintf ppf "users_default: %d@," v | None -> ()); 609 + Format.fprintf ppf "@]" 610 + 611 module StringMap = Map.Make(String) 612 613 let int_map_jsont = ··· 635 end 636 637 module Room_encryption_content = struct 638 + (** Room encryption state event content. 639 + 640 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomencryption> m.room.encryption *) 641 + 642 type t = { 643 algorithm : string; 644 rotation_period_ms : int64 option; 645 rotation_period_msgs : int option; 646 } 647 648 + let make ~algorithm ?rotation_period_ms ?rotation_period_msgs () = 649 + { algorithm; rotation_period_ms; rotation_period_msgs } 650 + 651 + let algorithm t = t.algorithm 652 + let rotation_period_ms t = t.rotation_period_ms 653 + let rotation_period_msgs t = t.rotation_period_msgs 654 + 655 + let pp ppf t = 656 + Format.fprintf ppf "@[<v>algorithm: %s" t.algorithm; 657 + (match t.rotation_period_ms with 658 + | Some ms -> Format.fprintf ppf "@,rotation_period_ms: %Ld" ms 659 + | None -> ()); 660 + (match t.rotation_period_msgs with 661 + | Some n -> Format.fprintf ppf "@,rotation_period_msgs: %d" n 662 + | None -> ()); 663 + Format.fprintf ppf "@]" 664 + 665 let jsont = 666 Jsont.Object.( 667 map (fun algorithm rotation_period_ms rotation_period_msgs -> ··· 673 end 674 675 module Room_pinned_events_content = struct 676 + (** Room pinned events state event content. 677 + 678 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroompinned_events> m.room.pinned_events *) 679 + 680 + type t = { pinned : string list } 681 + 682 + let make ?(pinned = []) () = { pinned } 683 + let pinned t = t.pinned 684 + 685 + let pp ppf t = 686 + Format.fprintf ppf "pinned: [%s]" (String.concat ", " t.pinned) 687 688 let jsont = 689 Jsont.Object.( ··· 693 end 694 695 module Room_server_acl_content = struct 696 + (** Room server ACL state event content. 697 + 698 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomserver_acl> m.room.server_acl *) 699 + 700 type t = { 701 allow : string list; 702 allow_ip_literals : bool; 703 deny : string list; 704 } 705 706 + let make ?(allow = []) ?(allow_ip_literals = true) ?(deny = []) () = 707 + { allow; allow_ip_literals; deny } 708 + 709 + let allow t = t.allow 710 + let allow_ip_literals t = t.allow_ip_literals 711 + let deny t = t.deny 712 + 713 + let pp ppf t = 714 + Format.fprintf ppf "@[<v>allow: [%s]@,allow_ip_literals: %b@,deny: [%s]@]" 715 + (String.concat ", " t.allow) t.allow_ip_literals (String.concat ", " t.deny) 716 + 717 let jsont = 718 Jsont.Object.( 719 map (fun allow allow_ip_literals deny -> ··· 725 end 726 727 module Room_tombstone_content = struct 728 + (** Room tombstone state event content. 729 + 730 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomtombstone> m.room.tombstone *) 731 + 732 type t = { 733 body : string; 734 replacement_room : Room_id.t; 735 } 736 737 + let make ~body ~replacement_room = { body; replacement_room } 738 + let body t = t.body 739 + let replacement_room t = t.replacement_room 740 + 741 + let pp ppf t = 742 + Format.fprintf ppf "@[<v>body: %s@,replacement_room: %a@]" 743 + t.body Room_id.pp t.replacement_room 744 + 745 let jsont = 746 Jsont.Object.( 747 map (fun body replacement_room -> { body; replacement_room }) ··· 751 end 752 753 module Room_guest_access_content = struct 754 + (** Room guest access state event content. 755 + 756 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomguest_access> m.room.guest_access *) 757 + 758 type access = 759 | Can_join 760 | Forbidden 761 762 + let access_to_string = function 763 + | Can_join -> "can_join" 764 + | Forbidden -> "forbidden" 765 + 766 + let pp_access ppf a = Format.pp_print_string ppf (access_to_string a) 767 + 768 let access_jsont = 769 Jsont.enum [ 770 ("can_join", Can_join); 771 ("forbidden", Forbidden); 772 ] 773 774 + type t = { guest_access : access } 775 + 776 + let make ~guest_access = { guest_access } 777 + let guest_access t = t.guest_access 778 + 779 + let pp ppf t = Format.fprintf ppf "guest_access: %a" pp_access t.guest_access 780 781 let jsont = 782 Jsont.Object.( ··· 788 (** {1 Space Event Contents} *) 789 790 module Space_child_content = struct 791 + (** Space child state event content. 792 + 793 + @see <https://spec.matrix.org/v1.11/client-server-api/#mspacechild> m.space.child *) 794 + 795 type t = { 796 via : string list option; 797 order : string option; 798 suggested : bool option; 799 } 800 801 + let make ?via ?order ?suggested () = { via; order; suggested } 802 + let via t = t.via 803 + let order t = t.order 804 + let suggested t = t.suggested 805 + 806 + let pp ppf t = 807 + Format.fprintf ppf "@[<v>"; 808 + (match t.via with 809 + | Some v -> Format.fprintf ppf "via: [%s]@," (String.concat ", " v) 810 + | None -> ()); 811 + (match t.order with Some o -> Format.fprintf ppf "order: %s@," o | None -> ()); 812 + (match t.suggested with Some s -> Format.fprintf ppf "suggested: %b@," s | None -> ()); 813 + Format.fprintf ppf "@]" 814 + 815 let jsont = 816 Jsont.Object.( 817 map (fun via order suggested -> { via; order; suggested }) ··· 822 end 823 824 module Space_parent_content = struct 825 + (** Space parent state event content. 826 + 827 + @see <https://spec.matrix.org/v1.11/client-server-api/#mspaceparent> m.space.parent *) 828 + 829 type t = { 830 via : string list option; 831 canonical : bool option; 832 } 833 834 + let make ?via ?canonical () = { via; canonical } 835 + let via t = t.via 836 + let canonical t = t.canonical 837 + 838 + let pp ppf t = 839 + Format.fprintf ppf "@[<v>"; 840 + (match t.via with 841 + | Some v -> Format.fprintf ppf "via: [%s]@," (String.concat ", " v) 842 + | None -> ()); 843 + (match t.canonical with Some c -> Format.fprintf ppf "canonical: %b@," c | None -> ()); 844 + Format.fprintf ppf "@]" 845 + 846 let jsont = 847 Jsont.Object.( 848 map (fun via canonical -> { via; canonical }) ··· 851 |> finish) 852 end 853 854 + (** {1 Call Event Contents} 855 + 856 + Call events are used for VoIP calling in Matrix. 857 + 858 + @see <https://spec.matrix.org/v1.11/client-server-api/#voice-over-ip> Voice over IP *) 859 860 module Call_invite_content = struct 861 + (** Call invite event content. 862 + 863 + @see <https://spec.matrix.org/v1.11/client-server-api/#mcallinvite> m.call.invite *) 864 + 865 + type sdp_content = { 866 + type_ : string; 867 + sdp : string; 868 + } 869 + 870 type t = { 871 call_id : string; 872 party_id : string option; ··· 875 offer : sdp_content; 876 invitee : string option; 877 } 878 + 879 + let make_sdp ~type_ ~sdp = { type_; sdp } 880 + 881 + let make ~call_id ?party_id ?(version = 0) ~lifetime ~offer ?invitee () = 882 + { call_id; party_id; version; lifetime; offer; invitee } 883 + 884 + let call_id t = t.call_id 885 + let party_id t = t.party_id 886 + let version t = t.version 887 + let lifetime t = t.lifetime 888 + let offer t = t.offer 889 + let invitee t = t.invitee 890 + 891 + let pp ppf t = 892 + Format.fprintf ppf "@[<v>call_id: %s@,version: %d@,lifetime: %d@]" 893 + t.call_id t.version t.lifetime 894 895 let sdp_content_jsont = 896 Jsont.Object.( ··· 913 end 914 915 module Call_answer_content = struct 916 + (** Call answer event content. 917 + 918 + @see <https://spec.matrix.org/v1.11/client-server-api/#mcallanswer> m.call.answer *) 919 + 920 type sdp_content = { 921 type_ : string; 922 sdp : string; ··· 929 answer : sdp_content; 930 } 931 932 + let make_sdp ~type_ ~sdp = { type_; sdp } 933 + 934 + let make ~call_id ?party_id ?(version = 0) ~answer () = 935 + { call_id; party_id; version; answer } 936 + 937 + let call_id t = t.call_id 938 + let party_id t = t.party_id 939 + let version t = t.version 940 + let answer t = t.answer 941 + 942 + let pp ppf t = 943 + Format.fprintf ppf "@[<v>call_id: %s@,version: %d@]" t.call_id t.version 944 + 945 let sdp_content_jsont = 946 Jsont.Object.( 947 map (fun type_ sdp -> { type_; sdp }) ··· 961 end 962 963 module Call_hangup_content = struct 964 + (** Call hangup event content. 965 + 966 + @see <https://spec.matrix.org/v1.11/client-server-api/#mcallhangup> m.call.hangup *) 967 + 968 type reason = 969 | Ice_failed 970 | Invite_timeout ··· 973 | User_busy 974 | Unknown_error 975 976 + let reason_to_string = function 977 + | Ice_failed -> "ice_failed" 978 + | Invite_timeout -> "invite_timeout" 979 + | User_hangup -> "user_hangup" 980 + | User_media_failed -> "user_media_failed" 981 + | User_busy -> "user_busy" 982 + | Unknown_error -> "unknown_error" 983 + 984 + let pp_reason ppf r = Format.pp_print_string ppf (reason_to_string r) 985 + 986 let reason_jsont = 987 Jsont.enum [ 988 ("ice_failed", Ice_failed); ··· 1000 reason : reason option; 1001 } 1002 1003 + let make ~call_id ?party_id ?(version = 0) ?reason () = 1004 + { call_id; party_id; version; reason } 1005 + 1006 + let call_id t = t.call_id 1007 + let party_id t = t.party_id 1008 + let version t = t.version 1009 + let reason t = t.reason 1010 + 1011 + let pp ppf t = 1012 + Format.fprintf ppf "@[<v>call_id: %s@,version: %d" t.call_id t.version; 1013 + (match t.reason with Some r -> Format.fprintf ppf "@,reason: %a" pp_reason r | None -> ()); 1014 + Format.fprintf ppf "@]" 1015 + 1016 let jsont = 1017 Jsont.Object.( 1018 map (fun call_id party_id version reason -> ··· 1025 end 1026 1027 module Call_candidates_content = struct 1028 + (** Call candidates event content. 1029 + 1030 + @see <https://spec.matrix.org/v1.11/client-server-api/#mcallcandidates> m.call.candidates *) 1031 + 1032 type candidate = { 1033 candidate : string; 1034 sdp_mid : string; 1035 sdp_m_line_index : int; 1036 } 1037 1038 + let make_candidate ~candidate ~sdp_mid ~sdp_m_line_index = 1039 + { candidate; sdp_mid; sdp_m_line_index } 1040 + 1041 let candidate_jsont = 1042 Jsont.Object.( 1043 map (fun candidate sdp_mid sdp_m_line_index -> ··· 1053 version : int; 1054 candidates : candidate list; 1055 } 1056 + 1057 + let make ~call_id ?party_id ?(version = 0) ?(candidates = []) () = 1058 + { call_id; party_id; version; candidates } 1059 + 1060 + let call_id t = t.call_id 1061 + let party_id t = t.party_id 1062 + let version t = t.version 1063 + let candidates t = t.candidates 1064 + 1065 + let pp ppf t = 1066 + Format.fprintf ppf "@[<v>call_id: %s@,version: %d@,candidates: %d@]" 1067 + t.call_id t.version (List.length t.candidates) 1068 1069 let jsont = 1070 Jsont.Object.( ··· 1081 (** {1 Call Member Content (m.call.member)} *) 1082 1083 module Call_member_content = struct 1084 + (** Call member state event content for MatrixRTC. 1085 + 1086 + @see <https://spec.matrix.org/v1.11/client-server-api/#mcallmember> m.call.member *) 1087 + 1088 type focus = { 1089 type_ : string; 1090 livekit_service_url : string option; 1091 livekit_alias : string option; 1092 } 1093 + 1094 + let make_focus ~type_ ?livekit_service_url ?livekit_alias () = 1095 + { type_; livekit_service_url; livekit_alias } 1096 1097 let focus_jsont = 1098 Jsont.Object.( ··· 1113 membership_id : string option; 1114 } 1115 1116 + let make_membership ~call_id ?(scope = "m.room") ~application ~device_id 1117 + ~expires ?foci_active ?membership_id () = 1118 + { call_id; scope; application; device_id; expires; foci_active; membership_id } 1119 + 1120 let membership_jsont = 1121 Jsont.Object.( 1122 map (fun call_id scope application device_id expires foci_active membership_id -> ··· 1130 |> opt_mem "membership_id" Jsont.string ~enc:(fun t -> t.membership_id) 1131 |> finish) 1132 1133 + type t = { memberships : membership list } 1134 + 1135 + let make ?(memberships = []) () = { memberships } 1136 + let memberships t = t.memberships 1137 + 1138 + let pp ppf t = 1139 + Format.fprintf ppf "@[<v>memberships: %d entries@]" (List.length t.memberships) 1140 1141 let jsont = 1142 Jsont.Object.( ··· 1613 (** {1 Message Event Contents} *) 1614 1615 module Msgtype = struct 1616 + (** Message types for room messages. 1617 + 1618 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroommessage-msgtypes> Message Types *) 1619 + 1620 type t = 1621 | Text 1622 | Emote ··· 1650 | "m.location" -> Location 1651 | s -> Custom s 1652 1653 + let pp ppf t = Format.pp_print_string ppf (to_string t) 1654 + 1655 let jsont = 1656 Jsont.of_of_string ~kind:"msgtype" 1657 ~enc:to_string ··· 1659 end 1660 1661 module Text_message_content = struct 1662 + (** Text message content. 1663 + 1664 + @see <https://spec.matrix.org/v1.11/client-server-api/#mtext> m.text *) 1665 + 1666 type t = { 1667 body : string; 1668 msgtype : Msgtype.t; ··· 1670 formatted_body : string option; 1671 } 1672 1673 + let make ?(msgtype = Msgtype.Text) ?(format = "org.matrix.custom.html") ?formatted_body body = 1674 + match formatted_body with 1675 + | None -> { body; msgtype; format = None; formatted_body = None } 1676 + | Some fb -> { body; msgtype; format = Some format; formatted_body = Some fb } 1677 + 1678 + let body t = t.body 1679 + let msgtype t = t.msgtype 1680 + let format t = t.format 1681 + let formatted_body t = t.formatted_body 1682 + 1683 + let pp ppf t = 1684 + Format.fprintf ppf "@[<v>msgtype: %a@,body: %s@]" Msgtype.pp t.msgtype t.body 1685 + 1686 let jsont = 1687 Jsont.Object.( 1688 map (fun body msgtype format formatted_body -> ··· 1692 |> opt_mem "format" Jsont.string ~enc:(fun t -> t.format) 1693 |> opt_mem "formatted_body" Jsont.string ~enc:(fun t -> t.formatted_body) 1694 |> finish) 1695 end 1696 1697 module Media_info = struct ··· 1831 |> finish) 1832 end 1833 1834 + (** {1 Event Types} 1835 + 1836 + Event types identify the kind of Matrix event. 1837 + 1838 + @see <https://spec.matrix.org/v1.11/client-server-api/#events> Events *) 1839 1840 module Event_type = struct 1841 + (** Matrix event types. *) 1842 + 1843 type t = 1844 (* Room state events *) 1845 | Room_create ··· 2040 | "m.poll.response" -> Poll_response 2041 | "m.poll.end" -> Poll_end 2042 | s -> Custom s 2043 + 2044 + let pp ppf t = Format.pp_print_string ppf (to_string t) 2045 2046 let jsont = 2047 Jsont.of_of_string ~kind:"event_type"
+425 -79
lib/matrix_proto/matrix_event.mli
··· 1 - (** Matrix event types with JSON codecs. *) 2 3 (** {1 Timestamps} *) 4 5 module Timestamp : sig 6 type t = int64 7 val of_ptime : Ptime.t -> t 8 val to_ptime_opt : t -> Ptime.t option 9 val jsont : t Jsont.t 10 end 11 12 (** {1 Unsigned Event Data} *) 13 14 module Unsigned : sig 15 - type t = { 16 - age : int64 option; 17 - prev_content : Jsont.json option; 18 - prev_sender : Matrix_id.User_id.t option; 19 - redacted_because : Jsont.json option; 20 - transaction_id : Matrix_id.Transaction_id.t option; 21 - } 22 val empty : t 23 val jsont : t Jsont.t 24 end 25 26 (** {1 Room Membership} *) 27 28 module Membership : sig 29 type t = Join | Invite | Leave | Ban | Knock 30 val to_string : t -> string 31 val of_string : string -> (t, [> `Unknown_membership of string ]) result 32 val jsont : t Jsont.t 33 end 34 35 (** {1 Join Rules} *) 36 37 module Join_rule : sig 38 type t = Public | Invite | Knock | Restricted | Knock_restricted | Private 39 val jsont : t Jsont.t 40 end 41 42 (** {1 History Visibility} *) 43 44 module History_visibility : sig 45 type t = Invited | Joined | Shared | World_readable 46 val jsont : t Jsont.t 47 end 48 49 (** {1 Room State Event Contents} *) 50 51 module Room_create_content : sig 52 - type t = { 53 - creator : Matrix_id.User_id.t option; 54 - room_version : string option; 55 - predecessor : predecessor option; 56 - type_ : string option; 57 - } 58 - and predecessor = { 59 - room_id : Matrix_id.Room_id.t; 60 - event_id : Matrix_id.Event_id.t; 61 - } 62 val jsont : t Jsont.t 63 end 64 65 module Room_name_content : sig 66 - type t = { name : string } 67 val jsont : t Jsont.t 68 end 69 70 module Room_topic_content : sig 71 - type t = { topic : string } 72 val jsont : t Jsont.t 73 end 74 75 module Room_avatar_content : sig 76 - type t = { 77 - url : string option; 78 - info : image_info option; 79 - } 80 - and image_info = { 81 - h : int option; 82 - w : int option; 83 - mimetype : string option; 84 - size : int option; 85 - } 86 val jsont : t Jsont.t 87 end 88 89 module Room_member_content : sig 90 - type t = { 91 - membership : Membership.t; 92 - displayname : string option; 93 - avatar_url : string option; 94 - is_direct : bool option; 95 - reason : string option; 96 - } 97 val jsont : t Jsont.t 98 end 99 100 module Room_join_rules_content : sig 101 - type t = { 102 - join_rule : Join_rule.t; 103 - allow : allow_condition list option; 104 - } 105 - and allow_condition = { 106 - type_ : string; 107 - room_id : Matrix_id.Room_id.t option; 108 - } 109 val jsont : t Jsont.t 110 end 111 112 module Room_history_visibility_content : sig 113 - type t = { history_visibility : History_visibility.t } 114 val jsont : t Jsont.t 115 end 116 117 module Room_canonical_alias_content : sig 118 - type t = { 119 - alias : Matrix_id.Room_alias.t option; 120 - alt_aliases : Matrix_id.Room_alias.t list option; 121 - } 122 val jsont : t Jsont.t 123 end 124 125 module Room_power_levels_content : sig 126 - type t = { 127 - ban : int option; 128 - events : (string * int) list option; 129 - events_default : int option; 130 - invite : int option; 131 - kick : int option; 132 - redact : int option; 133 - state_default : int option; 134 - users : (string * int) list option; 135 - users_default : int option; 136 - } 137 val jsont : t Jsont.t 138 end 139 140 module Room_encryption_content : sig 141 - type t = { 142 - algorithm : string; 143 - rotation_period_ms : int64 option; 144 - rotation_period_msgs : int option; 145 - } 146 val jsont : t Jsont.t 147 end 148 149 module Room_pinned_events_content : sig 150 - type t = { pinned : string list } 151 val jsont : t Jsont.t 152 end 153 154 module Room_server_acl_content : sig 155 - type t = { 156 - allow : string list; 157 - allow_ip_literals : bool; 158 - deny : string list; 159 - } 160 val jsont : t Jsont.t 161 end 162 163 module Room_tombstone_content : sig 164 - type t = { 165 - body : string; 166 - replacement_room : Matrix_id.Room_id.t; 167 - } 168 val jsont : t Jsont.t 169 end 170 171 module Room_guest_access_content : sig 172 type access = Can_join | Forbidden 173 val access_jsont : access Jsont.t 174 - type t = { guest_access : access } 175 val jsont : t Jsont.t 176 end 177 178 (** {1 Space Event Contents} *) 179 180 module Space_child_content : sig 181 type t = { 182 via : string list option; 183 order : string option; 184 suggested : bool option; 185 } 186 val jsont : t Jsont.t 187 end 188 189 module Space_parent_content : sig 190 type t = { 191 via : string list option; 192 canonical : bool option; 193 } 194 val jsont : t Jsont.t 195 end 196 197 - (** {1 Call Event Contents} *) 198 199 module Call_invite_content : sig 200 type sdp_content = { type_ : string; sdp : string } 201 type t = { 202 call_id : string; ··· 206 offer : sdp_content; 207 invitee : string option; 208 } 209 val jsont : t Jsont.t 210 end 211 212 module Call_answer_content : sig 213 type sdp_content = { type_ : string; sdp : string } 214 type t = { 215 call_id : string; ··· 217 version : int; 218 answer : sdp_content; 219 } 220 val jsont : t Jsont.t 221 end 222 223 module Call_hangup_content : sig 224 type reason = 225 | Ice_failed | Invite_timeout | User_hangup 226 | User_media_failed | User_busy | Unknown_error 227 type t = { 228 call_id : string; 229 party_id : string option; 230 version : int; 231 reason : reason option; 232 } 233 val jsont : t Jsont.t 234 end 235 236 module Call_candidates_content : sig 237 type candidate = { 238 candidate : string; 239 sdp_mid : string; 240 sdp_m_line_index : int; 241 } 242 type t = { 243 call_id : string; 244 party_id : string option; 245 version : int; 246 candidates : candidate list; 247 } 248 val jsont : t Jsont.t 249 end 250 251 (** {1 Call Member Content (m.call.member)} *) 252 253 module Call_member_content : sig 254 type focus = { 255 type_ : string; 256 livekit_service_url : string option; 257 livekit_alias : string option; 258 } 259 type membership = { 260 call_id : string; 261 scope : string; ··· 265 foci_active : focus list option; 266 membership_id : string option; 267 } 268 type t = { memberships : membership list } 269 val jsont : t Jsont.t 270 end 271 ··· 442 (** {1 Message Event Contents} *) 443 444 module Msgtype : sig 445 type t = 446 | Text | Emote | Notice | Image | File | Audio | Video | Location 447 | Custom of string 448 val to_string : t -> string 449 val of_string : string -> t 450 val jsont : t Jsont.t 451 end 452 453 module Text_message_content : sig 454 type t = { 455 body : string; 456 msgtype : Msgtype.t; 457 format : string option; 458 formatted_body : string option; 459 } 460 val jsont : t Jsont.t 461 - val make : ?format:string -> ?formatted_body:string -> string -> t 462 end 463 464 module Media_info : sig ··· 525 (** {1 Event Types} *) 526 527 module Event_type : sig 528 type t = 529 (* Room state events *) 530 | Room_create | Room_name | Room_topic | Room_avatar | Room_member ··· 558 | Poll_start | Poll_response | Poll_end 559 (* Custom *) 560 | Custom of string 561 val to_string : t -> string 562 val of_string : string -> t 563 val jsont : t Jsont.t 564 end 565
··· 1 + (** Matrix event types with JSON codecs. 2 + 3 + Events are the fundamental unit of data in Matrix. All communication 4 + in Matrix happens through events, which are JSON objects with a 5 + standardized structure. 6 + 7 + @see <https://spec.matrix.org/v1.11/client-server-api/#events> Events *) 8 9 (** {1 Timestamps} *) 10 11 module Timestamp : sig 12 + (** Server timestamps in milliseconds since Unix epoch. 13 + 14 + @see <https://spec.matrix.org/v1.11/client-server-api/#events> Event timestamps *) 15 + 16 type t = int64 17 + (** Milliseconds since Unix epoch. *) 18 + 19 + val of_int64 : int64 -> t 20 + val to_int64 : t -> int64 21 val of_ptime : Ptime.t -> t 22 val to_ptime_opt : t -> Ptime.t option 23 + val pp : Format.formatter -> t -> unit 24 val jsont : t Jsont.t 25 end 26 27 (** {1 Unsigned Event Data} *) 28 29 module Unsigned : sig 30 + (** Unsigned data added by the homeserver. 31 + 32 + This data is added by the homeserver and not part of the signed 33 + event content. *) 34 + 35 + type t 36 + 37 + val make : 38 + ?age:int64 -> 39 + ?prev_content:Jsont.json -> 40 + ?prev_sender:Matrix_id.User_id.t -> 41 + ?redacted_because:Jsont.json -> 42 + ?transaction_id:Matrix_id.Transaction_id.t -> 43 + unit -> t 44 + 45 val empty : t 46 + 47 + val age : t -> int64 option 48 + val prev_content : t -> Jsont.json option 49 + val prev_sender : t -> Matrix_id.User_id.t option 50 + val redacted_because : t -> Jsont.json option 51 + val transaction_id : t -> Matrix_id.Transaction_id.t option 52 + 53 + val pp : Format.formatter -> t -> unit 54 val jsont : t Jsont.t 55 end 56 57 (** {1 Room Membership} *) 58 59 module Membership : sig 60 + (** Room membership states. 61 + 62 + @see <https://spec.matrix.org/v1.11/client-server-api/#room-membership> Room Membership *) 63 + 64 type t = Join | Invite | Leave | Ban | Knock 65 + 66 val to_string : t -> string 67 val of_string : string -> (t, [> `Unknown_membership of string ]) result 68 + val pp : Format.formatter -> t -> unit 69 val jsont : t Jsont.t 70 end 71 72 (** {1 Join Rules} *) 73 74 module Join_rule : sig 75 + (** Room join rules. 76 + 77 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomjoin_rules> m.room.join_rules *) 78 + 79 type t = Public | Invite | Knock | Restricted | Knock_restricted | Private 80 + 81 + val to_string : t -> string 82 + val pp : Format.formatter -> t -> unit 83 val jsont : t Jsont.t 84 end 85 86 (** {1 History Visibility} *) 87 88 module History_visibility : sig 89 + (** Room history visibility settings. 90 + 91 + @see <https://spec.matrix.org/v1.11/client-server-api/#room-history-visibility> Room History Visibility *) 92 + 93 type t = Invited | Joined | Shared | World_readable 94 + 95 + val to_string : t -> string 96 + val pp : Format.formatter -> t -> unit 97 val jsont : t Jsont.t 98 end 99 100 (** {1 Room State Event Contents} *) 101 102 module Room_create_content : sig 103 + (** Room creation state event content. 104 + 105 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomcreate> m.room.create *) 106 + 107 + module Predecessor : sig 108 + (** Information about a room's predecessor. *) 109 + 110 + type t 111 + 112 + val make : room_id:Matrix_id.Room_id.t -> event_id:Matrix_id.Event_id.t -> t 113 + val room_id : t -> Matrix_id.Room_id.t 114 + val event_id : t -> Matrix_id.Event_id.t 115 + val pp : Format.formatter -> t -> unit 116 + val jsont : t Jsont.t 117 + end 118 + 119 + type predecessor = Predecessor.t 120 + type t 121 + 122 + val make : 123 + ?creator:Matrix_id.User_id.t -> 124 + ?room_version:string -> 125 + ?predecessor:Predecessor.t -> 126 + ?type_:string -> 127 + unit -> t 128 + 129 + val creator : t -> Matrix_id.User_id.t option 130 + val room_version : t -> string option 131 + val predecessor : t -> Predecessor.t option 132 + val room_type : t -> string option 133 + 134 + val pp : Format.formatter -> t -> unit 135 val jsont : t Jsont.t 136 end 137 138 module Room_name_content : sig 139 + (** Room name state event content. 140 + 141 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomname> m.room.name *) 142 + 143 + type t 144 + 145 + val make : name:string -> t 146 + val name : t -> string 147 + val pp : Format.formatter -> t -> unit 148 val jsont : t Jsont.t 149 end 150 151 module Room_topic_content : sig 152 + (** Room topic state event content. 153 + 154 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomtopic> m.room.topic *) 155 + 156 + type t 157 + 158 + val make : topic:string -> t 159 + val topic : t -> string 160 + val pp : Format.formatter -> t -> unit 161 val jsont : t Jsont.t 162 end 163 164 module Room_avatar_content : sig 165 + (** Room avatar state event content. 166 + 167 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomavatar> m.room.avatar *) 168 + 169 + module Image_info : sig 170 + (** Image metadata. *) 171 + 172 + type t 173 + 174 + val make : ?h:int -> ?w:int -> ?mimetype:string -> ?size:int -> unit -> t 175 + val height : t -> int option 176 + val width : t -> int option 177 + val mimetype : t -> string option 178 + val size : t -> int option 179 + val pp : Format.formatter -> t -> unit 180 + val jsont : t Jsont.t 181 + end 182 + 183 + type image_info = Image_info.t 184 + type t 185 + 186 + val make : ?url:string -> ?info:Image_info.t -> unit -> t 187 + val url : t -> string option 188 + val info : t -> Image_info.t option 189 + val pp : Format.formatter -> t -> unit 190 val jsont : t Jsont.t 191 end 192 193 module Room_member_content : sig 194 + (** Room member state event content. 195 + 196 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroommember> m.room.member *) 197 + 198 + type t 199 + 200 + val make : 201 + membership:Membership.t -> 202 + ?displayname:string -> 203 + ?avatar_url:string -> 204 + ?is_direct:bool -> 205 + ?reason:string -> 206 + unit -> t 207 + 208 + val membership : t -> Membership.t 209 + val displayname : t -> string option 210 + val avatar_url : t -> string option 211 + val is_direct : t -> bool option 212 + val reason : t -> string option 213 + 214 + val pp : Format.formatter -> t -> unit 215 val jsont : t Jsont.t 216 end 217 218 module Room_join_rules_content : sig 219 + (** Room join rules state event content. 220 + 221 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomjoin_rules> m.room.join_rules *) 222 + 223 + module Allow_condition : sig 224 + (** A condition for restricted room joins. *) 225 + 226 + type t 227 + 228 + val make : type_:string -> ?room_id:Matrix_id.Room_id.t -> unit -> t 229 + val condition_type : t -> string 230 + val room_id : t -> Matrix_id.Room_id.t option 231 + val pp : Format.formatter -> t -> unit 232 + val jsont : t Jsont.t 233 + end 234 + 235 + type allow_condition = Allow_condition.t 236 + type t 237 + 238 + val make : join_rule:Join_rule.t -> ?allow:Allow_condition.t list -> unit -> t 239 + val join_rule : t -> Join_rule.t 240 + val allow : t -> Allow_condition.t list option 241 + 242 + val pp : Format.formatter -> t -> unit 243 val jsont : t Jsont.t 244 end 245 246 module Room_history_visibility_content : sig 247 + (** Room history visibility state event content. 248 + 249 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomhistory_visibility> m.room.history_visibility *) 250 + 251 + type t 252 + 253 + val make : history_visibility:History_visibility.t -> t 254 + val history_visibility : t -> History_visibility.t 255 + val pp : Format.formatter -> t -> unit 256 val jsont : t Jsont.t 257 end 258 259 module Room_canonical_alias_content : sig 260 + (** Room canonical alias state event content. 261 + 262 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomcanonical_alias> m.room.canonical_alias *) 263 + 264 + type t 265 + 266 + val make : 267 + ?alias:Matrix_id.Room_alias.t -> 268 + ?alt_aliases:Matrix_id.Room_alias.t list -> 269 + unit -> t 270 + 271 + val alias : t -> Matrix_id.Room_alias.t option 272 + val alt_aliases : t -> Matrix_id.Room_alias.t list option 273 + 274 + val pp : Format.formatter -> t -> unit 275 val jsont : t Jsont.t 276 end 277 278 module Room_power_levels_content : sig 279 + (** Room power levels state event content. 280 + 281 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroompower_levels> m.room.power_levels *) 282 + 283 + type t 284 + 285 + val make : 286 + ?ban:int -> 287 + ?events:(string * int) list -> 288 + ?events_default:int -> 289 + ?invite:int -> 290 + ?kick:int -> 291 + ?redact:int -> 292 + ?state_default:int -> 293 + ?users:(string * int) list -> 294 + ?users_default:int -> 295 + unit -> t 296 + 297 + val ban : t -> int option 298 + val events : t -> (string * int) list option 299 + val events_default : t -> int option 300 + val invite : t -> int option 301 + val kick : t -> int option 302 + val redact : t -> int option 303 + val state_default : t -> int option 304 + val users : t -> (string * int) list option 305 + val users_default : t -> int option 306 + 307 + val pp : Format.formatter -> t -> unit 308 val jsont : t Jsont.t 309 end 310 311 module Room_encryption_content : sig 312 + (** Room encryption state event content. 313 + 314 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomencryption> m.room.encryption *) 315 + 316 + type t 317 + 318 + val make : 319 + algorithm:string -> 320 + ?rotation_period_ms:int64 -> 321 + ?rotation_period_msgs:int -> 322 + unit -> t 323 + 324 + val algorithm : t -> string 325 + val rotation_period_ms : t -> int64 option 326 + val rotation_period_msgs : t -> int option 327 + 328 + val pp : Format.formatter -> t -> unit 329 val jsont : t Jsont.t 330 end 331 332 module Room_pinned_events_content : sig 333 + (** Room pinned events state event content. 334 + 335 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroompinned_events> m.room.pinned_events *) 336 + 337 + type t 338 + 339 + val make : ?pinned:string list -> unit -> t 340 + val pinned : t -> string list 341 + val pp : Format.formatter -> t -> unit 342 val jsont : t Jsont.t 343 end 344 345 module Room_server_acl_content : sig 346 + (** Room server ACL state event content. 347 + 348 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomserver_acl> m.room.server_acl *) 349 + 350 + type t 351 + 352 + val make : 353 + ?allow:string list -> 354 + ?allow_ip_literals:bool -> 355 + ?deny:string list -> 356 + unit -> t 357 + 358 + val allow : t -> string list 359 + val allow_ip_literals : t -> bool 360 + val deny : t -> string list 361 + 362 + val pp : Format.formatter -> t -> unit 363 val jsont : t Jsont.t 364 end 365 366 module Room_tombstone_content : sig 367 + (** Room tombstone state event content. 368 + 369 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomtombstone> m.room.tombstone *) 370 + 371 + type t 372 + 373 + val make : body:string -> replacement_room:Matrix_id.Room_id.t -> t 374 + val body : t -> string 375 + val replacement_room : t -> Matrix_id.Room_id.t 376 + 377 + val pp : Format.formatter -> t -> unit 378 val jsont : t Jsont.t 379 end 380 381 module Room_guest_access_content : sig 382 + (** Room guest access state event content. 383 + 384 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroomguest_access> m.room.guest_access *) 385 + 386 type access = Can_join | Forbidden 387 + 388 + val access_to_string : access -> string 389 + val pp_access : Format.formatter -> access -> unit 390 val access_jsont : access Jsont.t 391 + 392 + type t 393 + 394 + val make : guest_access:access -> t 395 + val guest_access : t -> access 396 + 397 + val pp : Format.formatter -> t -> unit 398 val jsont : t Jsont.t 399 end 400 401 (** {1 Space Event Contents} *) 402 403 module Space_child_content : sig 404 + (** Space child state event content. 405 + 406 + @see <https://spec.matrix.org/v1.11/client-server-api/#mspacechild> m.space.child *) 407 + 408 type t = { 409 via : string list option; 410 order : string option; 411 suggested : bool option; 412 } 413 + 414 + val make : ?via:string list -> ?order:string -> ?suggested:bool -> unit -> t 415 + val via : t -> string list option 416 + val order : t -> string option 417 + val suggested : t -> bool option 418 + val pp : Format.formatter -> t -> unit 419 val jsont : t Jsont.t 420 end 421 422 module Space_parent_content : sig 423 + (** Space parent state event content. 424 + 425 + @see <https://spec.matrix.org/v1.11/client-server-api/#mspaceparent> m.space.parent *) 426 + 427 type t = { 428 via : string list option; 429 canonical : bool option; 430 } 431 + 432 + val make : ?via:string list -> ?canonical:bool -> unit -> t 433 + val via : t -> string list option 434 + val canonical : t -> bool option 435 + val pp : Format.formatter -> t -> unit 436 val jsont : t Jsont.t 437 end 438 439 + (** {1 Call Event Contents} 440 + 441 + Call events are used for VoIP calling in Matrix. 442 + 443 + @see <https://spec.matrix.org/v1.11/client-server-api/#voice-over-ip> Voice over IP *) 444 445 module Call_invite_content : sig 446 + (** Call invite event content. 447 + 448 + @see <https://spec.matrix.org/v1.11/client-server-api/#mcallinvite> m.call.invite *) 449 + 450 type sdp_content = { type_ : string; sdp : string } 451 type t = { 452 call_id : string; ··· 456 offer : sdp_content; 457 invitee : string option; 458 } 459 + 460 + val make_sdp : type_:string -> sdp:string -> sdp_content 461 + val make : call_id:string -> ?party_id:string -> ?version:int -> 462 + lifetime:int -> offer:sdp_content -> ?invitee:string -> unit -> t 463 + val call_id : t -> string 464 + val party_id : t -> string option 465 + val version : t -> int 466 + val lifetime : t -> int 467 + val offer : t -> sdp_content 468 + val invitee : t -> string option 469 + val pp : Format.formatter -> t -> unit 470 val jsont : t Jsont.t 471 end 472 473 module Call_answer_content : sig 474 + (** Call answer event content. 475 + 476 + @see <https://spec.matrix.org/v1.11/client-server-api/#mcallanswer> m.call.answer *) 477 + 478 type sdp_content = { type_ : string; sdp : string } 479 type t = { 480 call_id : string; ··· 482 version : int; 483 answer : sdp_content; 484 } 485 + 486 + val make_sdp : type_:string -> sdp:string -> sdp_content 487 + val make : call_id:string -> ?party_id:string -> ?version:int -> 488 + answer:sdp_content -> unit -> t 489 + val call_id : t -> string 490 + val party_id : t -> string option 491 + val version : t -> int 492 + val answer : t -> sdp_content 493 + val pp : Format.formatter -> t -> unit 494 val jsont : t Jsont.t 495 end 496 497 module Call_hangup_content : sig 498 + (** Call hangup event content. 499 + 500 + @see <https://spec.matrix.org/v1.11/client-server-api/#mcallhangup> m.call.hangup *) 501 + 502 type reason = 503 | Ice_failed | Invite_timeout | User_hangup 504 | User_media_failed | User_busy | Unknown_error 505 + 506 + val reason_to_string : reason -> string 507 + val pp_reason : Format.formatter -> reason -> unit 508 + 509 type t = { 510 call_id : string; 511 party_id : string option; 512 version : int; 513 reason : reason option; 514 } 515 + 516 + val make : call_id:string -> ?party_id:string -> ?version:int -> 517 + ?reason:reason -> unit -> t 518 + val call_id : t -> string 519 + val party_id : t -> string option 520 + val version : t -> int 521 + val reason : t -> reason option 522 + val pp : Format.formatter -> t -> unit 523 val jsont : t Jsont.t 524 end 525 526 module Call_candidates_content : sig 527 + (** Call candidates event content. 528 + 529 + @see <https://spec.matrix.org/v1.11/client-server-api/#mcallcandidates> m.call.candidates *) 530 + 531 type candidate = { 532 candidate : string; 533 sdp_mid : string; 534 sdp_m_line_index : int; 535 } 536 + 537 + val make_candidate : candidate:string -> sdp_mid:string -> 538 + sdp_m_line_index:int -> candidate 539 + 540 type t = { 541 call_id : string; 542 party_id : string option; 543 version : int; 544 candidates : candidate list; 545 } 546 + 547 + val make : call_id:string -> ?party_id:string -> ?version:int -> 548 + ?candidates:candidate list -> unit -> t 549 + val call_id : t -> string 550 + val party_id : t -> string option 551 + val version : t -> int 552 + val candidates : t -> candidate list 553 + val pp : Format.formatter -> t -> unit 554 val jsont : t Jsont.t 555 end 556 557 (** {1 Call Member Content (m.call.member)} *) 558 559 module Call_member_content : sig 560 + (** Call member state event content for MatrixRTC. 561 + 562 + @see <https://spec.matrix.org/v1.11/client-server-api/#mcallmember> m.call.member *) 563 + 564 type focus = { 565 type_ : string; 566 livekit_service_url : string option; 567 livekit_alias : string option; 568 } 569 + 570 + val make_focus : type_:string -> ?livekit_service_url:string -> 571 + ?livekit_alias:string -> unit -> focus 572 + 573 type membership = { 574 call_id : string; 575 scope : string; ··· 579 foci_active : focus list option; 580 membership_id : string option; 581 } 582 + 583 + val make_membership : call_id:string -> ?scope:string -> application:string -> 584 + device_id:string -> expires:int64 -> ?foci_active:focus list -> 585 + ?membership_id:string -> unit -> membership 586 + 587 type t = { memberships : membership list } 588 + 589 + val make : ?memberships:membership list -> unit -> t 590 + val memberships : t -> membership list 591 + val pp : Format.formatter -> t -> unit 592 val jsont : t Jsont.t 593 end 594 ··· 765 (** {1 Message Event Contents} *) 766 767 module Msgtype : sig 768 + (** Message types for room messages. 769 + 770 + @see <https://spec.matrix.org/v1.11/client-server-api/#mroommessage-msgtypes> Message Types *) 771 + 772 type t = 773 | Text | Emote | Notice | Image | File | Audio | Video | Location 774 | Custom of string 775 + 776 val to_string : t -> string 777 val of_string : string -> t 778 + val pp : Format.formatter -> t -> unit 779 val jsont : t Jsont.t 780 end 781 782 module Text_message_content : sig 783 + (** Text message content. 784 + 785 + @see <https://spec.matrix.org/v1.11/client-server-api/#mtext> m.text *) 786 + 787 type t = { 788 body : string; 789 msgtype : Msgtype.t; 790 format : string option; 791 formatted_body : string option; 792 } 793 + 794 + val make : ?msgtype:Msgtype.t -> ?format:string -> ?formatted_body:string -> 795 + string -> t 796 + val body : t -> string 797 + val msgtype : t -> Msgtype.t 798 + val format : t -> string option 799 + val formatted_body : t -> string option 800 + val pp : Format.formatter -> t -> unit 801 val jsont : t Jsont.t 802 end 803 804 module Media_info : sig ··· 865 (** {1 Event Types} *) 866 867 module Event_type : sig 868 + (** Matrix event types. 869 + 870 + @see <https://spec.matrix.org/v1.11/client-server-api/#events> Events *) 871 + 872 type t = 873 (* Room state events *) 874 | Room_create | Room_name | Room_topic | Room_avatar | Room_member ··· 902 | Poll_start | Poll_response | Poll_end 903 (* Custom *) 904 | Custom of string 905 + 906 val to_string : t -> string 907 val of_string : string -> t 908 + val pp : Format.formatter -> t -> unit 909 val jsont : t Jsont.t 910 end 911
+24
lib/matrix_proto/matrix_id.ml
··· 56 (** Convert to string representation. *) 57 let to_string t = t 58 59 (** JSON codec for server names. *) 60 let jsont = 61 Jsont.of_of_string ~kind:"server_name" ··· 125 126 (** Get the server name (the part after the colon). *) 127 let server_name t = t.server_name 128 129 (** JSON codec for user IDs. *) 130 let jsont = ··· 185 (** Get the server name of the room's creating server. *) 186 let server_name t = t.server_name 187 188 (** JSON codec for room IDs. *) 189 let jsont = 190 Jsont.of_of_string ~kind:"room_id" ··· 249 Printf.sprintf "%c%s:%s" sigil opaque_id (Server_name.to_string server_name) 250 | V4 { opaque_id } -> 251 Printf.sprintf "%c%s" sigil opaque_id 252 253 (** JSON codec for event IDs. *) 254 let jsont = ··· 311 (** Get the server that manages this alias. *) 312 let server_name t = t.server_name 313 314 (** JSON codec for room aliases. *) 315 let jsont = 316 Jsont.of_of_string ~kind:"room_alias" ··· 349 350 (** Convert to string representation. *) 351 let to_string t = t 352 353 (** JSON codec for device IDs. *) 354 let jsont = Jsont.string ··· 378 (** Convert to string representation. *) 379 let to_string t = t 380 381 (** JSON codec for session IDs. *) 382 let jsont = Jsont.string 383 end ··· 415 416 (** Convert to string representation. *) 417 let to_string t = t 418 419 (** JSON codec for transaction IDs. *) 420 let jsont = Jsont.string
··· 56 (** Convert to string representation. *) 57 let to_string t = t 58 59 + (** Pretty-print a server name. *) 60 + let pp ppf t = Format.pp_print_string ppf t 61 + 62 (** JSON codec for server names. *) 63 let jsont = 64 Jsont.of_of_string ~kind:"server_name" ··· 128 129 (** Get the server name (the part after the colon). *) 130 let server_name t = t.server_name 131 + 132 + (** Pretty-print a user ID. *) 133 + let pp ppf t = Format.pp_print_string ppf (to_string t) 134 135 (** JSON codec for user IDs. *) 136 let jsont = ··· 191 (** Get the server name of the room's creating server. *) 192 let server_name t = t.server_name 193 194 + (** Pretty-print a room ID. *) 195 + let pp ppf t = Format.pp_print_string ppf (to_string t) 196 + 197 (** JSON codec for room IDs. *) 198 let jsont = 199 Jsont.of_of_string ~kind:"room_id" ··· 258 Printf.sprintf "%c%s:%s" sigil opaque_id (Server_name.to_string server_name) 259 | V4 { opaque_id } -> 260 Printf.sprintf "%c%s" sigil opaque_id 261 + 262 + (** Pretty-print an event ID. *) 263 + let pp ppf t = Format.pp_print_string ppf (to_string t) 264 265 (** JSON codec for event IDs. *) 266 let jsont = ··· 323 (** Get the server that manages this alias. *) 324 let server_name t = t.server_name 325 326 + (** Pretty-print a room alias. *) 327 + let pp ppf t = Format.pp_print_string ppf (to_string t) 328 + 329 (** JSON codec for room aliases. *) 330 let jsont = 331 Jsont.of_of_string ~kind:"room_alias" ··· 364 365 (** Convert to string representation. *) 366 let to_string t = t 367 + 368 + (** Pretty-print a device ID. *) 369 + let pp ppf t = Format.pp_print_string ppf t 370 371 (** JSON codec for device IDs. *) 372 let jsont = Jsont.string ··· 396 (** Convert to string representation. *) 397 let to_string t = t 398 399 + (** Pretty-print a session ID. *) 400 + let pp ppf t = Format.pp_print_string ppf t 401 + 402 (** JSON codec for session IDs. *) 403 let jsont = Jsont.string 404 end ··· 436 437 (** Convert to string representation. *) 438 let to_string t = t 439 + 440 + (** Pretty-print a transaction ID. *) 441 + let pp ppf t = Format.pp_print_string ppf t 442 443 (** JSON codec for transaction IDs. *) 444 let jsont = Jsont.string
+8
lib/matrix_proto/matrix_id.mli
··· 11 val of_string : string -> (t, [> `Invalid_server_name of string ]) result 12 val of_string_exn : string -> t 13 val to_string : t -> string 14 val jsont : t Jsont.t 15 end 16 ··· 26 val to_string : t -> string 27 val localpart : t -> string 28 val server_name : t -> Server_name.t 29 val jsont : t Jsont.t 30 end 31 ··· 41 val to_string : t -> string 42 val opaque_id : t -> string 43 val server_name : t -> Server_name.t 44 val jsont : t Jsont.t 45 end 46 ··· 56 val of_string : string -> (t, [> `Invalid_event_id of string ]) result 57 val of_string_exn : string -> t 58 val to_string : t -> string 59 val jsont : t Jsont.t 60 end 61 ··· 71 val to_string : t -> string 72 val alias : t -> string 73 val server_name : t -> Server_name.t 74 val jsont : t Jsont.t 75 end 76 ··· 84 val of_string : string -> (t, [> `Invalid_device_id of string ]) result 85 val of_string_exn : string -> t 86 val to_string : t -> string 87 val jsont : t Jsont.t 88 end 89 ··· 96 97 val of_string : string -> (t, [> `Invalid_session_id of string ]) result 98 val to_string : t -> string 99 val jsont : t Jsont.t 100 end 101 ··· 109 val generate : unit -> t 110 val of_string : string -> t 111 val to_string : t -> string 112 val jsont : t Jsont.t 113 end
··· 11 val of_string : string -> (t, [> `Invalid_server_name of string ]) result 12 val of_string_exn : string -> t 13 val to_string : t -> string 14 + val pp : Format.formatter -> t -> unit 15 val jsont : t Jsont.t 16 end 17 ··· 27 val to_string : t -> string 28 val localpart : t -> string 29 val server_name : t -> Server_name.t 30 + val pp : Format.formatter -> t -> unit 31 val jsont : t Jsont.t 32 end 33 ··· 43 val to_string : t -> string 44 val opaque_id : t -> string 45 val server_name : t -> Server_name.t 46 + val pp : Format.formatter -> t -> unit 47 val jsont : t Jsont.t 48 end 49 ··· 59 val of_string : string -> (t, [> `Invalid_event_id of string ]) result 60 val of_string_exn : string -> t 61 val to_string : t -> string 62 + val pp : Format.formatter -> t -> unit 63 val jsont : t Jsont.t 64 end 65 ··· 75 val to_string : t -> string 76 val alias : t -> string 77 val server_name : t -> Server_name.t 78 + val pp : Format.formatter -> t -> unit 79 val jsont : t Jsont.t 80 end 81 ··· 89 val of_string : string -> (t, [> `Invalid_device_id of string ]) result 90 val of_string_exn : string -> t 91 val to_string : t -> string 92 + val pp : Format.formatter -> t -> unit 93 val jsont : t Jsont.t 94 end 95 ··· 102 103 val of_string : string -> (t, [> `Invalid_session_id of string ]) result 104 val to_string : t -> string 105 + val pp : Format.formatter -> t -> unit 106 val jsont : t Jsont.t 107 end 108 ··· 116 val generate : unit -> t 117 val of_string : string -> t 118 val to_string : t -> string 119 + val pp : Format.formatter -> t -> unit 120 val jsont : t Jsont.t 121 end