A Rust/Yew rewrite of the (deprecated, TypeScript) rings-dweb.
A self-contained decentralized web: every node is at once a tiny static-site host and a browser, exchanging pages peer-to-peer over rings with no central server.
- On start it builds an in-browser rings node (IndexedDB storage), installs the extension
backend, and registers a
dwebprotocol viaprovider.on(..). - The
dwebhandler is(ctx, event) -> { state, effects }:- a request
{"kind":"req","path":"/"}is answered with oneSendeffect carrying the hosted page ({"kind":"res","path":"/","body":"…"}), or a 404; - a response is surfaced to the UI.
- a request
- The UI shows this node's DID and the page it hosts, and lets you fetch a
pathfrom a peer's DID — the page is delivered over the overlay and rendered.
The rings wiring lives in src/lib.rs (build_node, dweb_handle, register_dweb,
fetch_path); src/main.rs just mounts the Yew app.
A fetched page is peer-controlled, untrusted HTML. It is never injected into the app's
DOM; instead it is rendered inside an <iframe srcdoc=… sandbox="">. The empty sandbox
attribute applies all restrictions — scripts are disabled, the frame has an opaque origin,
and forms/popups/top-navigation are blocked — so a hostile page cannot run JavaScript, read
cookies/storage, or reach the host app's origin or DOM.
cargo install trunk # one-time
trunk serve # → http://localhost:8080Open two instances, paste one node's DID into the other's "peer DID" box, and fetch /.
Runs in a real headless browser via the wasm-bindgen-test toolkit; webdriver.json
supplies the Chrome launch flags:
wasm-pack test --headless --chrome # 4 testsRequires a chromedriver whose version matches your installed Chrome (a mismatch makes
Chrome exit on launch). Firefox works too via --firefox + a matching geckodriver.