diff --git a/README.md b/README.md index cff36ad..99aa2d6 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ prove it's real without having to speak directly to the originating server. gleam add possum gleam_http gleam_json ``` -### Consulting your DID +### Decentralized Identifiers (DIDs) ```gleam import gleam/http/request @@ -35,20 +35,16 @@ request.new() |> request.set_host("slingshot.microcosm.blue") |> possum.resolve_handle("gleam.run") -// You also verify your DID without DNS by sending a request to `/.well-know/atproto-did` -// Your server can then respond with the DID value as plain text. -request.new() -|> possum.resolve_well_known_did("gleam.run") - // Use `did.parse` to turn strings into valid DID format let assert Ok(did) = did.parse("did:plc:ewvi7nxzyoun6zhxrhs64oiz") ``` -### Querying Public Data +### Building HTTP Requests ```gleam import gleam/http/request import possum +import possum/did let assert Ok(did) = did.parse("did:plc:ewvi7nxzyoun6zhxrhs64oiz") diff --git a/gleam.toml b/gleam.toml index 4f6d47b..aa79575 100644 --- a/gleam.toml +++ b/gleam.toml @@ -4,12 +4,20 @@ version = "1.0.9" description = "🐀 ATproto library for gleam" licences = ["Apache-2.0"] repository = { type = "tangled", user = "kacaii.dev", repo = "possum" } + links = [ { title = "AT Protocol", href = "https://atproto.com/" }, { title = "Bluesky HTTP API Reference", href = "https://endpoints.bsky.app/" }, { title = "Blogpost: A Social File System", href = "https://overreacted.io/a-social-filesystem/" }, ] +[documentation] +pages = [ + { title = "Consulting your DID", path = "consulting-your-did.html", source = "./pages/consulting-your-did.md" }, + { title = "Accessing your PDS", path = "accessing-your-pds.html", source = "./pages/accessing-your-pds.md" }, +] + + [dependencies] gleam_stdlib = ">= 1.0.0 and < 2.0.0" gleam_http = ">= 4.3.0 and < 5.0.0" diff --git a/pages/accessing-your-pds.md b/pages/accessing-your-pds.md new file mode 100644 index 0000000..3a8be1b --- /dev/null +++ b/pages/accessing-your-pds.md @@ -0,0 +1,40 @@ +# Accessing your PDS + +PLC is a persistent global identifier system, stands for "Public Ledger of Credentials", +it's a persistent global identifier system, which allows accounts to retain relationships +while changing names or migrating between service providers + +DID resolution can be as simple as: + +```gleam +import gleam/http/request +import possum + +let assert Ok(did) = did.parse("did:plc:z72i7hdynmk6r22z27h6tvur") + +request.new() +|> possum.get_plc_data(did) +``` + +## Response + + ```json +{ + "did": "string", + "verificationMethods": { + "atproto": "string" + }, + "rotationKeys": [ + "string", + "string" + ], + "alsoKnownAs": [ + "string" + ], + "services": { + "atproto_pds": { + "type": "string", + "endpoint": "string" + } +} +``` diff --git a/pages/consulting-your-did.md b/pages/consulting-your-did.md new file mode 100644 index 0000000..22df2bc --- /dev/null +++ b/pages/consulting-your-did.md @@ -0,0 +1,41 @@ +# Consulting your DID + +Users in AT Protocol have permanent decentralized identifiers (DIDs) for their accounts. +They also have a configurable domain name, which acts as a human-readable handle. +An example DID is `did:plc:ewvi7nxzyoun6zhxrhs64oiz.` + +```gleam +// Use `did.parse` to turn strings into valid DID format +let assert Ok(did) = did.parse("did:plc:ewvi7nxzyoun6zhxrhs64oiz") +``` + +## Handle Resolution + +Handles have a limited role in atproto, and need to be resolved to a DID in almost +all situations. Clients can rely on network services (eg, their PDS) to resolve +handles for them, using the `com.atproto.identity.resolveHandle` endpoint, and +don't usually need to implement resolution directly themselves. + +```gleam +// You can consult your identifier by sending a request directly to your PDS, +// or you can use projects like [Slingshot](https://slingshot.microcosm.blue) +// for easy access to cached data when resolving a handle. +request.new() +|> request.set_host("slingshot.microcosm.blue") +|> possum.resolve_handle("gleam.run") +``` + +## HTTPS well-known Method + +A web server at the handle domain implements a special well-known endpoint at the +path `/.well-known/atproto-did.` A valid HTTP response will have an HTTP success +status (2xx) and include the DID as the HTTP body with no prefix or wrapper formatting. + +```gleam +// You also verify your DID without DNS by sending a request to `/.well-know/atproto-did` +// Your server can then respond with the DID value as plain text. +// +// The response Content-Type header does not need to be strictly verified. +request.new() +|> possum.resolve_well_known_did("gleam.run") +``` diff --git a/src/possum.gleam b/src/possum.gleam index 3d4577b..9c22d21 100644 --- a/src/possum.gleam +++ b/src/possum.gleam @@ -59,9 +59,14 @@ const com_atproto_server = "xrpc/com.atproto.server" /// import gleam/http/request /// import possum /// +/// let assert Ok(did) = did.parse("did:plc:z72i7hdynmk6r22z27h6tvur") +/// /// let request = /// request.new() -/// |> possum.get_plc_data("did:plc:z72i7hdynmk6r22z27h6tvur") +/// |> possum.get_plc_data(did) +/// +/// // You can use this decoder to extract the server endpoint +/// let decoder = decode.at(["services", "atproto_pds", "endpoint"], decode.string) /// ``` /// /// ## Response diff --git a/src/possum/did.gleam b/src/possum/did.gleam index 2e921ac..7929fdd 100644 --- a/src/possum/did.gleam +++ b/src/possum/did.gleam @@ -23,9 +23,9 @@ pub type DidError { } /// AT Protocol uses Decentralized Identifiers (DIDs) as persistent account -/// identifiers. An example DID is did:plc:ewvi7nxzyoun6zhxrhs64oiz. +/// identifiers. An example DID is `did:plc:ewvi7nxzyoun6zhxrhs64oiz`. /// -/// Documentation: [DID](https://atproto.com/specs/did) +/// Documentation: [Decentralized Identifiers](https://atproto.com/specs/did) pub opaque type Did { Did(method: Method, identifier: String) } @@ -87,7 +87,7 @@ pub fn decoder() -> decode.Decoder(Did) { case parse(value) { Ok(did) -> decode.success(did) - Error(_) -> decode.failure(Did(Plc, "wibblewobble"), "DID") + Error(_) -> decode.failure(Did(method: Plc, identifier: "possum"), "DID") } }