tlsn_wasm/
types.rs

1use std::{collections::HashMap, ops::Range};
2
3use http_body_util::Full;
4use hyper::body::Bytes;
5use serde::{Deserialize, Serialize};
6use serde_json::Value as JsonValue;
7use tlsn_core::CryptoProvider;
8use tsify_next::Tsify;
9use wasm_bindgen::prelude::*;
10
11#[derive(Debug, Tsify, Deserialize)]
12#[tsify(from_wasm_abi)]
13#[serde(untagged)]
14#[non_exhaustive]
15pub enum Body {
16    Json(JsonValue),
17}
18
19#[derive(Debug, Tsify, Deserialize)]
20#[tsify(from_wasm_abi)]
21pub enum Method {
22    GET,
23    POST,
24    PUT,
25    DELETE,
26}
27
28impl From<Method> for hyper::Method {
29    fn from(value: Method) -> Self {
30        match value {
31            Method::GET => hyper::Method::GET,
32            Method::POST => hyper::Method::POST,
33            Method::PUT => hyper::Method::PUT,
34            Method::DELETE => hyper::Method::DELETE,
35        }
36    }
37}
38
39#[derive(Debug, Tsify, Deserialize)]
40#[tsify(from_wasm_abi)]
41pub struct HttpRequest {
42    pub uri: String,
43    pub method: Method,
44    pub headers: HashMap<String, Vec<u8>>,
45    pub body: Option<Body>,
46}
47
48impl TryFrom<HttpRequest> for hyper::Request<Full<Bytes>> {
49    type Error = JsError;
50
51    fn try_from(value: HttpRequest) -> Result<Self, Self::Error> {
52        let mut builder = hyper::Request::builder();
53        builder = builder.uri(value.uri).method(value.method);
54        for (name, value) in value.headers {
55            builder = builder.header(name, value);
56        }
57
58        if let Some(body) = value.body {
59            let body = match body {
60                Body::Json(value) => Full::new(Bytes::from(serde_json::to_vec(&value).unwrap())),
61            };
62            builder.body(body).map_err(Into::into)
63        } else {
64            builder.body(Full::new(Bytes::new())).map_err(Into::into)
65        }
66    }
67}
68
69#[derive(Debug, Tsify, Serialize)]
70#[tsify(into_wasm_abi)]
71pub struct HttpResponse {
72    pub status: u16,
73    pub headers: Vec<(String, Vec<u8>)>,
74}
75
76#[derive(Debug, Tsify, Serialize)]
77#[tsify(into_wasm_abi)]
78pub enum TlsVersion {
79    V1_2,
80    V1_3,
81}
82
83impl From<tlsn_core::connection::TlsVersion> for TlsVersion {
84    fn from(value: tlsn_core::connection::TlsVersion) -> Self {
85        match value {
86            tlsn_core::connection::TlsVersion::V1_2 => Self::V1_2,
87            tlsn_core::connection::TlsVersion::V1_3 => Self::V1_3,
88        }
89    }
90}
91
92#[derive(Debug, Tsify, Serialize)]
93#[tsify(into_wasm_abi)]
94pub struct TranscriptLength {
95    pub sent: usize,
96    pub recv: usize,
97}
98
99impl From<tlsn_core::connection::TranscriptLength> for TranscriptLength {
100    fn from(value: tlsn_core::connection::TranscriptLength) -> Self {
101        Self {
102            sent: value.sent as usize,
103            recv: value.received as usize,
104        }
105    }
106}
107
108#[derive(Debug, Tsify, Serialize)]
109#[tsify(into_wasm_abi)]
110pub struct ConnectionInfo {
111    time: u64,
112    version: TlsVersion,
113    transcript_length: TranscriptLength,
114}
115
116impl From<tlsn_core::connection::ConnectionInfo> for ConnectionInfo {
117    fn from(value: tlsn_core::connection::ConnectionInfo) -> Self {
118        Self {
119            time: value.time,
120            version: value.version.into(),
121            transcript_length: value.transcript_length.into(),
122        }
123    }
124}
125
126#[derive(Debug, Tsify, Serialize)]
127#[tsify(into_wasm_abi)]
128pub struct Transcript {
129    pub sent: Vec<u8>,
130    pub recv: Vec<u8>,
131}
132
133impl From<&tlsn_core::transcript::Transcript> for Transcript {
134    fn from(value: &tlsn_core::transcript::Transcript) -> Self {
135        Self {
136            sent: value.sent().to_vec(),
137            recv: value.received().to_vec(),
138        }
139    }
140}
141
142#[derive(Debug, Tsify, Serialize)]
143#[tsify(into_wasm_abi)]
144pub struct PartialTranscript {
145    pub sent: Vec<u8>,
146    pub sent_authed: Vec<Range<usize>>,
147    pub recv: Vec<u8>,
148    pub recv_authed: Vec<Range<usize>>,
149}
150
151impl From<tlsn_core::transcript::PartialTranscript> for PartialTranscript {
152    fn from(value: tlsn_core::transcript::PartialTranscript) -> Self {
153        Self {
154            sent: value.sent_unsafe().to_vec(),
155            sent_authed: value.sent_authed().iter_ranges().collect(),
156            recv: value.received_unsafe().to_vec(),
157            recv_authed: value.received_authed().iter_ranges().collect(),
158        }
159    }
160}
161
162#[derive(Debug, Tsify, Deserialize)]
163#[tsify(from_wasm_abi)]
164pub struct Commit {
165    pub sent: Vec<Range<usize>>,
166    pub recv: Vec<Range<usize>>,
167}
168
169#[derive(Debug, Tsify, Deserialize)]
170#[tsify(from_wasm_abi)]
171pub struct Reveal {
172    pub sent: Vec<Range<usize>>,
173    pub recv: Vec<Range<usize>>,
174    pub server_identity: bool,
175}
176
177#[derive(Debug, Tsify, Deserialize)]
178#[tsify(from_wasm_abi)]
179pub enum KeyType {
180    P256,
181}
182
183#[derive(Debug, Clone, Serialize, Deserialize)]
184#[wasm_bindgen]
185#[serde(transparent)]
186pub struct Attestation(pub(crate) tlsn_core::attestation::Attestation);
187
188#[wasm_bindgen]
189impl Attestation {
190    pub fn verifying_key(&self) -> VerifyingKey {
191        self.0.body.verifying_key().into()
192    }
193
194    /// Serializes to a byte array.
195    pub fn serialize(&self) -> Vec<u8> {
196        bincode::serialize(self).expect("Attestation should be serializable")
197    }
198
199    /// Deserializes from a byte array.
200    pub fn deserialize(bytes: Vec<u8>) -> Result<Attestation, JsError> {
201        Ok(bincode::deserialize(&bytes)?)
202    }
203}
204
205impl From<tlsn_core::attestation::Attestation> for Attestation {
206    fn from(value: tlsn_core::attestation::Attestation) -> Self {
207        Self(value)
208    }
209}
210
211#[derive(Debug, Clone, Serialize, Deserialize)]
212#[wasm_bindgen]
213#[serde(transparent)]
214pub struct Secrets(pub(crate) tlsn_core::Secrets);
215
216#[wasm_bindgen]
217impl Secrets {
218    /// Returns the transcript.
219    pub fn transcript(&self) -> Transcript {
220        self.0.transcript().into()
221    }
222
223    /// Serializes to a byte array.
224    pub fn serialize(&self) -> Vec<u8> {
225        bincode::serialize(self).expect("Secrets should be serializable")
226    }
227
228    /// Deserializes from a byte array.
229    pub fn deserialize(bytes: Vec<u8>) -> Result<Secrets, JsError> {
230        Ok(bincode::deserialize(&bytes)?)
231    }
232}
233
234impl From<tlsn_core::Secrets> for Secrets {
235    fn from(value: tlsn_core::Secrets) -> Self {
236        Self(value)
237    }
238}
239
240#[derive(Debug, Serialize, Deserialize)]
241#[wasm_bindgen]
242#[serde(transparent)]
243pub struct Presentation(tlsn_core::presentation::Presentation);
244
245#[wasm_bindgen]
246impl Presentation {
247    /// Returns the verifying key.
248    pub fn verifying_key(&self) -> VerifyingKey {
249        self.0.verifying_key().into()
250    }
251
252    /// Verifies the presentation.
253    pub fn verify(&self) -> Result<PresentationOutput, JsError> {
254        let provider = CryptoProvider::default();
255
256        self.0
257            .clone()
258            .verify(&provider)
259            .map(PresentationOutput::from)
260            .map_err(JsError::from)
261    }
262
263    pub fn serialize(&self) -> Vec<u8> {
264        bincode::serialize(self).expect("Presentation should be serializable")
265    }
266
267    pub fn deserialize(bytes: Vec<u8>) -> Result<Presentation, JsError> {
268        Ok(bincode::deserialize(&bytes)?)
269    }
270}
271
272impl From<tlsn_core::presentation::Presentation> for Presentation {
273    fn from(value: tlsn_core::presentation::Presentation) -> Self {
274        Self(value)
275    }
276}
277
278#[derive(Debug, Tsify, Serialize)]
279#[tsify(into_wasm_abi)]
280pub struct PresentationOutput {
281    pub attestation: Attestation,
282    pub server_name: Option<String>,
283    pub connection_info: ConnectionInfo,
284    pub transcript: Option<PartialTranscript>,
285}
286
287impl From<tlsn_core::presentation::PresentationOutput> for PresentationOutput {
288    fn from(value: tlsn_core::presentation::PresentationOutput) -> Self {
289        Self {
290            attestation: value.attestation.into(),
291            server_name: value.server_name.map(|name| name.as_str().to_string()),
292            connection_info: value.connection_info.into(),
293            transcript: value.transcript.map(PartialTranscript::from),
294        }
295    }
296}
297
298#[derive(Debug, Serialize)]
299#[wasm_bindgen(getter_with_clone)]
300pub struct NotarizationOutput {
301    pub attestation: Attestation,
302    pub secrets: Secrets,
303}
304
305#[derive(Debug, Tsify, Serialize)]
306#[tsify(into_wasm_abi)]
307pub struct VerifierOutput {
308    pub server_name: Option<String>,
309    pub connection_info: ConnectionInfo,
310    pub transcript: Option<PartialTranscript>,
311}
312
313#[derive(Debug, Tsify, Serialize)]
314#[tsify(into_wasm_abi)]
315pub struct VerifyingKey {
316    pub alg: u8,
317    pub data: Vec<u8>,
318}
319
320impl From<&tlsn_core::signing::VerifyingKey> for VerifyingKey {
321    fn from(value: &tlsn_core::signing::VerifyingKey) -> Self {
322        Self {
323            alg: value.alg.as_u8(),
324            data: value.data.clone(),
325        }
326    }
327}
328
329#[derive(Debug, Tsify, Deserialize)]
330#[tsify(from_wasm_abi)]
331pub enum NetworkSetting {
332    /// Prefers a bandwidth-heavy protocol.
333    Bandwidth,
334    /// Prefers a latency-heavy protocol.
335    Latency,
336}
337
338impl From<NetworkSetting> for tlsn::config::NetworkSetting {
339    fn from(value: NetworkSetting) -> Self {
340        match value {
341            NetworkSetting::Bandwidth => Self::Bandwidth,
342            NetworkSetting::Latency => Self::Latency,
343        }
344    }
345}