Expand description
Resolving a DID to its DID document, dispatched by method.
Two methods are supported. did:web — see the next section for why this
crate ships its own implementation rather than a library’s. did:plc
resolves by fetching https://plc.directory/<did> from the PLC
directory: no hostname to build, no percent-decoding, none of the
did:web hazards below apply. A DID of any other method is refused with
ResolveError::UnsupportedMethod naming the method, rather than
quietly answering “no document” for something this resolver simply does
not speak.
§Why this crate ships its own did:web resolver
jacquard-identity 0.12.1 builds the fetch URL by concatenating https://
with the method-specific identifier verbatim. Neither half of that works
for a development DID:
- The identifier is never percent-decoded, so
did:web:localhost%3A3000becomes a request for a host literally namedlocalhost%3A3000, which no resolver, DNS or otherwise, will ever answer. - The scheme is hardcoded to
https://, and nothing is listening on TLS on a developer’s loopback interface.
Both are correct for the production case that library targets. Neither is
fixable from outside it, and atproto explicitly permits the shape they
break: “The special localhost hostname is allowed, but only in testing
and development environments. Port numbers (with separating colon
hex-encoded) are only allowed for localhost, and only in testing and
development.” That did:web path is unchanged here.
did:plc is a different code path: no hostname is built from the
identifier and there is nothing to percent-decode, so jacquard-identity’s
objection above does not apply to it. This module still does not depend
on it. A did:plc resolves by a direct fetch to the directory over
DidDocumentSource, this module’s own transport trait, rather than
through jacquard-identity’s IdentityResolver, which is a much larger
surface (handle resolution, DNS, Slingshot fallbacks) built around its
own client trait and several dependencies (bon, http, n0_future,
optionally hickory_resolver) this crate does not otherwise need.
§Why the transport is a trait
No HTTP client is a dependency here. The fetch is a trait so that the PDS
crate can supply the real transport with whatever client and runtime it
already has, and so that every test in this crate runs against
InMemoryDocuments with no network access at all. A real transport is
also what makes ResolveError::NotFound and ResolveError::Transport
meaningfully different: the directory answering “no such DID” and the
directory being unreachable are different facts, and only the transport
that made the request can tell them apart.
Structs§
- InMemory
Documents - A
DidDocumentSourcebacked by a map from URL to response body.
Enums§
- Resolve
Error - Why resolution failed.
Constants§
- DEFAULT_
PLC_ DIRECTORY - The PLC directory
did:plcresolves against. - PLC_
IDENTIFIER_ 🔒LENGTH - Length of the identifier in a
did:plc.
Traits§
- DidDocument
Source - Where DID document bodies come from.
Functions§
- document_
url - The URL
did’s document lives at, or whydidcannot be resolved at all. - is_
plc_ 🔒identifier - Whether
identifieris the base32-sortable body of adid:plc. - resolve
- Resolves
didthroughsourceand verifies the result belongs to it.