@@ -118,6 +118,7 @@ pub async fn create_client(
118
118
nonce : u64 ,
119
119
legacy_signed_private_key_proto : Option < Vec < u8 > > ,
120
120
history_sync_url : Option < String > ,
121
+ version_info : Option < String > ,
121
122
) -> Result < Arc < FfiXmtpClient > , GenericError > {
122
123
let ident = account_identifier. clone ( ) ;
123
124
init_logger ( ) ;
@@ -160,6 +161,10 @@ pub async fn create_client(
160
161
builder = builder. history_sync_url ( url) ;
161
162
}
162
163
164
+ if let Some ( version) = & version_info {
165
+ builder = builder. version_info ( version) ;
166
+ }
167
+
163
168
let xmtp_client = builder. build ( ) . await ?;
164
169
165
170
log:: info!(
@@ -384,6 +389,10 @@ impl FfiXmtpClient {
384
389
Ok ( state. into ( ) )
385
390
}
386
391
392
+ pub async fn version_info ( & self ) -> Result < String , GenericError > {
393
+ Ok ( self . inner_client . version_info ( ) . pkg_version . to_string ( ) )
394
+ }
395
+
387
396
/**
388
397
* Get the inbox state for each `inbox_id`.
389
398
*
@@ -2107,6 +2116,11 @@ impl FfiConversation {
2107
2116
self . inner . paused_for_version ( & provider) . map_err ( Into :: into)
2108
2117
}
2109
2118
2119
+ pub async fn update_group_min_version_to_match_self ( & self ) -> Result < ( ) , GenericError > {
2120
+ self . inner . update_group_min_version_to_match_self ( ) . await ?;
2121
+ Ok ( ( ) )
2122
+ }
2123
+
2110
2124
pub fn consent_state ( & self ) -> Result < FfiConsentState , GenericError > {
2111
2125
self . inner
2112
2126
. consent_state ( )
@@ -2703,6 +2717,7 @@ mod tests {
2703
2717
FfiMessageWithReactions , FfiMetadataField , FfiMultiRemoteAttachment , FfiPasskeySignature ,
2704
2718
FfiPermissionPolicy , FfiPermissionPolicySet , FfiPermissionUpdateType , FfiReaction ,
2705
2719
FfiReactionAction , FfiReactionSchema , FfiRemoteAttachmentInfo , FfiSubscribeError ,
2720
+ GenericError ,
2706
2721
} ;
2707
2722
use ethers:: utils:: hex;
2708
2723
use prost:: Message ;
@@ -2941,6 +2956,39 @@ mod tests {
2941
2956
nonce,
2942
2957
None ,
2943
2958
history_sync_url,
2959
+ None ,
2960
+ )
2961
+ . await
2962
+ . unwrap ( ) ;
2963
+
2964
+ let conn = client. inner_client . context ( ) . store ( ) . conn ( ) . unwrap ( ) ;
2965
+ conn. register_triggers ( ) ;
2966
+
2967
+ register_client ( & ffi_inbox_owner, & client) . await ;
2968
+ client
2969
+ }
2970
+
2971
+ async fn new_test_client_with_wallet_and_version_info (
2972
+ wallet : xmtp_cryptography:: utils:: LocalWallet ,
2973
+ version_info : Option < String > ,
2974
+ ) -> Arc < FfiXmtpClient > {
2975
+ let ffi_inbox_owner = LocalWalletInboxOwner :: with_wallet ( wallet) ;
2976
+ let ident = ffi_inbox_owner. identifier ( ) ;
2977
+ let nonce = 1 ;
2978
+ let inbox_id = ident. inbox_id ( nonce) . unwrap ( ) ;
2979
+
2980
+ let client = create_client (
2981
+ connect_to_backend ( xmtp_api_grpc:: LOCALHOST_ADDRESS . to_string ( ) , false )
2982
+ . await
2983
+ . unwrap ( ) ,
2984
+ Some ( tmp_path ( ) ) ,
2985
+ Some ( xmtp_mls:: storage:: EncryptedMessageStore :: generate_enc_key ( ) . into ( ) ) ,
2986
+ & inbox_id,
2987
+ ident,
2988
+ nonce,
2989
+ None ,
2990
+ None ,
2991
+ version_info,
2944
2992
)
2945
2993
. await
2946
2994
. unwrap ( ) ;
@@ -2963,6 +3011,12 @@ mod tests {
2963
3011
. await
2964
3012
}
2965
3013
3014
+ async fn new_test_client_with_version_info ( ) -> Arc < FfiXmtpClient > {
3015
+ let wallet = xmtp_cryptography:: utils:: LocalWallet :: new ( & mut rng ( ) ) ;
3016
+ new_test_client_with_wallet_and_history_sync_url ( wallet, Some ( HISTORY_SYNC_URL . to_string ( ) ) )
3017
+ . await
3018
+ }
3019
+
2966
3020
impl FfiConversation {
2967
3021
#[ cfg( test) ]
2968
3022
async fn update_installations ( & self ) -> Result < ( ) , GroupError > {
@@ -3012,6 +3066,7 @@ mod tests {
3012
3066
nonce,
3013
3067
Some ( legacy_keys) ,
3014
3068
None ,
3069
+ None ,
3015
3070
)
3016
3071
. await
3017
3072
. unwrap ( ) ;
@@ -3039,6 +3094,7 @@ mod tests {
3039
3094
nonce,
3040
3095
None ,
3041
3096
None ,
3097
+ None ,
3042
3098
)
3043
3099
. await
3044
3100
. unwrap ( ) ;
@@ -3058,6 +3114,7 @@ mod tests {
3058
3114
nonce,
3059
3115
None ,
3060
3116
None ,
3117
+ None ,
3061
3118
)
3062
3119
. await
3063
3120
. unwrap ( ) ;
@@ -3093,6 +3150,7 @@ mod tests {
3093
3150
nonce,
3094
3151
None ,
3095
3152
None ,
3153
+ None ,
3096
3154
)
3097
3155
. await
3098
3156
. unwrap ( ) ;
@@ -3113,6 +3171,7 @@ mod tests {
3113
3171
nonce,
3114
3172
None ,
3115
3173
None ,
3174
+ None ,
3116
3175
)
3117
3176
. await
3118
3177
. is_err ( ) ;
@@ -3167,6 +3226,7 @@ mod tests {
3167
3226
nonce,
3168
3227
None ,
3169
3228
None ,
3229
+ None ,
3170
3230
)
3171
3231
. await
3172
3232
. unwrap ( ) ;
@@ -3349,6 +3409,7 @@ mod tests {
3349
3409
nonce,
3350
3410
None ,
3351
3411
None ,
3412
+ None ,
3352
3413
)
3353
3414
. await
3354
3415
. unwrap ( ) ;
@@ -3438,6 +3499,7 @@ mod tests {
3438
3499
nonce,
3439
3500
None , // v2_signed_private_key_proto
3440
3501
None ,
3502
+ None ,
3441
3503
)
3442
3504
. await
3443
3505
. unwrap ( ) ;
@@ -3469,6 +3531,7 @@ mod tests {
3469
3531
nonce,
3470
3532
None ,
3471
3533
None ,
3534
+ None ,
3472
3535
)
3473
3536
. await
3474
3537
. unwrap ( ) ;
@@ -3496,6 +3559,7 @@ mod tests {
3496
3559
nonce,
3497
3560
None ,
3498
3561
None ,
3562
+ None ,
3499
3563
)
3500
3564
. await
3501
3565
. unwrap ( ) ;
@@ -6635,6 +6699,7 @@ mod tests {
6635
6699
1 ,
6636
6700
None ,
6637
6701
Some ( HISTORY_SYNC_URL . to_string ( ) ) ,
6702
+ None ,
6638
6703
)
6639
6704
. await
6640
6705
. unwrap ( ) ;
@@ -6674,6 +6739,7 @@ mod tests {
6674
6739
nonce,
6675
6740
None ,
6676
6741
Some ( HISTORY_SYNC_URL . to_string ( ) ) ,
6742
+ None ,
6677
6743
)
6678
6744
. await
6679
6745
. unwrap ( ) ;
@@ -6738,6 +6804,7 @@ mod tests {
6738
6804
nonce,
6739
6805
None ,
6740
6806
Some ( HISTORY_SYNC_URL . to_string ( ) ) ,
6807
+ None ,
6741
6808
)
6742
6809
. await ;
6743
6810
@@ -6773,6 +6840,7 @@ mod tests {
6773
6840
1 ,
6774
6841
None ,
6775
6842
Some ( HISTORY_SYNC_URL . to_string ( ) ) ,
6843
+ None ,
6776
6844
)
6777
6845
. await
6778
6846
. unwrap ( ) ;
@@ -6795,6 +6863,7 @@ mod tests {
6795
6863
1 ,
6796
6864
None ,
6797
6865
Some ( HISTORY_SYNC_URL . to_string ( ) ) ,
6866
+ None ,
6798
6867
)
6799
6868
. await
6800
6869
. unwrap ( ) ;
@@ -6814,6 +6883,7 @@ mod tests {
6814
6883
1 ,
6815
6884
None ,
6816
6885
Some ( HISTORY_SYNC_URL . to_string ( ) ) ,
6886
+ None ,
6817
6887
)
6818
6888
. await
6819
6889
. unwrap ( ) ;
@@ -6844,6 +6914,7 @@ mod tests {
6844
6914
1 ,
6845
6915
None ,
6846
6916
Some ( HISTORY_SYNC_URL . to_string ( ) ) ,
6917
+ None ,
6847
6918
)
6848
6919
. await ;
6849
6920
@@ -7345,4 +7416,83 @@ mod tests {
7345
7416
assert_eq ! ( decoded. url, original. url) ;
7346
7417
}
7347
7418
}
7419
+
7420
+ #[ tokio:: test]
7421
+ async fn test_version_info ( ) {
7422
+ let amal_client = new_test_client_with_wallet_and_version_info (
7423
+ generate_local_wallet ( ) ,
7424
+ Some ( "2.0.0" . to_string ( ) ) ,
7425
+ )
7426
+ . await ;
7427
+ assert_eq ! ( amal_client. version_info( ) . await . unwrap( ) , "2.0.0" ) ;
7428
+ let bola_client = new_test_client ( ) . await ;
7429
+ assert_eq ! ( bola_client. version_info( ) . await . unwrap( ) , "1.0.0-rc1" ) ;
7430
+
7431
+ let amal_group = amal_client
7432
+ . conversations ( )
7433
+ . create_group (
7434
+ vec ! [ bola_client. account_identifier. clone( ) ] ,
7435
+ FfiCreateGroupOptions :: default ( ) ,
7436
+ )
7437
+ . await
7438
+ . unwrap ( ) ;
7439
+ let mut buf = Vec :: new ( ) ;
7440
+ TextCodec :: encode ( "hello" . to_string ( ) )
7441
+ . unwrap ( )
7442
+ . encode ( & mut buf)
7443
+ . unwrap ( ) ;
7444
+ amal_group. send ( buf) . await . unwrap ( ) ;
7445
+ amal_group. sync ( ) . await . unwrap ( ) ;
7446
+
7447
+ bola_client
7448
+ . conversations ( )
7449
+ . sync_all_conversations ( None )
7450
+ . await
7451
+ . unwrap ( ) ;
7452
+ let bola_groups = bola_client
7453
+ . conversations ( )
7454
+ . list_groups ( FfiListConversationsOptions :: default ( ) )
7455
+ . unwrap ( ) ;
7456
+ assert_eq ! ( bola_groups. len( ) , 1 ) ;
7457
+ let bola_group = bola_groups[ 0 ] . conversation . clone ( ) ;
7458
+ let messages = bola_group
7459
+ . find_messages ( FfiListMessagesOptions :: default ( ) )
7460
+ . await
7461
+ . unwrap ( ) ;
7462
+ assert_eq ! ( messages. len( ) , 1 ) ;
7463
+ let message = messages[ 0 ] . clone ( ) ;
7464
+ let decoded_content = EncodedContent :: decode ( message. content . as_slice ( ) ) . unwrap ( ) ;
7465
+ assert_eq ! ( TextCodec :: decode( decoded_content) . unwrap( ) , "hello" ) ;
7466
+
7467
+ let paused_for_version = bola_group. paused_for_version ( ) . unwrap ( ) ;
7468
+ assert_eq ! ( paused_for_version, None ) ;
7469
+
7470
+ // Update group min version
7471
+ amal_group
7472
+ . update_group_min_version_to_match_self ( )
7473
+ . await
7474
+ . unwrap ( ) ;
7475
+ amal_group. sync ( ) . await . unwrap ( ) ;
7476
+ bola_group. sync ( ) . await . unwrap ( ) ;
7477
+
7478
+ let paused_for_version = bola_group. paused_for_version ( ) . unwrap ( ) ;
7479
+ assert_eq ! ( paused_for_version, Some ( "2.0.0" . to_string( ) ) ) ;
7480
+
7481
+ // Bola tries to send a message
7482
+ let result = bola_group. send ( vec ! [ ] ) . await ;
7483
+ // This should fail with a GroupPausedUntilUpdate error
7484
+ assert ! ( result. is_err( ) ) ;
7485
+
7486
+ // Check the specific error type and message
7487
+ let error = result. unwrap_err ( ) ;
7488
+ match error {
7489
+ GenericError :: GroupError ( group_error) => {
7490
+ assert_eq ! (
7491
+ group_error. to_string( ) ,
7492
+ "Group is paused until version 2.0.0 is available"
7493
+ ) ;
7494
+ }
7495
+ _ => panic ! ( "Expected GroupError but got: {:?}" , error) ,
7496
+ }
7497
+ }
7348
7498
}
0 commit comments