Skip to content

Commit

Permalink
Sync Bindings (#1204)
Browse files Browse the repository at this point in the history
* bindings

* node bindings

* wasm bindings

* cli

* lint

* cleanup
  • Loading branch information
codabrink authored Oct 31, 2024
1 parent 6aae90b commit f87edf4
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 111 deletions.
2 changes: 2 additions & 0 deletions bindings_ffi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ pub enum GenericError {
Verifier(#[from] xmtp_id::scw_verifier::VerifierError),
#[error("Failed to convert to u32")]
FailedToConvertToU32,
#[error(transparent)]
DeviceSync(#[from] xmtp_mls::groups::device_sync::DeviceSyncError),
}

#[derive(uniffi::Error, thiserror::Error, Debug)]
Expand Down
28 changes: 20 additions & 8 deletions bindings_ffi/src/mls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ use xmtp_mls::{
},
AbortHandle, GenericStreamHandle, StreamHandle,
};
use xmtp_proto::xmtp::mls::message_contents::DeviceSyncKind;
pub type RustXmtpClient = MlsClient<TonicApiClient>;

/// It returns a new client of the specified `inbox_id`.
Expand Down Expand Up @@ -399,15 +400,11 @@ impl FfiXmtpClient {
Ok(())
}

pub async fn request_history_sync(&self) -> Result<(), GenericError> {
let provider = self
.inner_client
.mls_provider()
.map_err(GenericError::from_error)?;
pub async fn send_sync_request(&self, kind: FfiDeviceSyncKind) -> Result<(), GenericError> {
let provider = self.inner_client.mls_provider()?;
self.inner_client
.send_history_sync_request(&provider)
.await
.map_err(GenericError::from_error)?;
.send_sync_request(&provider, kind.into())
.await?;

Ok(())
}
Expand Down Expand Up @@ -1054,6 +1051,21 @@ impl From<FfiConsentState> for ConsentState {
}
}

#[derive(uniffi::Enum)]
pub enum FfiDeviceSyncKind {
Messages,
Consent,
}

impl From<FfiDeviceSyncKind> for DeviceSyncKind {
fn from(value: FfiDeviceSyncKind) -> Self {
match value {
FfiDeviceSyncKind::Consent => DeviceSyncKind::Consent,
FfiDeviceSyncKind::Messages => DeviceSyncKind::MessageHistory,
}
}
}

#[derive(uniffi::Enum)]
pub enum FfiConsentEntityType {
ConversationId,
Expand Down
16 changes: 13 additions & 3 deletions bindings_node/src/mls_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use xmtp_mls::groups::scoped_client::LocalScopedGroupClient;
use xmtp_mls::identity::IdentityStrategy;
use xmtp_mls::storage::{EncryptedMessageStore, EncryptionKey, StorageOption};
use xmtp_mls::Client as MlsClient;
use xmtp_proto::xmtp::mls::message_contents::DeviceSyncKind;

pub type RustXmtpClient = MlsClient<TonicApiClient>;
static LOGGER_INIT: Once = Once::new();
Expand Down Expand Up @@ -179,14 +180,23 @@ impl NapiClient {
}

#[napi]
pub async fn request_history_sync(&self) -> Result<()> {
pub async fn send_history_sync_request(&self) -> Result<()> {
self.send_sync_request(DeviceSyncKind::MessageHistory).await
}

#[napi]
pub async fn send_consent_sync_request(&self) -> Result<()> {
self.send_sync_request(DeviceSyncKind::Consent).await
}

async fn send_sync_request(&self, kind: DeviceSyncKind) -> Result<()> {
let provider = self
.inner_client
.mls_provider()
.map_err(ErrorWrapper::from)?;
let _ = self
self
.inner_client
.send_history_sync_request(&provider)
.send_sync_request(&provider, kind)
.await
.map_err(ErrorWrapper::from)?;

Expand Down
18 changes: 14 additions & 4 deletions bindings_wasm/src/mls_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use xmtp_mls::groups::scoped_client::ScopedGroupClient;
use xmtp_mls::identity::IdentityStrategy;
use xmtp_mls::storage::{EncryptedMessageStore, EncryptionKey, StorageOption};
use xmtp_mls::Client as MlsClient;
use xmtp_proto::xmtp::mls::message_contents::DeviceSyncKind;

use crate::conversations::WasmConversations;
use crate::signatures::WasmSignatureRequestType;
Expand Down Expand Up @@ -155,15 +156,24 @@ impl WasmClient {
Ok(())
}

#[wasm_bindgen(js_name = requestHistorySync)]
pub async fn request_history_sync(&self) -> Result<(), JsError> {
#[wasm_bindgen(js_name = sendHistorySyncRequest)]
pub async fn send_history_sync_request(&self) -> Result<(), JsError> {
self.send_sync_request(DeviceSyncKind::MessageHistory).await
}

#[wasm_bindgen(js_name = sendConsentSyncRequest)]
pub async fn send_consent_sync_request(&self) -> Result<(), JsError> {
self.send_sync_request(DeviceSyncKind::Consent).await
}

async fn send_sync_request(&self, kind: DeviceSyncKind) -> Result<(), JsError> {
let provider = self
.inner_client
.mls_provider()
.map_err(|e| JsError::new(format!("{}", e).as_str()))?;
let _ = self
self
.inner_client
.send_history_sync_request(&provider)
.send_sync_request(&provider, kind)
.await
.map_err(|e| JsError::new(format!("{}", e).as_str()))?;

Expand Down
18 changes: 14 additions & 4 deletions examples/cli/cli-client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use xmtp_mls::groups::device_sync::DeviceSyncContent;
use xmtp_mls::storage::group::GroupQueryArgs;
use xmtp_mls::storage::group_message::{GroupMessageKind, MsgQueryArgs};
use xmtp_mls::XmtpApi;
use xmtp_proto::xmtp::mls::message_contents::DeviceSyncKind;

use crate::{
json_logger::make_value,
Expand Down Expand Up @@ -355,7 +356,10 @@ async fn main() {
let provider = client.mls_provider().unwrap();
client.sync_welcomes(&conn).await.unwrap();
client.enable_sync(&provider).await.unwrap();
let (group_id, _) = client.send_history_sync_request(&provider).await.unwrap();
let (group_id, _) = client
.send_sync_request(&provider, DeviceSyncKind::MessageHistory)
.await
.unwrap();
let group_id_str = hex::encode(group_id);
info!("Sent history sync request in sync group {group_id_str}", { group_id: group_id_str})
}
Expand All @@ -364,7 +368,7 @@ async fn main() {
let group = client.get_sync_group().unwrap();
let group_id_str = hex::encode(group.group_id);
let reply = client
.reply_to_history_sync_request(&provider)
.reply_to_sync_request(&provider, DeviceSyncKind::MessageHistory)
.await
.unwrap();

Expand All @@ -376,7 +380,10 @@ async fn main() {
let provider = client.mls_provider().unwrap();
client.sync_welcomes(&conn).await.unwrap();
client.enable_sync(&provider).await.unwrap();
client.process_history_sync_reply(&provider).await.unwrap();
client
.process_sync_reply(&provider, DeviceSyncKind::MessageHistory)
.await
.unwrap();

info!("History bundle downloaded and inserted into user DB", {})
}
Expand All @@ -385,7 +392,10 @@ async fn main() {
let provider = client.mls_provider().unwrap();
client.sync_welcomes(&conn).await.unwrap();
client.enable_sync(&provider).await.unwrap();
client.process_consent_sync_reply(&provider).await.unwrap();
client
.process_sync_reply(&provider, DeviceSyncKind::Consent)
.await
.unwrap();

info!("Consent bundle downloaded and inserted into user DB", {})
}
Expand Down
32 changes: 29 additions & 3 deletions xmtp_mls/src/groups/device_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,30 @@ where
ApiClient: XmtpApi,
V: SmartContractSignatureVerifier,
{
pub async fn reply_to_sync_request(
&self,
provider: &XmtpOpenMlsProvider,
kind: DeviceSyncKind,
) -> Result<DeviceSyncReplyProto, DeviceSyncError> {
let conn = provider.conn_ref();

let (_msg, request) = self.pending_sync_request(provider, kind).await?;
let records = match kind {
DeviceSyncKind::Consent => vec![self.syncable_consent_records(conn)?],
DeviceSyncKind::MessageHistory => {
vec![self.syncable_groups(conn)?, self.syncable_messages(conn)?]
}
DeviceSyncKind::Unspecified => return Err(DeviceSyncError::UnspecifiedDeviceSyncKind),
};

let reply = self
.create_sync_reply(&request.request_id, &records, kind)
.await?;
self.send_sync_reply(provider, reply.clone()).await?;

Ok(reply)
}

pub async fn enable_sync(&self, provider: &XmtpOpenMlsProvider) -> Result<(), GroupError> {
let sync_group = match self.get_sync_group() {
Ok(group) => group,
Expand All @@ -123,11 +147,13 @@ where
Ok(())
}

async fn send_sync_request(
pub async fn send_sync_request(
&self,
provider: &XmtpOpenMlsProvider,
request: DeviceSyncRequest,
kind: DeviceSyncKind,
) -> Result<(String, String), DeviceSyncError> {
let request = DeviceSyncRequest::new(kind);

// find the sync group
let sync_group = self.get_sync_group()?;

Expand Down Expand Up @@ -267,7 +293,7 @@ where
Err(DeviceSyncError::NoReplyToProcess)
}

async fn process_sync_reply(
pub async fn process_sync_reply(
&self,
provider: &XmtpOpenMlsProvider,
kind: DeviceSyncKind,
Expand Down
47 changes: 4 additions & 43 deletions xmtp_mls/src/groups/device_sync/consent_sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,7 @@ where
ApiClient: XmtpApi,
V: SmartContractSignatureVerifier,
{
pub async fn send_consent_sync_request(
&self,
provider: &XmtpOpenMlsProvider,
) -> Result<(String, String), DeviceSyncError> {
let request = DeviceSyncRequest::new(DeviceSyncKind::Consent);
self.send_sync_request(provider, request).await
}

pub async fn reply_to_consent_sync_request(
&self,
provider: &XmtpOpenMlsProvider,
) -> Result<DeviceSyncReplyProto, DeviceSyncError> {
let conn = provider.conn_ref();
let (_msg, request) = self
.pending_sync_request(provider, DeviceSyncKind::Consent)
.await?;

let consent_records = self.syncable_consent_records(conn)?;

let reply = self
.create_sync_reply(
&request.request_id,
&[consent_records],
DeviceSyncKind::Consent,
)
.await?;
self.send_sync_reply(provider, reply.clone()).await?;

Ok(reply)
}

pub async fn process_consent_sync_reply(
&self,
provider: &XmtpOpenMlsProvider,
) -> Result<(), DeviceSyncError> {
self.process_sync_reply(provider, DeviceSyncKind::Consent)
.await
}

fn syncable_consent_records(
pub(super) fn syncable_consent_records(
&self,
conn: &DbConnection,
) -> Result<Vec<Syncable>, DeviceSyncError> {
Expand Down Expand Up @@ -128,7 +89,7 @@ pub(crate) mod tests {

// Have the second installation request for a consent sync.
let (_group_id, _pin_code) = amal_b
.send_consent_sync_request(&amal_b_provider)
.send_sync_request(&amal_b_provider, DeviceSyncKind::Consent)
.await
.expect("history request");

Expand All @@ -142,7 +103,7 @@ pub(crate) mod tests {
// has no problem packaging the consent records,
// and sends a reply message to the first installation.
let reply = amal_a
.reply_to_consent_sync_request(&amal_a_provider)
.reply_to_sync_request(&amal_a_provider, DeviceSyncKind::Consent)
.await
.unwrap();

Expand All @@ -167,7 +128,7 @@ pub(crate) mod tests {

// Have the second installation process the reply.
amal_b
.process_consent_sync_reply(&amal_b_provider)
.process_sync_reply(&amal_b_provider, DeviceSyncKind::Consent)
.await
.unwrap();

Expand Down
Loading

0 comments on commit f87edf4

Please sign in to comment.