@@ -23,7 +23,7 @@ use xmtp_mls::groups::device_sync::preference_sync::UserPreferenceUpdate;
23
23
use xmtp_mls:: groups:: device_sync:: ENC_KEY_SIZE ;
24
24
use xmtp_mls:: groups:: group_mutable_metadata:: MessageDisappearingSettings ;
25
25
use xmtp_mls:: groups:: scoped_client:: LocalScopedGroupClient ;
26
- use xmtp_mls:: groups:: HmacKey ;
26
+ use xmtp_mls:: groups:: { DMMetadataOptions , HmacKey } ;
27
27
use xmtp_mls:: storage:: group:: ConversationType ;
28
28
use xmtp_mls:: storage:: group_message:: { ContentType , MsgQueryArgs } ;
29
29
use xmtp_mls:: storage:: group_message:: { SortDirection , StoredGroupMessageWithReactions } ;
@@ -1102,10 +1102,11 @@ impl FfiConversations {
1102
1102
pub async fn find_or_create_dm (
1103
1103
& self ,
1104
1104
account_address : String ,
1105
+ opts : FfiCreateDMOptions ,
1105
1106
) -> Result < Arc < FfiConversation > , GenericError > {
1106
1107
log:: info!( "creating dm with target address: {}" , account_address) ;
1107
1108
self . inner_client
1108
- . find_or_create_dm ( account_address)
1109
+ . find_or_create_dm ( account_address, opts . into_dm_metadata_options ( ) )
1109
1110
. await
1110
1111
. map ( |g| Arc :: new ( g. into ( ) ) )
1111
1112
. map_err ( Into :: into)
@@ -1114,10 +1115,11 @@ impl FfiConversations {
1114
1115
pub async fn find_or_create_dm_by_inbox_id (
1115
1116
& self ,
1116
1117
inbox_id : String ,
1118
+ opts : FfiCreateDMOptions ,
1117
1119
) -> Result < Arc < FfiConversation > , GenericError > {
1118
1120
log:: info!( "creating dm with target inbox_id: {}" , inbox_id) ;
1119
1121
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 ( ) )
1121
1123
. await
1122
1124
. map ( |g| Arc :: new ( g. into ( ) ) )
1123
1125
. map_err ( Into :: into)
@@ -1622,6 +1624,26 @@ impl FfiCreateGroupOptions {
1622
1624
}
1623
1625
}
1624
1626
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
+
1625
1647
#[ uniffi:: export( async_runtime = "tokio" ) ]
1626
1648
impl FfiConversation {
1627
1649
pub async fn send ( & self , content_bytes : Vec < u8 > ) -> Result < Vec < u8 > , GenericError > {
@@ -1854,22 +1876,22 @@ impl FfiConversation {
1854
1876
1855
1877
pub fn conversation_message_disappearing_settings (
1856
1878
& 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 ( ) ) ?;
1862
1881
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
+ }
1867
1886
}
1868
1887
1869
1888
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
+ } )
1873
1895
}
1874
1896
1875
1897
pub fn admin_list ( & self ) -> Result < Vec < String > , GenericError > {
@@ -2411,11 +2433,11 @@ mod tests {
2411
2433
connect_to_backend, decode_reaction, encode_reaction, get_inbox_id_for_address,
2412
2434
inbox_owner:: SigningError , FfiConsent , FfiConsentEntityType , FfiConsentState ,
2413
2435
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 ,
2419
2441
} ;
2420
2442
use ethers:: utils:: hex;
2421
2443
use prost:: Message ;
@@ -2427,6 +2449,7 @@ mod tests {
2427
2449
} ,
2428
2450
} ;
2429
2451
use tokio:: { sync:: Notify , time:: error:: Elapsed } ;
2452
+ use xmtp_common:: time:: now_ns;
2430
2453
use xmtp_common:: tmp_path;
2431
2454
use xmtp_common:: { wait_for_eq, wait_for_ok} ;
2432
2455
use xmtp_content_types:: {
@@ -3143,13 +3166,15 @@ mod tests {
3143
3166
group
3144
3167
. conversation_message_disappearing_settings( )
3145
3168
. unwrap( )
3169
+ . unwrap( )
3146
3170
. from_ns,
3147
3171
conversation_message_disappearing_settings. clone( ) . from_ns
3148
3172
) ;
3149
3173
assert_eq ! (
3150
3174
group
3151
3175
. conversation_message_disappearing_settings( )
3152
3176
. unwrap( )
3177
+ . unwrap( )
3153
3178
. in_ns,
3154
3179
conversation_message_disappearing_settings. in_ns
3155
3180
) ;
@@ -3386,7 +3411,7 @@ mod tests {
3386
3411
3387
3412
let dm = bo
3388
3413
. conversations ( )
3389
- . find_or_create_dm ( alix. account_address . clone ( ) )
3414
+ . find_or_create_dm ( alix. account_address . clone ( ) , FfiCreateDMOptions :: default ( ) )
3390
3415
. await
3391
3416
. unwrap ( ) ;
3392
3417
dm. send ( b"Hello again" . to_vec ( ) ) . await . unwrap ( ) ;
@@ -4045,7 +4070,10 @@ mod tests {
4045
4070
// Create DM from client1 to client2
4046
4071
let dm_group = client1
4047
4072
. conversations ( )
4048
- . find_or_create_dm ( client2. account_address . clone ( ) )
4073
+ . find_or_create_dm (
4074
+ client2. account_address . clone ( ) ,
4075
+ FfiCreateDMOptions :: default ( ) ,
4076
+ )
4049
4077
. await
4050
4078
. unwrap ( ) ;
4051
4079
@@ -4863,7 +4891,7 @@ mod tests {
4863
4891
4864
4892
let alix_group_admin_only = alix
4865
4893
. conversations ( )
4866
- . find_or_create_dm ( bo. account_address . clone ( ) )
4894
+ . find_or_create_dm ( bo. account_address . clone ( ) , FfiCreateDMOptions :: default ( ) )
4867
4895
. await
4868
4896
. unwrap ( ) ;
4869
4897
@@ -5154,6 +5182,117 @@ mod tests {
5154
5182
// 3 messages got deleted, then two messages got added for metadataUpdate and one normal messaged added later
5155
5183
}
5156
5184
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
+
5157
5296
#[ tokio:: test( flavor = "multi_thread" , worker_threads = 5 ) ]
5158
5297
async fn test_group_creation_custom_permissions ( ) {
5159
5298
let alix = new_test_client ( ) . await ;
@@ -5483,7 +5622,7 @@ mod tests {
5483
5622
let bola_conversations = bola. conversations ( ) ;
5484
5623
5485
5624
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 ( ) )
5487
5626
. await
5488
5627
. unwrap ( ) ;
5489
5628
let alix_num_sync = alix_conversations
@@ -5551,7 +5690,7 @@ mod tests {
5551
5690
5552
5691
assert_eq ! ( stream_callback. message_count( ) , 1 ) ;
5553
5692
alix. conversations ( )
5554
- . find_or_create_dm ( bo. account_address . clone ( ) )
5693
+ . find_or_create_dm ( bo. account_address . clone ( ) , FfiCreateDMOptions :: default ( ) )
5555
5694
. await
5556
5695
. unwrap ( ) ;
5557
5696
stream_callback. wait_for_delivery ( None ) . await . unwrap ( ) ;
@@ -5580,7 +5719,7 @@ mod tests {
5580
5719
5581
5720
assert_eq ! ( stream_callback. message_count( ) , 1 ) ;
5582
5721
alix. conversations ( )
5583
- . find_or_create_dm ( bo. account_address . clone ( ) )
5722
+ . find_or_create_dm ( bo. account_address . clone ( ) , FfiCreateDMOptions :: default ( ) )
5584
5723
. await
5585
5724
. unwrap ( ) ;
5586
5725
let result = stream_callback. wait_for_delivery ( Some ( 2 ) ) . await ;
@@ -5595,7 +5734,7 @@ mod tests {
5595
5734
let stream = bo. conversations ( ) . stream_dms ( stream_callback. clone ( ) ) . await ;
5596
5735
5597
5736
caro. conversations ( )
5598
- . find_or_create_dm ( bo. account_address . clone ( ) )
5737
+ . find_or_create_dm ( bo. account_address . clone ( ) , FfiCreateDMOptions :: default ( ) )
5599
5738
. await
5600
5739
. unwrap ( ) ;
5601
5740
stream_callback. wait_for_delivery ( None ) . await . unwrap ( ) ;
@@ -5623,7 +5762,7 @@ mod tests {
5623
5762
let bo = new_test_client ( ) . await ;
5624
5763
let alix_dm = alix
5625
5764
. conversations ( )
5626
- . find_or_create_dm ( bo. account_address . clone ( ) )
5765
+ . find_or_create_dm ( bo. account_address . clone ( ) , FfiCreateDMOptions :: default ( ) )
5627
5766
. await
5628
5767
. unwrap ( ) ;
5629
5768
@@ -5865,7 +6004,7 @@ mod tests {
5865
6004
5866
6005
let alix_dm = alix
5867
6006
. conversations ( )
5868
- . find_or_create_dm ( bo. account_address . clone ( ) )
6007
+ . find_or_create_dm ( bo. account_address . clone ( ) , FfiCreateDMOptions :: default ( ) )
5869
6008
. await
5870
6009
. unwrap ( ) ;
5871
6010
@@ -5901,7 +6040,7 @@ mod tests {
5901
6040
5902
6041
let alix_dm = alix
5903
6042
. conversations ( )
5904
- . find_or_create_dm ( bo. account_address . clone ( ) )
6043
+ . find_or_create_dm ( bo. account_address . clone ( ) , FfiCreateDMOptions :: default ( ) )
5905
6044
. await
5906
6045
. unwrap ( ) ;
5907
6046
@@ -5963,7 +6102,7 @@ mod tests {
5963
6102
// Alix creates DM with Bo
5964
6103
let alix_dm = alix
5965
6104
. conversations ( )
5966
- . find_or_create_dm ( bo. account_address . clone ( ) )
6105
+ . find_or_create_dm ( bo. account_address . clone ( ) , FfiCreateDMOptions :: default ( ) )
5967
6106
. await
5968
6107
. unwrap ( ) ;
5969
6108
@@ -6108,7 +6247,10 @@ mod tests {
6108
6247
// Alix creates DM with Bo
6109
6248
let bo_dm = bo
6110
6249
. 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
+ )
6112
6254
. await
6113
6255
. unwrap ( ) ;
6114
6256
@@ -6549,7 +6691,7 @@ mod tests {
6549
6691
let inbox_id2 = client2. inbox_id ( ) ;
6550
6692
let dm_by_inbox = client1
6551
6693
. conversations ( )
6552
- . find_or_create_dm_by_inbox_id ( inbox_id2)
6694
+ . find_or_create_dm_by_inbox_id ( inbox_id2, FfiCreateDMOptions :: default ( ) )
6553
6695
. await
6554
6696
. expect ( "Should create DM with inbox ID" ) ;
6555
6697
@@ -6572,7 +6714,7 @@ mod tests {
6572
6714
// First client tries to create another DM with the same inbox id
6573
6715
let dm_by_inbox2 = client1
6574
6716
. 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 ( ) )
6576
6718
. await
6577
6719
. unwrap ( ) ;
6578
6720
@@ -6595,7 +6737,7 @@ mod tests {
6595
6737
// Second client tries to create a DM with the client 1 inbox id
6596
6738
let dm_by_inbox3 = client2
6597
6739
. 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 ( ) )
6599
6741
. await
6600
6742
. unwrap ( ) ;
6601
6743
0 commit comments