1use crate::api::IsConnectedCheck;
2pub use crate::backend_v1::{
3 CreateUploadRequest, CreateUploadResponse, GetConfigurationRequest, GetConfigurationResponse,
4 GetInboxIdsRequest, GetInboxIdsResponse, PublishRequest, PublishResponse, QueryNewestRequest,
5 QueryNewestResponse, QueryRequest, QueryResponse, RecipientState, RegisterRequest,
6 ServerEnvelope, UnregisterRequest, UnregisterResponse, UpdateSubscriptionsRequest,
7 VerifySmartContractWalletSignaturesRequest, VerifySmartContractWalletSignaturesResponse,
8};
9use crate::types::{
10 GroupId, GroupMessage, IncomingBatchLimits, IncomingEvent, IncomingSubscription,
11 InstallationId, ReceivedQueryResponse, TopicCursor, WelcomeMessage,
12};
13use futures::Stream;
14use std::pin::Pin;
15use std::sync::Arc;
16use xmtp_common::{MaybeSend, MaybeSync};
17use xmtp_common::{Retry, RetryableError};
18
19mod impls;
20mod stats;
21pub use stats::*;
22
23xmtp_common::if_test! {
24 mod tests;
25 pub use tests::*;
26}
27
28pub type BoxedXmtpApi<Error> = Box<dyn BoxableXmtpApi<Error>>;
30pub type ArcedXmtpApi<Error> = Arc<dyn BoxableXmtpApi<Error>>;
32
33pub type BoxedIncomingS<Err> = xmtp_common::BoxDynStream<'static, Result<IncomingEvent, Err>>;
35
36xmtp_common::if_native! {
37 pub type BoxedGroupS<Err> = Pin<Box<dyn Stream<Item = Result<GroupMessage, Err>> + Send>>;
38 pub type BoxedWelcomeS<Err> = Pin<Box<dyn Stream<Item = Result<WelcomeMessage, Err>> + Send>>;
39 pub type BoxedSubscribeS<Err> =
40 Pin<Box<dyn Stream<Item = Result<crate::types::ReceivedSubscribeResponse, Err>> + Send>>;
41}
42
43xmtp_common::if_wasm! {
44 pub type BoxedGroupS<Err> = Pin<Box<dyn Stream<Item = Result<GroupMessage, Err>>>>;
45 pub type BoxedWelcomeS<Err> = Pin<Box<dyn Stream<Item = Result<WelcomeMessage, Err>>>>;
46}
47
48pub trait BoxableXmtpApi<Err>
49where
50 Self: XmtpBackendClient<Error = Err>
51 + XmtpMlsStreams<
52 Error = Err,
53 WelcomeMessageStream = BoxedWelcomeS<Err>,
54 GroupMessageStream = BoxedGroupS<Err>,
55 > + IsConnectedCheck
56 + MaybeSend
57 + MaybeSync,
58{
59}
60
61impl<T, Err> BoxableXmtpApi<Err> for T where
62 T: XmtpBackendClient<Error = Err>
63 + XmtpMlsStreams<
64 Error = Err,
65 WelcomeMessageStream = BoxedWelcomeS<Err>,
66 GroupMessageStream = BoxedGroupS<Err>,
67 > + IsConnectedCheck
68 + MaybeSend
69 + MaybeSync
70 + ?Sized
71{
72}
73
74pub trait XmtpApi
75where
76 Self: XmtpBackendClient,
77{
78}
79
80impl<T> XmtpApi for T where T: XmtpBackendClient + ?Sized {}
81
82#[xmtp_common::async_trait]
84pub trait XmtpBackendClient: MaybeSend + MaybeSync {
85 type Error: RetryableError + MaybeSend + MaybeSync + 'static;
86 fn register_client_event_writer(&self, _writer: &Arc<dyn xmtp_events::EventWriter<()>>) {}
88 fn unregister_client_event_writer(&self, _writer: &Arc<dyn xmtp_events::EventWriter<()>>) {}
89 async fn publish(&self, request: PublishRequest) -> Result<PublishResponse, Self::Error>;
90 async fn create_upload(
91 &self,
92 request: CreateUploadRequest,
93 ) -> Result<CreateUploadResponse, Self::Error>;
94 async fn query(&self, request: QueryRequest) -> Result<QueryResponse, Self::Error>;
95 async fn query_raw_envelopes(
97 &self,
98 request: QueryRequest,
99 ) -> Result<ReceivedQueryResponse, Self::Error>;
100 async fn query_newest(
101 &self,
102 request: QueryNewestRequest,
103 ) -> Result<QueryNewestResponse, Self::Error>;
104 async fn get_inbox_ids(
105 &self,
106 request: GetInboxIdsRequest,
107 ) -> Result<GetInboxIdsResponse, Self::Error>;
108 async fn get_configuration(
112 &self,
113 request: GetConfigurationRequest,
114 ) -> Result<GetConfigurationResponse, Self::Error>;
115
116 fn backend_url(&self) -> Option<&str> {
123 None
124 }
125
126 fn has_credential_source(&self) -> bool {
132 true
133 }
134
135 fn set_limits(&self, limits: std::sync::Arc<xmtp_configuration::LimitsConfiguration>) {
140 let _ = limits;
141 }
142 async fn verify_smart_contract_wallet_signatures(
143 &self,
144 request: VerifySmartContractWalletSignaturesRequest,
145 ) -> Result<VerifySmartContractWalletSignaturesResponse, Self::Error>;
146 async fn register(&self, request: RegisterRequest) -> Result<RecipientState, Self::Error>;
147 async fn unregister(
148 &self,
149 request: UnregisterRequest,
150 ) -> Result<UnregisterResponse, Self::Error>;
151 async fn update_subscriptions(
152 &self,
153 request: UpdateSubscriptionsRequest,
154 ) -> Result<RecipientState, Self::Error>;
155}
156
157#[xmtp_common::async_trait]
160pub trait XmtpMlsStreams: MaybeSend + MaybeSync {
161 type GroupMessageStream: Stream<Item = Result<GroupMessage, Self::Error>> + MaybeSend;
162
163 type WelcomeMessageStream: Stream<Item = Result<WelcomeMessage, Self::Error>> + MaybeSend;
164
165 type Error: RetryableError + 'static;
166
167 async fn subscribe_envelopes_with_cursors(
170 &self,
171 cursors: &TopicCursor,
172 limits: IncomingBatchLimits,
173 ) -> Result<IncomingSubscription<Self::Error>, Self::Error>;
174
175 async fn subscribe_group_messages(
176 &self,
177 group_ids: &[&GroupId],
178 ) -> Result<Self::GroupMessageStream, Self::Error>;
179 async fn subscribe_group_messages_with_cursors(
180 &self,
181 groups_with_cursors: &TopicCursor,
182 ) -> Result<Self::GroupMessageStream, Self::Error>;
183 async fn subscribe_welcome_messages(
184 &self,
185 installations: &[&InstallationId],
186 ) -> Result<Self::WelcomeMessageStream, Self::Error>;
187 async fn subscribe_welcome_messages_with_cursors(
188 &self,
189 cursors: &TopicCursor,
190 ) -> Result<Self::WelcomeMessageStream, Self::Error>;
191}
192
193xmtp_common::if_native! {
194 #[xmtp_common::async_trait]
200 pub trait XmtpMlsBidiStreams: MaybeSend + MaybeSync {
201 type SubscribeStream: Stream<Item = Result<crate::types::ReceivedSubscribeResponse, Self::Error>>
203 + MaybeSend;
204
205 type Error: RetryableError + 'static;
206
207 fn bidi_limits(&self) -> std::sync::Arc<xmtp_configuration::LimitsConfiguration> {
213 std::sync::Arc::default()
214 }
215
216 fn host(&self) -> &str;
219
220 async fn subscribe_bidi(
225 &self,
226 requests: futures::stream::BoxStream<'static, crate::backend_v1::SubscribeRequest>,
227 ) -> Result<Self::SubscribeStream, Self::Error>;
228 }
229}
230
231pub trait NetConnectConfig: ApiBuilder + MaybeSend + MaybeSync {
236 fn set_libxmtp_version(&mut self, version: String) -> Result<(), Self::Error>;
238
239 fn set_app_version(&mut self, version: crate::types::AppVersion) -> Result<(), Self::Error>;
241
242 fn set_host(&mut self, host: url::Url);
244
245 fn set_retry(&mut self, retry: Retry);
247
248 fn rate_per_minute(&mut self, limit: u32);
250
251 fn port(&self) -> Result<Option<String>, Self::Error>;
253
254 fn host(&self) -> Option<&str>;
256}
257
258pub trait ApiBuilder: MaybeSend + MaybeSync {
260 type Output: MaybeSend + MaybeSync;
261 type Error: MaybeSend + MaybeSync + std::fmt::Debug;
262 fn build(self) -> Result<Self::Output, Self::Error>;
264}