very fast at protocol indexer with flexible filtering, xrpc queries, cursor-backed event stream, and more, built on fjall

resolver: #atproto signing key per the DID spec; two relay/jetstream doc notes #39

Merged bunny.fae.mom
targeting main from bunny.fae.mom/hydrant:spec-key-and-docs
Merged opened by and assigned to bunny.fae.mom
targeting main from bunny.fae.mom/hydrant:spec-key-and-docs

Three small things from running hydrant as a multi-relay Jetstream source for wisp.place's webhook service.

[resolver] take the signing key from the #atproto verification method

jacquard-common 0.12's atproto_public_key returns the first Multikey in verificationMethod, whatever its id. The DID spec (https://atproto.com/specs/did) says:

The public atproto signing key for the account is found under the verificationMethod array, in an object with id ending #atproto, the controller matching the DID itself, and type matching the fixed string Multikey. The first valid atproto signing key in the array should be used, and any others ignored.

did:web:offbeatwit.ch lists #atproto_old before #atproto, so every commit of theirs logged "commit signature verification failed" and was dropped, while the bsky relays accepted them. decode_mini_doc now picks the key by that rule. The new resolver test (old key listed first) fails without the change. Resolver tests pass with default features and with relay,jetstream.

The same bug is in jacquard itself; a fix for DidDocument::atproto_multikey and jacquard-axum's service auth is going upstream separately. This change can be dropped once hydrant is on a jacquard release with it.

[docs] two notes

  • concepts/relay.md: a relay build seeds https://bsky.network from SEED_HOSTS by default, which adds a firehose per PDS on top of RELAY_HOSTS. To follow only the listed relays, set HYDRANT_SEED_HOSTS= (empty).
  • api/jetstream.md: a single trusted consumer that has to catch up fast can leave jetstream out of HYDRANT_THROTTLED_STREAMS to replay uncapped.
Commits 2

[docs] note relay builds seed bsky.network, and uncapped jetstream replay
[resolver] take the signing key from the #atproto verification method