diff --git a/README.md b/README.md index cf66a00..174ccdc 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,27 @@ Requires a working Haskell environment and RocksDB development files: cabal install ``` +## WASM Outputs With Nix + +The flake exports both the combined WASM bundle and the individual modules: + +```bash +nix build .#wasm-artifacts +nix build .#csmt-verify-wasm +nix build .#csmt-write-wasm +nix build .#mpf-verify-wasm +nix build .#mpf-write-wasm +``` + +It also exports runnable local preview commands for the static demo bundles: + +```bash +PORT=8000 nix run .#csmt-verify-wasm-demo +PORT=8001 nix run .#csmt-wasm-write-demo +PORT=8002 nix run .#mpf-wasm-write-demo +PORT=8003 nix run .#docs +``` + ## CLI Tool The `mts` executable provides an interactive CLI for CSMT operations: diff --git a/docs/installation.md b/docs/installation.md index bc15cdf..844905a 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -55,6 +55,28 @@ Or via cabal provided you have a working Haskell environment and rocksdb develop cabal install ``` +## WASM Outputs And Preview Commands + +The flake exports the combined browser-WASM bundle plus one package per +module: + +```bash +nix build .#wasm-artifacts +nix build .#csmt-verify-wasm +nix build .#csmt-write-wasm +nix build .#mpf-verify-wasm +nix build .#mpf-write-wasm +``` + +It also exports local preview commands for each static bundle: + +```bash +PORT=8000 nix run .#csmt-verify-wasm-demo +PORT=8001 nix run .#csmt-wasm-write-demo +PORT=8002 nix run .#mpf-wasm-write-demo +PORT=8003 nix run .#docs +``` + ## Start With The Tutorials Once the project builds, the fastest way to understand the current diff --git a/docs/wasm-demo.md b/docs/wasm-demo.md index d3b0dc1..86d998e 100644 --- a/docs/wasm-demo.md +++ b/docs/wasm-demo.md @@ -42,7 +42,9 @@ exit code `1` means it does not (or the input was malformed). ## Build it yourself ```bash +nix build .#csmt-verify-wasm nix build .#csmt-verify-wasm-demo +PORT=8000 nix run .#csmt-verify-wasm-demo ``` The output is a plain tree of static files suitable for copying diff --git a/docs/wasm-mpf-demo.md b/docs/wasm-mpf-demo.md index 7a25210..f93c764 100644 --- a/docs/wasm-mpf-demo.md +++ b/docs/wasm-mpf-demo.md @@ -27,6 +27,15 @@ That matches the merged Aiken-parity exclusion-proof work: the browser transport reuses the canonical proof-step format instead of introducing a second exclusion-proof encoding. +## What the demo ships + +- `mpf-write.wasm` - the write entry point exported via + `nix build .#mpf-write-wasm` +- `mpf-verify.wasm` - the pure Aiken-compatible verifier exported via + `nix build .#mpf-verify-wasm` +- `index.html` + `write.js` - the static page that runs both modules + under `@bjorn3/browser_wasi_shim` + ## Workflow 1. Insert or delete key/value pairs and watch the MPF root update. @@ -73,7 +82,10 @@ do not carry the query context: ## Build it yourself ```bash +nix build .#mpf-write-wasm +nix build .#mpf-verify-wasm nix build .#mpf-wasm-write-demo +PORT=8002 nix run .#mpf-wasm-write-demo ``` The result is a static directory containing `index.html`, `write.js`, diff --git a/docs/wasm-write-demo.md b/docs/wasm-write-demo.md index f051a1a..27fbb84 100644 --- a/docs/wasm-write-demo.md +++ b/docs/wasm-write-demo.md @@ -13,12 +13,13 @@ them against the root - happens inside sandboxed WASM. ## What the demo ships - `csmt-write.wasm` - the write entry point produced by - `wasm32-wasi-cabal` via `nix build .#csmt-wasm-write-demo`. It takes + `wasm32-wasi-cabal` via `nix build .#csmt-write-wasm`. It takes a prior `InMemoryDB` blob, a batch of inserts/deletes, and a query key; it returns the updated blob, the post-mutation root, and either an inclusion proof or an exclusion proof. - `csmt-verify.wasm` - the existing verifier, reused by the page to - independently re-check each proof it produces. + independently re-check each proof it produces, exported via + `nix build .#csmt-verify-wasm`. - `index.html` + `write.js` - the static page that drives both modules under `@bjorn3/browser_wasi_shim`. @@ -63,7 +64,10 @@ no host-side translation is needed. ## Build it yourself ```bash +nix build .#csmt-write-wasm +nix build .#csmt-verify-wasm nix build .#csmt-wasm-write-demo +PORT=8001 nix run .#csmt-wasm-write-demo ``` The output is a plain tree of static files suitable for any static diff --git a/flake.nix b/flake.nix index 47176b2..eb35636 100644 --- a/flake.nix +++ b/flake.nix @@ -78,35 +78,24 @@ null; wasmPackages = if wasmBuild != null then - let - demo = import ./nix/wasm-demo.nix { - inherit pkgs; - wasm = wasmBuild.wasm; - fixtures = ./verifiers/typescript/test/fixtures.json; - }; - writeDemo = import ./nix/wasm-write-demo.nix { - inherit pkgs; - wasm = wasmBuild.wasm; - }; - mpfWriteDemo = import ./nix/mpf-wasm-write-demo.nix { - inherit pkgs; - wasm = wasmBuild.wasm; - }; - composedDocs = import ./nix/docs.nix { - inherit pkgs; - src = ./.; - mkdocsAssets = mkdocs.outPath; - verifyDemo = demo; - writeDemo = writeDemo; - mpfWriteDemo = mpfWriteDemo; - }; - in { - csmt-verify-wasm = wasmBuild.wasm; - csmt-verify-wasm-deps = wasmBuild.deps; - csmt-verify-wasm-demo = demo; - csmt-wasm-write-demo = writeDemo; - mpf-wasm-write-demo = mpfWriteDemo; - docs = composedDocs; + import ./nix/wasm-packages.nix { + inherit pkgs wasmBuild; + src = ./.; + mkdocsAssets = mkdocs.outPath; + fixtures = ./verifiers/typescript/test/fixtures.json; + } + else + { }; + + wasmApps = if wasmBuild != null then + import ./nix/apps.nix { + inherit pkgs; + demos = lib.getAttrs [ + "docs" + "csmt-verify-wasm-demo" + "csmt-wasm-write-demo" + "mpf-wasm-write-demo" + ] wasmPackages; } else { }; @@ -122,6 +111,7 @@ in { packages = fullPackages // { default = fullPackages.mts; }; + apps = wasmApps; inherit (project) devShells; }; diff --git a/nix/apps.nix b/nix/apps.nix new file mode 100644 index 0000000..72f2fc1 --- /dev/null +++ b/nix/apps.nix @@ -0,0 +1,27 @@ +{ pkgs, demos }: +let + mkStaticSiteApp = name: root: + let + server = pkgs.writeShellApplication { + name = "serve-${name}"; + runtimeInputs = [ pkgs.python3 ]; + text = '' + host=''${HOST:-127.0.0.1} + port=''${PORT:-8000} + echo "Serving ${name} at http://$host:$port/" + exec python -m http.server "$port" --bind "$host" --directory ${root} + ''; + }; + in { + type = "app"; + program = pkgs.lib.getExe server; + }; +in { + docs = mkStaticSiteApp "docs" demos.docs; + csmt-verify-wasm-demo = + mkStaticSiteApp "csmt-verify-wasm-demo" demos.csmt-verify-wasm-demo; + csmt-wasm-write-demo = + mkStaticSiteApp "csmt-wasm-write-demo" demos.csmt-wasm-write-demo; + mpf-wasm-write-demo = + mkStaticSiteApp "mpf-wasm-write-demo" demos.mpf-wasm-write-demo; +} diff --git a/nix/wasm-packages.nix b/nix/wasm-packages.nix new file mode 100644 index 0000000..9f87ae6 --- /dev/null +++ b/nix/wasm-packages.nix @@ -0,0 +1,41 @@ +{ pkgs, src, mkdocsAssets, fixtures, wasmBuild }: +let + mkWasmModule = pname: file: + pkgs.runCommand pname { + preferLocalBuild = true; + } '' + mkdir -p $out + cp ${wasmBuild.wasm}/${file} $out/${file} + ''; + + verifyDemo = import ./wasm-demo.nix { + inherit pkgs fixtures; + wasm = wasmBuild.wasm; + }; + writeDemo = import ./wasm-write-demo.nix { + inherit pkgs; + wasm = wasmBuild.wasm; + }; + mpfWriteDemo = import ./mpf-wasm-write-demo.nix { + inherit pkgs; + wasm = wasmBuild.wasm; + }; + docs = import ./docs.nix { + inherit pkgs src; + inherit mkdocsAssets; + inherit verifyDemo writeDemo mpfWriteDemo; + }; +in { + wasm-artifacts = wasmBuild.wasm; + wasm-artifacts-deps = wasmBuild.deps; + + csmt-verify-wasm = mkWasmModule "csmt-verify-wasm" "csmt-verify.wasm"; + csmt-write-wasm = mkWasmModule "csmt-write-wasm" "csmt-write.wasm"; + mpf-verify-wasm = mkWasmModule "mpf-verify-wasm" "mpf-verify.wasm"; + mpf-write-wasm = mkWasmModule "mpf-write-wasm" "mpf-write.wasm"; + + csmt-verify-wasm-demo = verifyDemo; + csmt-wasm-write-demo = writeDemo; + mpf-wasm-write-demo = mpfWriteDemo; + inherit docs; +}