Replace the IPFS-pinned-CID-behind-eth.limo pattern with one site-builder publish + one SuiNS link.
No EVM contract; no IPNS; no public IPFS gateway in the critical path. The ENS bridge is a single DNSLink
or CNAME from yourdapp.eth to the wal.app portal.
"ENS contenthash is non-negotiable; pay Pinata or Filebase rather than trusting any free gateway; treat IPNS as broken." — and Uniswap interface #7753 had to rewrite "all references to Cloudflare's IPFS gateway."— 2026 builder-sentiment survey
site-builder publish uploads the static build, creates a Walrus Site object on
Sui, and returns its site_object_id. A single Sui transaction then links a SuiNS name to that
object id — after the next epoch boundary the site resolves at <your-name>.wal.app.
Updating the site is republishing + re-linking. The SuiNS name is the only mutable surface; there is no IPNS, no DNSLink TTL race, no "what if the gateway operator forgets to renew DNS."
ENS users keep their .eth name and bridge to the wal.app portal via either DNSLink (closer to
decentralized contenthash) or a CNAME from a custom domain (simpler, more centralized).
# the entire publish flow pnpm build site-builder --context testnet publish ./out \ --epochs 200 \ --site-name "yourdapp-demo" # prints: # site_object_id: 0xa1b2c3... # resolves at <base36-of-id>.wal.app # (or yourdapp.wal.app once linked to SuiNS)
The site-builder binary is separate from the main walrus CLI. Follow the install instructions:
docs.wal.app/sites/getting-started/installing-the-site-builder/
You also need a Sui keypair with testnet SUI for gas and testnet WAL for storage. Get them from the Sui faucet and the WAL faucet.
cd showcases/02-walrus-sites ./publish.sh ./example-site # → site_object_id: 0xa1b2c3... # → log line ends with the <base36-of-id>.wal.app URL
The publish.sh wrapper hardens the raw CLI with input validation, a network selector (NETWORK=testnet|mainnet), and a configurable epoch budget (EPOCHS=200 default).
| Env | Default | Purpose |
|---|---|---|
| NETWORK | testnet | Sui + Walrus network the CLI talks to. |
| EPOCHS | 200 | How long the published blobs stay live before re-extension. |
| SITE_NAME | showcase-02-demo | Free-form label written on the Walrus Site object. |
Two paths — pick whichever fits your tooling:
site_object_id. Sign with the wallet that owns the name.sui client call (CI). Invoke the SuiNS package's set_walrus_site entry. The exact package id depends on the network — see docs.suins.io for current values.DNSLink path — closer to decentralized contenthash:
# at your DNS provider _dnslink.<yourdapp.eth> TXT "dnslink=/https/<your-suins-name>.wal.app" # in the ENS Manager (https://app.ens.domains) # set contenthash for <yourdapp.eth> → DNSLink('<yourdapp.eth>')
CNAME path — simpler, more centralized:
# at your DNS provider app.<yourdomain.com> CNAME <your-suins-name>.wal.app # in the ENS Manager # set the `url` text record to https://app.yourdomain.com
https://<your-suins-name>.wal.app in a normal browser. The served HTML matches ./example-site/index.html.end_epoch are all visible.ipfs:// won't transparently see Walrus URLs.site_object_id. The "mutable pointer" is the SuiNS link; re-link on each release.404.html that re-bootstraps the shell — the wal.app portal serves static bytes only.