Add SQLite-backed IPFS storage, minimal libp2p, and infrastructure hardening
Replace filesystem-based Helia storage with SQLite:
- SqliteBlockstore: implements Blockstore interface backed by ipfs_blocks table,
eliminating thousands of tiny files from FsBlockstore
- SqliteDatastore: implements Datastore interface backed by ipfs_datastore table,
replacing FsDatastore for libp2p peer/routing state
- All persistent state now lives in a single pds.db file
Strip libp2p down to minimal config (TCP + noise + yamux + identify only):
- Remove DHT, gossipsub, relay, autoNAT, UPnP, dcutr, WebRTC, ping
- These services pegged CPU connecting to random peers on the public network
- P2PDS dials known peers directly using multiaddrs from peer records
Harden auth and server lifecycle for OAuth mode:
- Guard legacy JWT endpoints (createSession, refreshSession, getSession)
against missing config when OAUTH_ENABLED=true — return 501 instead of crash
- Guard auth middleware against undefined PDS_HOSTNAME/JWT_SECRET
- Register SIGINT/SIGTERM handlers before awaiting startServer() so shutdown
signals during startup are handled cleanly
Add two-node manual testing scripts:
- scripts/start-node.sh: build + start a single node on a random port
- scripts/start-both.sh: start two nodes with separate data dirs
- scripts/stop-both.sh: stop both nodes
- scripts/clean.sh: wipe data for both nodes (preserves .env files)
- scripts/logs.sh: show recent logs
- scripts/test-add-did.sh: offer a DID on a running node
- npm scripts: start:node1, start:node2, start:both, stop, clean, logs, test:add-did
Update README with current architecture, configuration, and project structure.
Update .gitignore for test artifacts (data-node2/, plans/, .claude/settings.local.json).