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}