Skip to content

Commit f5b1089

Browse files
authored
fix(disappearing-messages): store settings from welcome message (#1619)
* store disappearing settings from welcome msg expose disappearing setting for creating dms returning disappearing settings from the db
1 parent 0c42018 commit f5b1089

File tree

14 files changed

+413
-81
lines changed

14 files changed

+413
-81
lines changed

bindings_ffi/src/mls.rs

+177-35
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use xmtp_mls::groups::device_sync::preference_sync::UserPreferenceUpdate;
2323
use xmtp_mls::groups::device_sync::ENC_KEY_SIZE;
2424
use xmtp_mls::groups::group_mutable_metadata::MessageDisappearingSettings;
2525
use xmtp_mls::groups::scoped_client::LocalScopedGroupClient;
26-
use xmtp_mls::groups::HmacKey;
26+
use xmtp_mls::groups::{DMMetadataOptions, HmacKey};
2727
use xmtp_mls::storage::group::ConversationType;
2828
use xmtp_mls::storage::group_message::{ContentType, MsgQueryArgs};
2929
use xmtp_mls::storage::group_message::{SortDirection, StoredGroupMessageWithReactions};
@@ -1102,10 +1102,11 @@ impl FfiConversations {
11021102
pub async fn find_or_create_dm(
11031103
&self,
11041104
account_address: String,
1105+
opts: FfiCreateDMOptions,
11051106
) -> Result<Arc<FfiConversation>, GenericError> {
11061107
log::info!("creating dm with target address: {}", account_address);
11071108
self.inner_client
1108-
.find_or_create_dm(account_address)
1109+
.find_or_create_dm(account_address, opts.into_dm_metadata_options())
11091110
.await
11101111
.map(|g| Arc::new(g.into()))
11111112
.map_err(Into::into)
@@ -1114,10 +1115,11 @@ impl FfiConversations {
11141115
pub async fn find_or_create_dm_by_inbox_id(
11151116
&self,
11161117
inbox_id: String,
1118+
opts: FfiCreateDMOptions,
11171119
) -> Result<Arc<FfiConversation>, GenericError> {
11181120
log::info!("creating dm with target inbox_id: {}", inbox_id);
11191121
self.inner_client
1120-
.find_or_create_dm_by_inbox_id(inbox_id)
1122+
.find_or_create_dm_by_inbox_id(inbox_id, opts.into_dm_metadata_options())
11211123
.await
11221124
.map(|g| Arc::new(g.into()))
11231125
.map_err(Into::into)
@@ -1622,6 +1624,26 @@ impl FfiCreateGroupOptions {
16221624
}
16231625
}
16241626

1627+
#[derive(uniffi::Record, Clone, Default)]
1628+
pub struct FfiCreateDMOptions {
1629+
pub message_disappearing_settings: Option<FfiMessageDisappearingSettings>,
1630+
}
1631+
1632+
impl FfiCreateDMOptions {
1633+
pub fn new(disappearing_settings: FfiMessageDisappearingSettings) -> Self {
1634+
FfiCreateDMOptions {
1635+
message_disappearing_settings: Some(disappearing_settings),
1636+
}
1637+
}
1638+
pub fn into_dm_metadata_options(self) -> DMMetadataOptions {
1639+
DMMetadataOptions {
1640+
message_disappearing_settings: self
1641+
.message_disappearing_settings
1642+
.map(|settings| settings.into()),
1643+
}
1644+
}
1645+
}
1646+
16251647
#[uniffi::export(async_runtime = "tokio")]
16261648
impl FfiConversation {
16271649
pub async fn send(&self, content_bytes: Vec<u8>) -> Result<Vec<u8>, GenericError> {
@@ -1854,22 +1876,22 @@ impl FfiConversation {
18541876

18551877
pub fn conversation_message_disappearing_settings(
18561878
&self,
1857-
) -> Result<FfiMessageDisappearingSettings, GenericError> {
1858-
let provider = self.inner.mls_provider()?;
1859-
let group_message_expiration_settings = self
1860-
.inner
1861-
.conversation_message_disappearing_settings(&provider)?;
1879+
) -> Result<Option<FfiMessageDisappearingSettings>, GenericError> {
1880+
let settings = self.inner.client.group_disappearing_settings(self.id())?;
18621881

1863-
Ok(FfiMessageDisappearingSettings::new(
1864-
group_message_expiration_settings.from_ns,
1865-
group_message_expiration_settings.in_ns,
1866-
))
1882+
match settings {
1883+
Some(s) => Ok(Some(FfiMessageDisappearingSettings::from(s))),
1884+
None => Ok(None),
1885+
}
18671886
}
18681887

18691888
pub fn is_conversation_message_disappearing_enabled(&self) -> Result<bool, GenericError> {
1870-
let settings = self.conversation_message_disappearing_settings()?;
1871-
1872-
Ok(settings.from_ns > 0 && settings.in_ns > 0)
1889+
self.conversation_message_disappearing_settings()
1890+
.map(|settings| {
1891+
settings
1892+
.as_ref()
1893+
.is_some_and(|s| s.from_ns > 0 && s.in_ns > 0)
1894+
})
18731895
}
18741896

18751897
pub fn admin_list(&self) -> Result<Vec<String>, GenericError> {
@@ -2411,11 +2433,11 @@ mod tests {
24112433
connect_to_backend, decode_reaction, encode_reaction, get_inbox_id_for_address,
24122434
inbox_owner::SigningError, FfiConsent, FfiConsentEntityType, FfiConsentState,
24132435
FfiContentType, FfiConversation, FfiConversationCallback, FfiConversationMessageKind,
2414-
FfiCreateGroupOptions, FfiDirection, FfiGroupPermissionsOptions, FfiInboxOwner,
2415-
FfiListConversationsOptions, FfiListMessagesOptions, FfiMessageDisappearingSettings,
2416-
FfiMessageWithReactions, FfiMetadataField, FfiPermissionPolicy, FfiPermissionPolicySet,
2417-
FfiPermissionUpdateType, FfiReaction, FfiReactionAction, FfiReactionSchema,
2418-
FfiSubscribeError,
2436+
FfiCreateDMOptions, FfiCreateGroupOptions, FfiDirection, FfiGroupPermissionsOptions,
2437+
FfiInboxOwner, FfiListConversationsOptions, FfiListMessagesOptions,
2438+
FfiMessageDisappearingSettings, FfiMessageWithReactions, FfiMetadataField,
2439+
FfiPermissionPolicy, FfiPermissionPolicySet, FfiPermissionUpdateType, FfiReaction,
2440+
FfiReactionAction, FfiReactionSchema, FfiSubscribeError,
24192441
};
24202442
use ethers::utils::hex;
24212443
use prost::Message;
@@ -2427,6 +2449,7 @@ mod tests {
24272449
},
24282450
};
24292451
use tokio::{sync::Notify, time::error::Elapsed};
2452+
use xmtp_common::time::now_ns;
24302453
use xmtp_common::tmp_path;
24312454
use xmtp_common::{wait_for_eq, wait_for_ok};
24322455
use xmtp_content_types::{
@@ -3143,13 +3166,15 @@ mod tests {
31433166
group
31443167
.conversation_message_disappearing_settings()
31453168
.unwrap()
3169+
.unwrap()
31463170
.from_ns,
31473171
conversation_message_disappearing_settings.clone().from_ns
31483172
);
31493173
assert_eq!(
31503174
group
31513175
.conversation_message_disappearing_settings()
31523176
.unwrap()
3177+
.unwrap()
31533178
.in_ns,
31543179
conversation_message_disappearing_settings.in_ns
31553180
);
@@ -3386,7 +3411,7 @@ mod tests {
33863411

33873412
let dm = bo
33883413
.conversations()
3389-
.find_or_create_dm(alix.account_address.clone())
3414+
.find_or_create_dm(alix.account_address.clone(), FfiCreateDMOptions::default())
33903415
.await
33913416
.unwrap();
33923417
dm.send(b"Hello again".to_vec()).await.unwrap();
@@ -4045,7 +4070,10 @@ mod tests {
40454070
// Create DM from client1 to client2
40464071
let dm_group = client1
40474072
.conversations()
4048-
.find_or_create_dm(client2.account_address.clone())
4073+
.find_or_create_dm(
4074+
client2.account_address.clone(),
4075+
FfiCreateDMOptions::default(),
4076+
)
40494077
.await
40504078
.unwrap();
40514079

@@ -4863,7 +4891,7 @@ mod tests {
48634891

48644892
let alix_group_admin_only = alix
48654893
.conversations()
4866-
.find_or_create_dm(bo.account_address.clone())
4894+
.find_or_create_dm(bo.account_address.clone(), FfiCreateDMOptions::default())
48674895
.await
48684896
.unwrap();
48694897

@@ -5154,6 +5182,117 @@ mod tests {
51545182
// 3 messages got deleted, then two messages got added for metadataUpdate and one normal messaged added later
51555183
}
51565184

5185+
#[tokio::test(flavor = "multi_thread", worker_threads = 5)]
5186+
async fn test_set_disappearing_messages_when_creating_group() {
5187+
let alix = new_test_client().await;
5188+
let alix_provider = alix.inner_client.mls_provider().unwrap();
5189+
let bola = new_test_client().await;
5190+
let disappearing_settings = FfiMessageDisappearingSettings::new(now_ns(), 2_000_000_000);
5191+
// Step 1: Create a group
5192+
let alix_group = alix
5193+
.conversations()
5194+
.create_group(
5195+
vec![bola.account_address.clone()],
5196+
FfiCreateGroupOptions {
5197+
permissions: Some(FfiGroupPermissionsOptions::AdminOnly),
5198+
group_name: Some("Group Name".to_string()),
5199+
group_image_url_square: Some("url".to_string()),
5200+
group_description: Some("group description".to_string()),
5201+
custom_permission_policy_set: None,
5202+
message_disappearing_settings: Some(disappearing_settings.clone()),
5203+
},
5204+
)
5205+
.await
5206+
.unwrap();
5207+
5208+
// Step 2: Send a message and sync
5209+
alix_group
5210+
.send("Msg 1 from group".as_bytes().to_vec())
5211+
.await
5212+
.unwrap();
5213+
alix_group.sync().await.unwrap();
5214+
5215+
// Step 3: Verify initial messages
5216+
let alix_messages = alix_group
5217+
.find_messages(FfiListMessagesOptions::default())
5218+
.await
5219+
.unwrap();
5220+
assert_eq!(alix_messages.len(), 2);
5221+
let group_from_db = alix_provider
5222+
.conn_ref()
5223+
.find_group(&alix_group.id())
5224+
.unwrap();
5225+
assert_eq!(
5226+
group_from_db
5227+
.clone()
5228+
.unwrap()
5229+
.message_disappear_from_ns
5230+
.unwrap(),
5231+
disappearing_settings.from_ns
5232+
);
5233+
assert!(alix_group
5234+
.is_conversation_message_disappearing_enabled()
5235+
.unwrap());
5236+
tokio::time::sleep(std::time::Duration::from_secs(3)).await;
5237+
let alix_messages = alix_group
5238+
.find_messages(FfiListMessagesOptions::default())
5239+
.await
5240+
.unwrap();
5241+
assert_eq!(alix_messages.len(), 1);
5242+
}
5243+
#[tokio::test(flavor = "multi_thread", worker_threads = 5)]
5244+
async fn test_set_disappearing_messages_when_creating_dm() {
5245+
let alix = new_test_client().await;
5246+
let alix_provider = alix.inner_client.mls_provider().unwrap();
5247+
let bola = new_test_client().await;
5248+
let disappearing_settings = FfiMessageDisappearingSettings::new(now_ns(), 2_000_000_000);
5249+
// Step 1: Create a group
5250+
let alix_group = alix
5251+
.conversations()
5252+
.find_or_create_dm(
5253+
bola.account_address.clone(),
5254+
FfiCreateDMOptions::new(disappearing_settings.clone()),
5255+
)
5256+
.await
5257+
.unwrap();
5258+
5259+
// Step 2: Send a message and sync
5260+
alix_group
5261+
.send("Msg 1 from group".as_bytes().to_vec())
5262+
.await
5263+
.unwrap();
5264+
alix_group.sync().await.unwrap();
5265+
5266+
// Step 3: Verify initial messages
5267+
let alix_messages = alix_group
5268+
.find_messages(FfiListMessagesOptions::default())
5269+
.await
5270+
.unwrap();
5271+
5272+
assert_eq!(alix_messages.len(), 1);
5273+
let group_from_db = alix_provider
5274+
.conn_ref()
5275+
.find_group(&alix_group.id())
5276+
.unwrap();
5277+
assert_eq!(
5278+
group_from_db
5279+
.clone()
5280+
.unwrap()
5281+
.message_disappear_from_ns
5282+
.unwrap(),
5283+
disappearing_settings.from_ns
5284+
);
5285+
assert!(alix_group
5286+
.is_conversation_message_disappearing_enabled()
5287+
.unwrap());
5288+
tokio::time::sleep(std::time::Duration::from_secs(3)).await;
5289+
let alix_messages = alix_group
5290+
.find_messages(FfiListMessagesOptions::default())
5291+
.await
5292+
.unwrap();
5293+
assert_eq!(alix_messages.len(), 0);
5294+
}
5295+
51575296
#[tokio::test(flavor = "multi_thread", worker_threads = 5)]
51585297
async fn test_group_creation_custom_permissions() {
51595298
let alix = new_test_client().await;
@@ -5483,7 +5622,7 @@ mod tests {
54835622
let bola_conversations = bola.conversations();
54845623

54855624
let _alix_dm = alix_conversations
5486-
.find_or_create_dm(bola.account_address.clone())
5625+
.find_or_create_dm(bola.account_address.clone(), FfiCreateDMOptions::default())
54875626
.await
54885627
.unwrap();
54895628
let alix_num_sync = alix_conversations
@@ -5551,7 +5690,7 @@ mod tests {
55515690

55525691
assert_eq!(stream_callback.message_count(), 1);
55535692
alix.conversations()
5554-
.find_or_create_dm(bo.account_address.clone())
5693+
.find_or_create_dm(bo.account_address.clone(), FfiCreateDMOptions::default())
55555694
.await
55565695
.unwrap();
55575696
stream_callback.wait_for_delivery(None).await.unwrap();
@@ -5580,7 +5719,7 @@ mod tests {
55805719

55815720
assert_eq!(stream_callback.message_count(), 1);
55825721
alix.conversations()
5583-
.find_or_create_dm(bo.account_address.clone())
5722+
.find_or_create_dm(bo.account_address.clone(), FfiCreateDMOptions::default())
55845723
.await
55855724
.unwrap();
55865725
let result = stream_callback.wait_for_delivery(Some(2)).await;
@@ -5595,7 +5734,7 @@ mod tests {
55955734
let stream = bo.conversations().stream_dms(stream_callback.clone()).await;
55965735

55975736
caro.conversations()
5598-
.find_or_create_dm(bo.account_address.clone())
5737+
.find_or_create_dm(bo.account_address.clone(), FfiCreateDMOptions::default())
55995738
.await
56005739
.unwrap();
56015740
stream_callback.wait_for_delivery(None).await.unwrap();
@@ -5623,7 +5762,7 @@ mod tests {
56235762
let bo = new_test_client().await;
56245763
let alix_dm = alix
56255764
.conversations()
5626-
.find_or_create_dm(bo.account_address.clone())
5765+
.find_or_create_dm(bo.account_address.clone(), FfiCreateDMOptions::default())
56275766
.await
56285767
.unwrap();
56295768

@@ -5865,7 +6004,7 @@ mod tests {
58656004

58666005
let alix_dm = alix
58676006
.conversations()
5868-
.find_or_create_dm(bo.account_address.clone())
6007+
.find_or_create_dm(bo.account_address.clone(), FfiCreateDMOptions::default())
58696008
.await
58706009
.unwrap();
58716010

@@ -5901,7 +6040,7 @@ mod tests {
59016040

59026041
let alix_dm = alix
59036042
.conversations()
5904-
.find_or_create_dm(bo.account_address.clone())
6043+
.find_or_create_dm(bo.account_address.clone(), FfiCreateDMOptions::default())
59056044
.await
59066045
.unwrap();
59076046

@@ -5963,7 +6102,7 @@ mod tests {
59636102
// Alix creates DM with Bo
59646103
let alix_dm = alix
59656104
.conversations()
5966-
.find_or_create_dm(bo.account_address.clone())
6105+
.find_or_create_dm(bo.account_address.clone(), FfiCreateDMOptions::default())
59676106
.await
59686107
.unwrap();
59696108

@@ -6108,7 +6247,10 @@ mod tests {
61086247
// Alix creates DM with Bo
61096248
let bo_dm = bo
61106249
.conversations()
6111-
.find_or_create_dm(wallet_a.get_address().clone())
6250+
.find_or_create_dm(
6251+
wallet_a.get_address().clone(),
6252+
FfiCreateDMOptions::default(),
6253+
)
61126254
.await
61136255
.unwrap();
61146256

@@ -6549,7 +6691,7 @@ mod tests {
65496691
let inbox_id2 = client2.inbox_id();
65506692
let dm_by_inbox = client1
65516693
.conversations()
6552-
.find_or_create_dm_by_inbox_id(inbox_id2)
6694+
.find_or_create_dm_by_inbox_id(inbox_id2, FfiCreateDMOptions::default())
65536695
.await
65546696
.expect("Should create DM with inbox ID");
65556697

@@ -6572,7 +6714,7 @@ mod tests {
65726714
// First client tries to create another DM with the same inbox id
65736715
let dm_by_inbox2 = client1
65746716
.conversations()
6575-
.find_or_create_dm_by_inbox_id(client2.inbox_id())
6717+
.find_or_create_dm_by_inbox_id(client2.inbox_id(), FfiCreateDMOptions::default())
65766718
.await
65776719
.unwrap();
65786720

@@ -6595,7 +6737,7 @@ mod tests {
65956737
// Second client tries to create a DM with the client 1 inbox id
65966738
let dm_by_inbox3 = client2
65976739
.conversations()
6598-
.find_or_create_dm_by_inbox_id(client1.inbox_id())
6740+
.find_or_create_dm_by_inbox_id(client1.inbox_id(), FfiCreateDMOptions::default())
65996741
.await
66006742
.unwrap();
66016743

0 commit comments

Comments
 (0)