Static, no-build interfaces for Uniteum contracts. Each page is a single
self-contained HTML file with inline CSS and an ES-module <script> that
imports viem from esm.sh. No bundler,
no framework, no backend — the same public/ tree deploys identically to
Cloudflare Workers and IPFS.
public/index.html— landing page with links to each dapppublic/notable/index.html— mint a1xETHERC-20 via the Notable prototype on Arbitrum (0x3131cE680E5Dd6d3fCF4BB3942186B49f7330080)
npm install
npm run dev # wrangler dev — serves public/ on http://localhost:8787Or just open public/notable/index.html directly in a browser — it's
plain static HTML.
Workers can serve static assets natively (no Pages required):
npm run deploy # wrangler deployDeploys to https://uniteum-dapps.<account>.workers.dev. Configure
custom domains in the Cloudflare dashboard or via routes in
wrangler.jsonc.
Every page uses relative paths (./notable/, ../) so the same
build works under an IPFS gateway path prefix (/ipfs/<cid>/...).
npm run ipfs # ipfs add -r --cid-version=1 publicPin the resulting root CID. Access via:
https://<cid>.ipfs.dweb.link/https://ipfs.io/ipfs/<cid>/- Set an ENS contenthash to
ipfs://<cid>for a human-readable URL
For pinning services: Pinata, web3.storage, or self-hosted Kubo.
mkdir public/<name>and createpublic/<name>/index.html.- Copy the
<style>and<script type="module">skeleton frompublic/notable/index.html. - Use relative paths for everything (
./,../) so IPFS gateways resolve correctly. - Import viem from
https://esm.sh/viem@2.21.0(pin the version — IPFS content is immutable, so a floating import would silently rot once esm.sh's resolution drifts). - Add a
<li>topublic/index.html.
- IPFS content is immutable. A bundler that pulls in
node_moduleswould change the CID on every dependency tree shake. - A single inline-CSS HTML file per dapp is the smallest possible blast radius — diff one file, redeploy one CID.
- ESM CDN imports are version-pinned, cacheable, and require no toolchain.
If a page outgrows this approach (multi-route SPA, heavy state, complex
component reuse), build it in liquid-app/ instead.