# mod.rs - source
Source of the Rust file `crates/wasm/src/prover/mod.rs`.

Skip to main content

#
tlsn_wasm/prover/
mod.rs

    1//! WASM Prover bindings.
    2
    3mod config;
    4
    5pub use config::ProverConfig;
    6
    7use tlsn_sdk_core::{
    8    NetworkSetting as CoreNetworkSetting, ProverConfig as CoreProverConfig, SdkProver,
    9};
    10use wasm_bindgen::{prelude::*, JsError};
    11
    12use crate::{
    13    io::{JsIo, JsIoAdapter},
    14    types::*,
    15};
    16
    17type Result<T> = std::result::Result<T, JsError>;
    18
    19/// Prover for the TLSNotary protocol.
    20///
    21/// The prover connects to both a verifier and a target server, executing the
    22/// MPC-TLS protocol to generate verifiable proofs of the TLS session.
    23#[wasm_bindgen(js_name = Prover)]
    24pub struct JsProver {
    25    inner: SdkProver,
    26    progress_callback: Option<js_sys::Function>,
    27}
    28
    29#[wasm_bindgen(js_class = Prover)]
    30impl JsProver {
    31    /// Creates a new Prover with the given configuration.
    32    #[wasm_bindgen(constructor)]
    33    pub fn new(config: ProverConfig) -> Result<JsProver> {
    34        let core_config = convert_prover_config(config);
    35        let inner = SdkProver::new(core_config).map_err(|e| JsError::new(&e.to_string()))?;
    36        Ok(JsProver {
    37            inner,
    38            progress_callback: None,
    39        })
    40    }
    41
    42    /// Sets a progress callback that receives structured progress updates.
    43    ///
    44    /// The callback receives a single argument: `{ step: string, progress:
    45    /// number, message: string }`.
    46    ///
    47    /// Steps emitted: `MPC_SETUP`, `CONNECTING_TO_SERVER`, `SENDING_REQUEST`,
    48    /// `REQUEST_COMPLETE`, `REVEAL`, `FINALIZED`.
    49    pub fn set_progress_callback(&mut self, callback: js_sys::Function) {
    50        self.progress_callback = Some(callback);
    51    }
    52
    53    /// Sets up the prover with the verifier.
    54    ///
    55    /// This performs all MPC setup prior to establishing the connection to the
    56    /// application server.
    57    ///
    58    /// # Arguments
    59    ///
    60    /// * `verifier_io` - A JavaScript object implementing the IoChannel
    61    ///   interface, connected to the verifier.
    62    pub async fn setup(&mut self, verifier_io: JsIo) -> Result<()> {
    63        self.emit_progress("MPC_SETUP", 0.1, "Connecting to verifier...");
    64
    65        let adapter = JsIoAdapter::new(verifier_io);
    66        self.inner
    67            .setup(adapter)
    68            .await
    69            .map_err(|e| JsError::new(&e.to_string()))?;
    70
    71        self.emit_progress("MPC_SETUP", 0.2, "MPC setup complete");
    72
    73        Ok(())
    74    }
    75
    76    /// Sends an HTTP request to the server.
    77    ///
    78    /// # Arguments
    79    ///
    80    /// * `server_io` - A JavaScript object implementing the IoChannel
    81    ///   interface, connected to the server (typically via a WebSocket proxy).
    82    /// * `request` - The HTTP request to send.
    83    pub async fn send_request(
    84        &mut self,
    85        server_io: JsIo,
    86        request: HttpRequest,
    87    ) -> Result<HttpResponse> {
    88        self.emit_progress(
    89            "CONNECTING_TO_SERVER",
    90            0.3,
    91            "Connecting to application server...",
    92        );
    93
    94        let adapter = JsIoAdapter::new(server_io);
    95        let core_request = convert_http_request(request);
    96
    97        self.emit_progress("SENDING_REQUEST", 0.4, "Sending request...");
    98
    99        let core_response = self
    100            .inner
    101            .send_request(adapter, core_request)
    102            .await
    103            .map_err(|e| JsError::new(&e.to_string()))?;
    104
    105        self.emit_progress("REQUEST_COMPLETE", 0.5, "Response received");
    106
    107        Ok(convert_http_response(core_response))
    108    }
    109
    110    /// Returns the transcript of the TLS session.
    111    pub fn transcript(&self) -> Result<Transcript> {
    112        let core_transcript = self
    113            .inner
    114            .transcript()
    115            .map_err(|e| JsError::new(&e.to_string()))?;
    116        Ok(convert_transcript(core_transcript))
    117    }
    118
    119    /// Reveals data to the verifier and finalizes the protocol.
    120    ///
    121    /// Optionally accepts a `Commit` object with ranges to hash-commit.
    122    /// Pass `undefined` or omit the second argument for reveal-only proofs.
    123    pub async fn reveal(&mut self, reveal: Reveal, commit: Option<Commit>) -> Result<()> {
    124        self.emit_progress("REVEAL", 0.7, "Proving and revealing data...");
    125
    126        let core_reveal = convert_reveal(reveal);
    127        let core_commit = commit.map(convert_commit);
    128
    129        self.inner
    130            .reveal(core_reveal, core_commit)
    131            .await
    132            .map_err(|e| JsError::new(&e.to_string()))?;
    133
    134        self.emit_progress("FINALIZED", 0.95, "Protocol finalized");
    135
    136        Ok(())
    137    }
    138}
    139
    140impl JsProver {
    141    /// Emits a structured progress event to the JS callback (if set).
    142    fn emit_progress(&self, step: &str, progress: f64, message: &str) {
    143        if let Some(ref cb) = self.progress_callback {
    144            let obj = js_sys::Object::new();
    145            let _ = js_sys::Reflect::set(&obj, &"step".into(), &step.into());
    146            let _ = js_sys::Reflect::set(&obj, &"progress".into(), &progress.into());
    147            let _ = js_sys::Reflect::set(&obj, &"message".into(), &message.into());
    148            let _ = js_sys::Reflect::set(&obj, &"source".into(), &"wasm".into());
    149            let _ = cb.call1(&JsValue::NULL, &obj);
    150        }
    151    }
    152}
    153
    154// Conversion functions between WASM types and sdk-core types.
    155
    156fn convert_prover_config(config: ProverConfig) -> CoreProverConfig {
    157    let mut builder = CoreProverConfig::builder(&config.server_name)
    158        .max_sent_data(config.max_sent_data)
    159        .max_recv_data(config.max_recv_data)
    160        .network(match config.network {
    161            NetworkSetting::Bandwidth => CoreNetworkSetting::Bandwidth,
    162            NetworkSetting::Latency => CoreNetworkSetting::Latency,
    163        });
    164
    165    if let Some(value) = config.max_sent_records {
    166        builder = builder.max_sent_records(value);
    167    }
    168
    169    if let Some(value) = config.max_recv_data_online {
    170        builder = builder.max_recv_data_online(value);
    171    }
    172
    173    if let Some(value) = config.max_recv_records_online {
    174        builder = builder.max_recv_records_online(value);
    175    }
    176
    177    if let Some(value) = config.defer_decryption_from_start {
    178        builder = builder.defer_decryption_from_start(value);
    179    }
    180
    181    if let Some((certs, key)) = config.client_auth {
    182        builder = builder.client_auth(certs, key);
    183    }
    184
    185    builder.build()
    186}
    187
    188fn convert_http_request(request: HttpRequest) -> tlsn_sdk_core::HttpRequest {
    189    let method = match request.method {
    190        Method::GET => tlsn_sdk_core::Method::GET,
    191        Method::POST => tlsn_sdk_core::Method::POST,
    192        Method::PUT => tlsn_sdk_core::Method::PUT,
    193        Method::DELETE => tlsn_sdk_core::Method::DELETE,
    194    };
    195
    196    let mut core_request = tlsn_sdk_core::HttpRequest::new(method, &request.uri);
    197
    198    for (name, value) in request.headers {
    199        core_request = core_request.header(name, value);
    200    }
    201
    202    if let Some(body) = request.body {
    203        let core_body = match body {
    204            Body::Json(value) => tlsn_sdk_core::Body::Json(value),
    205        };
    206        core_request = core_request.body(core_body);
    207    }
    208
    209    core_request
    210}
    211
    212fn convert_http_response(response: tlsn_sdk_core::HttpResponse) -> HttpResponse {
    213    HttpResponse {
    214        status: response.status,
    215        headers: response.headers,
    216    }
    217}
    218
    219fn convert_transcript(transcript: tlsn_sdk_core::Transcript) -> Transcript {
    220    Transcript {
    221        sent: transcript.sent,
    222        recv: transcript.recv,
    223    }
    224}
    225
    226fn convert_hash_algorithm(alg: HashAlgorithm) -> tlsn_sdk_core::HashAlgorithm {
    227    match alg {
    228        HashAlgorithm::BLAKE3 => tlsn_sdk_core::HashAlgorithm::Blake3,
    229        HashAlgorithm::SHA256 => tlsn_sdk_core::HashAlgorithm::Sha256,
    230        HashAlgorithm::KECCAK256 => tlsn_sdk_core::HashAlgorithm::Keccak256,
    231    }
    232}
    233
    234fn convert_commit_range(cr: CommitRange) -> tlsn_sdk_core::CommitRange {
    235    tlsn_sdk_core::CommitRange {
    236        start: cr.start,
    237        end: cr.end,
    238        algorithm: convert_hash_algorithm(cr.algorithm),
    239    }
    240}
    241
    242fn convert_commit(commit: Commit) -> tlsn_sdk_core::Commit {
    243    tlsn_sdk_core::Commit {
    244        sent: commit.sent.into_iter().map(convert_commit_range).collect(),
    245        recv: commit.recv.into_iter().map(convert_commit_range).collect(),
    246    }
    247}
    248
    249fn convert_reveal(reveal: Reveal) -> tlsn_sdk_core::Reveal {
    250    let mut core_reveal = tlsn_sdk_core::Reveal::new();
    251
    252    for range in reveal.sent {
    253        core_reveal = core_reveal.sent(range);
    254    }
    255
    256    for range in reveal.recv {
    257        core_reveal = core_reveal.recv(range);
    258    }
    259
    260    core_reveal = core_reveal.server_identity(reveal.server_identity);
    261
    262    core_reveal
    263}