Skip to content

Add ENSIP: ENS Package Manifest#80

Open
nxt3d wants to merge 3 commits into
ensdomains:masterfrom
nxt3d:ens-pkg
Open

Add ENSIP: ENS Package Manifest#80
nxt3d wants to merge 3 commits into
ensdomains:masterfrom
nxt3d:ens-pkg

Conversation

@nxt3d
Copy link
Copy Markdown
Contributor

@nxt3d nxt3d commented May 29, 2026

Summary

Adds a new draft ENSIP defining a JSON package manifest format for ENS names.

An ENS name points to the manifest via its contenthash record (per ENSIP-7), and the manifest tells clients the package name, version, files, executable commands, and where to fetch the package contents. The format reuses familiar package metadata conventions (npm/yarn/bun style) so existing package tooling concepts carry over, while letting package contents be distributed through ENS-compatible systems such as IPFS.

What it specifies

  • Manifest location: published at the ENS name's contenthash resource as a JSON document; recommended MIME type application/ens-pkg+json.
  • Top-level envelope: { manifest, signatures } so optional signatures sign the manifest object without mutating it.
  • Manifest fields: name, version, dist required; standard package metadata (author, contributors, description, license, repository, dependencies, devDependencies, scripts) optional; files and bin optional with npm-style semantics.
  • Distribution: a dist object with exactly one of tarball or directory. URIs may use https:, ipfs:, data:, or any other client-supported scheme. SRI-style integrity is required for non-content-addressed sources and optional for content-addressed ones (e.g. IPFS CIDs).
  • Signatures: optional signatures array, with EIP-191 as the recommended scheme, signing the canonical JSON serialization of the manifest object.
  • Client behavior: resolve contenthash → fetch manifest → verify signatures (optionally) → fetch package contents → verify integrity → select file or executable.

Why a JSON document instead of HTML

An earlier draft of this proposal embedded the JSON inside an HTML document so the manifest could double as a human-readable page. After feedback, the spec was simplified to a plain JSON document: clients have a single canonical format, and any HTML or other UI can load the JSON via fetch() and render it however it wants. That presentation layer is now explicitly out of scope of the spec.

Out of scope

  • HTML or other human-facing presentation layers (clients may build them on top of the JSON).
  • Per-file URI/hook entries — replaced by a dist artifact / directory with package-level integrity.
  • ERC-8121 hook sources — removed; if on-chain file resolution is needed it can be layered on top in a separate proposal.

Request

Requesting:

  1. Review of the spec.
  2. Assignment of an ENSIP number (currently uses the ENSIP-XX placeholder in the heading).

Open to feedback on field names, signature conventions, the dist shape, and whether the top-level envelope is the right place for signatures.

nxt3d added 3 commits March 12, 2026 11:17
- HTML manifest at contenthash listing files via URI or ERC-8121 hooks
- File entries: data-path, data-hash, data-hash-algorithm; URI (href) or hook (data-hook)
- Optional JSON manifest with bin (name→path), default (command name)
- Source indicators: ipfs: path (linked) or hook: path (non-link span)
- Full example with ensx CLI pseudocode

Made-with: Cursor
Switches the draft from an HTML wrapper with per-file URI/hook entries
to a plain JSON manifest using familiar package metadata fields, with
a top-level { manifest, signatures } envelope so signatures can attest
to the canonical manifest object.

Manifest fields now follow npm conventions where possible: name,
version, description, author, contributors, license, repository,
dependencies, devDependencies, scripts, files, bin. Distribution moves
to a dist object with exactly one of tarball or directory, addressable
via https, ipfs, data, or other URI schemes, and an SRI integrity
string for non-content-addressed sources.

Drops the HTML manifest wrapper, per-file hash/source entries, and the
ERC-8121 hook source mode. HTML or other human-facing UIs can still
load the JSON via fetch and present it; that layer is out of scope.

Adds an optional signatures array carrying EIP-191 signatures over the
manifest object so publishers can attest to releases without altering
the package metadata being signed.

Tightens path safety: package-relative paths MUST NOT be absolute,
URLs, or contain '..' segments. Security Considerations call this
out explicitly.
dist can now be either a single distribution object (unchanged) or a
non-empty array of distribution objects. When an array, clients try
entries in order; the first that successfully resolves and verifies
is used and the rest are ignored. All entries MUST resolve to the
same package contents.

This lets a manifest carry, e.g., an HTTPS tarball as the primary
source plus an IPFS fallback in the same release, without forcing
publishers to pick one or republish for each mirror.

Updates the worked example to demonstrate the array form (HTTPS
primary with SRI integrity, IPFS fallback by CID). Updates the
Client Behavior steps to read 'try entries in order' on array dist.
Integrity rules are unchanged per entry: required for non-content-
addressed sources, optional for content-addressed ones.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant