A library for handling DID identifiers used in Bluesky AT Protocol
at master 115 lines 4.4 kB view raw view rendered
1# DIDKit 🪪 2 3A small Ruby gem for handling Distributed Identifiers (DIDs) in Bluesky / AT Protocol. 4 5> [!NOTE] 6> Part of ATProto Ruby SDK: [ruby.sdk.blue](https://ruby.sdk.blue) 7 8 9## What does it do 10 11Accounts on Bluesky use identifiers like [did:plc:oio4hkxaop4ao4wz2pp3f4cr](https://plc.directory/did:plc:oio4hkxaop4ao4wz2pp3f4cr) as unique IDs, and they also have assigned human-readable handles like [@mackuba.eu](https://bsky.app/profile/mackuba.eu), which are verified either through a DNS TXT entry or a `/.well-known/atproto-did` file. This library allows you to look up any account's assigned handle using a DID string or vice versa, load the account's DID JSON document that specifies the handles and the PDS server hosting user's repo, and check if the assigned handle verifies correctly. 12 13 14## Installation 15 16To use DIDKit, you need a reasonably new version of Ruby – it should run on Ruby 2.6 and above, although it's recommended to use a version that's still getting maintainance updates, i.e. currently 3.2+. A compatible version should be preinstalled on macOS Big Sur and above and on many Linux systems. Otherwise, you can install one using tools such as [RVM](https://rvm.io), [asdf](https://asdf-vm.com), [ruby-install](https://github.com/postmodern/ruby-install) or [ruby-build](https://github.com/rbenv/ruby-build), or `rpm` or `apt-get` on Linux (see more installation options on [ruby-lang.org](https://www.ruby-lang.org/en/downloads/)). 17 18To install the gem, run in the command line: 19 20 [sudo] gem install didkit 21 22Or add this to your app's `Gemfile`: 23 24 gem 'didkit', '~> 0.3' 25 26 27## Usage 28 29The simplest way to use the gem is through the `DIDKit::DID` class, aliased as just `DID`: 30 31```rb 32did = DID.resolve_handle('jay.bsky.team') 33 # => #<DIDKit::DID:0x0... @did="did:plc:oky5czdrnfjpqslsw2a5iclo", 34 # @resolved_by=:dns, @type=:plc> 35``` 36 37This returns a `DID` object, which tells you: 38 39- the DID as a string (`#to_s` or `#did`) 40- the DID type (`#type`, `:plc` or `:web`) 41- if the handle was resolved via a DNS entry or a `.well-known` file (`#resolved_by`, `:dns` or `:http`) 42 43To go in the other direction – to find an assigned and verified handle given a DID – create a `DID` from a DID string and call `get_verified_handle`: 44 45```rb 46DID.new('did:plc:ewvi7nxzyoun6zhxrhs64oiz').get_verified_handle 47 # => "atproto.com" 48``` 49 50You can also load the DID JSON document using `#document`, which returns a `DIDKit::Document` (`DID` caches the document, so don't worry about calling this method multiple times): 51 52```rb 53did = DID.new('did:plc:ragtjsm2j2vknwkz3zp4oxrd') 54 55did.document.handles 56 # => ["pfrazee.com"] 57 58did.document.pds_host 59 # => "morel.us-east.host.bsky.network" 60``` 61 62 63### Checking account status 64 65`DIDKit::DID` also includes a few methods for checking the status of a given account (repo), which call the `com.atproto.sync.getRepoStatus` endpoint on the account's assigned PDS: 66 67```rb 68did = DID.new('did:plc:ch7azdejgddtlijyzurfdihn') 69did.account_status 70 # => :takendown 71did.account_active? 72 # => false 73did.account_exists? 74 # => true 75 76did = DID.new('did:plc:44ybard66vv44zksje25o7dz') 77did.account_status 78 # => :active 79did.account_active? 80 # => true 81``` 82 83### Configuration 84 85You can customize some things about the DID/handle lookups by using the `DIDKit::Resolver` class, which the methods in `DID` use behind the scenes. 86 87Currently available options include: 88 89- `:nameserver` - override the nameserver used for DNS lookups, e.g. to use Google's or CloudFlare's DNS 90- `:timeout` - change the connection/response timeout for HTTP requests (default: 15 s) 91- `:max_redirects` - change allowed maximum number of redirects (default: 5) 92 93Example: 94 95```rb 96resolver = DIDKit::Resolver.new(nameserver: '8.8.8.8', timeout: 30) 97 98did = resolver.resolve_handle('nytimes.com') 99 # => #<DIDKit::DID:0x0... @did="did:plc:eclio37ymobqex2ncko63h4r", 100 # @resolved_by=:dns, @type=:plc> 101 102resolver.resolve_did(did) 103 # => #<DIDKit::Document:0x0... @did=#<DIDKit::DID:...>, @json={...}> 104 105resolver.get_verified_handle(did) 106 # => 'nytimes.com' 107``` 108 109## Credits 110 111Copyright © 2026 Kuba Suder ([@mackuba.eu](https://bsky.app/profile/did:plc:oio4hkxaop4ao4wz2pp3f4cr)). 112 113The code is available under the terms of the [zlib license](https://choosealicense.com/licenses/zlib/) (permissive, similar to MIT). 114 115Bug reports and pull requests are welcome 😎