๐Ÿ€ ATproto library for gleam
atproto library gleam
35

Configure Feed

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

docs: add pages describing how to consult your did and access your PDS

kacaii.dev (Jul 5, 2026, 4:59 PM -0300) 42690c34 328d1c39

+101 -11
+3 -7
README.md
··· 20 20 gleam add possum gleam_http gleam_json 21 21 ``` 22 22 23 - ### Consulting your DID 23 + ### Decentralized Identifiers (DIDs) 24 24 25 25 ```gleam 26 26 import gleam/http/request ··· 35 35 |> request.set_host("slingshot.microcosm.blue") 36 36 |> possum.resolve_handle("gleam.run") 37 37 38 - // You also verify your DID without DNS by sending a request to `/.well-know/atproto-did` 39 - // Your server can then respond with the DID value as plain text. 40 - request.new() 41 - |> possum.resolve_well_known_did("gleam.run") 42 - 43 38 // Use `did.parse` to turn strings into valid DID format 44 39 let assert Ok(did) = did.parse("did:plc:ewvi7nxzyoun6zhxrhs64oiz") 45 40 ``` 46 41 47 - ### Querying Public Data 42 + ### Building HTTP Requests 48 43 49 44 ```gleam 50 45 import gleam/http/request 51 46 import possum 47 + import possum/did 52 48 53 49 let assert Ok(did) = did.parse("did:plc:ewvi7nxzyoun6zhxrhs64oiz") 54 50
+8
gleam.toml
··· 4 4 description = "๐Ÿ€ ATproto library for gleam" 5 5 licences = ["Apache-2.0"] 6 6 repository = { type = "tangled", user = "kacaii.dev", repo = "possum" } 7 + 7 8 links = [ 8 9 { title = "AT Protocol", href = "https://atproto.com/" }, 9 10 { title = "Bluesky HTTP API Reference", href = "https://endpoints.bsky.app/" }, 10 11 { title = "Blogpost: A Social File System", href = "https://overreacted.io/a-social-filesystem/" }, 11 12 ] 13 + 14 + [documentation] 15 + pages = [ 16 + { title = "Consulting your DID", path = "consulting-your-did.html", source = "./pages/consulting-your-did.md" }, 17 + { title = "Accessing your PDS", path = "accessing-your-pds.html", source = "./pages/accessing-your-pds.md" }, 18 + ] 19 + 12 20 13 21 [dependencies] 14 22 gleam_stdlib = ">= 1.0.0 and < 2.0.0"
+40
pages/accessing-your-pds.md
··· 1 + # Accessing your PDS 2 + 3 + PLC is a persistent global identifier system, stands for "Public Ledger of Credentials", 4 + it's a persistent global identifier system, which allows accounts to retain relationships 5 + while changing names or migrating between service providers 6 + 7 + DID resolution can be as simple as: 8 + 9 + ```gleam 10 + import gleam/http/request 11 + import possum 12 + 13 + let assert Ok(did) = did.parse("did:plc:z72i7hdynmk6r22z27h6tvur") 14 + 15 + request.new() 16 + |> possum.get_plc_data(did) 17 + ``` 18 + 19 + ## Response 20 + 21 + ```json 22 + { 23 + "did": "string", 24 + "verificationMethods": { 25 + "atproto": "string" 26 + }, 27 + "rotationKeys": [ 28 + "string", 29 + "string" 30 + ], 31 + "alsoKnownAs": [ 32 + "string" 33 + ], 34 + "services": { 35 + "atproto_pds": { 36 + "type": "string", 37 + "endpoint": "string" 38 + } 39 + } 40 + ```
+41
pages/consulting-your-did.md
··· 1 + # Consulting your DID 2 + 3 + Users in AT Protocol have permanent decentralized identifiers (DIDs) for their accounts. 4 + They also have a configurable domain name, which acts as a human-readable handle. 5 + An example DID is `did:plc:ewvi7nxzyoun6zhxrhs64oiz.` 6 + 7 + ```gleam 8 + // Use `did.parse` to turn strings into valid DID format 9 + let assert Ok(did) = did.parse("did:plc:ewvi7nxzyoun6zhxrhs64oiz") 10 + ``` 11 + 12 + ## Handle Resolution 13 + 14 + Handles have a limited role in atproto, and need to be resolved to a DID in almost 15 + all situations. Clients can rely on network services (eg, their PDS) to resolve 16 + handles for them, using the `com.atproto.identity.resolveHandle` endpoint, and 17 + don't usually need to implement resolution directly themselves. 18 + 19 + ```gleam 20 + // You can consult your identifier by sending a request directly to your PDS, 21 + // or you can use projects like [Slingshot](https://slingshot.microcosm.blue) 22 + // for easy access to cached data when resolving a handle. 23 + request.new() 24 + |> request.set_host("slingshot.microcosm.blue") 25 + |> possum.resolve_handle("gleam.run") 26 + ``` 27 + 28 + ## HTTPS well-known Method 29 + 30 + A web server at the handle domain implements a special well-known endpoint at the 31 + path `/.well-known/atproto-did.` A valid HTTP response will have an HTTP success 32 + status (2xx) and include the DID as the HTTP body with no prefix or wrapper formatting. 33 + 34 + ```gleam 35 + // You also verify your DID without DNS by sending a request to `/.well-know/atproto-did` 36 + // Your server can then respond with the DID value as plain text. 37 + // 38 + // The response Content-Type header does not need to be strictly verified. 39 + request.new() 40 + |> possum.resolve_well_known_did("gleam.run") 41 + ```
+6 -1
src/possum.gleam
··· 59 59 /// import gleam/http/request 60 60 /// import possum 61 61 /// 62 + /// let assert Ok(did) = did.parse("did:plc:z72i7hdynmk6r22z27h6tvur") 63 + /// 62 64 /// let request = 63 65 /// request.new() 64 - /// |> possum.get_plc_data("did:plc:z72i7hdynmk6r22z27h6tvur") 66 + /// |> possum.get_plc_data(did) 67 + /// 68 + /// // You can use this decoder to extract the server endpoint 69 + /// let decoder = decode.at(["services", "atproto_pds", "endpoint"], decode.string) 65 70 /// ``` 66 71 /// 67 72 /// ## Response
+3 -3
src/possum/did.gleam
··· 23 23 } 24 24 25 25 /// AT Protocol uses Decentralized Identifiers (DIDs) as persistent account 26 - /// identifiers. An example DID is did:plc:ewvi7nxzyoun6zhxrhs64oiz. 26 + /// identifiers. An example DID is `did:plc:ewvi7nxzyoun6zhxrhs64oiz`. 27 27 /// 28 - /// Documentation: [DID](https://atproto.com/specs/did) 28 + /// Documentation: [Decentralized Identifiers](https://atproto.com/specs/did) 29 29 pub opaque type Did { 30 30 Did(method: Method, identifier: String) 31 31 } ··· 87 87 88 88 case parse(value) { 89 89 Ok(did) -> decode.success(did) 90 - Error(_) -> decode.failure(Did(Plc, "wibblewobble"), "DID") 90 + Error(_) -> decode.failure(Did(method: Plc, identifier: "possum"), "DID") 91 91 } 92 92 } 93 93