sphinx_packet/packet/
builder.rs1use crate::version::Version;
2use crate::{
3 header::{delays::Delay, SphinxHeader},
4 payload::Payload,
5 route::{Destination, Node},
6 Result, SphinxPacket,
7};
8use x25519_dalek::StaticSecret;
9
10pub const DEFAULT_PAYLOAD_SIZE: usize = 1024;
11
12pub struct SphinxPacketBuilder<'a> {
13 payload_size: usize,
14 initial_secret: Option<&'a StaticSecret>,
15 version: Version,
16}
17
18impl<'a> SphinxPacketBuilder<'a> {
19 pub fn new() -> Self {
20 Self::default()
21 }
22
23 #[must_use]
24 pub fn with_version(mut self, version: Version) -> Self {
25 self.version = version;
26 self
27 }
28
29 #[must_use]
30 pub fn with_payload_size(mut self, payload_size: usize) -> Self {
31 self.payload_size = payload_size;
32 self
33 }
34
35 #[must_use]
36 pub fn with_initial_secret(mut self, initial_secret: &'a StaticSecret) -> Self {
37 self.initial_secret = Some(initial_secret);
38 self
39 }
40
41 pub fn build_packet<M: AsRef<[u8]>>(
42 &self,
43 message: M,
44 route: &[Node],
45 destination: &Destination,
46 delays: &[Delay],
47 ) -> Result<SphinxPacket> {
48 let initial_secret = match self.initial_secret.as_ref() {
49 Some(initial_secret) => initial_secret,
50 None => &StaticSecret::random(),
51 };
52
53 let built_header =
54 SphinxHeader::new_versioned(initial_secret, route, delays, destination, self.version);
55
56 let payload_keys = built_header.derive_payload_keys();
57 let header = built_header.into_header();
58
59 let payload =
61 Payload::encapsulate_message(message.as_ref(), &payload_keys, self.payload_size)?;
62 Ok(SphinxPacket { header, payload })
63 }
64}
65
66impl Default for SphinxPacketBuilder<'_> {
67 fn default() -> Self {
68 SphinxPacketBuilder {
69 payload_size: DEFAULT_PAYLOAD_SIZE,
70 initial_secret: None,
71 version: Default::default(),
72 }
73 }
74}