Onchfs
Choose a resolver
Resolve onchfs:// URLs in one of two ways: run the worker in the browser, or host an HTTP proxy endpoint for your app and server-side tools. Choose the one that fits your deployment.
// Client-side browser resolutionconst clientConfig = {resolver: {onchfs: { mode: "service-worker" },},}// Your own HTTP endpointconst serverConfig = {resolver: {onchfs: { mode: "proxy", baseUrl: "https://onchfs.example.com" },},}
1. Use the client-side worker
The standard Artwork component can resolve and execute onchfs:// artwork directly in the browser, without an fxhash endpoint or hosted backend.
Place the worker and its browser bundle in your public root. They must remain next to each other.
pnpm add @whitehash/onchfs-swcp node_modules/@whitehash/onchfs-sw/dist/worker.js public/onchfs-sw.jscp node_modules/@whitehash/onchfs-sw/dist/onchfs.global.js public/onchfs.global.js
2. Register the worker once
Mount the registration component beside your provider. After activation, every Artwork can resolve onchfs:// with no component changes.
"use client"import { useEffect } from "react"import { registerOnchfsWorker } from "@whitehash/onchfs-sw"export function OnchfsRegistration() {useEffect(() => {void registerOnchfsWorker().catch(console.error)}, [])return null}// Mount <OnchfsRegistration /> once beside your provider.
3. Render normally
const { token, loading } = useToken({chain: "eip155:1",contract: "0xBb47F0ED4A7E3BffcA75660dFa3B053FB7FcE78E",tokenId: "2953",})if (!loading && token) {return <Artwork.Root token={token}>…</Artwork.Root>}
Render an onchfs artwork in the browser
Genomes #2953
This example shows the composed Artwork component: an IPFS preview loads first, then Run onchfs live replaces it with the executable artwork. Its HTML, scripts, and assets are read from Ethereum through the same-origin worker.
- Network
- Ethereum
- Collection
- 0xBb47…E78E
- Token ID
- 2953
- Generator root
- 046f4712…77f61
/.whitehash/onchfs/eip155-1/046f4712c2aaa344f82f1ef8ffed2ab8c9714819228e29c6a28cf67b14377f61/?fxhash=0x4d47331fb7ef118d98ff2c313fe79d2a6870a62ad078f625623d1122989b545e&fxiteration=2953&fxminter=0xb29DDe74b1ba90f3b21F12bA7ae7583976562EDD
How onchfs reaches the iframe
The service worker translates a browser-unreadable onchfs:// URI into a same-origin response. The artwork bytes remain content-addressed and chain-native all the way to the iframe.
The same Artwork API now covers both IPFS and onchfs content.
Use a self-hosted proxy instead
Choose proxy mode when service workers are unavailable or your application needs ordinary HTTP responses. Host the endpoint yourself and point baseUrl at it. Immutable generator bytes receive long-lived cache headers; query parameters still reach the runtime without duplicating those bytes.
# From the onchfs-proxy app directorypnpm installPORT=3939 pnpm start
The same Hono app can run inside a Next.js route handler. Mount it under the path you will use as baseUrl:
import { Hono } from "hono"import { createApp } from "@whitehash/onchfs-proxy"const routes = new Hono()routes.route("/api/onchfs", createApp())export const runtime = "nodejs"export const GET = (request: Request) => routes.fetch(request)export const HEAD = GET
const config = {resolver: {onchfs: { mode: "proxy", baseUrl: "https://example.com/api/onchfs" },},}
ONCHFS_ETH_RPCS=https://ethereum-rpc.exampleONCHFS_BASE_RPCS=https://base-rpc.example