Skip to main content

Module resolve

Module resolve 

Source
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%3A3000 becomes a request for a host literally named localhost%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§

InMemoryDocuments
A DidDocumentSource backed by a map from URL to response body.

Enums§

ResolveError
Why resolution failed.

Constants§

DEFAULT_PLC_DIRECTORY
The PLC directory did:plc resolves against.
PLC_IDENTIFIER_LENGTH 🔒
Length of the identifier in a did:plc.

Traits§

DidDocumentSource
Where DID document bodies come from.

Functions§

document_url
The URL did’s document lives at, or why did cannot be resolved at all.
is_plc_identifier 🔒
Whether identifier is the base32-sortable body of a did:plc.
resolve
Resolves did through source and verifies the result belongs to it.