My own corner of monopam
2
fork

Configure Feed

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

did: expand README with MDX-tested examples

Build out the stub into a full README: DID syntax with method/id
component extraction, the case-sensitivity rule for method names,
did:web URL construction for both bare-domain and path-segmented
variants, a let-bound Eio resolver sketch, and service lookup by
fragment id using Did.Document.v.

Wire README.md into MDX via the (mdx ...) dune stanza so
dune runtest type-checks every example on every build.

+99 -10
+95 -10
ocaml-did/README.md
··· 1 1 # did 2 2 3 - Decentralized Identifiers (DIDs) per W3C DID Core 1.0. 3 + Decentralized Identifiers for OCaml. 4 + 5 + Implements the [W3C DID Core 1.0][did-core] syntax and document data 6 + model, with method-specific resolvers for [`did:web`][did-web] and 7 + [`did:plc`][did-plc] shipped as sublibraries. A DID is a URI of the 8 + form `did:<method>:<method-specific-id>` that identifies a subject 9 + without a centralised registry; resolution yields a DID document 10 + describing verification methods and service endpoints. 11 + 12 + [did-core]: https://www.w3.org/TR/did-1.0/ 13 + [did-web]: https://w3c-ccg.github.io/did-method-web/ 14 + [did-plc]: https://web.plc.directory/spec/v0.1/did-plc 4 15 5 16 ## Packages 6 17 7 - - `did` - Core DID syntax and document support. 8 - - `did-plc` - did:plc resolver for the Public Ledger of Credentials. 9 - - `did-web` - did:web resolver. 18 + - `did` — pure DID syntax and document data model. 19 + - `did-web` — `did:web` resolver (HTTPS). 20 + - `did-plc` — `did:plc` resolver (plc.directory lookup). 10 21 11 22 ## Installation 12 23 13 24 Install with opam: 14 25 26 + <!-- $MDX skip --> 15 27 ```sh 16 - opam install did did-plc did-web 28 + $ opam install did did-web did-plc 17 29 ``` 18 30 19 - If opam cannot find the packages, they may not yet be released in the public 20 - `opam-repository`. Add the overlay repository, then install them: 31 + If opam cannot find the packages, they may not yet be released in 32 + the public `opam-repository`. Add the overlay repository, then 33 + install them: 21 34 35 + <!-- $MDX skip --> 22 36 ```sh 23 - opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git 24 - opam update 25 - opam install did did-plc did-web 37 + $ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git 38 + $ opam update 39 + $ opam install did did-web did-plc 40 + ``` 41 + 42 + ## Usage 43 + 44 + ### Syntax 45 + 46 + Parse a DID and extract its method and method-specific id: 47 + 48 + ```ocaml 49 + # let did = Did.of_string_exn "did:plc:z72i7hdynmk6r22z27h6tvur" in 50 + (Did.method_name did, Did.method_specific_id did) 51 + - : string * string = ("plc", "z72i7hdynmk6r22z27h6tvur") 52 + ``` 53 + 54 + Method names must be lowercase; the method-specific id preserves 55 + case: 56 + 57 + ```ocaml 58 + # Did.of_string "did:Web:example.com" 59 + - : (Did.t, Did.error) result = 60 + Error (`Msg "invalid character 'W' in DID method name at offset 4") 61 + ``` 62 + 63 + ### URL construction 64 + 65 + `did:web` resolution is a pure function of the DID. The spec maps 66 + method-specific ids to HTTPS paths using `:` as a segment separator: 67 + 68 + ```ocaml 69 + # Did_web.url_of_did (Did.of_string_exn "did:web:example.com") 70 + - : (string, Did.error) result = 71 + Ok "https://example.com/.well-known/did.json" 72 + # Did_web.url_of_did (Did.of_string_exn "did:web:example.com:users:alice") 73 + - : (string, Did.error) result = 74 + Ok "https://example.com/users/alice/did.json" 75 + ``` 76 + 77 + ### Resolution 78 + 79 + `did:web` and `did:plc` resolvers require an Eio runtime: 80 + 81 + ```ocaml 82 + let resolve_web env did = 83 + Eio.Switch.run @@ fun sw -> 84 + match 85 + Did_web.resolve 86 + ~sw ~clock:(Eio.Stdenv.clock env) ~net:(Eio.Stdenv.net env) did 87 + with 88 + | Ok doc -> Fmt.pr "resolved: %a@." Did.Document.pp doc 89 + | Error e -> Fmt.pr "failed: %a@." Did_web.pp_error e 90 + ``` 91 + 92 + ### Service lookup 93 + 94 + A DID document indexes service endpoints by `id` (fragment) and by 95 + `type`. ATProto uses `#atproto_pds`: 96 + 97 + ```ocaml 98 + # let did = Did.of_string_exn "did:web:example.com" in 99 + let doc = 100 + Did.Document.v 101 + ~service:[{ 102 + id = "#atproto_pds"; 103 + type_ = ["AtprotoPersonalDataServer"]; 104 + service_endpoint = "https://pds.example.com"; 105 + }] 106 + did in 107 + Option.map 108 + (fun (s : Did.Document.service) -> s.service_endpoint) 109 + (Did.Document.service_by_id doc "#atproto_pds") 110 + - : string option = Some "https://pds.example.com" 26 111 ``` 27 112 28 113 ## Licence
+4
ocaml-did/dune
··· 1 1 (env 2 2 (dev 3 3 (flags :standard %{dune-warnings}))) 4 + 5 + (mdx 6 + (files README.md) 7 + (libraries did did-web eio eio.core fmt))