Conversation
- Extract platform-agnostic sdk-core crate (SdkProver, SdkVerifier, BoxedIo, Io trait) - WASM crate becomes thin binding layer injecting JS-backed IO streams - Simplify AsyncWrite/poll_close to fire-and-forget pattern
Move HTTP transcript parsing and handler-to-byte-range mapping from TypeScript into Rust sdk-core, using spansy for HTTP/JSON parsing. This enables mobile (iOS/Android) reuse of the range extraction logic. - Add Handler types (HandlerType, HandlerPart, HandlerAction, etc.) - Add compute_reveal() that maps handlers to byte ranges via spansy - Support all handler parts: start line, method, headers, body, regex - Add WASM binding in crates/wasm via serde_wasm_bindgen - Include comprehensive tests (24 test cases)
…o sdk-core - Move platform-agnostic logging types (LoggingLevel, LoggingConfig, CrateLogFilter, SpanEvent) and filter logic to sdk-core so mobile can reuse them - Replace tracing-web with wasm-tracing to remove web-sys from the WASM dependency tree - Remove unused time crate dependency - Clean up dead .with_timer().without_time() chain
Replace Rc<RefCell> with Arc<Mutex> in JsIoAdapter to make the state thread-safe, narrowing the unsafe Send impl to only cover the JsIo JS handle. Handle mutex poison errors gracefully instead of panicking. Make HyperIo::new safe by moving the unsafe into poll_read where the actual MaybeUninit invariant lives, removing the burden from callers.
When a JS string body is passed through wasm-bindgen, it arrives as serde_json::Value::String. Re-serializing this with serde_json::to_vec wraps it in extra quotes, causing the HTTP parser to fail with "trailing characters" errors. Handle Value::String specially by using the raw string bytes directly. Fixes tlsnotary/tlsn-extension#254
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
sdk-corecrate (Iotrait,SdkProver,SdkVerifier); wasm crate becomes a thin binding layerws_stream_wasmWebSocket creation with anIoChannelinterface injected from JS (Decouple wasm bindings fromweb-sys#542, Plugin I/O PoC #834, Remove HTTP client from WASM binding #749)AsyncWrite/poll_closeto fire-and-forget pattern, preventing microtask deadlocks in browsersdk-core extraction
Protocol logic (prover setup, TLS connection, request sending, reveal) is moved from the wasm crate
into a new
sdk-corecrate with no platform dependencies. The wasm crate becomes a thinwasm_bindgenlayer that converts JS types and delegates to sdk-core. This enables futurenative/mobile SDK bindings that share the same core logic.
IO injection
WASM methods previously took URL strings and created WebSockets internally via
ws_stream_wasm.Now they accept an
IoChannelobject withread(),write(),close()methods, injected from JS.sdk-core defines a platform-agnostic
Iotrait (AsyncRead + AsyncWrite + Send + Unpin)with a WASM adapter (
JsIoAdapter) that bridges JS Promises to Rust's async polling model.The host environment controls transport creation, lifecycle, and error handling — WASM only consumes bytes.
Removes
ws_stream_wasm(and transitivelyweb-sys) from the WASM crate.Browser event loop: fire-and-forget writes
The old
poll_writestarted a JS Promise and polled it to completion. In the browser, this deadlocks:the Rust future can't progress until the Promise resolves, but the Promise is a microtask blocked
behind the Rust future on the same single-threaded executor. Since WebSocket
send()is synchronous(it buffers internally), we skip awaiting the Promise entirely and return
Readyimmediately.Same for
poll_close. Errors surface on subsequent calls.This is orthogonal to #1100, which fixes a different microtask saturation issue in the MPC actor loop.
Builds on #1100.
Testing
Tested end-to-end with the tlsn-extension:
proof generation completes successfully with IO injected from JavaScript via WebSocket.
tlsnotary/tlsn-extension#248