xmtp_proto/
api_client.rs

1pub use super::xmtp::message_api::v1::{
2    BatchQueryRequest, BatchQueryResponse, Envelope, PublishRequest, PublishResponse, QueryRequest,
3    QueryResponse, SubscribeRequest,
4};
5use crate::api::IsConnectedCheck;
6use crate::mls_v1::{
7    BatchPublishCommitLogRequest, BatchQueryCommitLogRequest, BatchQueryCommitLogResponse,
8    GetNewestGroupMessageRequest, PagingInfo,
9};
10use crate::types::{
11    GroupId, GroupMessage, GroupMessageMetadata, InstallationId, TopicCursor, WelcomeMessage,
12};
13use crate::xmtp::identity::api::v1::{
14    GetIdentityUpdatesRequest as GetIdentityUpdatesV2Request,
15    GetIdentityUpdatesResponse as GetIdentityUpdatesV2Response, GetInboxIdsRequest,
16    GetInboxIdsResponse, PublishIdentityUpdateRequest, PublishIdentityUpdateResponse,
17    VerifySmartContractWalletSignaturesRequest, VerifySmartContractWalletSignaturesResponse,
18};
19use crate::xmtp::mls::api::v1::{
20    FetchKeyPackagesRequest, FetchKeyPackagesResponse, GroupMessage as ProtoGroupMessage,
21    QueryWelcomeMessagesResponse, SendGroupMessagesRequest, SendWelcomeMessagesRequest,
22    UploadKeyPackageRequest, WelcomeMessage as ProtoWelcomeMessage,
23};
24use futures::Stream;
25use std::pin::Pin;
26use std::sync::Arc;
27use xmtp_common::{MaybeSend, MaybeSync};
28use xmtp_common::{Retry, RetryableError};
29
30mod impls;
31mod stats;
32pub use stats::*;
33
34xmtp_common::if_test! {
35    mod tests;
36    pub use tests::*;
37}
38
39/// A type-erased version of the Xmtp Api in a [`Box`]
40pub type BoxedXmtpApi<Error> = Box<dyn BoxableXmtpApi<Error>>;
41/// A type-erased version of the Xntp Api in a [`Arc`]
42pub type ArcedXmtpApi<Error> = Arc<dyn BoxableXmtpApi<Error>>;
43
44xmtp_common::if_native! {
45    pub type BoxedGroupS<Err> = Pin<Box<dyn Stream<Item = Result<GroupMessage, Err>> + Send>>;
46    pub type BoxedWelcomeS<Err> = Pin<Box<dyn Stream<Item = Result<WelcomeMessage, Err>> + Send>>;
47}
48
49xmtp_common::if_wasm! {
50    pub type BoxedGroupS<Err> = Pin<Box<dyn Stream<Item = Result<GroupMessage, Err>>>>;
51    pub type BoxedWelcomeS<Err> = Pin<Box<dyn Stream<Item = Result<WelcomeMessage, Err>>>>;
52}
53
54pub trait BoxableXmtpApi<Err>
55where
56    Self: XmtpMlsClient<Error = Err>
57        + XmtpIdentityClient<Error = Err>
58        + XmtpMlsStreams<
59            Error = Err,
60            WelcomeMessageStream = BoxedWelcomeS<Err>,
61            GroupMessageStream = BoxedGroupS<Err>,
62        > + IsConnectedCheck
63        + MaybeSend
64        + MaybeSync,
65{
66}
67
68impl<T, Err> BoxableXmtpApi<Err> for T where
69    T: XmtpMlsClient<Error = Err>
70        + XmtpIdentityClient<Error = Err>
71        + XmtpMlsStreams<
72            Error = Err,
73            WelcomeMessageStream = BoxedWelcomeS<Err>,
74            GroupMessageStream = BoxedGroupS<Err>,
75        > + IsConnectedCheck
76        + MaybeSend
77        + MaybeSync
78        + ?Sized
79{
80}
81
82pub trait XmtpApi
83where
84    Self: XmtpMlsClient + XmtpIdentityClient,
85{
86}
87
88impl<T> XmtpApi for T where T: XmtpMlsClient + XmtpIdentityClient + ?Sized {}
89
90/// Trait which for protobuf-generated type
91/// which can be paged.
92/// Paged implementation indicates a response
93/// that returns a collection of envelopes
94pub trait Paged: MaybeSend + MaybeSync {
95    type Message: MaybeSend + MaybeSync;
96    fn info(&self) -> &Option<PagingInfo>;
97    fn messages(self) -> Vec<Self::Message>;
98}
99
100/// Represents the backend API required for an MLS Delivery Service
101/// to be compatible with XMTP
102#[xmtp_common::async_trait]
103pub trait XmtpMlsClient: MaybeSend + MaybeSync {
104    type Error: RetryableError + MaybeSend + MaybeSync + 'static;
105    async fn upload_key_package(&self, request: UploadKeyPackageRequest)
106    -> Result<(), Self::Error>;
107    async fn fetch_key_packages(
108        &self,
109        request: FetchKeyPackagesRequest,
110    ) -> Result<FetchKeyPackagesResponse, Self::Error>;
111    async fn send_group_messages(
112        &self,
113        request: SendGroupMessagesRequest,
114    ) -> Result<(), Self::Error>;
115    async fn send_welcome_messages(
116        &self,
117        request: SendWelcomeMessagesRequest,
118    ) -> Result<(), Self::Error>;
119    async fn query_group_messages(
120        &self,
121        group_id: crate::types::GroupId,
122    ) -> Result<Vec<GroupMessage>, Self::Error>;
123    async fn query_latest_group_message(
124        &self,
125        group_id: crate::types::GroupId,
126    ) -> Result<Option<GroupMessage>, Self::Error>;
127    async fn query_welcome_messages(
128        &self,
129        installation_key: InstallationId,
130    ) -> Result<Vec<WelcomeMessage>, Self::Error>;
131    async fn publish_commit_log(
132        &self,
133        request: BatchPublishCommitLogRequest,
134    ) -> Result<(), Self::Error>;
135    async fn query_commit_log(
136        &self,
137        request: BatchQueryCommitLogRequest,
138    ) -> Result<BatchQueryCommitLogResponse, Self::Error>;
139    async fn get_newest_group_message(
140        &self,
141        request: GetNewestGroupMessageRequest,
142    ) -> Result<Vec<Option<GroupMessageMetadata>>, Self::Error>;
143}
144
145/// Represents the backend API required for an MLS Delivery Service
146/// to be compatible with XMTP streaming
147#[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_group_messages(
156        &self,
157        group_ids: &[&GroupId],
158    ) -> Result<Self::GroupMessageStream, Self::Error>;
159    async fn subscribe_group_messages_with_cursors(
160        &self,
161        groups_with_cursors: &TopicCursor,
162    ) -> Result<Self::GroupMessageStream, Self::Error>;
163    async fn subscribe_welcome_messages(
164        &self,
165        installations: &[&InstallationId],
166    ) -> Result<Self::WelcomeMessageStream, Self::Error>;
167}
168
169/// Represents the backend API required for the XMTP
170/// Identity Service described by [XIP-46 Multi-Wallet Identity](https://github.com/xmtp/XIPs/blob/main/XIPs/xip-46-multi-wallet-identity.md)
171#[xmtp_common::async_trait]
172pub trait XmtpIdentityClient: MaybeSend + MaybeSync {
173    type Error: RetryableError + MaybeSend + MaybeSync + 'static;
174    async fn publish_identity_update(
175        &self,
176        request: PublishIdentityUpdateRequest,
177    ) -> Result<PublishIdentityUpdateResponse, Self::Error>;
178
179    async fn get_identity_updates_v2(
180        &self,
181        request: GetIdentityUpdatesV2Request,
182    ) -> Result<GetIdentityUpdatesV2Response, Self::Error>;
183
184    async fn get_inbox_ids(
185        &self,
186        request: GetInboxIdsRequest,
187    ) -> Result<GetInboxIdsResponse, Self::Error>;
188
189    async fn verify_smart_contract_wallet_signatures(
190        &self,
191        request: VerifySmartContractWalletSignaturesRequest,
192    ) -> Result<VerifySmartContractWalletSignaturesResponse, Self::Error>;
193}
194
195/// describe how to create a single network
196/// connection.
197/// Implement this trait if your type connects to a single
198/// network channel/connection (like gRPc or HTTP)
199pub trait NetConnectConfig: ApiBuilder + MaybeSend + MaybeSync {
200    /// set the libxmtp version (required)
201    fn set_libxmtp_version(&mut self, version: String) -> Result<(), Self::Error>;
202
203    /// set the sdk app version (required)
204    fn set_app_version(&mut self, version: crate::types::AppVersion) -> Result<(), Self::Error>;
205
206    /// Set the libxmtp host (required)
207    fn set_host(&mut self, host: String);
208
209    /// indicate tls (default: false)
210    fn set_tls(&mut self, tls: bool);
211
212    /// Set the retry strategy for this client
213    fn set_retry(&mut self, retry: Retry);
214
215    /// Set the rate limit per minute for this client
216    fn rate_per_minute(&mut self, limit: u32);
217
218    /// The port this api builder is using
219    fn port(&self) -> Result<Option<String>, Self::Error>;
220
221    /// Host of the builder
222    fn host(&self) -> Option<&str>;
223}
224
225/// Build an API from its parts for the XMTP Backend
226pub trait ApiBuilder: MaybeSend + MaybeSync {
227    type Output: MaybeSend + MaybeSync;
228    type Error: MaybeSend + MaybeSync + std::fmt::Debug;
229    /// Build the api client
230    fn build(self) -> Result<Self::Output, Self::Error>;
231}