The matrix-sdk-crypto crate provides a no-network-IO implementation of a state machine designed to handle end-to-end encryption (E2EE) for Matrix clients.
It operates using a push/pull model:
- Push: You push state changes and events (retrieved from a Matrix homeserver via
/sync responses) into the state machine. - Pull: You pull requests from the state machine that need to be sent back to the homeserver to maintain encryption state.
Note: If you are building a standard Matrix client or bot in Rust, you should use the high-level matrix-sdk crate instead. Use matrix-sdk-crypto only if you are adding E2EE support to an existing client or library.
use std::collections::BTreeMap;
use matrix_sdk_crypto::{
DecryptionSettings, EncryptionSyncChanges, OlmError, OlmMachine, TrustRequirement,
};
use ruma::{api::client::sync::sync_events::DeviceLists, device_id, user_id};
#[tokio::main]
async fn main() -> Result<(), OlmError> {
let alice = user_id!("@alice:example.org");
let machine = OlmMachine::new(&alice, device_id!("DEVICEID")).await;
let changed_devices = DeviceLists::default();
let one_time_key_counts = BTreeMap::default();
let unused_fallback_keys = Some(Vec::new());
let next_batch_token = "T0K3N".to_owned();
let decryption_settings =
DecryptionSettings { sender_device_trust_requirement: TrustRequirement::Untrusted };
// Push changes that the server sent to us in a sync response.
let decrypted_to_device = machine
.receive_sync_changes(
EncryptionSyncChanges {
to_device_events: vec![],
changed_devices: &changed_devices,
one_time_keys_counts: &one_time_key_counts,
unused_fallback_keys: unused_fallback_keys.as_deref(),
next_batch_token: Some(next_batch_token),
},
&decryption_settings,
)
.await?;
// Pull requests that we need to send out.
let outgoing_requests = machine.outgoing_requests().await?;
// Send the requests out here and call machine.mark_request_as_sent().
Ok()
}