xmtp_mls/groups/
welcome_pointer.rs1use super::GroupError;
2use xmtp_common::{Retry, retry_async};
3use xmtp_proto::{
4 types::{DecryptedWelcomePointer, WelcomeMessageType, WelcomeMessageV1},
5 xmtp::mls::message_contents::WelcomeWrapperAlgorithm,
6};
7
8pub async fn resolve_welcome_pointer<Context: crate::context::XmtpSharedContext>(
10 decrypted_welcome_pointer: &DecryptedWelcomePointer,
11 context: &Context,
12) -> Result<Option<WelcomeMessageV1>, GroupError> {
13 let retry = Retry::default();
14 let mut retries = 0;
15 let time_spent = xmtp_common::time::Instant::now();
16
17 let decrypted_v1 = decrypted_welcome_pointer;
18
19 tracing::debug!(
20 "Resolving welcome pointer for destination {}",
21 decrypted_v1.destination
22 );
23
24 let welcome = loop {
26 let welcome = retry_async!(
27 Retry::default(),
28 (context
29 .api()
30 .query_welcome_messages(decrypted_v1.destination.as_slice()))
32 );
33 if let Some(first) = welcome?.into_iter().next() {
34 break first;
35 }
36 retries += 1;
37 if retries <= retry.retries()
38 && let Some(d) = retry.backoff(retries, time_spent)
39 {
40 tracing::info!(
41 "Welcome pointee not found, backing off for {d:?}... (attempt {})",
42 retries
43 );
44 xmtp_common::time::sleep(d).await;
45 } else {
46 return Ok(None);
47 }
48 };
49 match welcome.variant {
52 WelcomeMessageType::V1(v1)
55 if v1.wrapper_algorithm == WelcomeWrapperAlgorithm::SymmetricKey =>
56 {
57 Ok(Some(v1))
58 }
59 WelcomeMessageType::V1(v1) => Err(xmtp_proto::ConversionError::InvalidValue {
60 item: "WelcomePointee.wrapper_algorithm",
61 expected: "SymmetricKey",
62 got: format!("{:?}", v1.wrapper_algorithm),
63 }
64 .into()),
65 WelcomeMessageType::WelcomePointer(_) => {
66 tracing::warn!("Got Another welcome pointer from a welcome pointer. Ignoring.");
67 Err(xmtp_proto::ConversionError::InvalidValue {
68 item: "WelcomeMessage.version",
69 expected: "V1",
70 got: "WelcomePointer".into(),
71 }
72 .into())
73 }
74 }
75}