didkit 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ae1ff103a9695991ae3e0e97072c2b10731e7c18e44cfa5f715995ef0631df4f
4
- data.tar.gz: b2bc822873a7804515d3ad06caa6c15e4177943668f6bcbb79f8c48fa87e4733
3
+ metadata.gz: 7f394023d5e7e3f864041dc39e81d1e2730972b6bfe8f3c0a0d0178e27e6557e
4
+ data.tar.gz: e622af3eea9c05a7831c7b4630e16e0a879faede2a38b6605bb622d0ebb2eaf6
5
5
  SHA512:
6
- metadata.gz: 5e4bbd991480a0a98c13c514e52a65bdceafd1c1a4feb75d60db07b22af10f376edaaea89bd98122c94c902c718c241a01965abaa801433b2a48162bb86d6ec1
7
- data.tar.gz: 791481ed39520a72eb750e2d511f6017ca476a1386c15d6d6a667e2a170a7e63d0723e868b2d843c87d66d3d33306fcc6bd5cd3d359cbea8e213e6ba8a401f99
6
+ metadata.gz: 1dd40553f1f96d93bb746d1cfc628d3f4a2a34df99634a88775c3673f4ef721c2e13f85110e7a3a0b2880f29ffcbe7da21838378cdd04a3ea346a7ab2ccb2bfc
7
+ data.tar.gz: f32fc83842dcd9a1bf88817aa8a286f5a1bdf42004416f74ec2450104388426456c2d16b598ba4439d9cb6c13f5035d800df2abada369656ac0c883797f05d1d
data/CHANGELOG.md CHANGED
@@ -1,3 +1,26 @@
1
+ ## [0.3.0] - 2025-12-15
2
+
3
+ Breaking changes:
4
+
5
+ * removed `DID#is_known_by_relay?` – it doesn't work anymore, since relays are now non-archival and they expose almost no XRPC routes
6
+ * renamed a few handle-related methods:
7
+ - `get_validated_handle` -> `get_verified_handle`
8
+ - `pick_valid_handle` -> `first_verified_handle`
9
+
10
+ Also:
11
+
12
+ - added `DID#account_status` method, which checks `getRepoStatus` endpoint to tell if an account is active, deactivated, taken down etc.
13
+ - added `DID#account_active?` helper (`account_status == :active`)
14
+ - `DID#account_exists?` now calls `getRepoStatus` (via `account_status`, checking if it's not nil) instead of `getLatestCommit`
15
+ - added `DID#document` which keeps a memoized copy of the document
16
+ - added `pds_host` & `labeler_host` methods to `PLCOperation` and `Document`, which return the PDS/labeller address without the `https://`
17
+ - added `labeller_endpoint` & `labeller_host` aliases for the double-L enjoyers :]
18
+ - added `PLCOperation#cid`
19
+ - `PLCImporter` now removes duplicate operations at the edge of pages returned from the `/export` API
20
+ - rewritten some networking code – all classes now use `Net::HTTP` with consistent options instead of `open-uri`
21
+
22
+ Note: `PLCImporter` will be rewritten soon to add support for updated [plc.directory](https://plc.directory) APIs, so be prepared for some breaking changes there in v. 0.4.
23
+
1
24
  ## [0.2.3] - 2024-07-02
2
25
 
3
26
  - added a `DID#get_audit_log` method that fetches the PLC audit log for a DID
data/LICENSE.txt CHANGED
@@ -1,6 +1,6 @@
1
1
  The zlib License
2
2
 
3
- Copyright (c) 2023 Jakub Suder
3
+ Copyright (c) 2025 Jakub Suder
4
4
 
5
5
  This software is provided 'as-is', without any express or implied
6
6
  warranty. In no event will the authors be held liable for any damages
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  A small Ruby gem for handling Distributed Identifiers (DIDs) in Bluesky / AT Protocol.
4
4
 
5
5
  > [!NOTE]
6
- > ATProto Ruby gems collection: [skyfall](https://github.com/mackuba/skyfall) | [blue_factory](https://github.com/mackuba/blue_factory) | [minisky](https://github.com/mackuba/minisky) | [didkit](https://github.com/mackuba/didkit)
6
+ > Part of ATProto Ruby SDK: [ruby.sdk.blue](https://ruby.sdk.blue)
7
7
 
8
8
 
9
9
  ## What does it do
@@ -13,75 +13,99 @@ Accounts on Bluesky use identifiers like [did:plc:oio4hkxaop4ao4wz2pp3f4cr](http
13
13
 
14
14
  ## Installation
15
15
 
16
+ From the command line:
17
+
16
18
  gem install didkit
17
19
 
20
+ Or, add this to your `Gemfile`:
18
21
 
19
- ## Usage
22
+ gem 'didkit', '~> 0.3'
20
23
 
21
- Use the `DIDKit::Resolver` class to look up DIDs and handles.
22
24
 
23
- To look up a handle:
25
+ ## Usage
26
+
27
+ The simplest way to use the gem is through the `DIDKit::DID` class, aliased as just `DID`:
24
28
 
25
29
  ```rb
26
- resolver = DIDKit::Resolver.new
27
- resolver.resolve_handle('nytimes.com')
28
- # => #<DIDKit::DID:0x00000001035956b0 @did="did:plc:eclio37ymobqex2ncko63h4r", @type=:plc, @resolved_by=:dns>
30
+ did = DID.resolve_handle('jay.bsky.team')
31
+ # => #<DIDKit::DID:0x0... @did="did:plc:oky5czdrnfjpqslsw2a5iclo",
32
+ # @resolved_by=:dns, @type=:plc>
29
33
  ```
30
34
 
31
- This returns an object of `DIDKit::DID` class (aliased as just `DID`), which tells you:
35
+ This returns a `DID` object, which tells you:
32
36
 
33
37
  - the DID as a string (`#to_s` or `#did`)
34
38
  - the DID type (`#type`, `:plc` or `:web`)
35
39
  - if the handle was resolved via a DNS entry or a `.well-known` file (`#resolved_by`, `:dns` or `:http`)
36
40
 
37
- To go in the other direction – to find an assigned and verified handle given a DID – use `get_validated_handle` (pass DID as a string or an object):
41
+ To 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`:
38
42
 
39
43
  ```rb
40
- resolver.get_validated_handle('did:plc:ewvi7nxzyoun6zhxrhs64oiz')
41
- # => "atproto.com"
44
+ DID.new('did:plc:ewvi7nxzyoun6zhxrhs64oiz').get_verified_handle
45
+ # => "atproto.com"
42
46
  ```
43
47
 
44
- You can also load the DID document using `resolve_did`:
48
+ You 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):
45
49
 
46
50
  ```rb
47
- doc = resolver.resolve_did('did:plc:ragtjsm2j2vknwkz3zp4oxrd')
48
- # => #<DIDKit::Document:0x0000000105d751f8 @did=#<DIDKit::DID:...>, @json={...}>
51
+ did = DID.new('did:plc:ragtjsm2j2vknwkz3zp4oxrd')
49
52
 
50
- doc.handles
51
- # => ["pfrazee.com"]
53
+ did.document.handles
54
+ # => ["pfrazee.com"]
52
55
 
53
- doc.pds_endpoint
54
- # => "https://morel.us-east.host.bsky.network"
56
+ did.document.pds_host
57
+ # => "morel.us-east.host.bsky.network"
55
58
  ```
56
59
 
57
- There are also some helper methods in the `DID` class that create a `Resolver` for you to save you some typing:
60
+
61
+ ### Checking account status
62
+
63
+ `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:
58
64
 
59
65
  ```rb
60
- did = DID.resolve_handle('jay.bsky.team')
61
- # => #<DIDKit::DID:0x000000010615ed28 @did="did:plc:oky5czdrnfjpqslsw2a5iclo", @type=:plc, @resolved_by=:dns>
66
+ did = DID.new('did:plc:ch7azdejgddtlijyzurfdihn')
67
+ did.account_status
68
+ # => :takendown
69
+ did.account_active?
70
+ # => false
71
+ did.account_exists?
72
+ # => true
73
+
74
+ did = DID.new('did:plc:44ybard66vv44zksje25o7dz')
75
+ did.account_status
76
+ # => :active
77
+ did.account_active?
78
+ # => true
79
+ ```
62
80
 
63
- did.to_s
64
- # => "did:plc:oky5czdrnfjpqslsw2a5iclo"
81
+ ### Configuration
65
82
 
66
- did.get_document
67
- # => #<DIDKit::Document:0x00000001066d4898 @did=#<DIDKit::DID:...>, @json={...}>
83
+ You can customize some things about the DID/handle lookups by using the `DIDKit::Resolver` class, which the methods in `DID` use behind the scenes.
68
84
 
69
- did.get_validated_handle
70
- # => "jay.bsky.team"
71
- ```
85
+ Currently available options include:
72
86
 
87
+ - `:nameserver` - override the nameserver used for DNS lookups, e.g. to use Google's or CloudFlare's DNS
88
+ - `:timeout` - change the connection/response timeout for HTTP requests (default: 15 s)
89
+ - `:max_redirects` - change allowed maximum number of redirects (default: 5)
73
90
 
74
- ### Configuration
91
+ Example:
92
+
93
+ ```rb
94
+ resolver = DIDKit::Resolver.new(nameserver: '8.8.8.8', timeout: 30)
75
95
 
76
- You can override the nameserver used for DNS lookups by setting the `nameserver` property in `Resolver`, e.g. to use Google's or CloudFlare's global DNS:
96
+ did = resolver.resolve_handle('nytimes.com')
97
+ # => #<DIDKit::DID:0x0... @did="did:plc:eclio37ymobqex2ncko63h4r",
98
+ # @resolved_by=:dns, @type=:plc>
77
99
 
78
- ```
79
- resolver.nameserver = '8.8.8.8'
80
- ```
100
+ resolver.resolve_did(did)
101
+ # => #<DIDKit::Document:0x0... @did=#<DIDKit::DID:...>, @json={...}>
81
102
 
103
+ resolver.get_verified_handle(did)
104
+ # => 'nytimes.com'
105
+ ```
82
106
 
83
107
  ## Credits
84
108
 
85
- Copyright © 2024 Kuba Suder ([@mackuba.eu](https://bsky.app/profile/mackuba.eu)).
109
+ Copyright © 2025 Kuba Suder ([@mackuba.eu](https://bsky.app/profile/did:plc:oio4hkxaop4ao4wz2pp3f4cr)).
86
110
 
87
111
  The code is available under the terms of the [zlib license](https://choosealicense.com/licenses/zlib/) (permissive, similar to MIT).
data/lib/didkit/did.rb CHANGED
@@ -1,3 +1,6 @@
1
+ require 'json'
2
+ require 'uri'
3
+
1
4
  require_relative 'errors'
2
5
  require_relative 'requests'
3
6
  require_relative 'resolver'
@@ -29,12 +32,16 @@ module DIDKit
29
32
 
30
33
  alias to_s did
31
34
 
35
+ def document
36
+ @document ||= get_document
37
+ end
38
+
32
39
  def get_document
33
40
  Resolver.new.resolve_did(self)
34
41
  end
35
42
 
36
- def get_validated_handle
37
- Resolver.new.get_validated_handle(self)
43
+ def get_verified_handle
44
+ Resolver.new.get_verified_handle(document)
38
45
  end
39
46
 
40
47
  def get_audit_log
@@ -49,32 +56,41 @@ module DIDKit
49
56
  did.gsub(/^did\:web\:/, '') if type == :web
50
57
  end
51
58
 
52
- def is_known_by_relay?(relay, options = {})
53
- relay_host = relay.include?('://') ? URI(relay).origin : "https://#{relay}"
54
- url = URI("#{relay_host}/xrpc/com.atproto.sync.getLatestCommit")
55
- url.query = URI.encode_www_form(:did => did)
59
+ def account_status(request_options = {})
60
+ doc = self.document
61
+ return nil if doc.pds_endpoint.nil?
56
62
 
57
- response = get_response(url, { timeout: 30, max_redirects: 5 }.merge(options))
63
+ pds_host = URI(doc.pds_endpoint).origin
64
+ url = URI("#{pds_host}/xrpc/com.atproto.sync.getRepoStatus")
65
+ url.query = URI.encode_www_form(:did => @did)
66
+
67
+ response = get_response(url, request_options)
58
68
  status = response.code.to_i
59
69
  is_json = (response['Content-Type'] =~ /^application\/json(;.*)?$/)
60
70
 
61
- if status == 200
62
- true
71
+ if status == 200 && is_json
72
+ json = JSON.parse(response.body)
73
+
74
+ if json['active'] == true
75
+ :active
76
+ elsif json['active'] == false && json['status'].is_a?(String) && json['status'].length <= 100
77
+ json['status'].to_sym
78
+ else
79
+ raise APIError.new(response)
80
+ end
63
81
  elsif status == 400 && is_json && JSON.parse(response.body)['error'] == 'RepoNotFound'
64
- false
65
- elsif status == 404 && is_json && JSON.parse(response.body)['error']
66
- false
82
+ nil
67
83
  else
68
84
  raise APIError.new(response)
69
85
  end
70
86
  end
71
87
 
72
- def account_exists?
73
- doc = get_document
74
- return false if doc.pds_endpoint.nil?
88
+ def account_active?
89
+ account_status == :active
90
+ end
75
91
 
76
- pds_host = URI(doc.pds_endpoint).origin
77
- is_known_by_relay?(pds_host, timeout: 10)
92
+ def account_exists?
93
+ account_status != nil
78
94
  end
79
95
 
80
96
  def ==(other)
@@ -37,8 +37,8 @@ module DIDKit
37
37
  @handles = parse_also_known_as(json['alsoKnownAs'] || [])
38
38
  end
39
39
 
40
- def get_validated_handle
41
- Resolver.new.pick_valid_handle(did, handles)
40
+ def get_verified_handle
41
+ Resolver.new.get_verified_handle(self)
42
42
  end
43
43
  end
44
44
  end
@@ -1,14 +1,22 @@
1
1
  require 'json'
2
- require 'open-uri'
3
2
  require 'time'
3
+ require 'uri'
4
4
 
5
5
  require_relative 'plc_operation'
6
+ require_relative 'requests'
7
+
8
+ #
9
+ # NOTE: this class is pending a rewrite once new APIs are deployed to plc.directory.
10
+ # Things will change here in v. 0.4.
11
+ #
6
12
 
7
13
  module DIDKit
8
14
  class PLCImporter
9
15
  PLC_SERVICE = 'plc.directory'
10
16
  MAX_PAGE = 1000
11
17
 
18
+ include Requests
19
+
12
20
  attr_accessor :ignore_errors, :last_date, :error_handler
13
21
 
14
22
  def initialize(since: nil)
@@ -22,6 +30,8 @@ module DIDKit
22
30
  @last_date = Time.now
23
31
  @eof = true
24
32
  end
33
+
34
+ @last_page_cids = []
25
35
  end
26
36
 
27
37
  def plc_service
@@ -42,13 +52,13 @@ module DIDKit
42
52
  url = URI("https://#{plc_service}/export")
43
53
  url.query = URI.encode_www_form(args)
44
54
 
45
- data = URI.open(url).read
55
+ data = get_data(url, content_type: 'application/jsonlines')
46
56
  data.lines.map(&:strip).reject(&:empty?).map { |x| JSON.parse(x) }
47
57
  end
48
58
 
49
59
  def fetch_audit_log(did)
50
- response = URI.open("https://#{plc_service}/#{did}/log/audit").read
51
- JSON.parse(response).map { |j| PLCOperation.new(j) }
60
+ json = get_json("https://#{plc_service}/#{did}/log/audit", :content_type => :json)
61
+ json.map { |j| PLCOperation.new(j) }
52
62
  end
53
63
 
54
64
  def fetch_page
@@ -57,16 +67,22 @@ module DIDKit
57
67
  query = @last_date ? { :after => @last_date.utc.iso8601(6) } : {}
58
68
  rows = get_export(query)
59
69
 
60
- operations = rows.filter_map do |json|
70
+ operations = rows.filter_map { |json|
61
71
  begin
62
72
  PLCOperation.new(json)
63
73
  rescue PLCOperation::FormatError, AtHandles::FormatError, ServiceRecord::FormatError => e
64
74
  @error_handler ? @error_handler.call(e, json) : raise
65
75
  nil
66
76
  end
67
- end
77
+ }.reject { |op|
78
+ # when you pass the most recent op's timestamp to ?after, it will be returned as the first op again,
79
+ # so we need to use this CID list to filter it out (so pages will usually be 999 items long)
80
+
81
+ @last_page_cids.include?(op.cid)
82
+ }
68
83
 
69
84
  @last_date = operations.last&.created_at || request_time
85
+ @last_page_cids = Set.new(operations.map(&:cid))
70
86
  @eof = (rows.length < MAX_PAGE)
71
87
 
72
88
  operations
@@ -12,7 +12,7 @@ module DIDKit
12
12
  include AtHandles
13
13
  include Services
14
14
 
15
- attr_reader :json, :did, :created_at, :type, :handles, :services
15
+ attr_reader :json, :did, :cid, :created_at, :type, :handles, :services
16
16
 
17
17
  def initialize(json)
18
18
  @json = json
@@ -20,6 +20,10 @@ module DIDKit
20
20
  raise FormatError, "Missing DID: #{json}" if @did.nil?
21
21
  raise FormatError, "Invalid DID: #{@did}" unless @did.is_a?(String) && @did.start_with?('did:')
22
22
 
23
+ @cid = json['cid']
24
+ raise FormatError, "Missing CID: #{json}" if @cid.nil?
25
+ raise FormatError, "Invalid CID: #{@cid}" unless @cid.is_a?(String)
26
+
23
27
  timestamp = json['createdAt']
24
28
  raise FormatError, "Missing createdAt: #{json}" if timestamp.nil?
25
29
  raise FormatError, "Invalid createdAt: #{timestamp.inspect}" unless timestamp.is_a?(String)
@@ -1,27 +1,77 @@
1
- module DIDKit::Requests
2
- def get_response(url, options = {})
3
- url = URI(url) unless url.is_a?(URI)
4
- request_options = { use_ssl: true }
5
-
6
- if timeout = options[:timeout]
7
- request_options[:open_timeout] = timeout
8
- request_options[:read_timeout] = timeout
1
+ require 'json'
2
+ require 'net/http'
3
+ require 'uri'
4
+
5
+ require_relative 'errors'
6
+
7
+ module DIDKit
8
+ module Requests
9
+ def get_response(url, options = {})
10
+ url = URI(url) unless url.is_a?(URI)
11
+
12
+ timeout = options[:timeout] || 15
13
+
14
+ request_options = {
15
+ use_ssl: true,
16
+ open_timeout: timeout,
17
+ read_timeout: timeout
18
+ }
19
+
20
+ redirects = 0
21
+ visited_urls = []
22
+ max_redirects = options[:max_redirects] || 5
23
+
24
+ loop do
25
+ visited_urls << url
26
+
27
+ response = Net::HTTP.start(url.host, url.port, request_options) do |http|
28
+ request = Net::HTTP::Get.new(url)
29
+ http.request(request)
30
+ end
31
+
32
+ if response.is_a?(Net::HTTPRedirection) && redirects < max_redirects && (location = response['Location'])
33
+ url = URI(location.include?('://') ? location : (url.origin + location))
34
+
35
+ if visited_urls.include?(url)
36
+ return response
37
+ else
38
+ redirects += 1
39
+ end
40
+ else
41
+ return response
42
+ end
43
+ end
9
44
  end
10
45
 
11
- redirects = 0
12
- max_redirects = options[:max_redirects] || 0
46
+ def get_data(url, options = {})
47
+ content_type = options.delete(:content_type)
48
+ response = get_response(url, options)
13
49
 
14
- loop do
15
- response = Net::HTTP.start(url.host, url.port, request_options) do |http|
16
- request = Net::HTTP::Get.new(url)
17
- http.request(request)
50
+ if response.is_a?(Net::HTTPSuccess) && content_type_matches(response, content_type) && (data = response.body)
51
+ data
52
+ else
53
+ raise APIError.new(response)
18
54
  end
55
+ end
56
+
57
+ def get_json(url, options = {})
58
+ JSON.parse(get_data(url, options))
59
+ end
60
+
61
+ def content_type_matches(response, expected_type)
62
+ content_type = response['Content-Type']
19
63
 
20
- if response.is_a?(Net::HTTPRedirection) && redirects < max_redirects && (location = response['Location'])
21
- url = URI(location.include?('://') ? location : (url.origin + location))
22
- redirects += 1
64
+ case expected_type
65
+ when String
66
+ content_type == expected_type
67
+ when Regexp
68
+ content_type =~ expected_type
69
+ when :json
70
+ content_type =~ /^application\/json(;.*)?$/
71
+ when nil
72
+ true
23
73
  else
24
- return response
74
+ raise ArgumentError, "Invalid expected_type: #{expected_type.inspect}"
25
75
  end
26
76
  end
27
77
  end
@@ -1,5 +1,3 @@
1
- require 'json'
2
- require 'open-uri'
3
1
  require 'net/http'
4
2
  require 'resolv'
5
3
 
@@ -10,7 +8,6 @@ require_relative 'requests'
10
8
  module DIDKit
11
9
  class Resolver
12
10
  RESERVED_DOMAINS = %w(alt arpa example internal invalid local localhost onion test)
13
- MAX_REDIRECTS = 5
14
11
 
15
12
  include Requests
16
13
 
@@ -18,6 +15,7 @@ module DIDKit
18
15
 
19
16
  def initialize(options = {})
20
17
  @nameserver = options[:nameserver]
18
+ @request_options = options.slice(:timeout, :max_redirects)
21
19
  end
22
20
 
23
21
  def resolve_handle(handle)
@@ -50,7 +48,7 @@ module DIDKit
50
48
 
51
49
  def resolve_handle_by_well_known(domain)
52
50
  url = "https://#{domain}/.well-known/atproto-did"
53
- response = get_response(url, timeout: 10, max_redirects: MAX_REDIRECTS)
51
+ response = get_response(url, @request_options)
54
52
 
55
53
  if response.is_a?(Net::HTTPSuccess) && (text = response.body)
56
54
  return parse_did_from_well_known(text)
@@ -83,25 +81,23 @@ module DIDKit
83
81
  end
84
82
 
85
83
  def resolve_did_plc(did)
86
- url = "https://plc.directory/#{did}"
87
- json = JSON.parse(URI.open(url).read)
84
+ json = get_json("https://plc.directory/#{did}", content_type: /^application\/did\+ld\+json(;.+)?$/)
88
85
  Document.new(did, json)
89
86
  end
90
87
 
91
88
  def resolve_did_web(did)
92
- url = "https://#{did.web_domain}/.well-known/did.json"
93
- json = JSON.parse(URI.open(url).read)
89
+ json = get_json("https://#{did.web_domain}/.well-known/did.json")
94
90
  Document.new(did, json)
95
91
  end
96
92
 
97
- def get_validated_handle(did_or_doc)
98
- document = did_or_doc.is_a?(Document) ? did_or_doc : resolve_did(did_or_doc)
93
+ def get_verified_handle(subject)
94
+ document = subject.is_a?(Document) ? subject : resolve_did(subject)
99
95
 
100
- pick_valid_handle(document.did, document.handles)
96
+ first_verified_handle(document.did, document.handles)
101
97
  end
102
98
 
103
- def pick_valid_handle(did, handles)
104
- handles.detect { |h| resolve_handle(h) == did }
99
+ def first_verified_handle(did, handles)
100
+ handles.detect { |h| resolve_handle(h) == did.to_s }
105
101
  end
106
102
  end
107
103
  end
@@ -1,3 +1,5 @@
1
+ require 'uri'
2
+
1
3
  module DIDKit
2
4
  module Services
3
5
  def get_service(key, type)
@@ -11,5 +13,16 @@ module DIDKit
11
13
  def labeler_endpoint
12
14
  @labeler_endpoint ||= get_service('atproto_labeler', 'AtprotoLabeler')&.endpoint
13
15
  end
16
+
17
+ def pds_host
18
+ pds_endpoint&.then { |x| URI(x).host }
19
+ end
20
+
21
+ def labeler_host
22
+ labeler_endpoint&.then { |x| URI(x).host }
23
+ end
24
+
25
+ alias labeller_endpoint labeler_endpoint
26
+ alias labeller_host labeler_host
14
27
  end
15
28
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DIDKit
4
- VERSION = "0.2.3"
4
+ VERSION = "0.3.0"
5
5
  end
metadata CHANGED
@@ -1,16 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: didkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kuba Suder
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-07-02 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies: []
13
- description:
14
12
  email:
15
13
  - jakub.suder@gmail.com
16
14
  executables: []
@@ -40,7 +38,6 @@ metadata:
40
38
  bug_tracker_uri: https://github.com/mackuba/didkit/issues
41
39
  changelog_uri: https://github.com/mackuba/didkit/blob/master/CHANGELOG.md
42
40
  source_code_uri: https://github.com/mackuba/didkit
43
- post_install_message:
44
41
  rdoc_options: []
45
42
  require_paths:
46
43
  - lib
@@ -55,8 +52,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
55
52
  - !ruby/object:Gem::Version
56
53
  version: '0'
57
54
  requirements: []
58
- rubygems_version: 3.4.10
59
- signing_key:
55
+ rubygems_version: 3.6.9
60
56
  specification_version: 4
61
57
  summary: A library for handling Distributed ID (DID) identifiers used in Bluesky AT
62
58
  Protocol