diff --git a/lib/didkit/did.rb b/lib/didkit/did.rb index e50dfc3..0b32328 100644 --- a/lib/didkit/did.rb +++ b/lib/didkit/did.rb @@ -1,8 +1,11 @@ require_relative 'errors' +require_relative 'requests' require_relative 'resolver' module DIDKit class DID + include Requests + def self.resolve_handle(handle) Resolver.new.resolve_handle(handle) end @@ -38,6 +41,34 @@ def web_domain did.gsub(/^did\:web\:/, '') if type == :web end + def is_known_by_relay?(relay, options = {}) + relay_host = relay.include?('://') ? URI(relay).origin : "https://#{relay}" + url = URI("#{relay_host}/xrpc/com.atproto.sync.getLatestCommit") + url.query = URI.encode_www_form(:did => did) + + response = get_response(url, { timeout: 30, max_redirects: 5 }.merge(options)) + status = response.code.to_i + is_json = (response['Content-Type'] =~ /^application\/json(;.*)?$/) + + if status == 200 + true + elsif status == 400 && is_json && JSON.parse(response.body)['error'] == 'RepoNotFound' + false + elsif status == 404 && is_json && JSON.parse(response.body)['error'] + false + else + raise APIError.new(response) + end + end + + def account_exists? + doc = get_document + return false if doc.pds_endpoint.nil? + + pds_host = URI(doc.pds_endpoint).origin + is_known_by_relay?(pds_host, timeout: 10) + end + def ==(other) if other.is_a?(String) self.did == other diff --git a/lib/didkit/errors.rb b/lib/didkit/errors.rb index 3cd98c7..002d8f7 100644 --- a/lib/didkit/errors.rb +++ b/lib/didkit/errors.rb @@ -1,4 +1,21 @@ module DIDKit class DIDError < StandardError end + + class APIError < StandardError + attr_reader :response + + def initialize(response) + @response = response + super("APIError: #{response}") + end + + def status + response.code.to_i + end + + def body + response.body + end + end end