nym_sdk/mixnet/
traits.rs

1// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::mixnet::{AnonymousSenderTag, IncludedSurbs, Recipient};
5use crate::Result;
6use async_trait::async_trait;
7use nym_client_core::client::inbound_messages::InputMessage;
8use nym_sphinx::params::PacketType;
9use nym_task::connections::TransmissionLane;
10
11// defined to guarantee common interface regardless of whether you're using the full client
12// or just the sending handler
13#[async_trait]
14pub trait MixnetMessageSender {
15    fn packet_type(&self) -> Option<PacketType> {
16        None
17    }
18
19    /// Sends a [`InputMessage`] to the mixnet. This is the most low-level sending function, for
20    /// full customization.
21    async fn send(&self, message: InputMessage) -> Result<()>;
22
23    /// Sends data to the supplied Nym address with the default surb behaviour.
24    ///
25    /// # Example
26    ///
27    /// ```no_run
28    /// use nym_sdk::mixnet::{self, MixnetMessageSender};
29    ///
30    /// #[tokio::main]
31    /// async fn main() {
32    ///     let address = "foobar";
33    ///     let recipient = mixnet::Recipient::try_from_base58_string(address).unwrap();
34    ///     let mut client = mixnet::MixnetClient::connect_new().await.unwrap();
35    ///     client.send_plain_message(recipient, "hi").await.unwrap();
36    /// }
37    /// ```
38    async fn send_plain_message<M>(&self, address: Recipient, message: M) -> Result<()>
39    where
40        M: AsRef<[u8]> + Send,
41    {
42        self.send_message(address, message, IncludedSurbs::default())
43            .await
44    }
45
46    /// Sends bytes to the supplied Nym address. There is the option to specify the number of
47    /// reply-SURBs to include.
48    ///
49    /// # Example
50    ///
51    /// ```no_run
52    /// use nym_sdk::mixnet::{self, MixnetMessageSender};
53    ///
54    /// #[tokio::main]
55    /// async fn main() {
56    ///     let address = "foobar";
57    ///     let recipient = mixnet::Recipient::try_from_base58_string(address).unwrap();
58    ///     let mut client = mixnet::MixnetClient::connect_new().await.unwrap();
59    ///     let surbs = mixnet::IncludedSurbs::default();
60    ///     client.send_message(recipient, "hi".to_owned().into_bytes(), surbs).await.unwrap();
61    /// }
62    /// ```
63    async fn send_message<M>(
64        &self,
65        address: Recipient,
66        message: M,
67        surbs: IncludedSurbs,
68    ) -> Result<()>
69    where
70        M: AsRef<[u8]> + Send,
71    {
72        let lane = TransmissionLane::General;
73        let input_msg = match surbs {
74            IncludedSurbs::Amount(surbs) => InputMessage::new_anonymous(
75                address,
76                message.as_ref().to_vec(),
77                surbs,
78                lane,
79                self.packet_type(),
80            ),
81            IncludedSurbs::ExposeSelfAddress => InputMessage::new_regular(
82                address,
83                message.as_ref().to_vec(),
84                lane,
85                self.packet_type(),
86            ),
87        };
88        self.send(input_msg).await
89    }
90
91    /// Sends reply data to the supplied anonymous recipient.
92    ///
93    /// # Example
94    ///
95    /// ```no_run
96    /// use nym_sdk::mixnet::{self, MixnetMessageSender};
97    ///
98    /// #[tokio::main]
99    /// async fn main() {
100    ///     let mut client = mixnet::MixnetClient::connect_new().await.unwrap();
101    ///     // note: the tag is something you would have received from a remote client sending you surbs!
102    ///     let tag = mixnet::AnonymousSenderTag::try_from_base58_string("foobar").unwrap();
103    ///     client.send_reply(tag, b"hi").await.unwrap();
104    /// }
105    /// ```
106    async fn send_reply<M>(&self, recipient_tag: AnonymousSenderTag, message: M) -> Result<()>
107    where
108        M: AsRef<[u8]> + Send,
109    {
110        let lane = TransmissionLane::General;
111        let input_msg = InputMessage::new_reply(
112            recipient_tag,
113            message.as_ref().to_vec(),
114            lane,
115            self.packet_type(),
116        );
117        self.send(input_msg).await
118    }
119}