xmtp_api_d14n/endpoints/d14n/
publish_client_envelopes.rs

1use derive_builder::Builder;
2use prost::Message;
3use prost::bytes::Bytes;
4use std::borrow::Cow;
5use xmtp_proto::api::{BodyError, Endpoint};
6use xmtp_proto::xmtp::xmtpv4::envelopes::ClientEnvelope;
7use xmtp_proto::xmtp::xmtpv4::payer_api::{
8    PublishClientEnvelopesRequest, PublishClientEnvelopesResponse,
9};
10
11#[derive(Debug, Builder, Default)]
12#[builder(setter(strip_option), build_fn(error = "BodyError"))]
13pub struct PublishClientEnvelopes {
14    #[builder(setter(each(name = "envelope", into)))]
15    envelopes: Vec<ClientEnvelope>,
16}
17
18impl PublishClientEnvelopes {
19    pub fn builder() -> PublishClientEnvelopesBuilder {
20        Default::default()
21    }
22}
23
24impl Endpoint for PublishClientEnvelopes {
25    type Output = PublishClientEnvelopesResponse;
26    fn grpc_endpoint(&self) -> Cow<'static, str> {
27        xmtp_proto::path_and_query::<PublishClientEnvelopesRequest>()
28    }
29
30    fn body(&self) -> Result<Bytes, BodyError> {
31        Ok(PublishClientEnvelopesRequest {
32            envelopes: self.envelopes.clone(),
33        }
34        .encode_to_vec()
35        .into())
36    }
37}
38
39#[cfg(test)]
40mod test {
41    use xmtp_proto::types::Topic;
42
43    use super::*;
44    use xmtp_api_grpc::{error::GrpcError, test::GatewayClient};
45    use xmtp_common::rand_vec;
46    use xmtp_proto::{
47        api,
48        prelude::*,
49        xmtp::xmtpv4::envelopes::{AuthenticatedData, client_envelope::Payload},
50    };
51
52    #[xmtp_common::test]
53    fn test_file_descriptor() {
54        use xmtp_proto::xmtp::xmtpv4::payer_api::PublishClientEnvelopesRequest;
55
56        let pnq = xmtp_proto::path_and_query::<PublishClientEnvelopesRequest>();
57        println!("{}", pnq);
58    }
59
60    #[xmtp_common::test]
61    fn test_grpc_endpoint_returns_correct_path() {
62        let endpoint = PublishClientEnvelopes::default();
63        assert_eq!(
64            endpoint.grpc_endpoint(),
65            "/xmtp.xmtpv4.payer_api.PayerApi/PublishClientEnvelopes"
66        );
67    }
68
69    #[xmtp_common::test]
70    async fn test_publish_client_envelopes() {
71        use xmtp_proto::xmtp::xmtpv4::envelopes::ClientEnvelope;
72
73        let client = GatewayClient::create();
74        let client = client.build().unwrap();
75
76        let aad = AuthenticatedData {
77            target_topic: Topic::new_group_message(rand_vec::<16>()).into(),
78            depends_on: None,
79        };
80        let e = ClientEnvelope {
81            aad: Some(aad),
82            payload: Some(Payload::GroupMessage(Default::default())),
83        };
84        let endpoint = PublishClientEnvelopes::builder()
85            .envelopes(vec![e])
86            .build()
87            .unwrap();
88
89        let err = api::ignore(endpoint).query(&client).await.unwrap_err();
90        // tracing::info!("{}", err);
91        // the request will fail b/c we're using dummy data but
92        // we just care if the endpoint is working
93        match err {
94            ApiClientError::<GrpcError>::ClientWithEndpoint {
95                source: GrpcError::Status(ref s),
96                ..
97            } => {
98                assert!(
99                    s.message().contains("invalid payload")
100                        || s.message().contains("invalid topic"),
101                    "{}",
102                    err
103                );
104            }
105            _ => panic!("request failed"),
106        }
107    }
108}