72e7f37b61
KtorRelay was carrying state that wasn't HTTP-specific: the Nip86Server, its InfoHolder adapter, and the adminPubkeys allow-list. Push them into RelayEngine — it already owns the info doc, ban store, and event store the Nip86Server consults; the allow-list is a relay-level "who is admin?" decision, not a transport-level one. RelayEngine gains adminPubkeys: Set<HexKey> = emptySet() and exposes nip86Server as a public property. Future non-HTTP admin transports (in-process tools, hypothetical NIP-86-over-WS) read it directly without re-deriving the wiring. KtorRelay shrinks to mostly Ktor structures — routing block, engine config, lifecycle. It just builds the Nip86HttpHandler around relay.nip86Server. Main.kt and Nip86EndToEndTest pass adminPubkeys to RelayEngine instead of KtorRelay. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>