use crate::types::helpers::BinaryData;
use crate::{GatewayRequestsError, SharedSymmetricKey};
use nym_sphinx::forwarding::packet::MixPacket;
use strum::FromRepr;
use tungstenite::Message;
#[non_exhaustive]
pub enum BinaryRequest {
ForwardSphinx { packet: MixPacket },
ForwardSphinxV2 { packet: MixPacket },
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, FromRepr, PartialEq)]
#[non_exhaustive]
pub enum BinaryRequestKind {
ForwardSphinx = 1,
ForwardSphinxV2 = 2,
}
impl BinaryRequest {
pub fn kind(&self) -> BinaryRequestKind {
match self {
BinaryRequest::ForwardSphinx { .. } => BinaryRequestKind::ForwardSphinx,
BinaryRequest::ForwardSphinxV2 { .. } => BinaryRequestKind::ForwardSphinxV2,
}
}
pub fn from_plaintext(
kind: BinaryRequestKind,
plaintext: &[u8],
) -> Result<Self, GatewayRequestsError> {
match kind {
BinaryRequestKind::ForwardSphinx => {
let packet = MixPacket::try_from_v1_bytes(plaintext)?;
Ok(BinaryRequest::ForwardSphinx { packet })
}
BinaryRequestKind::ForwardSphinxV2 => {
let packet = MixPacket::try_from_v2_bytes(plaintext)?;
Ok(BinaryRequest::ForwardSphinxV2 { packet })
}
}
}
pub fn try_from_encrypted_tagged_bytes(
bytes: Vec<u8>,
shared_key: &SharedSymmetricKey,
) -> Result<Self, GatewayRequestsError> {
BinaryData::from_raw(&bytes, shared_key)?.into_request(shared_key)
}
pub fn into_encrypted_tagged_bytes(
self,
shared_key: &SharedSymmetricKey,
) -> Result<Vec<u8>, GatewayRequestsError> {
let kind = self.kind();
let plaintext = match self {
BinaryRequest::ForwardSphinx { packet } => packet.into_v1_bytes()?,
BinaryRequest::ForwardSphinxV2 { packet } => packet.into_v2_bytes()?,
};
BinaryData::make_encrypted_blob(kind as u8, &plaintext, shared_key)
}
pub fn into_ws_message(
self,
shared_key: &SharedSymmetricKey,
) -> Result<Message, GatewayRequestsError> {
let blob = match self {
BinaryRequest::ForwardSphinx { .. } | BinaryRequest::ForwardSphinxV2 { .. } => {
self.into_encrypted_tagged_bytes(shared_key)?
}
};
Ok(Message::Binary(blob))
}
}