1use crate::api::IsConnectedCheck;
2pub use crate::backend_v1::{
3 GetConfigurationRequest, GetConfigurationResponse, GetInboxIdsRequest, GetInboxIdsResponse,
4 PublishRequest, PublishResponse, QueryNewestRequest, QueryNewestResponse, QueryRequest,
5 QueryResponse, RecipientState, RegisterRequest, ServerEnvelope, UnregisterRequest,
6 UnregisterResponse, UpdateSubscriptionsRequest, VerifySmartContractWalletSignaturesRequest,
7 VerifySmartContractWalletSignaturesResponse,
8};
9use crate::types::{
10 GroupId, GroupMessage, IncomingBatchLimits, IncomingEvent, IncomingSubscription,
11 InstallationId, 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::backend_v1::SubscribeResponse, 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 async fn publish(&self, request: PublishRequest) -> Result<PublishResponse, Self::Error>;
87 async fn query(&self, request: QueryRequest) -> Result<QueryResponse, Self::Error>;
88 async fn query_newest(
89 &self,
90 request: QueryNewestRequest,
91 ) -> Result<QueryNewestResponse, Self::Error>;
92 async fn get_inbox_ids(
93 &self,
94 request: GetInboxIdsRequest,
95 ) -> Result<GetInboxIdsResponse, Self::Error>;
96 async fn get_configuration(
100 &self,
101 request: GetConfigurationRequest,
102 ) -> Result<GetConfigurationResponse, Self::Error>;
103
104 fn backend_url(&self) -> Option<&str> {
111 None
112 }
113
114 fn has_credential_source(&self) -> bool {
120 true
121 }
122
123 fn set_limits(&self, limits: std::sync::Arc<xmtp_configuration::LimitsConfiguration>) {
128 let _ = limits;
129 }
130 async fn verify_smart_contract_wallet_signatures(
131 &self,
132 request: VerifySmartContractWalletSignaturesRequest,
133 ) -> Result<VerifySmartContractWalletSignaturesResponse, Self::Error>;
134 async fn register(&self, request: RegisterRequest) -> Result<RecipientState, Self::Error>;
135 async fn unregister(
136 &self,
137 request: UnregisterRequest,
138 ) -> Result<UnregisterResponse, Self::Error>;
139 async fn update_subscriptions(
140 &self,
141 request: UpdateSubscriptionsRequest,
142 ) -> Result<RecipientState, Self::Error>;
143}
144
145#[xmtp_common::async_trait]
148pub trait XmtpMlsStreams: MaybeSend + MaybeSync {
149 type GroupMessageStream: Stream<Item = Result<GroupMessage, Self::Error>> + MaybeSend;
150
151 type WelcomeMessageStream: Stream<Item = Result<WelcomeMessage, Self::Error>> + MaybeSend;
152
153 type Error: RetryableError + 'static;
154
155 async fn subscribe_envelopes_with_cursors(
158 &self,
159 cursors: &TopicCursor,
160 limits: IncomingBatchLimits,
161 ) -> Result<IncomingSubscription<Self::Error>, Self::Error>;
162
163 async fn subscribe_group_messages(
164 &self,
165 group_ids: &[&GroupId],
166 ) -> Result<Self::GroupMessageStream, Self::Error>;
167 async fn subscribe_group_messages_with_cursors(
168 &self,
169 groups_with_cursors: &TopicCursor,
170 ) -> Result<Self::GroupMessageStream, Self::Error>;
171 async fn subscribe_welcome_messages(
172 &self,
173 installations: &[&InstallationId],
174 ) -> Result<Self::WelcomeMessageStream, Self::Error>;
175 async fn subscribe_welcome_messages_with_cursors(
176 &self,
177 cursors: &TopicCursor,
178 ) -> Result<Self::WelcomeMessageStream, Self::Error>;
179}
180
181xmtp_common::if_native! {
182 #[xmtp_common::async_trait]
188 pub trait XmtpMlsBidiStreams: MaybeSend + MaybeSync {
189 type SubscribeStream: Stream<Item = Result<crate::backend_v1::SubscribeResponse, Self::Error>>
190 + MaybeSend;
191
192 type Error: RetryableError + 'static;
193
194 fn bidi_limits(&self) -> std::sync::Arc<xmtp_configuration::LimitsConfiguration> {
200 std::sync::Arc::default()
201 }
202
203 fn host(&self) -> &str;
206
207 async fn subscribe_bidi(
212 &self,
213 requests: futures::stream::BoxStream<'static, crate::backend_v1::SubscribeRequest>,
214 ) -> Result<Self::SubscribeStream, Self::Error>;
215 }
216}
217
218pub trait NetConnectConfig: ApiBuilder + MaybeSend + MaybeSync {
223 fn set_libxmtp_version(&mut self, version: String) -> Result<(), Self::Error>;
225
226 fn set_app_version(&mut self, version: crate::types::AppVersion) -> Result<(), Self::Error>;
228
229 fn set_host(&mut self, host: url::Url);
231
232 fn set_retry(&mut self, retry: Retry);
234
235 fn rate_per_minute(&mut self, limit: u32);
237
238 fn port(&self) -> Result<Option<String>, Self::Error>;
240
241 fn host(&self) -> Option<&str>;
243}
244
245pub trait ApiBuilder: MaybeSend + MaybeSync {
247 type Output: MaybeSend + MaybeSync;
248 type Error: MaybeSend + MaybeSync + std::fmt::Debug;
249 fn build(self) -> Result<Self::Output, Self::Error>;
251}