My own corner of monopam
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

README.md

did#

Decentralized Identifiers for OCaml.

Implements the W3C DID Core 1.0 syntax and document data model, with method-specific resolvers for did:web and did:plc shipped as sublibraries. A DID is a URI of the form did:<method>:<method-specific-id> that identifies a subject without a centralised registry; resolution yields a DID document describing verification methods and service endpoints.

Packages#

  • did — pure DID syntax and document data model.
  • did-webdid:web resolver (HTTPS).
  • did-plcdid:plc resolver (plc.directory lookup).

Installation#

Install with opam:

$ opam install did did-web did-plc

If opam cannot find the packages, they may not yet be released in the public opam-repository. Add the overlay repository, then install them:

$ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
$ opam update
$ opam install did did-web did-plc

Usage#

Syntax#

Parse a DID and extract its method and method-specific id:

# let did = Did.of_string_exn "did:plc:z72i7hdynmk6r22z27h6tvur" in
  (Did.method_name did, Did.method_specific_id did)
- : string * string = ("plc", "z72i7hdynmk6r22z27h6tvur")

Method names must be lowercase; the method-specific id preserves case:

# Did.of_string "did:Web:example.com"
- : (Did.t, Did.error) result =
Error (`Msg "invalid character 'W' in DID method name at offset 4")

URL construction#

did:web resolution is a pure function of the DID. The spec maps method-specific ids to HTTPS paths using : as a segment separator:

# Did_web.url_of_did (Did.of_string_exn "did:web:example.com")
- : (string, Did.error) result =
Ok "https://example.com/.well-known/did.json"
# Did_web.url_of_did (Did.of_string_exn "did:web:example.com:users:alice")
- : (string, Did.error) result =
Ok "https://example.com/users/alice/did.json"

Resolution#

did:web and did:plc resolvers require an Eio runtime:

let resolve_web env did =
  Eio.Switch.run @@ fun sw ->
  match
    Did_web.resolve
      ~sw ~clock:(Eio.Stdenv.clock env) ~net:(Eio.Stdenv.net env) did
  with
  | Ok doc -> Fmt.pr "resolved: %a@." Did.Document.pp doc
  | Error e -> Fmt.pr "failed: %a@." Did_web.pp_error e

Service lookup#

A DID document indexes service endpoints by id (fragment) and by type. ATProto uses #atproto_pds:

# let did = Did.of_string_exn "did:web:example.com" in
  let doc =
    Did.Document.v
      ~service:[{
        id = "#atproto_pds";
        type_ = ["AtprotoPersonalDataServer"];
        service_endpoint = "https://pds.example.com";
      }]
      did in
  Option.map
    (fun (s : Did.Document.service) -> s.service_endpoint)
    (Did.Document.service_by_id doc "#atproto_pds")
- : string option = Some "https://pds.example.com"

Licence#

ISC