xmtp_api_d14n/protocol/extractors/
identity_updates.rs

1use xmtp_proto::identity_v1::get_identity_updates_response::IdentityUpdateLog;
2
3use crate::protocol::traits::EnvelopeVisitor;
4use crate::protocol::{Extractor, PayloadExtractionError};
5use xmtp_proto::xmtp::identity::associations::IdentityUpdate;
6use xmtp_proto::xmtp::xmtpv4::envelopes::UnsignedOriginatorEnvelope;
7
8/// Extract Identity Updates from Envelopes
9#[derive(Default)]
10pub struct IdentityUpdateExtractor {
11    originator_node_id: u32,
12    originator_sequence_id: u64,
13    server_timestamp_ns: u64,
14    update: IdentityUpdate,
15}
16
17impl Extractor for IdentityUpdateExtractor {
18    type Output = (String, IdentityUpdateLog);
19
20    fn get(self) -> Self::Output {
21        (
22            self.update.inbox_id.clone(),
23            IdentityUpdateLog {
24                sequence_id: self.originator_sequence_id,
25                server_timestamp_ns: self.server_timestamp_ns,
26                update: Some(self.update),
27            },
28        )
29    }
30}
31
32/// extract an update from a single envelope
33impl IdentityUpdateExtractor {
34    pub fn new() -> Self {
35        Self::default()
36    }
37}
38
39impl EnvelopeVisitor<'_> for IdentityUpdateExtractor {
40    type Error = PayloadExtractionError; // mostly is infallible
41
42    fn visit_unsigned_originator(
43        &mut self,
44        envelope: &UnsignedOriginatorEnvelope,
45    ) -> Result<(), Self::Error> {
46        self.originator_node_id = envelope.originator_node_id;
47        self.originator_sequence_id = envelope.originator_sequence_id;
48        self.server_timestamp_ns = envelope.originator_ns as u64;
49        Ok(())
50    }
51
52    fn visit_identity_update(&mut self, u: &IdentityUpdate) -> Result<(), Self::Error> {
53        self.update = u.clone();
54        Ok(())
55    }
56}
57
58#[cfg(test)]
59mod tests {
60    use super::*;
61    use crate::protocol::ProtocolEnvelope;
62    use crate::protocol::extractors::test_utils::*;
63
64    #[xmtp_common::test]
65    fn test_extract_identity_update() {
66        let inbox_id = "test_inbox_id".to_string();
67        let envelope = TestEnvelopeBuilder::new()
68            .with_identity_update_custom(inbox_id.clone())
69            .build();
70        let mut extractor = IdentityUpdateExtractor::new();
71        envelope.accept(&mut extractor).unwrap();
72        let (extracted_inbox_id, log) = extractor.get();
73        assert_eq!(extracted_inbox_id, inbox_id);
74        assert_eq!(log.sequence_id, 0);
75        assert_eq!(log.server_timestamp_ns, 0);
76        assert!(log.update.is_some());
77        assert_eq!(log.update.unwrap().inbox_id, inbox_id);
78    }
79}