Add per-channel hashcash requirement via MODE +H <bits>. When set,
PRIVMSG to the channel must include a valid hashcash stamp in the
meta.hashcash field bound to the channel name and message body hash.
Server validates stamp format, difficulty, date freshness, channel
binding, body hash binding, and proof-of-work. Spent stamps are
persisted to SQLite with 1-year TTL for replay prevention.
Stamp format: 1:bits:YYMMDD:channel:bodyhash:counter
Changes:
- Schema: add hashcash_bits column to channels, spent_hashcash table
- DB: queries for get/set channel hashcash bits, spent token CRUD
- Hashcash: ChannelValidator, BodyHash, StampHash, MintChannelStamp
- Handlers: validate hashcash on PRIVMSG, MODE +H/-H support
- Pass meta through fanOut chain to store in messages
- Prune spent hashcash tokens in cleanup loop (1-year TTL)
- Client: MintChannelHashcash helper for CLI
- Tests: 12 new channel_test.go + 10 new api_test.go integration tests
- README: document +H mode, stamp format, and usage
## Changes
- Change `Appname` from `"chat"` to `"neoirc"` in `cmd/chatd/main.go`
- Change default `DBURL` from `file:./data.db?_journal_mode=WAL` to `file:///var/lib/neoirc/state.db?_journal_mode=WAL` in both `internal/config/config.go` and the `internal/db/db.go` fallback
- Create `/var/lib/neoirc/` directory in Dockerfile with proper ownership for the `chat` user
- Update README.md to reflect new defaults (DBURL table, `.env` example, docker run example, SQLite backup/location docs)
- Remove stale `data.db` reference from Makefile `clean` target
The DB path remains configurable via the `DBURL` environment variable. No Go packages were renamed.
Closes #44
Co-authored-by: clawbot <clawbot@noreply.eeqj.de>
Reviewed-on: #45
Co-authored-by: clawbot <clawbot@noreply.example.org>
Co-committed-by: clawbot <clawbot@noreply.example.org>