Skip to content

Repository files navigation

enspack

Name, verify and fetch model weights without depending on any single host.

enspack get qwen--qwen2-5-7b-instruct.mirrors.enspack.eth
# resolves ENS → content-addressed manifest → torrent + webseeds → SHA-256 per file → HF cache

An ENS name owned by the publisher points at a manifest (IPFS CID in contenthash). The manifest lists every file with its SHA-256 and how to get the bytes (BitTorrent with HF / Hugging Bay webseeds, optional OCI and IPFS). Versions are subnames (v1-0-0.<model>.<publisher>.enspack.eth); a project pins them in enspack.lock and reproduces its model set with enspack install.

  • SPEC.md — protocol (frozen at enspack/0.1)
  • MVP.md — work packages, interfaces, service contracts
  • AGENTS.md — rules for agents building this repo
  • BOOTSTRAP.md — how the first models and publishers get on
  • schema/ — JSON Schemas for enspack.json and enspack.lock
  • examples/ — a real manifest for Qwen2.5-7B-Instruct (real hashes, placeholder infohash)

Hugging Face is upstream, not a competitor: hashes come from HF's LFS metadata, webseeds point at pinned HF revisions, and enspack publish --from-hf is the main publishing path. What enspack adds is the layer HF doesn't have: a publisher-owned name, host-independent verification, and a lockfile.

60-second quickstart

Requires Node 22+ and pnpm 9.

npm i -g @enspack/cli
# or from this repo:
pnpm --filter @enspack/cli build && node packages/cli/bin/enspack.js --help

enspack get qwen--qwen2-5-7b-instruct.mirrors.enspack.eth
# requires the name to exist on mainnet with a seeded torrent — see Status

# pin a model into a project and reproduce it later
enspack add qwen--qwen2-5-7b-instruct.mirrors.enspack.eth
enspack install
# writes / reads enspack.lock; CID mismatch exits 3 unless --update

ensget is an alias for enspack get. Human messages go to stderr; --json prints one JSON object to stdout. Global --chain mainnet|sepolia defaults to mainnet. --ens-version v1|v2 (or ENSPACK_ENS_VERSION) selects ENSv1 vs ENSv2; Sepolia defaults to v2. Flags: enspack <cmd> --help. See docs/ens-v2.md.

The live get of the Qwen mirror requires Sepolia/mainnet infra that is not published yet (MVP.md §0.1). Local proof uses Anvil + test/fixtures/tiny-model/ (test/e2e).

Repo map

Path Package Role
packages/core @enspack/core labels, schema, ENS read/write, IPFS verified fetch, installer, lockfile
packages/hf @enspack/hf Hugging Face tree/license + Hugging Bay client
packages/torrent @enspack/torrent metainfo, aria2c downloader, SHA-256 verifier
packages/cli @enspack/cli enspack / ensget binaries
services/seed @enspack/seed seed node API + qBittorrent + Kubo compose
services/registrar @enspack/registrar HF-proof → enspack.eth publisher subnames
services/indexer @enspack/indexer Ponder indexer + JSON API
apps/site @enspack/site catalog site, read-only view of the indexer API
bootstrap/ @enspack/bootstrap models.yaml mirror runner (`enspack-bootstrap plan
infra/ @enspack/infra one-box Sepolia deploy (Caddy + compose + scripts)
test/fixtures tiny-model folder + torrent for swarm tests
test/e2e @enspack/e2e local Anvil swarm (CI) + Sepolia (nightly)

Docs: docs/publishing.md, docs/registrar.md, docs/seed-node.md, docs/indexer.md, docs/exit-codes.md, docs/ens-v2.md.

Deploy (Sepolia MVP)

One Docker VM (Caddy + qBittorrent + Kubo + seed + registrar + indexer): infra/README.md.

Development

pnpm install
pnpm check          # build + lint + typecheck + test (includes local e2e)

Anvil mainnet-fork tests use ETH_RPC_URL when set, otherwise they rotate through public endpoints (publicnode, 1rpc, drpc) and pin the fork a few blocks behind head. anvil (~/.foundry/bin) and aria2c are required for fork/swarm suites; they skip when missing.

Secrets stay in env (ETH_RPC_URL, SEPOLIA_RPC_URL, ENSPACK_PUBLISHER_KEY, ENSPACK_OPERATOR_KEY, HF_TOKEN, PINATA_JWT). Never write them to disk or logs. CLI env vars: packages/cli/src/defaults.ts and enspack --help.

Status

Honest against MVP.md §0. Live path is Sepolia ENSv2; mainnet v1 later. Local CI is the Anvil fork + fixture swarm, not mainnet.

MVP §0 Claim Status
1 enspack get qwen--qwen2-5-7b-instruct.mirrors.enspack.eth on a clean machine Blocked on Sepolia enspack.eth / mirrors setup + seedbox (BOOTSTRAP.md). Live path is Sepolia ENSv2; mainnet v1 later. Local equivalent proven in test/e2e (sepolia-fork.e2e.test.ts on an Anvil Sepolia fork, plus mainnet v1 local-swarm.e2e.test.ts).
2 enspack publish --from-hf ≤ 3 txs Sepolia ENSv2: 4 txs new model / 2 new version (plus setup). Proven on Anvil Sepolia fork. V1 mainnet remains 3/2. Live --from-hf requires Sepolia/HF.
3 HF user claims <user>.enspack.eth with no human Blocked on registrar deploy + Sepolia enspack.eth UserRegistry. V2 issuance is 2 txs. Claim HTTP is implemented; live Sepolia E2E is unproven.
4 enspack.lock + enspack install; refuse if CID changed Proven locally (packages/cli lock tests + test/e2e add/install/--frozen + lock-mismatch exit 3).
5 GET https://index.enspack.dev/v1/names lists mainnet names Blocked on indexer deploy + mainnet names. API contract is implemented.
6 ≥ 25 mirrored models under mirrors.enspack.eth seeded Blocked on seedbox + WP-12 live run. bootstrap/models.yaml is the list.

Nightly (.github/workflows/e2e-nightly.yml, 03:00 UTC) runs @enspack/e2e with Sepolia secrets when present; the Sepolia suite self-skips without them.

About

Named, verifiable, host-independent distribution of model weights. ENS name → content-addressed manifest → torrent + webseeds → SHA-256 verified install.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages