The Seed daemon
The Go node at the centre of every Seed installation, where it stores data, what it listens on, which flags matter, and what its local API does and does not protect.

The Seed daemon, seed-daemon, is the program that implements the Hypermedia protocol. It stores signed blobs, verifies and indexes them, keeps account keys, syncs with other nodes over libp2p, and serves everything to the apps through gRPC and HTTP. The desktop app spawns one for you. A site runs one in a container. The CLI and the agents service never need one, because they talk to a site's Seed API.

Where the code is

The daemon lives in backend/, written in Go. The entry point is backend/cmd/seed-daemon. The main packages are backend/blob (blob types, verification, the indexer), backend/api (the gRPC services), backend/hmnet (libp2p, sync, the file gateway), backend/storage (SQLite schema and migrations), backend/core (keys and signing) and backend/config (flags). The protobuf definitions are in proto/ and generate both the Go server and the TypeScript clients. Run ./dev gen after changing them.

Other binaries beside the daemon: monitord (health checks of sites), relayd (a libp2p relay), pingp2p (connectivity test), seed-sqlite and mkdb (database tooling).

What it listens on

Listener

Flag

Default

Serves

libp2p

-p2p.port

55000

peer-to-peer sync and the P2P RPCs

HTTP

-http.port

55001

gRPC-web for every service, /ipfs/*, /hm/api/config, /debug/*

gRPC

-grpc.port

55002

the same services over plain gRPC

Both gRPC and HTTP bind all interfaces, so other machines can reach them unless a firewall blocks them. The desktop app passes its own ports, listed on its page. A daemon you run yourself keeps the 55000 defaults. Every flag can also be set as an environment variable with the SEED_ prefix, so -p2p.port is SEED_P2P_PORT. SEED_DAEMON_FLAGS prepends extra flags.

Flags that matter to operators

Flag

Default

Meaning

-data-dir

~/.mtt

Where everything is stored. The desktop app passes its own data directory.

-public-only

false

Serve only public data in the APIs and over HTTP. Hosted sites and gateways use this mode.

-keystore-dir

empty

Use a file-based keystore in place of the OS keychain or vault. It is marked insecure. Sites use it inside their container.

-p2p.testnet-name

empty

Joins a named testnet in place of mainnet by adding a suffix to the protocol id.

-p2p.no-relay

false

Disables circuit relay.

-p2p.bootstrap-peers

the Seed gateways and the public IPFS bootstrap peers

The peers a fresh node connects to first.

-syncing.no-discovery

false

Refuse to fetch content the node does not have, turning off discovery.

-syncing.no-pull

false

Disable the sync scheduler, which also runs every DiscoverEntity request and subscription rerun.

-log-level

info

debug, info, warning or error.

Network lists every timeout and constant. Self-hosting shows the flags a site container uses.

What it stores

The data directory holds three things.

    keys/libp2p_id_ed25519 is the device key. It is separate from every account key.

    vault.json is the encrypted local keystore for account keys. A secret in the OS keychain decrypts it.

    db/db.sqlite is the SQLite database. It holds every blob, the index derived from them, full-text search, and the domain store.

The schema in backend/storage/schema.sql is the source of truth, and migrations only go forward. Reindexing rebuilds everything derived from the blobs and can take a long time on a large node. A debug flag forces a reindex with profiling.

The HTTP surface

Besides gRPC-web, the HTTP port serves the file gateway and a few utility routes.

    GET /ipfs/<cid> returns a file or block. If the node does not have it, the daemon searches the network for up to a minute. GET /ipfs/<cid>.dagjson decodes a DAG-CBOR blob and pretty-prints it. It is the quickest way to inspect a change, ref or comment. POST /ipfs/file-upload chunks a file into UnixFS and returns its CID. POST /ipfs/<cid> stores one raw block. Both uploads accept up to 150 MiB and require no authentication. See Files.

    GET /hm/api/config on the daemon returns its peer id, addresses and protocol id. The web app's version of the same route adds the registered account.

    GET /debug/version reports the build. The other /debug/* pages answer only to loopback callers that send no cross-site fetch header. They cover metrics, pprof, the p2p and network reports, the SQLite pool and an embedded grpcui.

Authentication, plainly

The local gRPC and HTTP API has no authentication. Whoever can reach the port can read everything the node holds and can write as any key the node keeps, because signing happens inside the daemon. Bearer tokens exist, but they only widen reads on a public-only node. They never gate writes. The mitigations are deliberate and simple. Keep the ports on localhost or behind a firewall. Run any daemon that faces the internet with -public-only behind the web app. Sites are deployed this way. Integrity spells out what is verified and what is trusted.

Working with it

In the Seed app

The desktop app starts the daemon, waits for /debug/version, and then starts its own API bridge and the local agents server. Its settings show the daemon's peer id and addresses.

CLI

The CLI does not need a local daemon. seed-cli space dev talks to the desktop's API bridge and the daemon's HTTP port to publish a folder into the running app; see Publish a folder.

SDK

The SDK targets the Seed API. It does not call the daemon. The daemon's protobuf messages are available to TypeScript through the generated clients in @shm/shared.

Web API

The web app answers every site's /api/<Key> routes by calling the daemon over gRPC-web. Over plain HTTP, the daemon itself serves only /ipfs and /hm/api/config. Building with gRPC lists the services for direct callers.

Agents

Seed Agents read and write through a site's Seed API and fetch media from the daemon's /ipfs route. In the desktop app they use the bundled daemon through the API bridge. Hosted agents use hyper.media.

Do you like what you are reading? Subscribe to receive updates.

Unsubscribe anytime