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}
175
176#[derive(Debug, Tsify, Deserialize)]
177#[tsify(from_wasm_abi)]
178pub enum KeyType {
179 P256,
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize)]
183#[wasm_bindgen]
184#[serde(transparent)]
185pub struct Attestation(pub(crate) tlsn_core::attestation::Attestation);
186
187#[wasm_bindgen]
188impl Attestation {
189 pub fn verifying_key(&self) -> VerifyingKey {
190 self.0.body.verifying_key().into()
191 }
192
193 pub fn serialize(&self) -> Vec<u8> {
195 bincode::serialize(self).expect("Attestation should be serializable")
196 }
197
198 pub fn deserialize(bytes: Vec<u8>) -> Result<Attestation, JsError> {
200 Ok(bincode::deserialize(&bytes)?)
201 }
202}
203
204impl From<tlsn_core::attestation::Attestation> for Attestation {
205 fn from(value: tlsn_core::attestation::Attestation) -> Self {
206 Self(value)
207 }
208}
209
210#[derive(Debug, Clone, Serialize, Deserialize)]
211#[wasm_bindgen]
212#[serde(transparent)]
213pub struct Secrets(pub(crate) tlsn_core::Secrets);
214
215#[wasm_bindgen]
216impl Secrets {
217 pub fn transcript(&self) -> Transcript {
219 self.0.transcript().into()
220 }
221
222 pub fn serialize(&self) -> Vec<u8> {
224 bincode::serialize(self).expect("Secrets should be serializable")
225 }
226
227 pub fn deserialize(bytes: Vec<u8>) -> Result<Secrets, JsError> {
229 Ok(bincode::deserialize(&bytes)?)
230 }
231}
232
233impl From<tlsn_core::Secrets> for Secrets {
234 fn from(value: tlsn_core::Secrets) -> Self {
235 Self(value)
236 }
237}
238
239#[derive(Debug, Serialize, Deserialize)]
240#[wasm_bindgen]
241#[serde(transparent)]
242pub struct Presentation(tlsn_core::presentation::Presentation);
243
244#[wasm_bindgen]
245impl Presentation {
246 pub fn verifying_key(&self) -> VerifyingKey {
248 self.0.verifying_key().into()
249 }
250
251 pub fn verify(&self) -> Result<PresentationOutput, JsError> {
253 let provider = CryptoProvider::default();
254
255 self.0
256 .clone()
257 .verify(&provider)
258 .map(PresentationOutput::from)
259 .map_err(JsError::from)
260 }
261
262 pub fn serialize(&self) -> Vec<u8> {
263 bincode::serialize(self).expect("Presentation should be serializable")
264 }
265
266 pub fn deserialize(bytes: Vec<u8>) -> Result<Presentation, JsError> {
267 Ok(bincode::deserialize(&bytes)?)
268 }
269}
270
271impl From<tlsn_core::presentation::Presentation> for Presentation {
272 fn from(value: tlsn_core::presentation::Presentation) -> Self {
273 Self(value)
274 }
275}
276
277#[derive(Debug, Tsify, Serialize)]
278#[tsify(into_wasm_abi)]
279pub struct PresentationOutput {
280 pub attestation: Attestation,
281 pub server_name: Option<String>,
282 pub connection_info: ConnectionInfo,
283 pub transcript: Option<PartialTranscript>,
284}
285
286impl From<tlsn_core::presentation::PresentationOutput> for PresentationOutput {
287 fn from(value: tlsn_core::presentation::PresentationOutput) -> Self {
288 Self {
289 attestation: value.attestation.into(),
290 server_name: value.server_name.map(|name| name.as_str().to_string()),
291 connection_info: value.connection_info.into(),
292 transcript: value.transcript.map(PartialTranscript::from),
293 }
294 }
295}
296
297#[derive(Debug, Serialize)]
298#[wasm_bindgen(getter_with_clone)]
299pub struct NotarizationOutput {
300 pub attestation: Attestation,
301 pub secrets: Secrets,
302}
303
304#[derive(Debug, Tsify, Serialize)]
305#[tsify(into_wasm_abi)]
306pub struct VerifierOutput {
307 pub server_name: String,
308 pub connection_info: ConnectionInfo,
309 pub transcript: PartialTranscript,
310}
311
312#[derive(Debug, Tsify, Serialize)]
313#[tsify(into_wasm_abi)]
314pub struct VerifyingKey {
315 pub alg: u8,
316 pub data: Vec<u8>,
317}
318
319impl From<&tlsn_core::signing::VerifyingKey> for VerifyingKey {
320 fn from(value: &tlsn_core::signing::VerifyingKey) -> Self {
321 Self {
322 alg: value.alg.as_u8(),
323 data: value.data.clone(),
324 }
325 }
326}