xmtp_api_d14n/protocol/
traits.rs

1//! Traits to implement functionality according to
2//! <https://github.com/xmtp/XIPs/blob/main/XIPs/xip-49-decentralized-backend.md#33-client-to-node-protocol>
3
4use crate::protocol::GroupMessageExtractor;
5use crate::protocol::SequencedExtractor;
6use crate::protocol::V3GroupMessageExtractor;
7use crate::protocol::V3WelcomeMessageExtractor;
8use crate::protocol::WelcomeMessageExtractor;
9use derive_builder::UninitializedFieldError;
10use itertools::Itertools;
11use xmtp_proto::types::GlobalCursor;
12use xmtp_proto::types::GroupMessage;
13use xmtp_proto::types::Topic;
14use xmtp_proto::types::WelcomeMessage;
15
16use super::ExtractionError;
17use super::PayloadExtractor;
18use super::TopicExtractor;
19use xmtp_common::RetryableError;
20use xmtp_common::retryable;
21use xmtp_proto::ConversionError;
22use xmtp_proto::xmtp::xmtpv4::envelopes::AuthenticatedData;
23use xmtp_proto::xmtp::xmtpv4::envelopes::ClientEnvelope;
24use xmtp_proto::xmtp::xmtpv4::envelopes::client_envelope::Payload;
25
26mod visitor;
27pub use visitor::*;
28
29mod cursor_store;
30pub use cursor_store::*;
31
32mod envelopes;
33pub use envelopes::*;
34
35mod xmtp_query;
36pub use xmtp_query::*;
37
38mod extractor;
39pub use extractor::*;
40
41mod envelope_collection;
42pub use envelope_collection::*;
43
44mod full_api;
45pub use full_api::*;
46
47mod dependency_resolution;
48pub use dependency_resolution::*;
49
50mod sort;
51pub use sort::*;
52
53mod ordered_collection;
54pub use ordered_collection::*;
55
56#[derive(thiserror::Error, Debug)]
57pub enum EnvelopeError {
58    #[error(transparent)]
59    Conversion(#[from] ConversionError),
60    #[error(transparent)]
61    Extraction(#[from] ExtractionError),
62    #[error("Each topic must have a payload")]
63    TopicMismatch,
64    #[error("Envelope not found")]
65    NotFound(&'static str),
66    #[error(transparent)]
67    MissingBuilderField(#[from] UninitializedFieldError),
68    #[error(transparent)]
69    Store(#[from] CursorStoreError),
70    #[error(transparent)]
71    Decode(#[from] prost::DecodeError),
72    // for extractors defined outside of this crate or
73    // generic implementations like Tuples
74    #[error("{0}")]
75    DynError(Box<dyn RetryableError>),
76}
77
78impl EnvelopeError {
79    pub fn other(self) -> Self {
80        EnvelopeError::DynError(Box::new(self) as _)
81    }
82}
83
84impl RetryableError for EnvelopeError {
85    fn is_retryable(&self) -> bool {
86        match self {
87            Self::Conversion(c) => retryable!(c),
88            Self::Extraction(e) => retryable!(e),
89            Self::TopicMismatch => false,
90            Self::DynError(d) => retryable!(d),
91            Self::NotFound(_) => false,
92            Self::MissingBuilderField(_) => false,
93            Self::Store(s) => retryable!(s),
94            Self::Decode(_) => true,
95        }
96    }
97}