A Ruby library for resolving Decentralized Identifiers (DIDs) according to the W3C DID Core specification.
Inspired by the Decentralized Identity Foundation's did-resolver JavaScript library.
- Pluggable Architecture: Easily add support for new DID methods
- Built-in Method Resolvers:
did:web- Resolve DIDs from web domainsdid:key- Self-describing DIDs with embedded public keysdid:jwk- DIDs with embedded JWK (JSON Web Key)
- Caching: Optional in-memory caching with TTL support
- Standards Compliant: Follows W3C DID Core specification for resolution results
- EBSI Support: Supports
jwk_jcs-pubmulticodec (0xeb51) for EBSI compatibility
Add this line to your application's Gemfile:
gem 'did_resolver'And then execute:
$ bundle installOr install it yourself as:
$ gem install did_resolverrequire 'did_resolver'
# Resolve a DID using the default resolver
result = DidResolver::Resolver.resolve("did:web:example.com")
if result.error?
puts "Error: #{result.error_message}"
else
puts result.did_document.to_h
endrequire 'did_resolver'
# Create a resolver with specific methods and caching
resolver = DidResolver::Resolver.new(
DidResolver::Methods::Web.resolver,
DidResolver::Methods::Key.resolver,
DidResolver::Methods::Jwk.resolver,
cache: true # Enable default in-memory cache
)
# Resolve a did:key
result = resolver.resolve("did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK")
did_document = result.did_document
# Access verification methods
did_document.verification_method.each do |vm|
puts "Key ID: #{vm['id']}"
puts "Type: #{vm['type']}"
endresult = resolver.resolve("did:web:example.com")
doc = result.did_document
# Find a specific verification method
vm = doc.find_verification_method("#key-1")
# Get verification methods for a purpose
auth_keys = doc.verification_methods_for(:authentication)
# Extract public key info
key_info = doc.first_public_key_for(:assertion_method)
# => { id: "did:...#key-1", type: "JsonWebKey2020", format: :jwk, value: {...} }Resolves DIDs from web domains by fetching /.well-known/did.json or a custom path.
# Standard domain
resolver.resolve("did:web:example.com")
# => fetches https://example.com/.well-known/did.json
# With path
resolver.resolve("did:web:example.com:users:alice")
# => fetches https://example.com/users/alice/did.json
# With port
resolver.resolve("did:web:localhost%3A8080")
# => fetches https://localhost:8080/.well-known/did.jsonSelf-describing DIDs with the public key encoded in the identifier.
# Ed25519 key
resolver.resolve("did:key:z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK")
# P-256 key
resolver.resolve("did:key:zDnaerDaTF5BXEavCrfRZEk316dpbLsfPDZ3WJ5hRTPFU2169")
# EBSI jwk_jcs-pub format
resolver.resolve("did:key:z2dmzD81cgPx8Vki7JbuuMmFYrWPgYoytykUZ3eyqht1j9KbrD...")Supported key types:
- Ed25519 (0xed)
- X25519 (0xec)
- secp256k1 (0xe7)
- P-256 (0x1200)
- P-384 (0x1201)
- P-521 (0x1202)
- RSA (0x1205)
- jwk_jcs-pub (0xeb51) - EBSI format
DIDs with a base64url-encoded JWK as the identifier.
# EC P-256 key
jwk = { "kty" => "EC", "crv" => "P-256", "x" => "...", "y" => "..." }
encoded = Base64.urlsafe_encode64(jwk.to_json, padding: false)
resolver.resolve("did:jwk:#{encoded}")# Use default cache (5 minute TTL)
resolver = DidResolver::Resolver.new(
DidResolver::Methods::Web.resolver,
cache: true
)
# Custom TTL
cache = DidResolver::Cache.new(ttl: 3600) # 1 hour
resolver = DidResolver::Resolver.new(
DidResolver::Methods::Web.resolver,
cache: cache
)
# Skip cache for a specific resolution
result = resolver.resolve("did:web:example.com", no_cache: true)module DidResolver
module Methods
class MyMethod
class << self
def resolver
{ "mymethod" => method(:resolve) }
end
def resolve(did, parsed, resolver, options = {})
# parsed.did - the base DID
# parsed.method - "mymethod"
# parsed.id - method-specific identifier
# Your resolution logic here...
did_document = DIDDocument.new(id: did, ...)
ResolutionResult.success(did_document)
rescue => e
ResolutionResult.error("internalError", e.message)
end
end
end
end
end
# Register the custom resolver
resolver = DidResolver::Resolver.new(
DidResolver::Methods::MyMethod.resolver
)After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests.
bundle install
bundle exec rake spec
bundle exec rubocopBug reports and pull requests are welcome on GitHub.
The gem is available as open source under the terms of the Apache License 2.0.